From f56eb271a11a49008337426bf2fb6c1bacc4d16f Mon Sep 17 00:00:00 2001 From: Skylot <118523+skylot@users.noreply.github.com> Date: Sat, 3 May 2025 20:24:49 +0100 Subject: [PATCH] feat(gui): allow to set code area theme with custom code (#2471) --- .../java/jadx/gui/settings/JadxSettings.java | 24 ++--- .../gui/settings/ui/JadxSettingsWindow.java | 33 ++----- .../src/main/java/jadx/gui/ui/MainWindow.java | 53 ++-------- .../gui/ui/codearea/AbstractCodeArea.java | 16 +-- .../java/jadx/gui/ui/codearea/CodeArea.java | 12 ++- .../jadx/gui/ui/codearea/EditorTheme.java | 49 --------- .../java/jadx/gui/ui/codearea/HexArea.java | 10 +- .../jadx/gui/ui/codearea/HexPreviewPanel.java | 11 +-- .../ui/codearea/MouseHoverHighlighter.java | 16 ++- .../java/jadx/gui/ui/codearea/SmaliArea.java | 27 ++--- .../DynamicCodeAreaTheme.java} | 59 ++++++----- .../ui/codearea/theme/EditorThemeManager.java | 99 +++++++++++++++++++ .../codearea/theme/FallbackEditorTheme.java | 28 ++++++ .../gui/ui/codearea/theme/IEditorTheme.java | 20 ++++ .../ui/codearea/theme/RSTABundledTheme.java | 55 +++++++++++ .../gui/ui/codearea/theme/RSTAThemeXML.java | 56 +++++++++++ .../gui/ui/codearea/theme/ThemeIdAndName.java | 37 +++++++ .../resources/i18n/Messages_de_DE.properties | 2 +- .../resources/i18n/Messages_en_US.properties | 2 +- .../resources/i18n/Messages_es_ES.properties | 2 +- .../resources/i18n/Messages_id_ID.properties | 2 +- .../resources/i18n/Messages_ko_KR.properties | 2 +- .../resources/i18n/Messages_pt_BR.properties | 2 +- .../resources/i18n/Messages_ru_RU.properties | 2 +- .../resources/i18n/Messages_zh_CN.properties | 2 +- .../resources/i18n/Messages_zh_TW.properties | 2 +- 26 files changed, 411 insertions(+), 212 deletions(-) delete mode 100644 jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorTheme.java rename jadx-gui/src/main/java/jadx/gui/ui/codearea/{DynamicCoreAreaTheme.java => theme/DynamicCodeAreaTheme.java} (81%) create mode 100644 jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/EditorThemeManager.java create mode 100644 jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/FallbackEditorTheme.java create mode 100644 jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/IEditorTheme.java create mode 100644 jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTABundledTheme.java create mode 100644 jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTAThemeXML.java create mode 100644 jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/ThemeIdAndName.java diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java index 6b773d8e6..4fe755ba2 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java @@ -41,7 +41,6 @@ import jadx.gui.cache.usage.UsageCacheMode; import jadx.gui.settings.data.ShortcutsWrapper; import jadx.gui.ui.MainWindow; import jadx.gui.ui.action.ActionModel; -import jadx.gui.ui.codearea.EditorTheme; import jadx.gui.ui.tab.dnd.TabDndGhostType; import jadx.gui.utils.FontUtils; import jadx.gui.utils.LafManager; @@ -73,7 +72,11 @@ public class JadxSettings extends JadxCLIArgs { private List recentProjects = new ArrayList<>(); private String fontStr = ""; private String smaliFontStr = ""; - private String editorThemePath = EditorTheme.getDefaultTheme().getPath(); + private String editorTheme = ""; + + // Deprecated. Keep for backward compatibility + private String editorThemePath = "/org/fife/ui/rsyntaxtextarea/themes/default.xml"; + private String lafTheme = LafManager.INITIAL_THEME_NAME; private LangLocale langLocale = NLS.defaultLocale(); private boolean autoStartJobs = false; @@ -102,7 +105,6 @@ public class JadxSettings extends JadxCLIArgs { private boolean showHeapUsageBar = false; private boolean alwaysSelectOpened = false; private boolean useAlternativeFileDialog = false; - private boolean useDynamicEditorTheme = false; private Map windowPos = new HashMap<>(); private int mainWindowExtendedState = JFrame.NORMAL; @@ -325,14 +327,6 @@ public class JadxSettings extends JadxCLIArgs { this.useAlternativeFileDialog = useAlternativeFileDialog; } - public boolean isUseDynamicEditorTheme() { - return useDynamicEditorTheme; - } - - public void setUseDynamicEditorTheme(boolean useDynamicEditorTheme) { - this.useDynamicEditorTheme = useDynamicEditorTheme; - } - public String getExcludedPackages() { return excludedPackages; } @@ -587,12 +581,12 @@ public class JadxSettings extends JadxCLIArgs { this.logLevel = level; } - public String getEditorThemePath() { - return editorThemePath; + public String getEditorTheme() { + return editorTheme; } - public void setEditorThemePath(String editorThemePath) { - this.editorThemePath = editorThemePath; + public void setEditorTheme(String editorTheme) { + this.editorTheme = editorTheme; } public String getLafTheme() { diff --git a/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java b/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java index 3bfb5b37f..9faf3f608 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/ui/JadxSettingsWindow.java @@ -67,7 +67,8 @@ import jadx.gui.settings.ui.font.JadxFontDialog; import jadx.gui.settings.ui.plugins.PluginSettings; import jadx.gui.settings.ui.shortcut.ShortcutsSettingsGroup; import jadx.gui.ui.MainWindow; -import jadx.gui.ui.codearea.EditorTheme; +import jadx.gui.ui.codearea.theme.EditorThemeManager; +import jadx.gui.ui.codearea.theme.ThemeIdAndName; import jadx.gui.ui.tab.dnd.TabDndGhostType; import jadx.gui.utils.FontUtils; import jadx.gui.utils.LafManager; @@ -351,28 +352,15 @@ public class JadxSettingsWindow extends JDialog { JButton fontBtn = new JButton(NLS.str("preferences.select_font")); JButton smaliFontBtn = new JButton(NLS.str("preferences.select_smali_font")); - EditorTheme[] editorThemes = EditorTheme.getAllThemes(); - JComboBox themesCbx = new JComboBox<>(editorThemes); - themesCbx.setEnabled(!settings.isUseDynamicEditorTheme()); - for (EditorTheme theme : editorThemes) { - if (theme.getPath().equals(settings.getEditorThemePath())) { - themesCbx.setSelectedItem(theme); - break; + EditorThemeManager editorThemeManager = mainWindow.getEditorThemeManager(); + JComboBox themesCbx = new JComboBox<>(editorThemeManager.getThemeIdNameArray()); + themesCbx.setSelectedItem(editorThemeManager.getCurrentThemeIdName()); + themesCbx.addActionListener(evt -> { + ThemeIdAndName selected = (ThemeIdAndName) themesCbx.getSelectedItem(); + if (selected != null) { + settings.setEditorTheme(selected.getId()); + mainWindow.loadSettings(); } - } - themesCbx.addActionListener(e -> { - int i = themesCbx.getSelectedIndex(); - EditorTheme editorTheme = editorThemes[i]; - settings.setEditorThemePath(editorTheme.getPath()); - mainWindow.loadSettings(); - }); - - JCheckBox useDynamicEditorTheme = new JCheckBox(); - useDynamicEditorTheme.setSelected(settings.isUseDynamicEditorTheme()); - useDynamicEditorTheme.addItemListener(e -> { - settings.setUseDynamicEditorTheme(e.getStateChange() == ItemEvent.SELECTED); - mainWindow.loadSettings(); - themesCbx.setEnabled(!settings.isUseDynamicEditorTheme()); }); JComboBox lafCbx = new JComboBox<>(LafManager.getThemes()); @@ -385,7 +373,6 @@ public class JadxSettingsWindow extends JDialog { SettingsGroup group = new SettingsGroup(NLS.str("preferences.appearance")); group.addRow(NLS.str("preferences.language"), languageCbx); group.addRow(NLS.str("preferences.laf_theme"), lafCbx); - group.addRow(NLS.str("preferences.dynamic_editor_theme"), useDynamicEditorTheme); group.addRow(NLS.str("preferences.theme"), themesCbx); JLabel fontLabel = group.addRow(getFontLabelStr(), fontBtn); JLabel smaliFontLabel = group.addRow(getSmaliFontLabelStr(), smaliFontBtn); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index 462c52c8c..9944ce016 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -21,11 +21,8 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.AffineTransform; import java.io.File; -import java.io.InputStream; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -67,8 +64,6 @@ import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.Theme; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -129,8 +124,8 @@ import jadx.gui.ui.action.ActionModel; import jadx.gui.ui.action.JadxGuiAction; import jadx.gui.ui.codearea.AbstractCodeArea; import jadx.gui.ui.codearea.AbstractCodeContentPanel; -import jadx.gui.ui.codearea.EditorTheme; import jadx.gui.ui.codearea.EditorViewState; +import jadx.gui.ui.codearea.theme.EditorThemeManager; import jadx.gui.ui.dialog.ADBDialog; import jadx.gui.ui.dialog.AboutDialog; import jadx.gui.ui.dialog.ExceptionDialog; @@ -192,6 +187,7 @@ public class MainWindow extends JFrame { private final TabsController tabsController; private final NavigationController navController; private final EditorSyncManager editorSyncManager; + private final EditorThemeManager editorThemeManager; private transient @NotNull JadxProject project; @@ -223,7 +219,6 @@ public class MainWindow extends JFrame { private transient Link updateLink; private transient ProgressPanel progressPane; - private transient Theme editorTheme; private transient IssuesPanel issuesPanel; private transient @Nullable LogPanel logPanel; @@ -252,11 +247,12 @@ public class MainWindow extends JFrame { this.shortcutsController = new ShortcutsController(settings); this.tabsController = new TabsController(this); this.navController = new NavigationController(this); + this.editorThemeManager = new EditorThemeManager(settings); JadxEventQueue.register(); resetCache(); FontUtils.registerBundledFonts(); - setEditorTheme(settings.getEditorThemePath()); + editorThemeManager.setTheme(settings.getEditorTheme()); initUI(); this.editorSyncManager = new EditorSyncManager(this, tabbedPane); this.backgroundExecutor = new BackgroundExecutor(settings, progressPane); @@ -1443,40 +1439,6 @@ public class MainWindow extends JFrame { setLocationRelativeTo(null); } - private void setEditorTheme(String editorThemePath) { - try { - URL themeUrl = getClass().getResource(editorThemePath); - if (themeUrl != null) { - try (InputStream is = themeUrl.openStream()) { - editorTheme = Theme.load(is); - return; - } - } - Path themePath = Paths.get(editorThemePath); - if (Files.isRegularFile(themePath)) { - try (InputStream is = Files.newInputStream(themePath)) { - editorTheme = Theme.load(is); - return; - } - } - } catch (Exception e) { - LOG.error("Failed to load editor theme: {}", editorThemePath, e); - } - LOG.warn("Falling back to default editor theme: {}", editorThemePath); - editorThemePath = EditorTheme.getDefaultTheme().getPath(); - try (InputStream is = getClass().getResourceAsStream(editorThemePath)) { - editorTheme = Theme.load(is); - return; - } catch (Exception e) { - LOG.error("Failed to load default editor theme: {}", editorThemePath, e); - editorTheme = new Theme(new RSyntaxTextArea()); - } - } - - public Theme getEditorTheme() { - return editorTheme; - } - private void openSettings() { settingsOpen = true; @@ -1501,12 +1463,12 @@ public class MainWindow extends JFrame { private void updateUiSettings() { LafManager.updateLaf(settings); + editorThemeManager.setTheme(settings.getEditorTheme()); Font font = settings.getFont(); Font largerFont = font.deriveFont(font.getSize() + 2.f); setFont(largerFont); - setEditorTheme(settings.getEditorThemePath()); tree.setFont(largerFont); tree.setRowHeight(-1); @@ -1535,6 +1497,7 @@ public class MainWindow extends JFrame { heapUsageBar.reset(); closeAll(); + editorThemeManager.unload(); dispose(); System.exit(0); } @@ -1754,6 +1717,10 @@ public class MainWindow extends JFrame { return cacheManager; } + public EditorThemeManager getEditorThemeManager() { + return editorThemeManager; + } + public JadxGuiEventsImpl events() { return events; } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java index 971733704..360f70fd4 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java @@ -374,18 +374,12 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea { public static void loadCommonSettings(MainWindow mainWindow, RSyntaxTextArea area) { JadxSettings settings = mainWindow.getSettings(); - if (settings.isUseDynamicEditorTheme()) { - DynamicCoreAreaTheme.applyCustomTheme(area); - } else { - mainWindow.getEditorTheme().apply(area); - } - + mainWindow.getEditorThemeManager().apply(area); area.setFont(settings.getFont()); Gutter gutter = RSyntaxUtilities.getGutter(area); if (gutter != null) { gutter.setLineNumberFont(settings.getFont()); } - } public void loadSettings() { @@ -520,14 +514,6 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea { } } - @Override - public void updateUI() { - super.updateUI(); - if (contentPanel != null && contentPanel.getMainWindow() != null) { - loadSettings(); - } - } - @Override public Dimension getPreferredSize() { try { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java index 57e03bd47..e8b9b7a83 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeArea.java @@ -45,6 +45,7 @@ public final class CodeArea extends AbstractCodeArea { private static final long serialVersionUID = 6312736869579635796L; private @Nullable ICodeInfo cachedCodeInfo; + private @Nullable MouseHoverHighlighter mouseHoverHighlighter; private final ShortcutsController shortcutsController; CodeArea(ContentPanel contentPanel, JNode node) { @@ -76,7 +77,16 @@ public final class CodeArea extends AbstractCodeArea { }); if (isJavaCode) { - addMouseMotionListener(new MouseHoverHighlighter(this, codeLinkGenerator)); + mouseHoverHighlighter = new MouseHoverHighlighter(this, codeLinkGenerator); + addMouseMotionListener(mouseHoverHighlighter); + } + } + + @Override + public void loadSettings() { + super.loadSettings(); + if (mouseHoverHighlighter != null) { + mouseHoverHighlighter.loadSettings(); } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorTheme.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorTheme.java deleted file mode 100644 index 3fa504aa8..000000000 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorTheme.java +++ /dev/null @@ -1,49 +0,0 @@ -package jadx.gui.ui.codearea; - -public final class EditorTheme { - private static final String RSTA_THEME_PATH = "/org/fife/ui/rsyntaxtextarea/themes/"; - - private static final EditorTheme[] ALL_THEMES = - new EditorTheme[] { - new EditorTheme("default"), - new EditorTheme("eclipse"), - new EditorTheme("idea"), - new EditorTheme("vs"), - new EditorTheme("dark"), - new EditorTheme("monokai"), - new EditorTheme("druid") - }; - - public static EditorTheme[] getAllThemes() { - return ALL_THEMES; - } - - public static EditorTheme getDefaultTheme() { - return ALL_THEMES[0]; - } - - private final String name; - private final String path; - - public EditorTheme(String name) { - this(name, RSTA_THEME_PATH + name + ".xml"); - } - - public EditorTheme(String name, String path) { - this.name = name; - this.path = path; - } - - public String getName() { - return name; - } - - public String getPath() { - return path; - } - - @Override - public String toString() { - return name; - } -} diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexArea.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexArea.java index 487d378e7..41aebb4f0 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexArea.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexArea.java @@ -9,7 +9,6 @@ import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import org.apache.commons.lang3.StringUtils; -import org.fife.ui.rsyntaxtextarea.Theme; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,6 +18,7 @@ import jadx.api.ResourcesLoader; import jadx.core.utils.exceptions.JadxException; import jadx.gui.treemodel.JNode; import jadx.gui.treemodel.JResource; +import jadx.gui.ui.MainWindow; import jadx.gui.ui.panel.ContentPanel; import jadx.gui.utils.UiUtils; @@ -85,12 +85,12 @@ public class HexArea extends AbstractCodeArea { } private void applyTheme() { - Font font = getContentPanel().getMainWindow().getSettings().getSmaliFont(); + MainWindow mainWindow = getContentPanel().getMainWindow(); + mainWindow.getEditorThemeManager().apply(this); + Font font = mainWindow.getSettings().getSmaliFont(); setFont(font); - - Theme theme = contentPanel.getMainWindow().getEditorTheme(); if (hexPreviewPanel != null) { - hexPreviewPanel.applyTheme(theme, font); + hexPreviewPanel.applyTheme(this, font); } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexPreviewPanel.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexPreviewPanel.java index 20df6f179..564f68602 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexPreviewPanel.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/HexPreviewPanel.java @@ -10,7 +10,6 @@ import javax.swing.text.DefaultHighlighter; import javax.swing.text.Highlighter; import org.fife.ui.rsyntaxtextarea.SyntaxScheme; -import org.fife.ui.rsyntaxtextarea.Theme; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -79,11 +78,11 @@ public class HexPreviewPanel extends JTextArea { setBorder(new MatteBorder(0, 2, 0, 0, borderColor)); } - public void applyTheme(Theme theme, Font font) { - setBackground(theme.bgColor); - setHighlightColor(theme.selectionBG); - setBorderColor(theme.gutterBorderColor); - setDisabledTextColor(theme.scheme.getStyle(SyntaxScheme.IDENTIFIER).foreground); + public void applyTheme(HexArea hexArea, Font font) { + setBackground(hexArea.getBackground()); + setHighlightColor(hexArea.getSelectionColor()); + setBorderColor(hexArea.getMatchedBracketBorderColor()); + setDisabledTextColor(hexArea.getSyntaxScheme().getStyle(SyntaxScheme.IDENTIFIER).foreground); setFont(font); } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java index 31a0d6ef7..cae341e57 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java @@ -3,7 +3,7 @@ package jadx.gui.ui.codearea; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; -import javax.swing.text.Highlighter; +import javax.swing.text.Caret; import org.fife.ui.rsyntaxtextarea.Token; import org.fife.ui.rtextarea.SmartHighlightPainter; @@ -19,7 +19,7 @@ class MouseHoverHighlighter extends MouseMotionAdapter { private final CodeArea codeArea; private final CodeLinkGenerator codeLinkGenerator; - private final Highlighter.HighlightPainter highlighter; + private final SmartHighlightPainter highlighter; private Object tag; private int highlightedTokenOffset = -1; @@ -27,7 +27,12 @@ class MouseHoverHighlighter extends MouseMotionAdapter { public MouseHoverHighlighter(CodeArea codeArea, CodeLinkGenerator codeLinkGenerator) { this.codeArea = codeArea; this.codeLinkGenerator = codeLinkGenerator; - this.highlighter = new SmartHighlightPainter(codeArea.getMarkOccurrencesColor()); + this.highlighter = new SmartHighlightPainter(); + loadSettings(); + } + + public void loadSettings() { + highlighter.setPaint(codeArea.getMarkOccurrencesColor()); } @Override @@ -41,6 +46,11 @@ class MouseHoverHighlighter extends MouseMotionAdapter { if (e.getModifiersEx() != 0) { return false; } + Caret caret = codeArea.getCaret(); + if (caret.getDot() != caret.getMark()) { + // selection in action, highlight will interfere with selection + return false; + } try { Token token = codeArea.viewToToken(e.getPoint()); if (token == null) { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/SmaliArea.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/SmaliArea.java index 51f469177..d86ddedc0 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/SmaliArea.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/SmaliArea.java @@ -26,7 +26,6 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; import org.fife.ui.rsyntaxtextarea.Style; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.SyntaxScheme; -import org.fife.ui.rsyntaxtextarea.Theme; import org.fife.ui.rtextarea.Gutter; import org.fife.ui.rtextarea.GutterIconInfo; import org.fife.ui.rtextarea.IconRowHeader; @@ -122,7 +121,7 @@ public final class SmaliArea extends AbstractCodeArea { if (model != null) { model.unload(); } - model = shouldUseSmaliPrinterV2() ? new DebugModel() : new NormalModel(); + model = shouldUseSmaliPrinterV2() ? new DebugModel() : new NormalModel(this); } public void scrollToDebugPos(int pos) { @@ -175,11 +174,8 @@ public final class SmaliArea extends AbstractCodeArea { private class NormalModel extends SmaliModel { - public NormalModel() { - if (!getContentPanel().getMainWindow().getSettings().isUseDynamicEditorTheme()) { - Theme theme = getContentPanel().getMainWindow().getEditorTheme(); - setSyntaxScheme(theme.scheme); - } + public NormalModel(SmaliArea smaliArea) { + getContentPanel().getMainWindow().getEditorThemeManager().apply(smaliArea); setSyntaxEditingStyle(SYNTAX_STYLE_SMALI); } @@ -200,7 +196,7 @@ public final class SmaliArea extends AbstractCodeArea { private Object runningHighlightTag = null; // running line private final SmaliV2Style smaliV2Style = new SmaliV2Style(SmaliArea.this); private final Map bpMap = new HashMap<>(); - private final PropertyChangeListener listener = evt -> { + private final PropertyChangeListener schemeListener = evt -> { if (smaliV2Style.refreshTheme()) { setSyntaxScheme(smaliV2Style); } @@ -209,7 +205,7 @@ public final class SmaliArea extends AbstractCodeArea { public DebugModel() { loadV2Style(); setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_ASSEMBLER_6502); - addPropertyChangeListener(SYNTAX_SCHEME_PROPERTY, listener); + addPropertyChangeListener(SYNTAX_SCHEME_PROPERTY, schemeListener); regBreakpointEvents(); } @@ -229,7 +225,7 @@ public final class SmaliArea extends AbstractCodeArea { @Override public void unload() { - removePropertyChangeListener(listener); + removePropertyChangeListener(schemeListener); removeLineHighlight(runningHighlightTag); UiUtils.removeKeyBinding(SmaliArea.this, bpShortcut, "set a break point"); BreakpointManager.removeListener((JClass) node); @@ -316,11 +312,9 @@ public final class SmaliArea extends AbstractCodeArea { } private class SmaliV2Style extends SyntaxScheme { - Theme curTheme; - public SmaliV2Style(SmaliArea smaliArea) { super(true); - curTheme = smaliArea.getContentPanel().getMainWindow().getEditorTheme(); + smaliArea.getContentPanel().getMainWindow().getEditorThemeManager().apply(smaliArea); updateTheme(); } @@ -329,13 +323,8 @@ public final class SmaliArea extends AbstractCodeArea { } public boolean refreshTheme() { - if (getContentPanel().getMainWindow().getSettings().isUseDynamicEditorTheme()) { - return false; - } - Theme theme = getContentPanel().getMainWindow().getEditorTheme(); - boolean refresh = theme != curTheme; + boolean refresh = getSyntaxScheme() != this; if (refresh) { - curTheme = theme; updateTheme(); } return refresh; diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/DynamicCoreAreaTheme.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/DynamicCodeAreaTheme.java similarity index 81% rename from jadx-gui/src/main/java/jadx/gui/ui/codearea/DynamicCoreAreaTheme.java rename to jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/DynamicCodeAreaTheme.java index 25aa57aad..940ae4162 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/DynamicCoreAreaTheme.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/DynamicCodeAreaTheme.java @@ -1,4 +1,4 @@ -package jadx.gui.ui.codearea; +package jadx.gui.ui.codearea.theme; import java.awt.Color; @@ -9,20 +9,36 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; import org.fife.ui.rsyntaxtextarea.SyntaxScheme; import org.fife.ui.rsyntaxtextarea.Token; import org.fife.ui.rtextarea.Gutter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -public class DynamicCoreAreaTheme { - private static final Logger LOG = LoggerFactory.getLogger(DynamicCoreAreaTheme.class); +import jadx.gui.utils.NLS; - public static void applyCustomTheme(RSyntaxTextArea textArea) { - // Get the current theme's background color from UIManager +/** + * Mix current UI theme colors and apply to code area theme. + */ +public class DynamicCodeAreaTheme implements IEditorTheme { + + @Override + public String getId() { + return "DynamicCodeAreaTheme"; + } + + @Override + public String getName() { + return NLS.str("preferences.dynamic_editor_theme"); + } + + public void apply(RSyntaxTextArea textArea) { + // Get the current colors from UIManager Color themeBackground = UIManager.getColor("Panel.background"); - - boolean isDarkTheme = isDarkTheme(themeBackground); + Color themeForeground = UIManager.getColor("Panel.foreground"); + Color separatorForeground = UIManager.getColor("Separator.foreground"); + Color editorSelectionBackground = UIManager.getColor("EditorPane.selectionBackground"); + Color caretForeground = UIManager.getColor("EditorPane.caretForeground"); SyntaxScheme scheme = textArea.getSyntaxScheme(); + boolean isDarkTheme = isDarkTheme(themeBackground); + // Background colors based on the theme Color editorBackground = isDarkTheme ? themeBackground : Color.WHITE; // Use white for light theme Color lineHighlight = isDarkTheme @@ -36,15 +52,12 @@ public class DynamicCoreAreaTheme { : new Color(51, 153, 255, 50); // Lighter blue for light theme Color markAllHighlightColor = isDarkTheme ? Color.decode("#32593D") : Color.decode("#ffc800"); - Color markOccurrencesColor = isDarkTheme ? Color.decode("#52503A") : Color.decode("#FCE8F4"); Color matchedBracketBackground = isDarkTheme ? adjustBrightness(Color.decode("#3B514D"), 1.2f) : Color.decode("#93D9D9"); - Color gutterBorderColor = UIManager.getColor("Separator.foreground"); - Color hyperlinkColor = UIManager.getColor("EditorPane.selectionBackground"); + Color markOccurrencesColor = adjustBrightness(editorSelectionBackground, isDarkTheme ? 0.6f : 1.4f); // Set the syntax colors for the theme if (isDarkTheme) { Color dataTypeColor = Color.decode("#4EC9B0"); - Color booleanColor = Color.decode("#569CD6"); scheme.getStyle(Token.COMMENT_EOL).foreground = Color.decode("#57A64A"); scheme.getStyle(Token.COMMENT_MULTILINE).foreground = Color.decode("#57A64A"); scheme.getStyle(Token.COMMENT_DOCUMENTATION).foreground = Color.decode("#57A64A"); @@ -56,21 +69,19 @@ public class DynamicCoreAreaTheme { scheme.getStyle(Token.LITERAL_NUMBER_DECIMAL_INT).foreground = Color.decode("#D7BA7D"); scheme.getStyle(Token.LITERAL_NUMBER_FLOAT).foreground = Color.decode("#D7BA7D"); scheme.getStyle(Token.LITERAL_NUMBER_HEXADECIMAL).foreground = Color.decode("#D7BA7D"); - scheme.getStyle(Token.LITERAL_BOOLEAN).foreground = booleanColor; + scheme.getStyle(Token.LITERAL_BOOLEAN).foreground = Color.decode("#569CD6"); scheme.getStyle(Token.LITERAL_CHAR).foreground = Color.decode("#CE9178"); scheme.getStyle(Token.LITERAL_STRING_DOUBLE_QUOTE).foreground = Color.decode("#CE9178"); scheme.getStyle(Token.DATA_TYPE).foreground = dataTypeColor; scheme.getStyle(Token.OPERATOR).foreground = Color.WHITE; scheme.getStyle(Token.SEPARATOR).foreground = Color.WHITE; - scheme.getStyle(Token.IDENTIFIER).foreground = Color.decode("#9CDCFE"); + scheme.getStyle(Token.IDENTIFIER).foreground = themeForeground; // XML-specific colors for dark theme scheme.getStyle(Token.MARKUP_TAG_DELIMITER).foreground = Color.decode("#808080"); // Gray for < > / scheme.getStyle(Token.MARKUP_TAG_NAME).foreground = Color.decode("#569CD6"); // Blue for tag names scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE).foreground = Color.decode("#9CDCFE"); // Light blue for attributes scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE_VALUE).foreground = Color.decode("#CE9178"); // Orange for values } else { - Color booleanColor = Color.decode("#0451A5"); - Color keyColor = Color.decode("#4A7A4F"); // Soft green for keys Color dataTypeColor = Color.decode("#267F99"); scheme.getStyle(Token.COMMENT_EOL).foreground = Color.decode("#008000"); scheme.getStyle(Token.COMMENT_MULTILINE).foreground = Color.decode("#008000"); @@ -84,39 +95,39 @@ public class DynamicCoreAreaTheme { scheme.getStyle(Token.LITERAL_NUMBER_DECIMAL_INT).foreground = Color.decode("#098658"); scheme.getStyle(Token.LITERAL_NUMBER_FLOAT).foreground = Color.decode("#098658"); scheme.getStyle(Token.LITERAL_NUMBER_HEXADECIMAL).foreground = Color.decode("#098658"); - scheme.getStyle(Token.LITERAL_BOOLEAN).foreground = booleanColor; + scheme.getStyle(Token.LITERAL_BOOLEAN).foreground = Color.decode("#0451A5"); scheme.getStyle(Token.LITERAL_CHAR).foreground = Color.decode("#067d17"); scheme.getStyle(Token.LITERAL_STRING_DOUBLE_QUOTE).foreground = Color.decode("#067d17"); // Soft blue for values scheme.getStyle(Token.DATA_TYPE).foreground = dataTypeColor; scheme.getStyle(Token.OPERATOR).foreground = Color.decode("#333333"); scheme.getStyle(Token.SEPARATOR).foreground = Color.decode("#333333"); - scheme.getStyle(Token.IDENTIFIER).foreground = Color.decode("#001080"); + scheme.getStyle(Token.IDENTIFIER).foreground = themeForeground; // XML-specific colors for light theme scheme.getStyle(Token.MARKUP_TAG_DELIMITER).foreground = Color.decode("#800000"); // Dark red for < > / - scheme.getStyle(Token.MARKUP_TAG_NAME).foreground = keyColor; // Soft green for tag names (keys) + scheme.getStyle(Token.MARKUP_TAG_NAME).foreground = Color.decode("#4A7A4F"); // Soft green for tag names (keys) scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE).foreground = Color.decode("#FF0000"); // Red for attributes scheme.getStyle(Token.MARKUP_TAG_ATTRIBUTE_VALUE).foreground = Color.decode("#0000FF"); // Blue for values } - // Apply background colors textArea.setBackground(editorBackground); - textArea.setCaretColor(UIManager.getColor("EditorPane.caretForeground")); + textArea.setCaretColor(caretForeground); textArea.setSelectionColor(selectionColor); textArea.setCurrentLineHighlightColor(lineHighlight); textArea.setMarkAllHighlightColor(markAllHighlightColor); textArea.setMarkOccurrencesColor(markOccurrencesColor); - textArea.setHyperlinkForeground(hyperlinkColor); + textArea.setHyperlinkForeground(editorSelectionBackground); textArea.setMatchedBracketBGColor(matchedBracketBackground); textArea.setMatchedBracketBorderColor(lineNumberForeground); textArea.setPaintMatchedBracketPair(true); textArea.setAnimateBracketMatching(false); textArea.setFadeCurrentLineHighlight(true); + // Reset gutter colors directly to ensure the change applies Gutter gutter = RSyntaxUtilities.getGutter(textArea); if (gutter != null) { gutter.setBackground(editorBackground); - gutter.setBorderColor(gutterBorderColor); + gutter.setBorderColor(separatorForeground); gutter.setLineNumberColor(lineNumberForeground); } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/EditorThemeManager.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/EditorThemeManager.java new file mode 100644 index 000000000..fcba57563 --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/EditorThemeManager.java @@ -0,0 +1,99 @@ +package jadx.gui.ui.codearea.theme; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jadx.core.utils.StringUtils; +import jadx.gui.settings.JadxSettings; + +public class EditorThemeManager { + private static final Logger LOG = LoggerFactory.getLogger(EditorThemeManager.class); + + private final List themes = new ArrayList<>(); + private final Map themesMap = new HashMap<>(); + + private IEditorTheme currentTheme = new FallbackEditorTheme(); + + public EditorThemeManager(JadxSettings settings) { + registerThemes(); + if (StringUtils.isEmpty(settings.getEditorTheme())) { + // set default theme + IEditorTheme defaultTheme = themes.get(0); + settings.setEditorTheme(defaultTheme.getId()); + } + } + + private void registerThemes() { + registerTheme(new DynamicCodeAreaTheme()); + registerTheme(new RSTABundledTheme("default")); + registerTheme(new RSTABundledTheme("eclipse")); + registerTheme(new RSTABundledTheme("idea")); + registerTheme(new RSTABundledTheme("vs")); + registerTheme(new RSTABundledTheme("dark")); + registerTheme(new RSTABundledTheme("monokai")); + registerTheme(new RSTABundledTheme("druid")); + } + + public void registerTheme(IEditorTheme editorTheme) { + IEditorTheme prev = themesMap.put(editorTheme.getId(), editorTheme); + if (prev != null) { + themes.remove(prev); + } + themes.add(editorTheme); + } + + public synchronized void setTheme(String id) { + if (currentTheme.getId().equals(id)) { + // already set + return; + } + // resolve new + IEditorTheme newTheme = themesMap.get(id); + if (newTheme == null) { + LOG.warn("Failed to resolve editor theme: {}", id); + return; + } + // unload current + unload(); + + // load new + try { + newTheme.load(); + } catch (Throwable t) { + LOG.warn("Failed to load editor theme: {}", id, t); + } + currentTheme = newTheme; + } + + public void apply(RSyntaxTextArea textArea) { + this.currentTheme.apply(textArea); + } + + public ThemeIdAndName[] getThemeIdNameArray() { + return themes.stream() + .map(EditorThemeManager::toThemeIdAndName) + .toArray(ThemeIdAndName[]::new); + } + + public ThemeIdAndName getCurrentThemeIdName() { + return toThemeIdAndName(currentTheme); + } + + private static ThemeIdAndName toThemeIdAndName(IEditorTheme t) { + return new ThemeIdAndName(t.getId(), t.getName()); + } + + public void unload() { + try { + currentTheme.unload(); + } catch (Throwable t) { + LOG.warn("Failed to unload editor theme: {}", currentTheme.getId(), t); + } + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/FallbackEditorTheme.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/FallbackEditorTheme.java new file mode 100644 index 000000000..9ad16e845 --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/FallbackEditorTheme.java @@ -0,0 +1,28 @@ +package jadx.gui.ui.codearea.theme; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Theme; + +public class FallbackEditorTheme implements IEditorTheme { + private Theme baseTheme; + + @Override + public String getId() { + return "fallback"; + } + + @Override + public String getName() { + return "Fallback"; + } + + @Override + public void load() { + baseTheme = new Theme(new RSyntaxTextArea()); + } + + @Override + public void apply(RSyntaxTextArea textArea) { + baseTheme.apply(textArea); + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/IEditorTheme.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/IEditorTheme.java new file mode 100644 index 000000000..86c0393f9 --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/IEditorTheme.java @@ -0,0 +1,20 @@ +package jadx.gui.ui.codearea.theme; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; + +public interface IEditorTheme { + + String getId(); + + String getName(); + + default void load() { + // optional method + } + + void apply(RSyntaxTextArea textArea); + + default void unload() { + // optional method + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTABundledTheme.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTABundledTheme.java new file mode 100644 index 000000000..03b83a3a1 --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTABundledTheme.java @@ -0,0 +1,55 @@ +package jadx.gui.ui.codearea.theme; + +import java.io.InputStream; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RSTABundledTheme implements IEditorTheme { + private static final Logger LOG = LoggerFactory.getLogger(RSTABundledTheme.class); + + private static final String RSTA_THEME_PATH = "/org/fife/ui/rsyntaxtextarea/themes/"; + + private final String name; + + private Theme loadedTheme; + + public RSTABundledTheme(String name) { + this.name = name; + } + + @Override + public String getId() { + return "RSTA:" + name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void load() { + String path = RSTA_THEME_PATH + name + ".xml"; + try { + try (InputStream is = RSTABundledTheme.class.getResourceAsStream(path)) { + loadedTheme = Theme.load(is); + } + } catch (Throwable t) { + LOG.error("Failed to load editor theme: {}", path, t); + loadedTheme = new Theme(new RSyntaxTextArea()); + } + } + + @Override + public void apply(RSyntaxTextArea textArea) { + loadedTheme.apply(textArea); + } + + @Override + public void unload() { + loadedTheme = null; + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTAThemeXML.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTAThemeXML.java new file mode 100644 index 000000000..d2d31944d --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/RSTAThemeXML.java @@ -0,0 +1,56 @@ +package jadx.gui.ui.codearea.theme; + +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RSTAThemeXML implements IEditorTheme { + private static final Logger LOG = LoggerFactory.getLogger(RSTAThemeXML.class); + + private final Path themePath; + private final String name; + + private Theme loadedTheme; + + public RSTAThemeXML(Path themeXmlPath, String name) { + this.themePath = themeXmlPath; + this.name = name; + } + + @Override + public String getId() { + return "file:" + themePath; + } + + @Override + public String getName() { + return name; + } + + @Override + public void load() { + try { + try (InputStream is = Files.newInputStream(themePath)) { + loadedTheme = Theme.load(is); + } + } catch (Exception e) { + LOG.warn("Failed to load editor theme: {}", themePath, e); + loadedTheme = new Theme(new RSyntaxTextArea()); + } + } + + @Override + public void apply(RSyntaxTextArea textArea) { + loadedTheme.apply(textArea); + } + + @Override + public void unload() { + loadedTheme = null; + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/ThemeIdAndName.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/ThemeIdAndName.java new file mode 100644 index 000000000..aa0e26544 --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/theme/ThemeIdAndName.java @@ -0,0 +1,37 @@ +package jadx.gui.ui.codearea.theme; + +public class ThemeIdAndName { + private final String id; + private final String name; + + public ThemeIdAndName(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public final boolean equals(Object other) { + if (!(other instanceof ThemeIdAndName)) { + return false; + } + return id.equals(((ThemeIdAndName) other).id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public String toString() { + return name; + } +} diff --git a/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties b/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties index 0958ee179..032c1cb88 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_de_DE.properties @@ -242,7 +242,7 @@ preferences.integerFormat=Ganzzahlformat preferences.font=Schriftart ändern preferences.smali_font=Monospaced-Schriftart (Smali/Hex) preferences.laf_theme=Thema -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=Thema ändern preferences.start_jobs=Autom. Hintergrunddekompilierung starten preferences.select_font=Ändern diff --git a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties index 3c364bebd..dfc8e4112 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties @@ -242,7 +242,7 @@ preferences.integerFormat=Integer format preferences.font=Editor font preferences.smali_font=Monospaced font (Smali/Hex) preferences.laf_theme=Theme -preferences.dynamic_editor_theme=Use dynamic editor theme +preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=Editor theme preferences.start_jobs=Auto start background decompilation preferences.select_font=Change diff --git a/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties b/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties index 99e2708cd..f5fb4c93f 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_es_ES.properties @@ -242,7 +242,7 @@ preferences.raw_cfg=Generate RAW CFG graphs preferences.font=Fuente del editor #preferences.smali_font=Monospaced font (Smali/Hex) #preferences.laf_theme=Theme -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=Tema del editor preferences.start_jobs=Inicio autom. descompilación de fondo preferences.select_font=Seleccionar diff --git a/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties b/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties index a852c9cd5..0e70ea335 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_id_ID.properties @@ -242,7 +242,7 @@ preferences.integerFormat=Format bilangan bulat preferences.font=Font editor preferences.smali_font=Font monospasi (Smali/Hex) preferences.laf_theme=Tema -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=Tema editor preferences.start_jobs=Deskompilasi latar belakang otomatis preferences.select_font=Ubah diff --git a/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties b/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties index 5737b5cb6..732f55299 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties @@ -242,7 +242,7 @@ preferences.raw_cfg=RAW CFG 그래프 생성 preferences.font=에디터 글씨체 #preferences.smali_font=Monospaced font (Smali/Hex) preferences.laf_theme=테마 -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=에디터 테마 preferences.start_jobs=백그라운드에서 디컴파일 자동 시작 preferences.select_font=변경 diff --git a/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties b/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties index 2492d3aa7..ffacb1a83 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties @@ -242,7 +242,7 @@ preferences.raw_cfg=Gera gráficos CFG no formato RAW preferences.font=Fonte do editor #preferences.smali_font=Monospaced font (Smali/Hex) preferences.laf_theme=Tema -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=Tema do editor preferences.start_jobs=Inicializar descompilação automaticamente em segundo-plano preferences.select_font=Alterar diff --git a/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties b/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties index 43f336312..18a435864 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties @@ -242,7 +242,7 @@ preferences.integerFormat=Формат чисел preferences.font=Шрифт редактора Java preferences.smali_font=Шрифт smali/HEX редактора preferences.laf_theme=Тема приложения -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=Тема редактора preferences.start_jobs=Автоматическая декомпиляция preferences.select_font=Изменить diff --git a/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties b/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties index 60f2db84f..97d5bbd94 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties @@ -242,7 +242,7 @@ preferences.integerFormat=数值格式化 preferences.font=编辑器字体 preferences.smali_font=等宽字体 (Smali/Hex) preferences.laf_theme=主题 -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=编辑器主题 preferences.start_jobs=自动进行后台反编译 preferences.select_font=修改 diff --git a/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties b/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties index 16970b736..cb50beb96 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties @@ -242,7 +242,7 @@ preferences.integerFormat=整數模式 preferences.font=編輯器字型 preferences.smali_font=等寬字型 (Smali/Hex) preferences.laf_theme=主題 -#preferences.dynamic_editor_theme=Use dynamic editor theme +#preferences.dynamic_editor_theme=Use UI theme colors preferences.theme=編輯器主題 preferences.start_jobs=自動開始背景反編譯 preferences.select_font=變更