upgrade to new data structure
This commit is contained in:
parent
d48986ea78
commit
5fa8c46efc
@ -1,6 +1,6 @@
|
|||||||
package de.marhali.easyi18n;
|
package de.marhali.easyi18n;
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.BusListener;
|
import de.marhali.easyi18n.model.bus.BusListener;
|
||||||
import de.marhali.easyi18n.model.TranslationData;
|
import de.marhali.easyi18n.model.TranslationData;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -4,7 +4,7 @@ import com.intellij.icons.AllIcons;
|
|||||||
import com.intellij.openapi.actionSystem.AnAction;
|
import com.intellij.openapi.actionSystem.AnAction;
|
||||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
import de.marhali.easyi18n.InstanceManager;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -23,6 +23,6 @@ public class ReloadAction extends AnAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||||
LegacyDataStore.getInstance(e.getProject()).reloadFromDisk();
|
InstanceManager.get(e.getProject()).store().loadFromPersistenceLayer((success) -> {});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,8 +7,9 @@ import com.intellij.ui.components.JBLabel;
|
|||||||
import com.intellij.ui.components.JBScrollPane;
|
import com.intellij.ui.components.JBScrollPane;
|
||||||
import com.intellij.ui.components.JBTextField;
|
import com.intellij.ui.components.JBTextField;
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
import de.marhali.easyi18n.InstanceManager;
|
||||||
import de.marhali.easyi18n.model.LegacyKeyedTranslation;
|
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||||
|
import de.marhali.easyi18n.model.Translation;
|
||||||
import de.marhali.easyi18n.model.TranslationCreate;
|
import de.marhali.easyi18n.model.TranslationCreate;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@ -48,16 +49,16 @@ public class AddDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void saveTranslation() {
|
private void saveTranslation() {
|
||||||
Map<String, String> messages = new HashMap<>();
|
Translation translation = new Translation();
|
||||||
|
|
||||||
valueTextFields.forEach((k, v) -> {
|
valueTextFields.forEach((k, v) -> {
|
||||||
if(!v.getText().isEmpty()) {
|
if(!v.getText().isEmpty()) {
|
||||||
messages.put(k, v.getText());
|
translation.put(k, v.getText());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
TranslationCreate creation = new TranslationCreate(new LegacyKeyedTranslation(keyTextField.getText(), messages));
|
TranslationCreate creation = new TranslationCreate(new KeyedTranslation(keyTextField.getText(), translation));
|
||||||
LegacyDataStore.getInstance(project).processUpdate(creation);
|
InstanceManager.get(project).processUpdate(creation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DialogBuilder prepare() {
|
private DialogBuilder prepare() {
|
||||||
@ -75,7 +76,8 @@ public class AddDialog {
|
|||||||
|
|
||||||
JPanel valuePanel = new JPanel(new GridLayout(0, 1, 2, 2));
|
JPanel valuePanel = new JPanel(new GridLayout(0, 1, 2, 2));
|
||||||
valueTextFields = new HashMap<>();
|
valueTextFields = new HashMap<>();
|
||||||
for(String locale : LegacyDataStore.getInstance(project).getTranslations().getLocales()) {
|
|
||||||
|
for(String locale : InstanceManager.get(project).store().getData().getLocales()) {
|
||||||
JBLabel localeLabel = new JBLabel(locale);
|
JBLabel localeLabel = new JBLabel(locale);
|
||||||
JBTextField localeText = new JBTextField();
|
JBTextField localeText = new JBTextField();
|
||||||
localeLabel.setLabelFor(localeText);
|
localeLabel.setLabelFor(localeText);
|
||||||
|
@ -6,11 +6,12 @@ import com.intellij.openapi.ui.DialogWrapper;
|
|||||||
import com.intellij.ui.components.JBLabel;
|
import com.intellij.ui.components.JBLabel;
|
||||||
import com.intellij.ui.components.JBScrollPane;
|
import com.intellij.ui.components.JBScrollPane;
|
||||||
import com.intellij.ui.components.JBTextField;
|
import com.intellij.ui.components.JBTextField;
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
import de.marhali.easyi18n.InstanceManager;
|
||||||
import de.marhali.easyi18n.model.LegacyKeyedTranslation;
|
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||||
|
import de.marhali.easyi18n.model.Translation;
|
||||||
import de.marhali.easyi18n.model.TranslationDelete;
|
import de.marhali.easyi18n.model.TranslationDelete;
|
||||||
import de.marhali.easyi18n.model.LegacyTranslationUpdate;
|
|
||||||
import de.marhali.easyi18n.dialog.descriptor.DeleteActionDescriptor;
|
import de.marhali.easyi18n.dialog.descriptor.DeleteActionDescriptor;
|
||||||
|
import de.marhali.easyi18n.model.TranslationUpdate;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.EtchedBorder;
|
import javax.swing.border.EtchedBorder;
|
||||||
@ -26,12 +27,12 @@ import java.util.ResourceBundle;
|
|||||||
public class EditDialog {
|
public class EditDialog {
|
||||||
|
|
||||||
private final Project project;
|
private final Project project;
|
||||||
private final LegacyKeyedTranslation origin;
|
private final KeyedTranslation origin;
|
||||||
|
|
||||||
private JBTextField keyTextField;
|
private JBTextField keyTextField;
|
||||||
private Map<String, JBTextField> valueTextFields;
|
private Map<String, JBTextField> valueTextFields;
|
||||||
|
|
||||||
public EditDialog(Project project, LegacyKeyedTranslation origin) {
|
public EditDialog(Project project, KeyedTranslation origin) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
}
|
}
|
||||||
@ -40,23 +41,22 @@ public class EditDialog {
|
|||||||
int code = prepare().show();
|
int code = prepare().show();
|
||||||
|
|
||||||
if(code == DialogWrapper.OK_EXIT_CODE) { // Edit
|
if(code == DialogWrapper.OK_EXIT_CODE) { // Edit
|
||||||
LegacyDataStore.getInstance(project).processUpdate(new LegacyTranslationUpdate(origin, getChanges()));
|
InstanceManager.get(project).processUpdate(new TranslationUpdate(origin, getChanges()));
|
||||||
|
|
||||||
} else if(code == DeleteActionDescriptor.EXIT_CODE) { // Delete
|
} else if(code == DeleteActionDescriptor.EXIT_CODE) { // Delete
|
||||||
LegacyDataStore.getInstance(project).processUpdate(new TranslationDelete(origin));
|
InstanceManager.get(project).processUpdate(new TranslationDelete(origin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LegacyKeyedTranslation getChanges() {
|
private KeyedTranslation getChanges() {
|
||||||
Map<String, String> messages = new HashMap<>();
|
Translation translation = new Translation();
|
||||||
|
|
||||||
valueTextFields.forEach((k, v) -> {
|
valueTextFields.forEach((k, v) -> {
|
||||||
if(!v.getText().isEmpty()) {
|
if(!v.getText().isEmpty()) {
|
||||||
messages.put(k, v.getText());
|
translation.put(k, v.getText());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new LegacyKeyedTranslation(keyTextField.getText(), messages);
|
return new KeyedTranslation(keyTextField.getText(), translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DialogBuilder prepare() {
|
private DialogBuilder prepare() {
|
||||||
@ -74,9 +74,10 @@ public class EditDialog {
|
|||||||
|
|
||||||
JPanel valuePanel = new JPanel(new GridLayout(0, 1, 2, 2));
|
JPanel valuePanel = new JPanel(new GridLayout(0, 1, 2, 2));
|
||||||
valueTextFields = new HashMap<>();
|
valueTextFields = new HashMap<>();
|
||||||
for(String locale : LegacyDataStore.getInstance(project).getTranslations().getLocales()) {
|
|
||||||
|
for(String locale : InstanceManager.get(project).store().getData().getLocales()) {
|
||||||
JBLabel localeLabel = new JBLabel(locale);
|
JBLabel localeLabel = new JBLabel(locale);
|
||||||
JBTextField localeText = new JBTextField(this.origin.getTranslations().get(locale));
|
JBTextField localeText = new JBTextField(this.origin.getTranslation().get(locale));
|
||||||
localeLabel.setLabelFor(localeText);
|
localeLabel.setLabelFor(localeText);
|
||||||
|
|
||||||
valuePanel.add(localeLabel);
|
valuePanel.add(localeLabel);
|
||||||
|
@ -9,9 +9,9 @@ import com.intellij.ui.components.JBCheckBox;
|
|||||||
import com.intellij.ui.components.JBLabel;
|
import com.intellij.ui.components.JBLabel;
|
||||||
import com.intellij.ui.components.JBTextField;
|
import com.intellij.ui.components.JBTextField;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.InstanceManager;
|
||||||
import de.marhali.easyi18n.model.SettingsState;
|
import de.marhali.easyi18n.model.SettingsState;
|
||||||
import de.marhali.easyi18n.service.SettingsService;
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@ -50,7 +50,7 @@ public class SettingsDialog {
|
|||||||
state.setCodeAssistance(codeAssistanceCheckbox.isSelected());
|
state.setCodeAssistance(codeAssistanceCheckbox.isSelected());
|
||||||
|
|
||||||
// Reload instance
|
// Reload instance
|
||||||
LegacyDataStore.getInstance(project).reloadFromDisk();
|
InstanceManager.get(project).store().loadFromPersistenceLayer((success) -> {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@ import com.intellij.lang.annotation.AnnotationHolder;
|
|||||||
import com.intellij.lang.annotation.HighlightSeverity;
|
import com.intellij.lang.annotation.HighlightSeverity;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
|
||||||
import de.marhali.easyi18n.service.SettingsService;
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -5,9 +5,7 @@ import com.intellij.codeInsight.lookup.*;
|
|||||||
import com.intellij.icons.AllIcons;
|
import com.intellij.icons.AllIcons;
|
||||||
import com.intellij.openapi.project.*;
|
import com.intellij.openapi.project.*;
|
||||||
import com.intellij.util.*;
|
import com.intellij.util.*;
|
||||||
import de.marhali.easyi18n.model.*;
|
|
||||||
import de.marhali.easyi18n.service.*;
|
import de.marhali.easyi18n.service.*;
|
||||||
import de.marhali.easyi18n.util.TranslationsUtil;
|
|
||||||
import org.jetbrains.annotations.*;
|
import org.jetbrains.annotations.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -6,9 +6,6 @@ import com.intellij.psi.impl.FakePsiElement;
|
|||||||
|
|
||||||
import de.marhali.easyi18n.dialog.AddDialog;
|
import de.marhali.easyi18n.dialog.AddDialog;
|
||||||
import de.marhali.easyi18n.dialog.EditDialog;
|
import de.marhali.easyi18n.dialog.EditDialog;
|
||||||
import de.marhali.easyi18n.model.LegacyKeyedTranslation;
|
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -5,7 +5,6 @@ import com.intellij.psi.*;
|
|||||||
import com.intellij.util.ProcessingContext;
|
import com.intellij.util.ProcessingContext;
|
||||||
|
|
||||||
import de.marhali.easyi18n.editor.KeyReference;
|
import de.marhali.easyi18n.editor.KeyReference;
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
|
||||||
import de.marhali.easyi18n.service.SettingsService;
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -6,7 +6,6 @@ import com.intellij.psi.*;
|
|||||||
import com.intellij.util.ProcessingContext;
|
import com.intellij.util.ProcessingContext;
|
||||||
|
|
||||||
import de.marhali.easyi18n.editor.KeyReference;
|
import de.marhali.easyi18n.editor.KeyReference;
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
|
||||||
import de.marhali.easyi18n.service.SettingsService;
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -2,8 +2,6 @@ package de.marhali.easyi18n.io;
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -7,10 +7,6 @@ import com.intellij.openapi.vfs.LocalFileSystem;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
import de.marhali.easyi18n.io.TranslatorIO;
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
import de.marhali.easyi18n.util.IOUtil;
|
|
||||||
import de.marhali.easyi18n.util.JsonUtil;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -10,10 +10,6 @@ import com.intellij.openapi.vfs.LocalFileSystem;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
import de.marhali.easyi18n.io.TranslatorIO;
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
import de.marhali.easyi18n.util.IOUtil;
|
|
||||||
import de.marhali.easyi18n.util.JsonUtil;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -6,12 +6,8 @@ import com.intellij.openapi.vfs.LocalFileSystem;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
import de.marhali.easyi18n.io.TranslatorIO;
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
import de.marhali.easyi18n.util.IOUtil;
|
|
||||||
import de.marhali.easyi18n.util.SortedProperties;
|
import de.marhali.easyi18n.util.SortedProperties;
|
||||||
import de.marhali.easyi18n.util.StringUtil;
|
import de.marhali.easyi18n.util.StringUtil;
|
||||||
import de.marhali.easyi18n.util.TranslationsUtil;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for communication of changes for participants of the data bus.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
public interface BusListener {
|
|
||||||
/**
|
|
||||||
* Update the translations based on the supplied data.
|
|
||||||
* @param data Updated translations
|
|
||||||
*/
|
|
||||||
void onUpdateData(@NotNull TranslationData data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move the specified translation key (full-key) into focus.
|
|
||||||
* @param key Absolute translation key
|
|
||||||
*/
|
|
||||||
void onFocusKey(@Nullable String key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter the displayed data according to the search query. Supply 'null' to return to the normal state.
|
|
||||||
* The keys and the content itself should be considered.
|
|
||||||
* @param query Filter key or content
|
|
||||||
*/
|
|
||||||
void onSearchQuery(@Nullable String query);
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface to communicate data changes between data store and ui components.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface DataSynchronizer {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Propagates data changes to implementation classes.
|
|
||||||
* @param translations Updated translations model
|
|
||||||
* @param searchQuery Can be used to filter visible data. Like a search function for the full key path
|
|
||||||
* @param scrollToKey Focus specific translation. Can be null to disable this function
|
|
||||||
*/
|
|
||||||
void synchronize(@NotNull Translations translations, @Nullable String searchQuery, @Nullable String scrollToKey);
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translated messages for a dedicated key.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated // Might be deprecated
|
|
||||||
public class LegacyKeyedTranslation {
|
|
||||||
|
|
||||||
private String key;
|
|
||||||
private Map<String, String> translations;
|
|
||||||
|
|
||||||
public LegacyKeyedTranslation(String key, Map<String, String> translations) {
|
|
||||||
this.key = key;
|
|
||||||
this.translations = translations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKey(String key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getTranslations() {
|
|
||||||
return translations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTranslations(Map<String, String> translations) {
|
|
||||||
this.translations = translations;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "KeyedTranslation{" +
|
|
||||||
"key='" + key + '\'' +
|
|
||||||
", translations=" + translations +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an update for a translated I18n-Key. Supports key creation, manipulation and deletion.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class LegacyTranslationUpdate {
|
|
||||||
|
|
||||||
private final @Nullable LegacyKeyedTranslation origin;
|
|
||||||
private final @Nullable LegacyKeyedTranslation change;
|
|
||||||
|
|
||||||
public LegacyTranslationUpdate(@Nullable LegacyKeyedTranslation origin, @Nullable LegacyKeyedTranslation change) {
|
|
||||||
this.origin = origin;
|
|
||||||
this.change = change;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LegacyKeyedTranslation getOrigin() {
|
|
||||||
return origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LegacyKeyedTranslation getChange() {
|
|
||||||
return change;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCreation() {
|
|
||||||
return origin == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDeletion() {
|
|
||||||
return change == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isKeyChange() {
|
|
||||||
return origin != null && change != null && !origin.getKey().equals(change.getKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "TranslationUpdate{" +
|
|
||||||
"origin=" + origin +
|
|
||||||
", change=" + change +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.util.MapUtil;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents structured tree view for translated messages.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class LocalizedNode {
|
|
||||||
|
|
||||||
public static final String ROOT_KEY = "root";
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final String key;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private TreeMap<String, LocalizedNode> children;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Map<String, String> value;
|
|
||||||
|
|
||||||
public LocalizedNode(@NotNull String key, @NotNull List<LocalizedNode> children) {
|
|
||||||
this.key = key;
|
|
||||||
this.children = MapUtil.convertToTreeMap(children);
|
|
||||||
this.value = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalizedNode(@NotNull String key, @NotNull Map<String, String> value) {
|
|
||||||
this.key = key;
|
|
||||||
this.children = new TreeMap<>();
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLeaf() {
|
|
||||||
return children.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull Collection<LocalizedNode> getChildren() {
|
|
||||||
return children.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable LocalizedNode getChildren(@NotNull String key) {
|
|
||||||
return children.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildren(@NotNull LocalizedNode... children) {
|
|
||||||
this.value.clear();
|
|
||||||
this.children = MapUtil.convertToTreeMap(Arrays.asList(children));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addChildren(@NotNull LocalizedNode... children) {
|
|
||||||
this.value.clear();
|
|
||||||
Arrays.stream(children).forEach(e -> this.children.put(e.getKey(), e));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeChildren(@NotNull String key) {
|
|
||||||
this.children.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull Map<String, String> getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(@NotNull Map<String, String> value) {
|
|
||||||
this.children.clear();
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,8 +6,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* Represents update request to create a new translation.
|
* Represents update request to create a new translation.
|
||||||
* @author marhali
|
* @author marhali
|
||||||
*/
|
*/
|
||||||
public class TranslationCreate extends LegacyTranslationUpdate {
|
public class TranslationCreate extends TranslationUpdate {
|
||||||
public TranslationCreate(@NotNull LegacyKeyedTranslation translation) {
|
public TranslationCreate(@NotNull KeyedTranslation translation) {
|
||||||
super(null, translation);
|
super(null, translation);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,8 +6,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* Represents update request to delete a existing translation.
|
* Represents update request to delete a existing translation.
|
||||||
* @author marhali
|
* @author marhali
|
||||||
*/
|
*/
|
||||||
public class TranslationDelete extends LegacyTranslationUpdate {
|
public class TranslationDelete extends TranslationUpdate {
|
||||||
public TranslationDelete(@NotNull LegacyKeyedTranslation translation) {
|
public TranslationDelete(@NotNull KeyedTranslation translation) {
|
||||||
super(translation, null);
|
super(translation, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,109 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.util.TranslationsUtil;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents translation state instance. IO operations will be based on this file.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class Translations {
|
|
||||||
|
|
||||||
public static Translations empty() {
|
|
||||||
return new Translations(new ArrayList<>(), new LocalizedNode(LocalizedNode.ROOT_KEY, new ArrayList<>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final List<String> locales;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final LocalizedNode nodes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new translation state instance.
|
|
||||||
* @param locales List of all locales which are used for create / edit I18n-Key operations
|
|
||||||
* @param nodes Represents the translation state. Internally handled as a tree. See {@link LocalizedNode}
|
|
||||||
*/
|
|
||||||
public Translations(@NotNull List<String> locales, @NotNull LocalizedNode nodes) {
|
|
||||||
this.locales = locales;
|
|
||||||
this.nodes = nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull List<String> getLocales() {
|
|
||||||
return locales;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull LocalizedNode getNodes() {
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable LocalizedNode getNode(@NotNull String fullPath) {
|
|
||||||
List<String> sections = TranslationsUtil.getSections(fullPath);
|
|
||||||
|
|
||||||
LocalizedNode node = nodes;
|
|
||||||
|
|
||||||
for(String section : sections) {
|
|
||||||
if(node == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
node = node.getChildren(section);
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull LocalizedNode getOrCreateNode(@NotNull String fullPath) {
|
|
||||||
List<String> sections = TranslationsUtil.getSections(fullPath);
|
|
||||||
|
|
||||||
LocalizedNode node = nodes;
|
|
||||||
|
|
||||||
for(String section : sections) {
|
|
||||||
LocalizedNode subNode = node.getChildren(section);
|
|
||||||
|
|
||||||
if(subNode == null) {
|
|
||||||
subNode = new LocalizedNode(section, new ArrayList<>());
|
|
||||||
node.addChildren(subNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = subNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull List<String> getFullKeys() {
|
|
||||||
List<String> keys = new ArrayList<>();
|
|
||||||
|
|
||||||
if(nodes.isLeaf()) { // Root has no children
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(LocalizedNode children : nodes.getChildren()) {
|
|
||||||
keys.addAll(getFullKeys("", children));
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull List<String> getFullKeys(String parentFullPath, LocalizedNode localizedNode) {
|
|
||||||
List<String> keys = new ArrayList<>();
|
|
||||||
|
|
||||||
if(localizedNode.isLeaf()) {
|
|
||||||
keys.add(parentFullPath + (parentFullPath.isEmpty() ? "" : ".") + localizedNode.getKey());
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(LocalizedNode children : localizedNode.getChildren()) {
|
|
||||||
String childrenPath = parentFullPath + (parentFullPath.isEmpty() ? "" : ".") + localizedNode.getKey();
|
|
||||||
keys.addAll(getFullKeys(childrenPath, children));
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,8 @@
|
|||||||
|
package de.marhali.easyi18n.model.bus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for communication of changes for participants of the data bus.
|
||||||
|
* Every listener needs to be registered manually via {@link de.marhali.easyi18n.DataBus}.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public interface BusListener extends UpdateDataListener, FocusKeyListener, SearchQueryListener {}
|
@ -0,0 +1,15 @@
|
|||||||
|
package de.marhali.easyi18n.model.bus;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single event listener.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public interface FocusKeyListener {
|
||||||
|
/**
|
||||||
|
* Move the specified translation key (full-key) into focus.
|
||||||
|
* @param key Absolute translation key
|
||||||
|
*/
|
||||||
|
void onFocusKey(@Nullable String key);
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package de.marhali.easyi18n.model.bus;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single event listener.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public interface SearchQueryListener {
|
||||||
|
/**
|
||||||
|
* Filter the displayed data according to the search query. Supply 'null' to return to the normal state.
|
||||||
|
* The keys and the content itself should be considered.
|
||||||
|
* @param query Filter key or content
|
||||||
|
*/
|
||||||
|
void onSearchQuery(@Nullable String query);
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package de.marhali.easyi18n.model.bus;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.model.TranslationData;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single event listener.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public interface UpdateDataListener {
|
||||||
|
/**
|
||||||
|
* Update the translations based on the supplied data.
|
||||||
|
* @param data Updated translations
|
||||||
|
*/
|
||||||
|
void onUpdateData(@NotNull TranslationData data);
|
||||||
|
}
|
@ -1,10 +1,5 @@
|
|||||||
package de.marhali.easyi18n.model.table;
|
package de.marhali.easyi18n.model.table;
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.model.LegacyKeyedTranslation;
|
|
||||||
import de.marhali.easyi18n.model.LegacyTranslationUpdate;
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nls;
|
import org.jetbrains.annotations.Nls;
|
||||||
|
|
||||||
import javax.swing.event.TableModelListener;
|
import javax.swing.event.TableModelListener;
|
||||||
|
@ -5,9 +5,6 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.ui.JBColor;
|
import com.intellij.ui.JBColor;
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.SettingsService;
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
import de.marhali.easyi18n.util.TranslationsUtil;
|
|
||||||
import de.marhali.easyi18n.util.UiUtil;
|
import de.marhali.easyi18n.util.UiUtil;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -1,174 +0,0 @@
|
|||||||
package de.marhali.easyi18n.service;
|
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
|
||||||
import com.intellij.openapi.application.ModalityState;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
|
||||||
import de.marhali.easyi18n.model.DataSynchronizer;
|
|
||||||
import de.marhali.easyi18n.model.LegacyKeyedTranslation;
|
|
||||||
import de.marhali.easyi18n.model.TranslationDelete;
|
|
||||||
import de.marhali.easyi18n.model.LegacyTranslationUpdate;
|
|
||||||
import de.marhali.easyi18n.util.IOUtil;
|
|
||||||
import de.marhali.easyi18n.util.TranslationsUtil;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory service to manage localized messages for multiple projects at once.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class LegacyDataStore {
|
|
||||||
|
|
||||||
private static final Map<Project, LegacyDataStore> INSTANCES = new WeakHashMap<>();
|
|
||||||
|
|
||||||
private final Project project;
|
|
||||||
private final List<DataSynchronizer> synchronizer;
|
|
||||||
|
|
||||||
private Translations translations;
|
|
||||||
private String searchQuery;
|
|
||||||
|
|
||||||
public static LegacyDataStore getInstance(@NotNull Project project) {
|
|
||||||
LegacyDataStore store = INSTANCES.get(project);
|
|
||||||
|
|
||||||
if(store == null) {
|
|
||||||
store = new LegacyDataStore(project);
|
|
||||||
INSTANCES.put(project, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LegacyDataStore(@NotNull Project project) {
|
|
||||||
this.project = project;
|
|
||||||
this.synchronizer = new ArrayList<>();
|
|
||||||
this.translations = Translations.empty();
|
|
||||||
|
|
||||||
// Load data after first initialization
|
|
||||||
ApplicationManager.getApplication().invokeLater(this::reloadFromDisk, ModalityState.NON_MODAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a new synchronizer which will receive {@link #translations} updates.
|
|
||||||
* @param synchronizer Synchronizer. See {@link DataSynchronizer}
|
|
||||||
*/
|
|
||||||
public void addSynchronizer(DataSynchronizer synchronizer) {
|
|
||||||
this.synchronizer.add(synchronizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads all translations from disk and overrides current {@link #translations} state.
|
|
||||||
*/
|
|
||||||
public void reloadFromDisk() {
|
|
||||||
String localesPath = SettingsService.getInstance(project).getState().getLocalesPath();
|
|
||||||
|
|
||||||
if(localesPath == null || localesPath.isEmpty()) {
|
|
||||||
// Propagate empty state
|
|
||||||
this.translations = Translations.empty();
|
|
||||||
synchronize(searchQuery, null);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
TranslatorIO io = IOUtil.determineFormat(project, localesPath);
|
|
||||||
|
|
||||||
io.read(project, localesPath, (loadedTranslations) -> {
|
|
||||||
this.translations = loadedTranslations == null ? Translations.empty() : loadedTranslations;
|
|
||||||
synchronize(searchQuery, null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves the current translation state to disk. See {@link TranslatorIO#save(Project, Translations, String, Consumer)}
|
|
||||||
* @param callback Complete callback. Indicates if operation was successful(true) or not
|
|
||||||
*/
|
|
||||||
public void saveToDisk(@NotNull Consumer<Boolean> callback) {
|
|
||||||
String localesPath = SettingsService.getInstance(project).getState().getLocalesPath();
|
|
||||||
|
|
||||||
if(localesPath == null || localesPath.isEmpty()) { // Cannot save without valid path
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TranslatorIO io = IOUtil.determineFormat(project, localesPath);
|
|
||||||
io.save(project, translations, localesPath, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Propagates provided search string to all synchronizer to display only relevant keys
|
|
||||||
* @param fullPath Full i18n key (e.g. user.username.title). Can be null to display all keys
|
|
||||||
*/
|
|
||||||
public void searchBeyKey(@Nullable String fullPath) {
|
|
||||||
// Use synchronizer to propagate search instance to all views
|
|
||||||
synchronize(this.searchQuery = fullPath, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes the provided update. Updates translation instance and propagates changes. See {@link DataSynchronizer}
|
|
||||||
* @param update The update to process. For more information see {@link LegacyTranslationUpdate}
|
|
||||||
*/
|
|
||||||
public void processUpdate(LegacyTranslationUpdate update) {
|
|
||||||
if(update.isDeletion() || update.isKeyChange()) { // Delete origin i18n key
|
|
||||||
String originKey = update.getOrigin().getKey();
|
|
||||||
List<String> sections = TranslationsUtil.getSections(originKey);
|
|
||||||
String nodeKey = sections.remove(sections.size() - 1); // Remove last node, which needs to be removed by parent
|
|
||||||
|
|
||||||
LocalizedNode node = translations.getNodes();
|
|
||||||
for(String section : sections) {
|
|
||||||
if(node == null) { // Might be possible on multi-delete
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
node = node.getChildren(section);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node != null) { // Only remove if parent exists. Might be already deleted on multi-delete
|
|
||||||
node.removeChildren(nodeKey);
|
|
||||||
|
|
||||||
// Parent is empty now, we need to remove it as well (except root)
|
|
||||||
if(node.getChildren().isEmpty() && !node.getKey().equals(LocalizedNode.ROOT_KEY)) {
|
|
||||||
processUpdate(new TranslationDelete(new LegacyKeyedTranslation(
|
|
||||||
TranslationsUtil.sectionsToFullPath(sections), null)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String scrollTo = update.isDeletion() ? null : update.getChange().getKey();
|
|
||||||
|
|
||||||
if(!update.isDeletion()) { // Recreate with changed val / create
|
|
||||||
LocalizedNode node = translations.getOrCreateNode(update.getChange().getKey());
|
|
||||||
node.setValue(update.getChange().getTranslations());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Persist changes and propagate them on success
|
|
||||||
saveToDisk(success -> {
|
|
||||||
if(success) {
|
|
||||||
synchronize(searchQuery, scrollTo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Current translation state
|
|
||||||
*/
|
|
||||||
public @NotNull Translations getTranslations() {
|
|
||||||
return translations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Synchronizes current translation's state to all connected subscribers.
|
|
||||||
* @param searchQuery Optional search by full key filter (ui view)
|
|
||||||
* @param scrollTo Optional scroll to full key (ui view)
|
|
||||||
*/
|
|
||||||
public void synchronize(@Nullable String searchQuery, @Nullable String scrollTo) {
|
|
||||||
synchronizer.forEach(subscriber -> subscriber.synchronize(this.translations, searchQuery, scrollTo));
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,8 +7,7 @@ import com.intellij.openapi.wm.ToolWindowFactory;
|
|||||||
import com.intellij.ui.content.Content;
|
import com.intellij.ui.content.Content;
|
||||||
import com.intellij.ui.content.ContentFactory;
|
import com.intellij.ui.content.ContentFactory;
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
import de.marhali.easyi18n.InstanceManager;
|
||||||
import de.marhali.easyi18n.service.WindowManager;
|
|
||||||
import de.marhali.easyi18n.action.*;
|
import de.marhali.easyi18n.action.*;
|
||||||
import de.marhali.easyi18n.tabs.TableView;
|
import de.marhali.easyi18n.tabs.TableView;
|
||||||
import de.marhali.easyi18n.tabs.TreeView;
|
import de.marhali.easyi18n.tabs.TreeView;
|
||||||
@ -48,16 +47,16 @@ public class TranslatorToolWindowFactory implements ToolWindowFactory {
|
|||||||
actions.add(new AddAction());
|
actions.add(new AddAction());
|
||||||
actions.add(new ReloadAction());
|
actions.add(new ReloadAction());
|
||||||
actions.add(new SettingsAction());
|
actions.add(new SettingsAction());
|
||||||
actions.add(new SearchAction((searchString) -> LegacyDataStore.getInstance(project).searchBeyKey(searchString)));
|
actions.add(new SearchAction((query) -> InstanceManager.get(project).bus().propagate().onSearchQuery(query)));
|
||||||
toolWindow.setTitleActions(actions);
|
toolWindow.setTitleActions(actions);
|
||||||
|
|
||||||
// Initialize Window Manager
|
// Initialize Window Manager
|
||||||
WindowManager.getInstance().initialize(toolWindow, treeView, tableView);
|
WindowManager.getInstance().initialize(toolWindow, treeView, tableView);
|
||||||
|
|
||||||
// Synchronize ui with underlying data
|
// Synchronize ui with underlying data
|
||||||
LegacyDataStore store = LegacyDataStore.getInstance(project);
|
InstanceManager manager = InstanceManager.get(project);
|
||||||
store.addSynchronizer(treeView);
|
manager.bus().addListener(treeView);
|
||||||
store.addSynchronizer(tableView);
|
manager.bus().addListener(tableView);
|
||||||
store.synchronize(null, null);
|
manager.bus().propagate().onUpdateData(manager.store().getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,17 +4,14 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.ui.components.JBScrollPane;
|
import com.intellij.ui.components.JBScrollPane;
|
||||||
import com.intellij.ui.table.JBTable;
|
import com.intellij.ui.table.JBTable;
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
import de.marhali.easyi18n.InstanceManager;
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
import de.marhali.easyi18n.model.*;
|
||||||
import de.marhali.easyi18n.model.DataSynchronizer;
|
|
||||||
import de.marhali.easyi18n.model.Translations;
|
|
||||||
import de.marhali.easyi18n.model.LegacyKeyedTranslation;
|
|
||||||
import de.marhali.easyi18n.model.TranslationDelete;
|
|
||||||
import de.marhali.easyi18n.model.table.TableModelTranslator;
|
|
||||||
import de.marhali.easyi18n.dialog.EditDialog;
|
import de.marhali.easyi18n.dialog.EditDialog;
|
||||||
import de.marhali.easyi18n.listener.DeleteKeyListener;
|
import de.marhali.easyi18n.listener.DeleteKeyListener;
|
||||||
import de.marhali.easyi18n.listener.PopupClickListener;
|
import de.marhali.easyi18n.listener.PopupClickListener;
|
||||||
|
import de.marhali.easyi18n.model.bus.BusListener;
|
||||||
import de.marhali.easyi18n.renderer.TableRenderer;
|
import de.marhali.easyi18n.renderer.TableRenderer;
|
||||||
|
import de.marhali.easyi18n.tabs.mapper.TableModelMapper;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -28,7 +25,7 @@ import java.util.ResourceBundle;
|
|||||||
* Shows translation state as table.
|
* Shows translation state as table.
|
||||||
* @author marhali
|
* @author marhali
|
||||||
*/
|
*/
|
||||||
public class TableView implements DataSynchronizer {
|
public class TableView implements BusListener {
|
||||||
|
|
||||||
private final Project project;
|
private final Project project;
|
||||||
|
|
||||||
@ -54,10 +51,10 @@ public class TableView implements DataSynchronizer {
|
|||||||
|
|
||||||
if(row >= 0) {
|
if(row >= 0) {
|
||||||
String fullPath = String.valueOf(table.getValueAt(row, 0));
|
String fullPath = String.valueOf(table.getValueAt(row, 0));
|
||||||
LocalizedNode node = LegacyDataStore.getInstance(project).getTranslations().getNode(fullPath);
|
Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath);
|
||||||
|
|
||||||
if(node != null) {
|
if(translation != null) {
|
||||||
new EditDialog(project, new LegacyKeyedTranslation(fullPath, node.getValue())).showAndHandle();
|
new EditDialog(project, new KeyedTranslation(fullPath, translation)).showAndHandle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,33 +64,38 @@ public class TableView implements DataSynchronizer {
|
|||||||
for (int selectedRow : table.getSelectedRows()) {
|
for (int selectedRow : table.getSelectedRows()) {
|
||||||
String fullPath = String.valueOf(table.getValueAt(selectedRow, 0));
|
String fullPath = String.valueOf(table.getValueAt(selectedRow, 0));
|
||||||
|
|
||||||
LegacyDataStore.getInstance(project).processUpdate(
|
InstanceManager.get(project).processUpdate(
|
||||||
new TranslationDelete(new LegacyKeyedTranslation(fullPath, null)));
|
new TranslationDelete(new KeyedTranslation(fullPath, null))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void synchronize(@NotNull Translations translations,
|
public void onUpdateData(@NotNull TranslationData data) {
|
||||||
@Nullable String searchQuery, @Nullable String scrollTo) {
|
table.setModel(new TableModelMapper(data, update ->
|
||||||
|
InstanceManager.get(project).processUpdate(update)));
|
||||||
|
}
|
||||||
|
|
||||||
table.setModel(new TableModelTranslator(translations, searchQuery, update ->
|
@Override
|
||||||
LegacyDataStore.getInstance(project).processUpdate(update)));
|
public void onFocusKey(@Nullable String key) {
|
||||||
|
int row = -1;
|
||||||
|
|
||||||
if(scrollTo != null) {
|
for (int i = 0; i < table.getRowCount(); i++) {
|
||||||
int row = -1;
|
if (String.valueOf(table.getValueAt(i, 0)).equals(key)) {
|
||||||
|
row = i;
|
||||||
for (int i = 0; i < table.getRowCount(); i++) {
|
|
||||||
if (String.valueOf(table.getValueAt(i, 0)).equals(scrollTo)) {
|
|
||||||
row = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row > -1) { // Matched @scrollTo
|
|
||||||
table.scrollRectToVisible(
|
|
||||||
new Rectangle(0, (row * table.getRowHeight()) + table.getHeight(), 0, 0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (row > -1) { // Matched @scrollTo
|
||||||
|
table.scrollRectToVisible(
|
||||||
|
new Rectangle(0, (row * table.getRowHeight()) + table.getHeight(), 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSearchQuery(@Nullable String query) {
|
||||||
|
// TODO: handle search functionality
|
||||||
}
|
}
|
||||||
|
|
||||||
public JPanel getRootPanel() {
|
public JPanel getRootPanel() {
|
||||||
|
@ -8,19 +8,20 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.ui.components.JBScrollPane;
|
import com.intellij.ui.components.JBScrollPane;
|
||||||
import com.intellij.ui.treeStructure.Tree;
|
import com.intellij.ui.treeStructure.Tree;
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.LegacyDataStore;
|
import de.marhali.easyi18n.InstanceManager;
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||||
import de.marhali.easyi18n.model.DataSynchronizer;
|
import de.marhali.easyi18n.model.Translation;
|
||||||
import de.marhali.easyi18n.model.Translations;
|
import de.marhali.easyi18n.model.TranslationData;
|
||||||
import de.marhali.easyi18n.model.LegacyKeyedTranslation;
|
|
||||||
import de.marhali.easyi18n.model.TranslationDelete;
|
import de.marhali.easyi18n.model.TranslationDelete;
|
||||||
import de.marhali.easyi18n.model.tree.TreeModelTranslator;
|
import de.marhali.easyi18n.model.bus.BusListener;
|
||||||
import de.marhali.easyi18n.action.treeview.CollapseTreeViewAction;
|
import de.marhali.easyi18n.action.treeview.CollapseTreeViewAction;
|
||||||
import de.marhali.easyi18n.action.treeview.ExpandTreeViewAction;
|
import de.marhali.easyi18n.action.treeview.ExpandTreeViewAction;
|
||||||
import de.marhali.easyi18n.dialog.EditDialog;
|
import de.marhali.easyi18n.dialog.EditDialog;
|
||||||
import de.marhali.easyi18n.listener.DeleteKeyListener;
|
import de.marhali.easyi18n.listener.DeleteKeyListener;
|
||||||
import de.marhali.easyi18n.listener.PopupClickListener;
|
import de.marhali.easyi18n.listener.PopupClickListener;
|
||||||
import de.marhali.easyi18n.renderer.TreeRenderer;
|
import de.marhali.easyi18n.renderer.TreeRenderer;
|
||||||
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
|
import de.marhali.easyi18n.tabs.mapper.TreeModelMapper;
|
||||||
import de.marhali.easyi18n.util.TreeUtil;
|
import de.marhali.easyi18n.util.TreeUtil;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -36,7 +37,7 @@ import java.util.ResourceBundle;
|
|||||||
* Show translation state as tree.
|
* Show translation state as tree.
|
||||||
* @author marhali
|
* @author marhali
|
||||||
*/
|
*/
|
||||||
public class TreeView implements DataSynchronizer {
|
public class TreeView implements BusListener {
|
||||||
|
|
||||||
private final Project project;
|
private final Project project;
|
||||||
|
|
||||||
@ -46,6 +47,8 @@ public class TreeView implements DataSynchronizer {
|
|||||||
|
|
||||||
private Tree tree;
|
private Tree tree;
|
||||||
|
|
||||||
|
private TreeModelMapper mapper;
|
||||||
|
|
||||||
public TreeView(Project project) {
|
public TreeView(Project project) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
|
|
||||||
@ -77,19 +80,20 @@ public class TreeView implements DataSynchronizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void synchronize(@NotNull Translations translations,
|
public void onUpdateData(@NotNull TranslationData data) {
|
||||||
@Nullable String searchQuery, @Nullable String scrollTo) {
|
tree.setModel(this.mapper = new TreeModelMapper(data, SettingsService.getInstance(project).getState(), null));
|
||||||
|
}
|
||||||
|
|
||||||
TreeModelTranslator model = new TreeModelTranslator(project, translations, searchQuery);
|
@Override
|
||||||
tree.setModel(model);
|
public void onFocusKey(@Nullable String key) {
|
||||||
|
if(key != null && mapper != null) {
|
||||||
if(searchQuery != null && !searchQuery.isEmpty()) {
|
this.tree.scrollPathToVisible(mapper.findTreePath(key));
|
||||||
expandAll().run();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(scrollTo != null) {
|
@Override
|
||||||
tree.scrollPathToVisible(model.findTreePath(scrollTo));
|
public void onSearchQuery(@Nullable String query) {
|
||||||
}
|
// TODO: handle search functionality
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePopup(MouseEvent e) {
|
private void handlePopup(MouseEvent e) {
|
||||||
@ -100,10 +104,10 @@ public class TreeView implements DataSynchronizer {
|
|||||||
|
|
||||||
if(node.getUserObject() instanceof PresentationData) {
|
if(node.getUserObject() instanceof PresentationData) {
|
||||||
String fullPath = TreeUtil.getFullPath(path);
|
String fullPath = TreeUtil.getFullPath(path);
|
||||||
LocalizedNode localizedNode = LegacyDataStore.getInstance(project).getTranslations().getNode(fullPath);
|
Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath);
|
||||||
|
|
||||||
if(localizedNode != null) {
|
if(translation != null) {
|
||||||
new EditDialog(project,new LegacyKeyedTranslation(fullPath, localizedNode.getValue())).showAndHandle();
|
new EditDialog(project, new KeyedTranslation(fullPath, translation)).showAndHandle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,8 +124,9 @@ public class TreeView implements DataSynchronizer {
|
|||||||
for (TreePath path : tree.getSelectionPaths()) {
|
for (TreePath path : tree.getSelectionPaths()) {
|
||||||
String fullPath = TreeUtil.getFullPath(path);
|
String fullPath = TreeUtil.getFullPath(path);
|
||||||
|
|
||||||
LegacyDataStore.getInstance(project).processUpdate(
|
InstanceManager.get(project).processUpdate(
|
||||||
new TranslationDelete(new LegacyKeyedTranslation(fullPath, null)));
|
new TranslationDelete(new KeyedTranslation(fullPath, null))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
package de.marhali.easyi18n.tabs.mapper;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.model.*;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.model.bus.BusListener;
|
||||||
|
import de.marhali.easyi18n.model.bus.SearchQueryListener;
|
||||||
|
import de.marhali.easyi18n.model.bus.UpdateDataListener;
|
||||||
|
import org.jetbrains.annotations.Nls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.swing.event.TableModelListener;
|
||||||
|
import javax.swing.table.TableModel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping {@link TranslationData} to {@link TableModel}.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class TableModelMapper implements TableModel {
|
||||||
|
|
||||||
|
private final @NotNull TranslationData data;
|
||||||
|
private final @NotNull List<String> locales;
|
||||||
|
private final @NotNull List<String> fullKeys;
|
||||||
|
|
||||||
|
private final @NotNull Consumer<TranslationUpdate> updater;
|
||||||
|
|
||||||
|
public TableModelMapper(@NotNull TranslationData data, Consumer<TranslationUpdate> updater) {
|
||||||
|
this.data = data;
|
||||||
|
this.locales = new ArrayList<>(data.getLocales());
|
||||||
|
this.fullKeys = new ArrayList<>(data.getFullKeys());
|
||||||
|
|
||||||
|
this.updater = updater;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return this.fullKeys.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return this.locales.size() + 1; // Number of locales + 1 (key column)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nls
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int columnIndex) {
|
||||||
|
if(columnIndex == 0) {
|
||||||
|
return "<html><b>Key</b></html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<html><b>" + this.locales.get(columnIndex - 1) + "</b></html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getColumnClass(int columnIndex) {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||||
|
return rowIndex > 0; // Everything should be editable except the headline
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
|
if(columnIndex == 0) { // Keys
|
||||||
|
return this.fullKeys.get(rowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = this.fullKeys.get(rowIndex);
|
||||||
|
String locale = this.locales.get(columnIndex - 1);
|
||||||
|
Translation translation = this.data.getTranslation(key);
|
||||||
|
|
||||||
|
return translation == null ? null : translation.get(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||||
|
String key = String.valueOf(this.getValueAt(rowIndex, 0));
|
||||||
|
Translation translation = this.data.getTranslation(key);
|
||||||
|
|
||||||
|
if(translation == null) { // Unknown cell
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String newKey = columnIndex == 0 ? String.valueOf(aValue) : key;
|
||||||
|
|
||||||
|
// Translation content update
|
||||||
|
if(columnIndex > 0) {
|
||||||
|
if(aValue == null || ((String) aValue).isEmpty()) {
|
||||||
|
translation.remove(this.locales.get(columnIndex - 1));
|
||||||
|
} else {
|
||||||
|
translation.put(this.locales.get(columnIndex - 1), String.valueOf(aValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TranslationUpdate update = new TranslationUpdate(new KeyedTranslation(key, translation),
|
||||||
|
new KeyedTranslation(newKey, translation));
|
||||||
|
|
||||||
|
this.updater.accept(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTableModelListener(TableModelListener l) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeTableModelListener(TableModelListener l) {}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package de.marhali.easyi18n.tabs.mapper;
|
||||||
|
|
||||||
|
import com.intellij.ide.projectView.PresentationData;
|
||||||
|
import com.intellij.ui.JBColor;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.model.SettingsState;
|
||||||
|
import de.marhali.easyi18n.model.TranslationData;
|
||||||
|
import de.marhali.easyi18n.model.TranslationNode;
|
||||||
|
import de.marhali.easyi18n.util.PathUtil;
|
||||||
|
import de.marhali.easyi18n.util.UiUtil;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.swing.tree.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping {@link TranslationData} to {@link TreeModel}.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class TreeModelMapper extends DefaultTreeModel {
|
||||||
|
|
||||||
|
private final TranslationData data;
|
||||||
|
private final SettingsState state;
|
||||||
|
|
||||||
|
public TreeModelMapper(TranslationData data, SettingsState state, String searchQuery) {
|
||||||
|
super(null);
|
||||||
|
|
||||||
|
this.data = data;
|
||||||
|
this.state = state;
|
||||||
|
|
||||||
|
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||||
|
this.generateNodes(rootNode, this.data.getRootNode());
|
||||||
|
super.setRoot(rootNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateNodes(DefaultMutableTreeNode parent, TranslationNode translationNode) {
|
||||||
|
for(Map.Entry<String, TranslationNode> entry : translationNode.getChildren().entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
TranslationNode childTranslationNode = entry.getValue();
|
||||||
|
|
||||||
|
if(!childTranslationNode.isLeaf()) {
|
||||||
|
// Nested node - run recursively
|
||||||
|
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(key);
|
||||||
|
this.generateNodes(childNode, childTranslationNode);
|
||||||
|
parent.add(childNode);
|
||||||
|
} else {
|
||||||
|
String previewLocale = this.state.getPreviewLocale();
|
||||||
|
String sub = "(" + previewLocale + ": " + childTranslationNode.getValue().get(previewLocale) + ")";
|
||||||
|
String tooltip = UiUtil.generateHtmlTooltip(childTranslationNode.getValue());
|
||||||
|
|
||||||
|
PresentationData data = new PresentationData(key, sub, null, null);
|
||||||
|
data.setTooltip(tooltip);
|
||||||
|
|
||||||
|
if(childTranslationNode.getValue().size() != this.data.getLocales().size()) {
|
||||||
|
data.setForcedTextForeground(JBColor.RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.add(new DefaultMutableTreeNode(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public @NotNull TreePath findTreePath(@NotNull String fullPath) {
|
||||||
|
List<String> sections = new PathUtil(this.state.isNestedKeys()).split(fullPath);
|
||||||
|
Object[] nodes = new Object[sections.size() + 1];
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
TreeNode currentNode = (TreeNode) this.getRoot();
|
||||||
|
nodes[pos] = currentNode;
|
||||||
|
|
||||||
|
for(String section : sections) {
|
||||||
|
pos++;
|
||||||
|
currentNode = this.findNode(currentNode, section);
|
||||||
|
nodes[pos] = currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TreePath(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable DefaultMutableTreeNode findNode(@NotNull TreeNode parent, @NotNull String key) {
|
||||||
|
for(int i = 0; i < parent.getChildCount(); i++) {
|
||||||
|
TreeNode child = parent.getChildAt(i);
|
||||||
|
|
||||||
|
if(child instanceof DefaultMutableTreeNode) {
|
||||||
|
DefaultMutableTreeNode mutableChild = (DefaultMutableTreeNode) child;
|
||||||
|
String childKey = mutableChild.getUserObject().toString();
|
||||||
|
|
||||||
|
if(mutableChild.getUserObject() instanceof PresentationData) {
|
||||||
|
childKey = ((PresentationData) mutableChild.getUserObject()).getPresentableText();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(childKey != null && childKey.equals(key)) {
|
||||||
|
return mutableChild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NullPointerException("Cannot find node by key: " + key);
|
||||||
|
}
|
||||||
|
}
|
@ -1,72 +0,0 @@
|
|||||||
package de.marhali.easyi18n.util;
|
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
import de.marhali.easyi18n.io.implementation.*;
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.SettingsService;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO operations utility.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class IOUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the {@link TranslatorIO} which should be used for the specified directoryPath
|
|
||||||
* @param project Current intellij project
|
|
||||||
* @param directoryPath The full path to the parent directory which holds the translation files
|
|
||||||
* @return IO handler to use for file operations
|
|
||||||
*/
|
|
||||||
public static TranslatorIO determineFormat(@NotNull Project project, @NotNull String directoryPath) {
|
|
||||||
VirtualFile directory = LocalFileSystem.getInstance().findFileByIoFile(new File(directoryPath));
|
|
||||||
|
|
||||||
if(directory == null || directory.getChildren() == null) {
|
|
||||||
throw new IllegalArgumentException("Specified folder is invalid (" + directoryPath + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualFile[] children = directory.getChildren();
|
|
||||||
|
|
||||||
for(VirtualFile file : children) {
|
|
||||||
if(file.isDirectory()) { // Modularized locale files
|
|
||||||
// ATM we only support modularized JSON files
|
|
||||||
return new ModularizedJsonTranslatorIO();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isFileRelevant(project, file)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(file.getFileType().getDefaultExtension().toLowerCase()) {
|
|
||||||
case "json":
|
|
||||||
return new JsonTranslatorIO();
|
|
||||||
case "properties":
|
|
||||||
return new PropertiesTranslatorIO();
|
|
||||||
case "yml":
|
|
||||||
return new YamlTranslatorIO();
|
|
||||||
default:
|
|
||||||
System.err.println("Unsupported i18n locale file format: "
|
|
||||||
+ file.getFileType().getDefaultExtension());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException("Could not determine i18n format. At least one locale file must be defined");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the provided file matches the file pattern specified by configuration
|
|
||||||
* @param project Current intellij project
|
|
||||||
* @param file File to check
|
|
||||||
* @return True if relevant otherwise false
|
|
||||||
*/
|
|
||||||
public static boolean isFileRelevant(@NotNull Project project, @NotNull VirtualFile file) {
|
|
||||||
String pattern = SettingsService.getInstance(project).getState().getFilePattern();
|
|
||||||
return file.getName().matches(pattern);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
package de.marhali.easyi18n.util;
|
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.util.array.JsonArrayUtil;
|
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Json tree utilities for writing and reading {@link LocalizedNode}'s
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
public class JsonUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a {@link JsonObject} based from an {@link LocalizedNode}
|
|
||||||
* @param locale Current locale
|
|
||||||
* @param parent Parent json. Can be an entire json document
|
|
||||||
* @param node The node instance
|
|
||||||
*/
|
|
||||||
public static void writeTree(String locale, JsonObject parent, LocalizedNode node) {
|
|
||||||
if(node.isLeaf() && !node.getKey().equals(LocalizedNode.ROOT_KEY)) {
|
|
||||||
if(node.getValue().get(locale) != null) {
|
|
||||||
|
|
||||||
if(JsonArrayUtil.isArray(node.getValue().get(locale))) {
|
|
||||||
parent.add(node.getKey(), JsonArrayUtil.write(node.getValue().get(locale)));
|
|
||||||
} else {
|
|
||||||
String value = StringEscapeUtils.unescapeJava(node.getValue().get(locale));
|
|
||||||
parent.add(node.getKey(), new JsonPrimitive(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
for(LocalizedNode children : node.getChildren()) {
|
|
||||||
if(children.isLeaf()) {
|
|
||||||
writeTree(locale, parent, children);
|
|
||||||
} else {
|
|
||||||
JsonObject childrenJson = new JsonObject();
|
|
||||||
writeTree(locale, childrenJson, children);
|
|
||||||
if(childrenJson.size() > 0) {
|
|
||||||
parent.add(children.getKey(), childrenJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a {@link JsonObject} and writes the tree into the provided {@link LocalizedNode}
|
|
||||||
* @param locale Current locale
|
|
||||||
* @param json Json to read
|
|
||||||
* @param data Node. Can be a root node
|
|
||||||
*/
|
|
||||||
public static void readTree(String locale, JsonObject json, LocalizedNode data) {
|
|
||||||
for(Map.Entry<String, JsonElement> entry : json.entrySet()) {
|
|
||||||
String key = entry.getKey();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Try to go one level deeper
|
|
||||||
JsonObject childObject = entry.getValue().getAsJsonObject();
|
|
||||||
|
|
||||||
LocalizedNode childrenNode = data.getChildren(key);
|
|
||||||
|
|
||||||
if(childrenNode == null) {
|
|
||||||
childrenNode = new LocalizedNode(key, new ArrayList<>());
|
|
||||||
data.addChildren(childrenNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
readTree(locale, childObject, childrenNode);
|
|
||||||
|
|
||||||
} catch(IllegalStateException e) { // Reached end for this node
|
|
||||||
LocalizedNode leafNode = data.getChildren(key);
|
|
||||||
|
|
||||||
if(leafNode == null) {
|
|
||||||
leafNode = new LocalizedNode(key, new HashMap<>());
|
|
||||||
data.addChildren(leafNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> messages = leafNode.getValue();
|
|
||||||
|
|
||||||
String value = entry.getValue().isJsonArray()
|
|
||||||
? JsonArrayUtil.read(entry.getValue().getAsJsonArray())
|
|
||||||
: StringUtil.escapeControls(entry.getValue().getAsString(), true);
|
|
||||||
|
|
||||||
messages.put(locale, value);
|
|
||||||
leafNode.setValue(messages);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,5 @@
|
|||||||
package de.marhali.easyi18n.util;
|
package de.marhali.easyi18n.util;
|
||||||
|
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@ -9,6 +7,7 @@ import java.util.TreeMap;
|
|||||||
* Map utilities.
|
* Map utilities.
|
||||||
* @author marhali
|
* @author marhali
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class MapUtil {
|
public class MapUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,6 +6,7 @@ import java.util.*;
|
|||||||
* Applies sorting to {@link Properties} files.
|
* Applies sorting to {@link Properties} files.
|
||||||
* @author marhali
|
* @author marhali
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class SortedProperties extends Properties {
|
public class SortedProperties extends Properties {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package de.marhali.easyi18n.util;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility tool to support the translations instance
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated // SectionUtil
|
|
||||||
public class TranslationsUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve all sections for the specified path (mostly fullPath)
|
|
||||||
* @param path The path
|
|
||||||
* @return Sections. E.g. input user.username.title -> Output: [user, username, title]
|
|
||||||
*/
|
|
||||||
public static @NotNull List<String> getSections(@NotNull String path) {
|
|
||||||
if(!path.contains(".")) {
|
|
||||||
return new ArrayList<>(Collections.singletonList(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ArrayList<>(Arrays.asList(path.split("\\.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concatenate the given sections to a single string.
|
|
||||||
* @param sections The sections
|
|
||||||
* @return Full path. E.g. input [user, username, title] -> Output: user.username.title
|
|
||||||
*/
|
|
||||||
public static @NotNull String sectionsToFullPath(@NotNull List<String> sections) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
for (String section : sections) {
|
|
||||||
if(builder.length() > 0) {
|
|
||||||
builder.append(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.append(section);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
package de.marhali.easyi18n.util;
|
package de.marhali.easyi18n.util;
|
||||||
|
|
||||||
import com.intellij.ide.projectView.PresentationData;
|
import com.intellij.ide.projectView.PresentationData;
|
||||||
import de.marhali.easyi18n.model.LocalizedNode;
|
|
||||||
|
|
||||||
import javax.swing.tree.DefaultMutableTreeNode;
|
import javax.swing.tree.DefaultMutableTreeNode;
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
@ -20,14 +19,13 @@ public class TreeUtil {
|
|||||||
public static String getFullPath(TreePath path) {
|
public static String getFullPath(TreePath path) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
|
||||||
for (Object obj : path.getPath()) {
|
for (Object obj : path.getPath()) {
|
||||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj;
|
DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj;
|
||||||
Object value = node.getUserObject();
|
Object value = node.getUserObject();
|
||||||
String section = value instanceof PresentationData ?
|
String section = value instanceof PresentationData ?
|
||||||
((PresentationData) value).getPresentableText() : String.valueOf(value);
|
((PresentationData) value).getPresentableText() : String.valueOf(value);
|
||||||
|
|
||||||
if(section == null || section.equals(LocalizedNode.ROOT_KEY)) { // Skip root node
|
if(section == null) { // Skip empty sections
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user