easy-18in/src/main/java/de/marhali/easyi18n/settings/ProjectSettingsComponent.java
JPilson a709db810e Add i18n flavor template setting
A new setting, `flavorTemplate` is introduced to specify how strings are replaced with i18n representation. This includes code modifications for handling this new feature and also updates in the messages.properties file for the associated UI text. The feature is especially useful for customizing how localization strings are generated in different project setups.
2023-12-16 17:50:29 +01:00

245 lines
11 KiB
Java

package de.marhali.easyi18n.settings;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.ui.JBColor;
import com.intellij.ui.TitledSeparator;
import com.intellij.ui.components.*;
import com.intellij.ui.components.fields.ExtendableTextField;
import com.intellij.util.ui.FormBuilder;
import de.marhali.easyi18n.io.parser.ArrayMapper;
import de.marhali.easyi18n.io.parser.ParserStrategyType;
import de.marhali.easyi18n.settings.presets.Preset;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ResourceBundle;
/**
* Configuration panel with all possible options for this plugin.
*
* @author marhali
*/
public class ProjectSettingsComponent extends ProjectSettingsComponentState {
private final Project project;
private final ResourceBundle bundle;
private final JPanel mainPanel;
// Data fields are provided by the underlying state class
public ProjectSettingsComponent(Project project) {
this.project = project;
this.bundle = ResourceBundle.getBundle("messages");
this.mainPanel = FormBuilder.createFormBuilder()
.addComponent(new JBLabel(bundle.getString("settings.hint.text")))
.addComponent(new ActionLink(bundle.getString("settings.hint.action"),
(ActionListener) (var) -> BrowserUtil.browse("https://github.com/marhali/easy-i18n")))
.addVerticalGap(24)
.addLabeledComponent(bundle.getString("settings.preset.title"), constructPresetField(), 1, false)
.addVerticalGap(12)
.addComponent(new TitledSeparator(bundle.getString("settings.resource.title")))
.addLabeledComponent(bundle.getString("settings.resource.path.title"), constructLocalesDirectoryField(), 1, false)
.addLabeledComponent(bundle.getString("settings.resource.strategy"), constructFileStrategyPanel(), 1, false)
.addVerticalGap(12)
.addComponent(constructIncludeSubDirsField())
.addComponent(constructSortingField())
.addVerticalGap(24)
.addComponent(new TitledSeparator(bundle.getString("settings.editor.title")))
.addLabeledComponent(bundle.getString("settings.editor.key.title"), constructKeyStrategyPanel(), 1, false)
.addLabeledComponent(bundle.getString("settings.editor.default-namespace.title"), constructDefaultNamespaceField(), 1, false)
.addLabeledComponent(bundle.getString("settings.editor.preview.title"), constructPreviewLocaleField(), 1, false)
.addVerticalGap(12)
.addComponent(constructNestedKeysField())
.addComponent(constructAssistanceField())
.addVerticalGap(24)
.addComponent(new TitledSeparator(bundle.getString("settings.experimental.title")))
.addComponent(constructAlwaysFoldField())
.addLabeledComponent(bundle.getString("settings.experimental.flavor-template"), constructFlavorTemplate(), 1, false)
.addComponentFillVertically(new JPanel(), 0)
.getPanel();
}
private JComponent constructPresetField() {
preset = new ComboBox<>(Preset.values());
preset.setToolTipText(bundle.getString("settings.preset.tooltip"));
preset.setMinimumAndPreferredWidth(196);
preset.addActionListener(e -> setState(preset.getItem().config())); // Listen to selection change
return preset;
}
private JComponent constructLocalesDirectoryField() {
localesDirectory = new TextFieldWithBrowseButton();
localesDirectory.setToolTipText(bundle.getString("settings.resource.path.tooltip"));
localesDirectory.addBrowseFolderListener(bundle.getString("settings.resource.path.window"),
bundle.getString("settings.resource.path.tooltip"), project,
new FileChooserDescriptor(false, true,
false, false, false, false));
// Listen to value change
localesDirectory.getTextField().getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
validateLocalesDirectory();
}
@Override
public void removeUpdate(DocumentEvent e) {
validateLocalesDirectory();
}
@Override
public void changedUpdate(DocumentEvent e) {
validateLocalesDirectory();
}
});
validateLocalesDirectory();
return localesDirectory;
}
private void validateLocalesDirectory() {
// Paint red border to indicate missing value
localesDirectory.setBorder(localesDirectory.getText().isEmpty()
? BorderFactory.createLineBorder(JBColor.red) : null);
}
private JPanel constructFileStrategyPanel() {
JPanel panel = new JBPanel<>(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
/* folder strategy */
folderStrategy = new ComboBox<>(bundle.getString("settings.resource.folder.items").split(ArrayMapper.SPLITERATOR_REGEX));
folderStrategy.setToolTipText(bundle.getString("settings.resource.folder.tooltip"));
folderStrategy.setMinimumAndPreferredWidth(256);
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 0;
constraints.gridy = 0;
panel.add(folderStrategy, constraints);
/* parser strategy */
parserStrategy = new ComboBox<>(bundle.getString("settings.resource.parser.items").split(ArrayMapper.SPLITERATOR_REGEX));
parserStrategy.setToolTipText(bundle.getString("settings.resource.parser.tooltip"));
parserStrategy.addItemListener(handleParserChange());
parserStrategy.setMinimumAndPreferredWidth(128);
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 1;
constraints.gridy = 0;
panel.add(parserStrategy, constraints);
/* file pattern strategy */
filePattern = new JBTextField();
filePattern.setToolTipText(bundle.getString("settings.resource.file-pattern.tooltip"));
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 2;
constraints.gridy = 0;
constraints.weightx = 1;
panel.add(filePattern, constraints);
return panel;
}
private JComponent constructIncludeSubDirsField() {
includeSubDirs = new JBCheckBox(bundle.getString("settings.resource.nesting.title"));
includeSubDirs.setToolTipText(bundle.getString("settings.resource.nesting.tooltip"));
return includeSubDirs;
}
private JComponent constructSortingField() {
sorting = new JBCheckBox(bundle.getString("settings.resource.sorting.title"));
sorting.setToolTipText(bundle.getString("settings.resource.sorting.tooltip"));
return sorting;
}
private JPanel constructKeyStrategyPanel() {
JPanel panel = new JBPanel<>(new FlowLayout(FlowLayout.LEFT));
panel.add(new JBLabel(bundle.getString("settings.editor.key.namespace.title")));
panel.add(namespaceDelimiter = createDelimiterField(bundle.getString("settings.editor.key.namespace.tooltip")));
panel.add(new JBLabel(bundle.getString("settings.editor.key.section.title")));
panel.add(sectionDelimiter = createDelimiterField(bundle.getString("settings.editor.key.section.tooltip")));
panel.add(createBoldLabel(bundle.getString("settings.editor.key.leaf.title")));
panel.add(contextDelimiter = createDelimiterField(bundle.getString("settings.editor.key.context.tooltip")));
panel.add(createBoldLabel(bundle.getString("settings.editor.key.context.title")));
panel.add(pluralDelimiter = createDelimiterField(bundle.getString("settings.editor.key.plural.tooltip")));
panel.add(createBoldLabel(bundle.getString("settings.editor.key.plural.title")));
return panel;
}
private JLabel createBoldLabel(String title) {
JBLabel label = new JBLabel(title);
Font font = label.getFont();
label.setFont(font.deriveFont(font.getStyle() | Font.BOLD));
return label;
}
private JTextField createDelimiterField(String tooltip) {
JBTextField field = new JBTextField();
field.setHorizontalAlignment(JTextField.CENTER);
field.setToolTipText(tooltip);
return field;
}
private JComponent constructDefaultNamespaceField() {
defaultNamespace = new ExtendableTextField(20);
defaultNamespace.setToolTipText(bundle.getString("settings.editor.default-namespace.tooltip"));
return defaultNamespace;
}
private JComponent constructPreviewLocaleField() {
previewLocale = new ExtendableTextField(12);
previewLocale.setToolTipText(bundle.getString("settings.editor.preview.tooltip"));
return previewLocale;
}
private JComponent constructNestedKeysField() {
nestedKeys = new JBCheckBox(bundle.getString("settings.editor.key.nesting.title"));
nestedKeys.setToolTipText(bundle.getString("settings.editor.key.nesting.tooltip"));
return nestedKeys;
}
private JComponent constructAssistanceField() {
assistance = new JBCheckBox(bundle.getString("settings.editor.assistance.title"));
assistance.setToolTipText(bundle.getString("settings.editor.assistance.tooltip"));
return assistance;
}
private JComponent constructAlwaysFoldField() {
alwaysFold = new JBCheckBox(bundle.getString("settings.experimental.always-fold.title"));
alwaysFold.setToolTipText(bundle.getString("settings.experimental.always-fold.tooltip"));
return alwaysFold;
}
private JComponent constructFlavorTemplate() {
flavorTemplate = new ExtendableTextField(20);
flavorTemplate.setToolTipText(bundle.getString("settings.experimental.flavor-template-tooltip"));
return flavorTemplate;
}
private ItemListener handleParserChange() {
return e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
// Automatically suggest file pattern option on parser change
ParserStrategyType newStrategy = ParserStrategyType.fromIndex(parserStrategy.getSelectedIndex());
filePattern.setText(newStrategy.getExampleFilePattern());
}
};
}
public JPanel getMainPanel() {
return mainPanel;
}
}