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

View File

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

View File

@ -1,5 +1,6 @@
package de.marhali.easyi18n.settings; package de.marhali.easyi18n.settings;
import com.google.common.base.CaseFormat;
import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Property;
import de.marhali.easyi18n.io.parser.ParserStrategyType; import de.marhali.easyi18n.io.parser.ParserStrategyType;
@ -13,32 +14,48 @@ import java.util.Objects;
/** /**
* Represents the project-specific configuration of this plugin. * Represents the project-specific configuration of this plugin.
*
* @author marhali * @author marhali
*/ */
public class ProjectSettingsState implements ProjectSettings { public class ProjectSettingsState implements ProjectSettings {
// Resource Configuration // Resource Configuration
@Property private String localesDirectory; @Property
@Property private FolderStrategyType folderStrategy; private String localesDirectory;
@Property private ParserStrategyType parserStrategy; @Property
@Property private String filePattern; private FolderStrategyType folderStrategy;
@Property
private ParserStrategyType parserStrategy;
@Property
private String filePattern;
@Property private Boolean includeSubDirs; @Property
@Property private boolean sorting; private Boolean includeSubDirs;
@Property
private boolean sorting;
// Editor configuration // Editor configuration
@Property private String namespaceDelimiter; @Property
@Property private String sectionDelimiter; private String namespaceDelimiter;
@Property private String contextDelimiter; @Property
@Property private String pluralDelimiter; private String sectionDelimiter;
@Property private String defaultNamespace; @Property
@Property private String previewLocale; private String contextDelimiter;
@Property
private String pluralDelimiter;
@Property
private String defaultNamespace;
@Property
private String previewLocale;
@Property private Boolean nestedKeys; @Property
@Property private Boolean assistance; private Boolean nestedKeys;
@Property
private Boolean assistance;
// Experimental configuration // Experimental configuration
@Property private Boolean alwaysFold; @Property
private Boolean alwaysFold;
/** /**
* The `flavorTemplate` specifies the format used for replacing strings with their i18n (internationalization) counterparts. * 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 * 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. * to cater to different i18n handling methods.
*/ */
@Property private String flavorTemplate; @Property
private String flavorTemplate;
@Property
private NamingConvention caseFormat;
public ProjectSettingsState() { public ProjectSettingsState() {
this(new DefaultPreset()); this(new DefaultPreset());
@ -158,6 +178,11 @@ public class ProjectSettingsState implements ProjectSettings {
return this.flavorTemplate; return this.flavorTemplate;
} }
@Override
public @NotNull NamingConvention getCaseFormat() {
return this.caseFormat;
}
public void setLocalesDirectory(String localesDirectory) { public void setLocalesDirectory(String localesDirectory) {
this.localesDirectory = localesDirectory; this.localesDirectory = localesDirectory;
} }
@ -218,10 +243,15 @@ public class ProjectSettingsState implements ProjectSettings {
this.alwaysFold = alwaysFold; this.alwaysFold = alwaysFold;
} }
public void setFlavorTemplate(String flavorTemplate){ public void setFlavorTemplate(String flavorTemplate) {
this.flavorTemplate = flavorTemplate; this.flavorTemplate = flavorTemplate;
} }
public void setCaseFormat(NamingConvention caseFormat) {
this.caseFormat = caseFormat;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
@ -242,7 +272,8 @@ public class ProjectSettingsState implements ProjectSettings {
&& Objects.equals(nestedKeys, that.nestedKeys) && Objects.equals(nestedKeys, that.nestedKeys)
&& Objects.equals(assistance, that.assistance) && Objects.equals(assistance, that.assistance)
&& Objects.equals(alwaysFold, that.alwaysFold) && Objects.equals(alwaysFold, that.alwaysFold)
&& Objects.equals(flavorTemplate,that.flavorTemplate); && Objects.equals(flavorTemplate, that.flavorTemplate)
&& Objects.equals(caseFormat, that.caseFormat);
} }
@Override @Override
@ -250,7 +281,7 @@ public class ProjectSettingsState implements ProjectSettings {
return Objects.hash( return Objects.hash(
localesDirectory, folderStrategy, parserStrategy, filePattern, includeSubDirs, localesDirectory, folderStrategy, parserStrategy, filePattern, includeSubDirs,
sorting, namespaceDelimiter, sectionDelimiter, contextDelimiter, pluralDelimiter, 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 + ", assistance=" + assistance +
", alwaysFold=" + alwaysFold + ", alwaysFold=" + alwaysFold +
", flavorTemplate=" + flavorTemplate + ", 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.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 =I18n flavor template
settings.experimental.flavor-template-tooltip = Specify how to replace strings with i18n representation. 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\ error.io=An error occurred while processing translation files. \n\
Config: {0} => {1} ({2}) \n\ Config: {0} => {1} ({2}) \n\
Path: {3} \n\ Path: {3} \n\