1
2
3
4
5
6
7
8
9
10
11 package com.jsql.view.swing.menubar;
12
13 import com.jsql.util.GitUtil.ShowOnConsole;
14 import com.jsql.util.I18nUtil;
15 import com.jsql.util.LogLevelUtil;
16 import com.jsql.view.swing.action.ActionSaveTab;
17 import com.jsql.view.swing.action.HotkeyUtil;
18 import com.jsql.view.swing.console.JTextPaneAppender;
19 import com.jsql.view.swing.dialog.DialogAbout;
20 import com.jsql.view.swing.dialog.DialogTranslate;
21 import com.jsql.view.swing.dialog.translate.Language;
22 import com.jsql.view.swing.panel.preferences.PanelExploit;
23 import com.jsql.view.swing.panel.preferences.PanelTampering;
24 import com.jsql.view.swing.sql.SqlEngine;
25 import com.jsql.view.swing.table.PanelTable;
26 import com.jsql.view.swing.text.JPopupTextArea;
27 import com.jsql.view.swing.text.JToolTipI18n;
28 import com.jsql.view.swing.util.I18nViewUtil;
29 import com.jsql.view.swing.util.MediatorHelper;
30 import com.jsql.view.swing.util.ModelSvgIcon;
31 import com.jsql.view.swing.util.UiUtil;
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.logging.log4j.LogManager;
34 import org.apache.logging.log4j.Logger;
35
36 import javax.swing.*;
37 import javax.swing.table.JTableHeader;
38 import javax.swing.table.TableColumnModel;
39 import javax.swing.text.JTextComponent;
40 import javax.swing.text.StyleConstants;
41 import java.awt.*;
42 import java.awt.event.InputEvent;
43 import java.awt.event.KeyEvent;
44 import java.awt.event.MouseAdapter;
45 import java.awt.event.MouseEvent;
46 import java.util.Arrays;
47 import java.util.List;
48 import java.util.Locale;
49 import java.util.stream.Stream;
50
51
52
53
54 public class AppMenubar extends JMenuBar {
55
56 private static final Logger LOGGER = LogManager.getRootLogger();
57
58 public static final String MENU_COMMUNITY = "menuCommunity";
59 public static final String MENU_I18N_CONTRIBUTION = "menuI18nContribution";
60 public static final String ITEM_INTO_FRENCH = "itemIntoFrench";
61 public static final String MENU_HELP = "menuHelp";
62 public static final String ITEM_HELP = "itemHelp";
63
64 private final MenuWindows menuWindows;
65
66 protected static final List<ModelItemTranslate> ITEMS_TRANSLATE = Stream.of(
67 Language.EN, Language.FR, Language.ES, Language.IT, Language.AR, Language.ZH, Language.RU, Language.TR, Language.KO,
68 Language.SE, Language.FI, Language.CS, Language.PT, Language.PL, Language.ID, Language.NL, Language.RO, Language.DE
69 ).map(ModelItemTranslate::new).toList();
70
71 private static final List<ModelItemTranslate> ITEMS_TRANSLATE_INTO = Stream.of(
72 Language.FR, Language.ES, Language.SE, Language.FI, Language.TR, Language.CS, Language.RO, Language.IT, Language.PT, Language.AR,
73 Language.PL, Language.RU, Language.ZH, Language.DE, Language.ID, Language.JA, Language.KO, Language.HI, Language.NL, Language.TA
74 ).map(ModelItemTranslate::new).toList();
75
76
77
78
79 public AppMenubar() {
80 this.add(this.initMenuFile());
81 this.add(this.initMenuEdit());
82 this.add(this.initMenuCommunity());
83 this.menuWindows = new MenuWindows(this);
84 this.add(this.menuWindows);
85 this.add(this.initMenuHelp());
86 }
87
88 private JMenu initMenuFile() {
89 var menuFile = new JMenu(I18nUtil.valueByKey("MENUBAR_FILE"));
90 I18nViewUtil.addComponentForKey("MENUBAR_FILE", menuFile);
91 menuFile.setMnemonic('F');
92
93 JMenuItem itemSave = new JMenuItem(new ActionSaveTab());
94 I18nViewUtil.addComponentForKey("MENUBAR_FILE_SAVETABAS", itemSave);
95
96 JMenuItem itemExit = new JMenuItem(I18nUtil.valueByKey("MENUBAR_FILE_EXIT"), 'x');
97 I18nViewUtil.addComponentForKey("MENUBAR_FILE_EXIT", itemExit);
98 itemExit.addActionListener(actionEvent -> MediatorHelper.frame().dispose());
99
100 HotkeyUtil.addShortcut(this);
101
102 menuFile.add(itemSave);
103 menuFile.add(new JSeparator());
104 menuFile.add(itemExit);
105 return menuFile;
106 }
107
108 private JMenu initMenuEdit() {
109 var menuEdit = new JMenu(I18nUtil.valueByKey("MENUBAR_EDIT"));
110 I18nViewUtil.addComponentForKey("MENUBAR_EDIT", menuEdit);
111 menuEdit.setMnemonic('E');
112
113 JMenuItem itemCopy = new JMenuItem(I18nUtil.valueByKey("CONTEXT_MENU_COPY"), 'C');
114 I18nViewUtil.addComponentForKey("CONTEXT_MENU_COPY", itemCopy);
115 itemCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK));
116 itemCopy.addActionListener(actionEvent -> {
117 if (MediatorHelper.tabResults().getSelectedComponent() instanceof PanelTable panelTable) {
118 panelTable.copyTable();
119 } else if (MediatorHelper.tabResults().getSelectedComponent() instanceof JScrollPane jScrollPane) {
120 ((JTextComponent) jScrollPane.getViewport().getView()).copy();
121 }
122 });
123
124 JMenuItem itemSelectAll = new JMenuItem(I18nUtil.valueByKey("CONTEXT_MENU_SELECT_ALL"), 'A');
125 I18nViewUtil.addComponentForKey("CONTEXT_MENU_SELECT_ALL", itemSelectAll);
126 itemSelectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
127 itemSelectAll.addActionListener(actionEvent -> {
128 if (MediatorHelper.tabResults().getSelectedComponent() instanceof PanelTable panelTable) {
129 panelTable.selectTable();
130 } else if (MediatorHelper.tabResults().getSelectedComponent() instanceof JScrollPane jScrollPane) {
131
132 jScrollPane.getViewport().getView().requestFocusInWindow();
133 ((JTextComponent) jScrollPane.getViewport().getView()).selectAll();
134 }
135 });
136
137 menuEdit.add(itemCopy);
138 menuEdit.add(new JSeparator());
139 menuEdit.add(itemSelectAll);
140 return menuEdit;
141 }
142
143 private JMenu initMenuCommunity() {
144 var menuCommunity = new JMenu(I18nUtil.valueByKey("MENUBAR_COMMUNITY"));
145 menuCommunity.setMnemonic('C');
146 menuCommunity.setName(AppMenubar.MENU_COMMUNITY);
147 I18nViewUtil.addComponentForKey("MENUBAR_COMMUNITY", menuCommunity);
148
149 JMenu menuI18nContribution = this.initMenuI18nContribution();
150 menuI18nContribution.setName(AppMenubar.MENU_I18N_CONTRIBUTION);
151
152 JMenuItem itemReportIssue = this.initItemReportIssue();
153 itemReportIssue.setName("itemReportIssue");
154
155 menuCommunity.add(menuI18nContribution);
156 menuCommunity.add(new JSeparator());
157 menuCommunity.add(itemReportIssue);
158 return menuCommunity;
159 }
160
161 private JMenu initMenuI18nContribution() {
162 var menuI18nContribution = new JMenu(I18nUtil.valueByKey("MENUBAR_COMMUNITY_HELPTRANSLATE"));
163 I18nViewUtil.addComponentForKey("MENUBAR_COMMUNITY_HELPTRANSLATE", menuI18nContribution);
164
165 final var dialogTranslate = new DialogTranslate();
166 AppMenubar.ITEMS_TRANSLATE_INTO.forEach(model -> {
167 model.setMenuItem(new JMenuItem(model.getLanguage().getMenuItemLabel(), model.getLanguage().getFlag()));
168 model.getMenuItem().addActionListener(new ActionTranslate(dialogTranslate, model.getLanguage()));
169 menuI18nContribution.add(model.getMenuItem());
170 });
171
172 var itemIntoOther = new JMenuItem(I18nUtil.valueByKey("MENUBAR_COMMUNITY_ANOTHERLANGUAGE"));
173 I18nViewUtil.addComponentForKey("MENUBAR_COMMUNITY_ANOTHERLANGUAGE", itemIntoOther);
174
175 AppMenubar.ITEMS_TRANSLATE_INTO.stream().filter(model -> model.getLanguage() == Language.AR)
176 .forEach(modelItemTranslate -> modelItemTranslate.getMenuItem().setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT));
177 AppMenubar.ITEMS_TRANSLATE_INTO.stream().filter(model -> model.getLanguage() == Language.FR)
178 .forEach(modelItemTranslate -> modelItemTranslate.getMenuItem().setName(AppMenubar.ITEM_INTO_FRENCH));
179
180 menuI18nContribution.add(new JSeparator());
181 menuI18nContribution.add(itemIntoOther);
182 itemIntoOther.addActionListener(new ActionTranslate(dialogTranslate, Language.OT));
183
184 return menuI18nContribution;
185 }
186
187 private JMenuItem initItemReportIssue() {
188 JMenuItem itemReportIssue = new JMenuItem(I18nUtil.valueByKey("MENUBAR_COMMUNITY_REPORTISSUE"), 'R');
189 I18nViewUtil.addComponentForKey("MENUBAR_COMMUNITY_REPORTISSUE", itemReportIssue);
190
191 String reportBody = """
192 ## What's the expected behavior?
193
194 ## What's the actual behavior?
195
196 ## Any other detailed information on the Issue?
197
198 ## Steps to reproduce the problem
199
200 1. ...
201 2. ...
202
203 ## [Community] Request for new feature
204
205 """;
206 itemReportIssue.addActionListener(actionEvent -> {
207 var panel = new JPanel(new BorderLayout());
208 final JTextArea textarea = new JPopupTextArea(new JTextArea()).getProxy();
209 textarea.setFont(new Font(
210 UiUtil.FONT_NAME_MONOSPACED,
211 Font.PLAIN,
212 UIManager.getDefaults().getFont("TextField.font").getSize()
213 ));
214 textarea.setText(reportBody);
215 panel.add(new JLabel("Describe your bug or issue:"), BorderLayout.NORTH);
216 panel.add(new JScrollPane(textarea));
217 panel.setPreferredSize(new Dimension(500, 350));
218 panel.setMinimumSize(new Dimension(500, 350));
219
220 textarea.addMouseListener(new MouseAdapter() {
221 @Override
222 public void mousePressed(MouseEvent e) {
223 super.mousePressed(e);
224 textarea.requestFocusInWindow();
225 }
226 });
227
228 int result = JOptionPane.showOptionDialog(
229 MediatorHelper.frame(),
230 panel,
231 "Report an issue or a bug",
232 JOptionPane.OK_CANCEL_OPTION,
233 JOptionPane.QUESTION_MESSAGE,
234 null,
235 new String[] {
236 "Send",
237 I18nUtil.valueByKey("LIST_ADD_VALUE_CANCEL")
238 },
239 I18nUtil.valueByKey("LIST_ADD_VALUE_CANCEL")
240 );
241
242 if (StringUtils.isNotEmpty(textarea.getText()) && result == JOptionPane.YES_OPTION) {
243 MediatorHelper.model().getMediatorUtils().gitUtil().sendReport(textarea.getText(), ShowOnConsole.YES, "Report");
244 }
245 });
246
247 return itemReportIssue;
248 }
249
250 private JMenu initMenuHelp() {
251 var menuHelp = new JMenu(I18nUtil.valueByKey("MENUBAR_HELP"));
252 menuHelp.setMnemonic('H');
253 I18nViewUtil.addComponentForKey("MENUBAR_HELP", menuHelp);
254 menuHelp.setName(AppMenubar.MENU_HELP);
255
256 JMenuItem itemHelp = new JMenuItem(I18nUtil.valueByKey("MENUBAR_HELP_ABOUT"), 'A');
257 I18nViewUtil.addComponentForKey("MENUBAR_HELP_ABOUT", itemHelp);
258 itemHelp.setName(AppMenubar.ITEM_HELP);
259
260 JMenuItem itemUpdate = new JMenuItem(I18nUtil.valueByKey("MENUBAR_HELP_UPDATE"), 'U');
261 I18nViewUtil.addComponentForKey("MENUBAR_HELP_UPDATE", itemUpdate);
262
263
264 itemHelp.addActionListener(actionEvent -> {
265 final var dialogAbout = new DialogAbout();
266 if (!dialogAbout.isVisible()) {
267 dialogAbout.initDialog();
268 dialogAbout.setVisible(true);
269 dialogAbout.requestButtonFocus();
270 }
271 dialogAbout.setVisible(true);
272 });
273 itemUpdate.addActionListener(new ActionCheckUpdate());
274
275 menuHelp.add(itemUpdate);
276 menuHelp.add(new JSeparator());
277 menuHelp.add(itemHelp);
278 return menuHelp;
279 }
280
281 public static void applyTheme(String nameTheme) {
282 UiUtil.applyTheme(nameTheme);
283
284 for (String key : I18nViewUtil.keys()) {
285 for (Object component : I18nViewUtil.componentsByKey(key)) {
286 if (component instanceof JToolTipI18n jToolTipI18n) {
287 jToolTipI18n.updateUI();
288 }
289 }
290 }
291
292 Arrays.asList(
293 UiUtil.DATABASE_BOLD, UiUtil.ADMIN, UiUtil.DOWNLOAD, UiUtil.TERMINAL, UiUtil.UPLOAD, UiUtil.LOCK, UiUtil.TEXTFIELD, UiUtil.BATCH,
294 UiUtil.TABLE_LINEAR, UiUtil.TABLE_BOLD, UiUtil.NETWORK, UiUtil.DATABASE_LINEAR, UiUtil.COG, UiUtil.CUP, UiUtil.CONSOLE, UiUtil.BINARY, UiUtil.CHUNK,
295 UiUtil.ARROW, UiUtil.ARROW_HOVER, UiUtil.ARROW_PRESSED, UiUtil.ARROW_LEFT, UiUtil.ARROW_LEFT_HOVER, UiUtil.ARROW_LEFT_PRESSED,
296 UiUtil.EXPAND, UiUtil.EXPAND_HOVER, UiUtil.EXPAND_PRESSED,
297 UiUtil.HOURGLASS, UiUtil.ARROW_DOWN, UiUtil.ARROW_UP, UiUtil.SQUARE, UiUtil.GLOBE, UiUtil.TICK_GREEN, UiUtil.CROSS_RED,
298 UiUtil.APP_ICON, UiUtil.APP_BIG, UiUtil.APP_MIDDLE
299 ).forEach(ModelSvgIcon::setColorFilter);
300
301 SqlEngine.applyTheme();
302 PanelTampering.applyTheme();
303 PanelExploit.applyTheme();
304 MediatorHelper.panelConsoles().getTabbedPaneNetworkTab().applyTheme();
305 MediatorHelper.frame().setIconImages(UiUtil.getIcons());
306 MediatorHelper.frame().revalidate();
307
308 MediatorHelper.model().getMediatorUtils().preferencesUtil().withThemeFlatLafName(nameTheme).persist();
309 }
310
311 public void switchLocale(Locale newLocale) {
312 Locale oldLocale = I18nUtil.getCurrentLocale();
313 I18nUtil.setCurrentBundle(newLocale);
314
315 Stream.of(
316 JTextPaneAppender.ATTRIBUTE_WARN,
317 JTextPaneAppender.ATTRIBUTE_INFORM,
318 JTextPaneAppender.ATTRIBUTE_SUCCESS,
319 JTextPaneAppender.ATTRIBUTE_ALL
320 )
321 .forEach(attribute -> {
322 StyleConstants.setFontFamily(attribute, I18nViewUtil.isNonUbuntu(newLocale) ? UiUtil.FONT_NAME_MONO_ASIAN : UiUtil.FONT_NAME_MONO_NON_ASIAN);
323 StyleConstants.setFontSize(attribute, I18nViewUtil.isNonUbuntu(newLocale) ? UiUtil.FONT_SIZE_MONO_ASIAN : UiUtil.FONT_SIZE_MONO_NON_ASIAN);
324 });
325
326 MediatorHelper.managerBruteForce().getResult().setFont(I18nViewUtil.isNonUbuntu(newLocale) ? UiUtil.FONT_MONO_ASIAN : UiUtil.FONT_MONO_NON_ASIAN);
327
328 this.switchNetworkTable();
329 I18nViewUtil.switchI18nComponents();
330 this.switchOrientation(oldLocale, newLocale);
331 this.switchMenuItems();
332
333 MediatorHelper.treeDatabase().reloadNodes();
334 MediatorHelper.panelAddressBar().getPanelTrailingAddress().buttonStart.setIcons();
335 int textPosition = ComponentOrientation.getOrientation(newLocale).isLeftToRight()
336 ? SwingConstants.LEFT
337 : SwingConstants.RIGHT;
338 MediatorHelper.panelAddressBar().getAtomicRadioRequest().setHorizontalTextPosition(textPosition);
339 MediatorHelper.panelAddressBar().getAtomicRadioMethod().setHorizontalTextPosition(textPosition);
340 MediatorHelper.panelAddressBar().getAtomicRadioHeader().setHorizontalTextPosition(textPosition);
341
342
343
344
345 try {
346 MediatorHelper.frame().revalidate();
347 } catch (NullPointerException | IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
348 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
349 }
350 }
351
352 private void switchOrientation(Locale oldLocale, Locale newLocale) {
353 var componentOrientation = ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale());
354 MediatorHelper.frame().applyComponentOrientation(componentOrientation);
355
356 if (!ComponentOrientation.getOrientation(oldLocale).equals(ComponentOrientation.getOrientation(newLocale))) {
357
358
359 AppMenubar.reverse(MediatorHelper.frame().getSplitNS().getSplitEW());
360 AppMenubar.reverse(MediatorHelper.panelConsoles().getNetworkSplitPane());
361 }
362
363 MediatorHelper.tabResults().setComponentOrientation(ComponentOrientation.getOrientation(newLocale));
364 }
365
366 private static void reverse(JSplitPane splitPane) {
367 var componentLeft = splitPane.getLeftComponent();
368 var componentRight = splitPane.getRightComponent();
369
370
371 splitPane.setLeftComponent(null);
372 splitPane.setRightComponent(null);
373 splitPane.setLeftComponent(componentRight);
374 splitPane.setRightComponent(componentLeft);
375
376
377 splitPane.setDividerLocation(splitPane.getWidth() - splitPane.getDividerLocation());
378 }
379
380 private void switchMenuItems() {
381 Stream.concat(AppMenubar.ITEMS_TRANSLATE.stream(), AppMenubar.ITEMS_TRANSLATE_INTO.stream())
382 .forEach(model -> model.getMenuItem().setComponentOrientation(
383 model.getLanguage().isRightToLeft()
384 ? ComponentOrientation.RIGHT_TO_LEFT
385 : ComponentOrientation.LEFT_TO_RIGHT
386 ));
387 }
388
389 private void switchNetworkTable() {
390 JTableHeader header = MediatorHelper.panelConsoles().getNetworkTable().getTableHeader();
391 TableColumnModel columnModel = header.getColumnModel();
392 columnModel.getColumn(0).setHeaderValue(I18nUtil.valueByKey("NETWORK_TAB_URL_COLUMN"));
393 columnModel.getColumn(1).setHeaderValue(I18nUtil.valueByKey("NETWORK_TAB_SIZE_COLUMN") +" (KB)");
394 columnModel.getColumn(2).setHeaderValue(I18nUtil.valueByKey("SQLENGINE_STRATEGY"));
395 columnModel.getColumn(3).setHeaderValue(I18nUtil.valueByKey("SQLENGINE_METADATA"));
396 header.repaint();
397 }
398
399
400
401
402 public JMenu getMenuView() {
403 return this.menuWindows.getMenuView();
404 }
405
406 public MenuWindows getMenuWindows() {
407 return this.menuWindows;
408 }
409 }