feat: Add key naming convention selection for extracted translations

This update enables the user to specify a key naming convention (Camel Case or Snake Case) for extracted translations. This option is made available in the settings panel, and has been included in the project-specific configuration and state management for the project settings component.
This commit is contained in:
JPilson 2024-04-16 20:34:12 +02:00
parent 0c1710029f
commit 667b748614
4 changed files with 76 additions and 19 deletions

View File

@ -1,5 +1,6 @@
package de.marhali.easyi18n.settings;
import com.google.common.base.CaseFormat;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.Project;
@ -26,6 +27,7 @@ import java.util.ResourceBundle;
/**
* Configuration panel with all possible options for this plugin.
*
* @author marhali
*/
public class ProjectSettingsComponent extends ProjectSettingsComponentState {
@ -64,7 +66,9 @@ public class ProjectSettingsComponent extends ProjectSettingsComponentState {
.addVerticalGap(24)
.addComponent(new TitledSeparator(bundle.getString("settings.experimental.title")))
.addComponent(constructAlwaysFoldField())
.addVerticalGap(12)
.addLabeledComponent(bundle.getString("settings.experimental.flavor-template"), constructFlavorTemplate(), 1, false)
.addLabeledComponent(bundle.getString("settings.experimental.key-naming-format.title"), constructKeyCaseFormater(), 1, false)
.addComponentFillVertically(new JPanel(), 0)
.getPanel();
}
@ -226,6 +230,17 @@ public class ProjectSettingsComponent extends ProjectSettingsComponentState {
return flavorTemplate;
}
private JComponent constructKeyCaseFormater() {
KeyCaseFormater = new ComboBox<>(bundle.getString("settings.experimental.key-naming-format.items").split(ArrayMapper.SPLITERATOR_REGEX));
KeyCaseFormater.setToolTipText(bundle.getString("settings.experimental.key-naming-format.tooltip"));
KeyCaseFormater.setMinimumAndPreferredWidth(120);
KeyCaseFormater.addActionListener(e -> {
});
return KeyCaseFormater;
}
private ItemListener handleParserChange() {
return e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {

View File

@ -1,5 +1,6 @@
package de.marhali.easyi18n.settings;
import com.google.common.base.CaseFormat;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
@ -11,6 +12,7 @@ import javax.swing.*;
/**
* Mandatory for state management for the project settings component.
*
* @author marhali
*/
public class ProjectSettingsComponentState {
@ -41,6 +43,7 @@ public class ProjectSettingsComponentState {
protected JCheckBox alwaysFold;
protected JTextField flavorTemplate;
protected ComboBox<String> KeyCaseFormater;
protected ProjectSettingsState getState() {
// Every field needs to provide its state
@ -67,6 +70,8 @@ public class ProjectSettingsComponentState {
state.setAlwaysFold(alwaysFold.isSelected());
state.setFlavorTemplate(flavorTemplate.getText());
state.setCaseFormat(NamingConvention.valueOf(KeyCaseFormater.getSelectedItem().toString().replace("Case", "").trim()));
return state;
}
@ -92,5 +97,6 @@ public class ProjectSettingsComponentState {
alwaysFold.setSelected(state.isAlwaysFold());
flavorTemplate.setText(state.getFlavorTemplate());
KeyCaseFormater.setSelectedItem(state.getCaseFormat().name());
}
}

View File

@ -1,5 +1,6 @@
package de.marhali.easyi18n.settings;
import com.google.common.base.CaseFormat;
import com.intellij.util.xmlb.annotations.Property;
import de.marhali.easyi18n.io.parser.ParserStrategyType;
@ -13,32 +14,48 @@ import java.util.Objects;
/**
* Represents the project-specific configuration of this plugin.
*
* @author marhali
*/
public class ProjectSettingsState implements ProjectSettings {
// Resource Configuration
@Property private String localesDirectory;
@Property private FolderStrategyType folderStrategy;
@Property private ParserStrategyType parserStrategy;
@Property private String filePattern;
@Property
private String localesDirectory;
@Property
private FolderStrategyType folderStrategy;
@Property
private ParserStrategyType parserStrategy;
@Property
private String filePattern;
@Property private Boolean includeSubDirs;
@Property private boolean sorting;
@Property
private Boolean includeSubDirs;
@Property
private boolean sorting;
// Editor configuration
@Property private String namespaceDelimiter;
@Property private String sectionDelimiter;
@Property private String contextDelimiter;
@Property private String pluralDelimiter;
@Property private String defaultNamespace;
@Property private String previewLocale;
@Property
private String namespaceDelimiter;
@Property
private String sectionDelimiter;
@Property
private String contextDelimiter;
@Property
private String pluralDelimiter;
@Property
private String defaultNamespace;
@Property
private String previewLocale;
@Property private Boolean nestedKeys;
@Property private Boolean assistance;
@Property
private Boolean nestedKeys;
@Property
private Boolean assistance;
// Experimental configuration
@Property private Boolean alwaysFold;
@Property
private Boolean alwaysFold;
/**
* The `flavorTemplate` specifies the format used for replacing strings with their i18n (internationalization) counterparts.
@ -47,7 +64,10 @@ public class ProjectSettingsState implements ProjectSettings {
* the specific framework or developers' preferences for handling i18n. The ability to dynamically change this template adds flexibility and customization
* to cater to different i18n handling methods.
*/
@Property private String flavorTemplate;
@Property
private String flavorTemplate;
@Property
private NamingConvention caseFormat;
public ProjectSettingsState() {
this(new DefaultPreset());
@ -158,6 +178,11 @@ public class ProjectSettingsState implements ProjectSettings {
return this.flavorTemplate;
}
@Override
public @NotNull NamingConvention getCaseFormat() {
return this.caseFormat;
}
public void setLocalesDirectory(String localesDirectory) {
this.localesDirectory = localesDirectory;
}
@ -222,6 +247,11 @@ public class ProjectSettingsState implements ProjectSettings {
this.flavorTemplate = flavorTemplate;
}
public void setCaseFormat(NamingConvention caseFormat) {
this.caseFormat = caseFormat;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -242,7 +272,8 @@ public class ProjectSettingsState implements ProjectSettings {
&& Objects.equals(nestedKeys, that.nestedKeys)
&& Objects.equals(assistance, that.assistance)
&& Objects.equals(alwaysFold, that.alwaysFold)
&& Objects.equals(flavorTemplate,that.flavorTemplate);
&& Objects.equals(flavorTemplate, that.flavorTemplate)
&& Objects.equals(caseFormat, that.caseFormat);
}
@Override
@ -250,7 +281,7 @@ public class ProjectSettingsState implements ProjectSettings {
return Objects.hash(
localesDirectory, folderStrategy, parserStrategy, filePattern, includeSubDirs,
sorting, namespaceDelimiter, sectionDelimiter, contextDelimiter, pluralDelimiter,
defaultNamespace, previewLocale, nestedKeys, assistance, alwaysFold,flavorTemplate
defaultNamespace, previewLocale, nestedKeys, assistance, alwaysFold, flavorTemplate, caseFormat
);
}
@ -273,6 +304,7 @@ public class ProjectSettingsState implements ProjectSettings {
", assistance=" + assistance +
", alwaysFold=" + alwaysFold +
", flavorTemplate=" + flavorTemplate +
", caseFormat=" + caseFormat.toString() +
'}';
}
}

View File

@ -62,6 +62,10 @@ settings.experimental.always-fold.title=Always fold translation keys
settings.experimental.always-fold.tooltip=Forces the editor to always display the value behind a translation key. The value cannot be unfolded when this function is active.
settings.experimental.flavor-template =I18n flavor template
settings.experimental.flavor-template-tooltip = Specify how to replace strings with i18n representation.
settings.experimental.key-naming-format.title=Key format of extracted translation
settings.experimental.key-naming-format.tooltip=Choose Naming Convention for the keys of extracted translation
settings.experimental.key-naming-format.items=Camel Case;Snake Case
error.io=An error occurred while processing translation files. \n\
Config: {0} => {1} ({2}) \n\
Path: {3} \n\