|
11 | 11 | import com.bookmap.python.api.addon.settings.PythonApiSettings; |
12 | 12 | import com.bookmap.python.api.addon.ui.ExecutablesFileFilter; |
13 | 13 | import com.bookmap.python.api.addon.ui.JLabelLink; |
| 14 | +import com.bookmap.python.api.addon.ui.custom.CustomCollapsibleSectionPanel; |
| 15 | +import com.bookmap.python.api.addon.ui.custom.CustomFindToolBar; |
| 16 | +import com.bookmap.python.api.addon.ui.custom.CustomReplaceToolBar; |
14 | 17 | import com.bookmap.python.api.addon.ui.filetree.JFileTree; |
| 18 | +import com.bookmap.python.api.addon.ui.listeners.EditorSearchListener; |
15 | 19 | import com.bookmap.python.api.addon.ui.listeners.EditorStateListener; |
16 | 20 | import com.bookmap.python.api.addon.ui.listeners.EditorTextFileTrackerListener; |
17 | 21 | import com.bookmap.python.api.addon.ui.listeners.SavingTextEditorFileSelectionListener; |
|
79 | 83 | import javax.swing.event.DocumentEvent; |
80 | 84 | import javax.swing.event.DocumentListener; |
81 | 85 | import javax.swing.text.JTextComponent; |
| 86 | +import org.fife.rsta.ui.search.FindToolBar; |
| 87 | +import org.fife.rsta.ui.search.ReplaceToolBar; |
| 88 | +import org.fife.rsta.ui.search.SearchListener; |
82 | 89 | import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; |
83 | 90 | import org.fife.ui.rsyntaxtextarea.SyntaxConstants; |
84 | 91 | import org.fife.ui.rsyntaxtextarea.Theme; |
85 | 92 | import org.fife.ui.rtextarea.FoldIndicatorStyle; |
86 | 93 | import org.fife.ui.rtextarea.RTextArea; |
87 | 94 | import org.fife.ui.rtextarea.RTextScrollPane; |
| 95 | +import org.fife.ui.rtextarea.SearchContext; |
88 | 96 | import velox.api.layer1.Layer1ApiFinishable; |
89 | 97 | import velox.api.layer1.Layer1ApiInstrumentSpecificEnabledStateProvider; |
90 | 98 | import velox.api.layer1.Layer1ApiProvider; |
@@ -153,6 +161,12 @@ public class DeveloperAddon |
153 | 161 | private SettingsAccess settingsAccess; |
154 | 162 | private PythonApiSettings pythonApiSettings; |
155 | 163 | private RSyntaxTextArea textArea; |
| 164 | + private FindToolBar findToolBar; |
| 165 | + private ReplaceToolBar replaceToolBar; |
| 166 | + |
| 167 | + private CustomCollapsibleSectionPanel collapsibleSectionPanel; |
| 168 | + |
| 169 | + private SearchListener searchListener; |
156 | 170 |
|
157 | 171 | private final ExecutorService executorService = Executors.newSingleThreadExecutor(); |
158 | 172 |
|
@@ -312,6 +326,8 @@ private void initEditorFrame(JFrame jFrame, ActionListener newFileAction, File r |
312 | 326 | textArea.setAnimateBracketMatching(pythonApiSettings.isBracketMatchingAnimationEnabled()); |
313 | 327 | textArea.setPaintTabLines(pythonApiSettings.isTabLinesEnabled()); |
314 | 328 |
|
| 329 | + initSearchDialogs(); |
| 330 | + |
315 | 331 | loadNonDefaultTheme(); |
316 | 332 |
|
317 | 333 | titleLabel = new JLabel(""); |
@@ -445,6 +461,21 @@ public void changedUpdate(DocumentEvent e) {} |
445 | 461 | } |
446 | 462 | }; |
447 | 463 |
|
| 464 | + collapsibleSectionPanel = new CustomCollapsibleSectionPanel(textArea); |
| 465 | + var collapsibleSectionPanelConstrains = new GridBagConstraints(); |
| 466 | + collapsibleSectionPanelConstrains.anchor = GridBagConstraints.FIRST_LINE_START; |
| 467 | + collapsibleSectionPanelConstrains.fill = GridBagConstraints.HORIZONTAL; |
| 468 | + collapsibleSectionPanelConstrains.gridy = 1; |
| 469 | + collapsibleSectionPanelConstrains.gridx = 0; |
| 470 | + collapsibleSectionPanelConstrains.gridwidth = 4; |
| 471 | + collapsibleSectionPanelConstrains.ipady = 0; |
| 472 | + collapsibleSectionPanelConstrains.weightx = 0; |
| 473 | + collapsibleSectionPanelConstrains.insets = new Insets(5, 5, 5, 5); |
| 474 | + rightComponent.add(collapsibleSectionPanel, collapsibleSectionPanelConstrains); |
| 475 | + collapsibleSectionPanel.add(textEditorScrollPanel); |
| 476 | + collapsibleSectionPanel.addBottomComponent(findToolBar); |
| 477 | + collapsibleSectionPanel.addBottomComponent(replaceToolBar); |
| 478 | + |
448 | 479 | /* |
449 | 480 | * Buttons. |
450 | 481 | */ |
@@ -615,6 +646,9 @@ public void changedUpdate(DocumentEvent e) {} |
615 | 646 | editMenu.add(createMenuItem(RTextArea.getAction(RTextArea.PASTE_ACTION))); |
616 | 647 | editMenu.add(createMenuItem(RTextArea.getAction(RTextArea.DELETE_ACTION))); |
617 | 648 | editMenu.addSeparator(); |
| 649 | + editMenu.add(new ShowFindToolBarAction(findToolBar)); |
| 650 | + editMenu.add(new ShowReplaceToolBarAction(replaceToolBar)); |
| 651 | + editMenu.addSeparator(); |
618 | 652 | editMenu.add(createMenuItem(RTextArea.getAction(RTextArea.SELECT_ALL_ACTION))); |
619 | 653 | menuBar.add(editMenu); |
620 | 654 |
|
@@ -792,6 +826,22 @@ public void windowClosed(WindowEvent e) { |
792 | 826 | jFrame.pack(); |
793 | 827 | } |
794 | 828 |
|
| 829 | + /** |
| 830 | + * Creates our Find and Replace toolbars. |
| 831 | + */ |
| 832 | + private void initSearchDialogs() { |
| 833 | + searchListener = new EditorSearchListener(textArea); |
| 834 | + |
| 835 | + // Create toolbars and tie their search contexts together also. |
| 836 | + findToolBar = new CustomFindToolBar(searchListener); |
| 837 | + replaceToolBar = new CustomReplaceToolBar(searchListener); |
| 838 | + |
| 839 | + // This ties the properties of the two toolbars together (match case, |
| 840 | + // regex, etc.). |
| 841 | + SearchContext context = findToolBar.getSearchContext(); |
| 842 | + replaceToolBar.setSearchContext(context); |
| 843 | + } |
| 844 | + |
795 | 845 | private JMenuItem createMenuItem(Action action) { |
796 | 846 | JMenuItem item = new JMenuItem(action); |
797 | 847 | item.setToolTipText(null); // Swing annoyingly adds tool tip text to the menu item. |
@@ -1404,24 +1454,64 @@ public void actionPerformed(ActionEvent e) { |
1404 | 1454 | Log.error("Failed to build addon.", ex); |
1405 | 1455 | SwingUtilities.invokeLater(() -> { |
1406 | 1456 | JOptionPane.showMessageDialog( |
1407 | | - jFrame, |
1408 | | - String.format("Failed to build addon:\n%s", ex.getMessage()) |
| 1457 | + jFrame, |
| 1458 | + String.format("Failed to build addon:\n%s", ex.getMessage()) |
1409 | 1459 | ); |
1410 | 1460 | }); |
1411 | 1461 | return; |
1412 | 1462 | } |
1413 | 1463 |
|
1414 | 1464 | SwingUtilities.invokeLater(() -> { |
1415 | 1465 | JOptionPane.showMessageDialog( |
1416 | | - jFrame, |
1417 | | - "Build success.\n\n" + |
1418 | | - "You can find your addon JAR file by opening 'File' -> 'Open build folder' here in the code editor.\n\n" + |
1419 | | - "To load your addon, open the main Bookmap window, go under 'Settings' -> 'Configure addons' and add your addon JAR file.\n", |
1420 | | - "Build", |
1421 | | - JOptionPane.INFORMATION_MESSAGE |
| 1466 | + jFrame, |
| 1467 | + "Build success.\n\n" + |
| 1468 | + "You can find your addon JAR file by opening 'File' -> 'Open build folder' here in the code editor.\n\n" + |
| 1469 | + "To load your addon, open the main Bookmap window, go under 'Settings' -> 'Configure addons' and add your addon JAR file.\n", |
| 1470 | + "Build", |
| 1471 | + JOptionPane.INFORMATION_MESSAGE |
1422 | 1472 | ); |
1423 | 1473 | }); |
1424 | 1474 | }); |
1425 | 1475 | } |
1426 | 1476 | } |
| 1477 | + |
| 1478 | + /** |
| 1479 | + * Shows the Find toolbar. |
| 1480 | + */ |
| 1481 | + private class ShowFindToolBarAction extends AbstractAction { |
| 1482 | + |
| 1483 | + private final FindToolBar findToolBar; |
| 1484 | + |
| 1485 | + ShowFindToolBarAction(FindToolBar findToolBar) { |
| 1486 | + super("Find"); |
| 1487 | + this.findToolBar = findToolBar; |
| 1488 | + int c = InputEvent.CTRL_DOWN_MASK; |
| 1489 | + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, c)); |
| 1490 | + } |
| 1491 | + |
| 1492 | + @Override |
| 1493 | + public void actionPerformed(ActionEvent e) { |
| 1494 | + collapsibleSectionPanel.showBottomComponent(findToolBar); |
| 1495 | + } |
| 1496 | + } |
| 1497 | + |
| 1498 | + /** |
| 1499 | + * Shows the Replace toolbar. |
| 1500 | + */ |
| 1501 | + private class ShowReplaceToolBarAction extends AbstractAction { |
| 1502 | + |
| 1503 | + private final ReplaceToolBar replaceToolBar; |
| 1504 | + |
| 1505 | + ShowReplaceToolBarAction(ReplaceToolBar replaceToolBar) { |
| 1506 | + super("Replace"); |
| 1507 | + this.replaceToolBar = replaceToolBar; |
| 1508 | + int c = InputEvent.CTRL_DOWN_MASK; |
| 1509 | + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, c)); |
| 1510 | + } |
| 1511 | + |
| 1512 | + @Override |
| 1513 | + public void actionPerformed(ActionEvent e) { |
| 1514 | + collapsibleSectionPanel.showBottomComponent(replaceToolBar); |
| 1515 | + } |
| 1516 | + } |
1427 | 1517 | } |
0 commit comments