mirror of
https://github.com/arduino/Arduino.git
synced 2025-02-26 20:54:22 +01:00
Initial implementation of bookmarks
Toggle on the left, find next with F3
This commit is contained in:
parent
b8a6e6d589
commit
b2546131d8
@ -130,6 +130,7 @@ public class Preferences extends javax.swing.JDialog {
|
|||||||
checkboxesContainer = new javax.swing.JPanel();
|
checkboxesContainer = new javax.swing.JPanel();
|
||||||
displayLineNumbersBox = new javax.swing.JCheckBox();
|
displayLineNumbersBox = new javax.swing.JCheckBox();
|
||||||
enableCodeFoldingBox = new javax.swing.JCheckBox();
|
enableCodeFoldingBox = new javax.swing.JCheckBox();
|
||||||
|
enableBookmarks = new javax.swing.JCheckBox();
|
||||||
verifyUploadBox = new javax.swing.JCheckBox();
|
verifyUploadBox = new javax.swing.JCheckBox();
|
||||||
externalEditorBox = new javax.swing.JCheckBox();
|
externalEditorBox = new javax.swing.JCheckBox();
|
||||||
checkUpdatesBox = new javax.swing.JCheckBox();
|
checkUpdatesBox = new javax.swing.JCheckBox();
|
||||||
@ -255,6 +256,9 @@ public class Preferences extends javax.swing.JDialog {
|
|||||||
enableCodeFoldingBox.setText(tr("Enable Code Folding"));
|
enableCodeFoldingBox.setText(tr("Enable Code Folding"));
|
||||||
checkboxesContainer.add(enableCodeFoldingBox);
|
checkboxesContainer.add(enableCodeFoldingBox);
|
||||||
|
|
||||||
|
enableBookmarks.setText(tr("Enable Bookmarks"));
|
||||||
|
checkboxesContainer.add(enableBookmarks);
|
||||||
|
|
||||||
verifyUploadBox.setText(tr("Verify code after upload"));
|
verifyUploadBox.setText(tr("Verify code after upload"));
|
||||||
checkboxesContainer.add(verifyUploadBox);
|
checkboxesContainer.add(verifyUploadBox);
|
||||||
|
|
||||||
@ -725,6 +729,7 @@ public class Preferences extends javax.swing.JDialog {
|
|||||||
private javax.swing.JLabel comboWarningsLabel;
|
private javax.swing.JLabel comboWarningsLabel;
|
||||||
private javax.swing.JCheckBox displayLineNumbersBox;
|
private javax.swing.JCheckBox displayLineNumbersBox;
|
||||||
private javax.swing.JCheckBox enableCodeFoldingBox;
|
private javax.swing.JCheckBox enableCodeFoldingBox;
|
||||||
|
private javax.swing.JCheckBox enableBookmarks;
|
||||||
private javax.swing.JButton extendedAdditionalUrlFieldWindow;
|
private javax.swing.JButton extendedAdditionalUrlFieldWindow;
|
||||||
private javax.swing.JCheckBox externalEditorBox;
|
private javax.swing.JCheckBox externalEditorBox;
|
||||||
private javax.swing.JTextField fontSizeField;
|
private javax.swing.JTextField fontSizeField;
|
||||||
@ -823,6 +828,8 @@ public class Preferences extends javax.swing.JDialog {
|
|||||||
|
|
||||||
PreferencesData.setBoolean("editor.code_folding", enableCodeFoldingBox.isSelected());
|
PreferencesData.setBoolean("editor.code_folding", enableCodeFoldingBox.isSelected());
|
||||||
|
|
||||||
|
PreferencesData.setBoolean("editor.bookmarks", enableBookmarks.isSelected());
|
||||||
|
|
||||||
PreferencesData.setBoolean("upload.verify", verifyUploadBox.isSelected());
|
PreferencesData.setBoolean("upload.verify", verifyUploadBox.isSelected());
|
||||||
|
|
||||||
PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
|
PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
|
||||||
@ -897,6 +904,8 @@ public class Preferences extends javax.swing.JDialog {
|
|||||||
|
|
||||||
enableCodeFoldingBox.setSelected(PreferencesData.getBoolean("editor.code_folding"));
|
enableCodeFoldingBox.setSelected(PreferencesData.getBoolean("editor.code_folding"));
|
||||||
|
|
||||||
|
enableBookmarks.setSelected(PreferencesData.getBoolean("editor.bookmarks"));
|
||||||
|
|
||||||
verifyUploadBox.setSelected(PreferencesData.getBoolean("upload.verify"));
|
verifyUploadBox.setSelected(PreferencesData.getBoolean("upload.verify"));
|
||||||
|
|
||||||
externalEditorBox.setSelected(PreferencesData.getBoolean("editor.external"));
|
externalEditorBox.setSelected(PreferencesData.getBoolean("editor.external"));
|
||||||
|
@ -28,18 +28,30 @@ import static processing.app.Theme.scale;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseWheelListener;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.InputMap;
|
||||||
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.ToolTipManager;
|
import javax.swing.ToolTipManager;
|
||||||
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.MatteBorder;
|
import javax.swing.border.MatteBorder;
|
||||||
import javax.swing.event.PopupMenuEvent;
|
import javax.swing.event.PopupMenuEvent;
|
||||||
import javax.swing.event.PopupMenuListener;
|
import javax.swing.event.PopupMenuListener;
|
||||||
@ -51,6 +63,8 @@ import javax.swing.text.Document;
|
|||||||
|
|
||||||
import static java.nio.file.StandardWatchEventKinds.*;
|
import static java.nio.file.StandardWatchEventKinds.*;
|
||||||
import java.nio.file.WatchService;
|
import java.nio.file.WatchService;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.nio.file.WatchKey;
|
import java.nio.file.WatchKey;
|
||||||
import java.nio.file.WatchEvent;
|
import java.nio.file.WatchEvent;
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
@ -61,15 +75,23 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.fife.ui.autocomplete.AutoCompletion;
|
import org.fife.ui.autocomplete.AutoCompletion;
|
||||||
import org.fife.ui.autocomplete.DefaultCompletionProvider;
|
import org.fife.ui.autocomplete.DefaultCompletionProvider;
|
||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
|
||||||
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
|
||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
||||||
import org.fife.ui.rtextarea.Gutter;
|
import org.fife.ui.rtextarea.Gutter;
|
||||||
|
import org.fife.ui.rtextarea.GutterIconInfo;
|
||||||
|
import org.fife.ui.rtextarea.RTADefaultInputMap;
|
||||||
|
import org.fife.ui.rtextarea.RTextArea;
|
||||||
|
import org.fife.ui.rtextarea.RTextAreaEditorKit;
|
||||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||||
|
import org.fife.ui.rtextarea.RecordableTextAction;
|
||||||
|
|
||||||
import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
|
import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
|
||||||
import cc.arduino.autocomplete.ClangCompletionProvider;
|
import cc.arduino.autocomplete.ClangCompletionProvider;
|
||||||
|
import cc.arduino.autocomplete.CompletionType;
|
||||||
import cc.arduino.autocomplete.CompletionsRenderer;
|
import cc.arduino.autocomplete.CompletionsRenderer;
|
||||||
import processing.app.helpers.DocumentTextChangeListener;
|
import processing.app.helpers.DocumentTextChangeListener;
|
||||||
|
import processing.app.helpers.PreferencesMap;
|
||||||
import processing.app.syntax.ArduinoTokenMakerFactory;
|
import processing.app.syntax.ArduinoTokenMakerFactory;
|
||||||
import processing.app.syntax.PdeKeywords;
|
import processing.app.syntax.PdeKeywords;
|
||||||
import processing.app.syntax.SketchTextArea;
|
import processing.app.syntax.SketchTextArea;
|
||||||
@ -153,6 +175,8 @@ public class EditorTab extends JPanel implements SketchFile.TextStorage {
|
|||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String rtaNextBookmarkAction = "RTA.NextBookmarkAction";
|
||||||
|
|
||||||
private RTextScrollPane createScrollPane(SketchTextArea textArea) throws IOException {
|
private RTextScrollPane createScrollPane(SketchTextArea textArea) throws IOException {
|
||||||
RTextScrollPane scrollPane = new RTextScrollPane(textArea, true);
|
RTextScrollPane scrollPane = new RTextScrollPane(textArea, true);
|
||||||
scrollPane.setBorder(new MatteBorder(0, 6, 0, 0, Theme.getColor("editor.bgcolor")));
|
scrollPane.setBorder(new MatteBorder(0, 6, 0, 0, Theme.getColor("editor.bgcolor")));
|
||||||
@ -161,13 +185,118 @@ public class EditorTab extends JPanel implements SketchFile.TextStorage {
|
|||||||
scrollPane.setIconRowHeaderEnabled(false);
|
scrollPane.setIconRowHeaderEnabled(false);
|
||||||
|
|
||||||
Gutter gutter = scrollPane.getGutter();
|
Gutter gutter = scrollPane.getGutter();
|
||||||
gutter.setBookmarkingEnabled(false);
|
|
||||||
//gutter.setBookmarkIcon(CompletionsRenderer.getIcon(CompletionType.TEMPLATE));
|
if (PreferencesData.getBoolean("editor.bookmarks")) {
|
||||||
|
gutter.setBookmarkingEnabled(true);
|
||||||
|
gutter.setBookmarkIcon(CompletionsRenderer.getIcon(CompletionType.FUNCTION));
|
||||||
|
InputMap map = SwingUtilities.getUIInputMap(textArea, JComponent.WHEN_FOCUSED);
|
||||||
|
NextBookmarkAction action = new NextBookmarkAction(rtaNextBookmarkAction);
|
||||||
|
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0), action);
|
||||||
|
SwingUtilities.replaceUIInputMap(textArea,JComponent.WHEN_FOCUSED,map);
|
||||||
|
}
|
||||||
|
|
||||||
gutter.setIconRowHeaderInheritsGutterBackground(true);
|
gutter.setIconRowHeaderInheritsGutterBackground(true);
|
||||||
|
|
||||||
return scrollPane;
|
return scrollPane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GutterIconInfoTabs {
|
||||||
|
GutterIconInfo bookmark;
|
||||||
|
SketchFile file;
|
||||||
|
RTextArea textArea;
|
||||||
|
|
||||||
|
public String toString( ) {
|
||||||
|
return "File:" + file.getFileName() + " -- Line:" + bookmark.getMarkedOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that moves the caret to the next bookmark.
|
||||||
|
*/
|
||||||
|
public class NextBookmarkAction extends RecordableTextAction {
|
||||||
|
|
||||||
|
public NextBookmarkAction(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
|
||||||
|
|
||||||
|
Gutter gutter = RSyntaxUtilities.getGutter(textArea);
|
||||||
|
|
||||||
|
List<GutterIconInfoTabs> bookmarks = new ArrayList<GutterIconInfoTabs>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
for (EditorTab tab : editor.getTabs()) {
|
||||||
|
gutter = RSyntaxUtilities.getGutter(tab.getTextArea());
|
||||||
|
|
||||||
|
if (gutter!=null) {
|
||||||
|
GutterIconInfo[] tabBookmarks = gutter.getBookmarks();
|
||||||
|
for (GutterIconInfo element : tabBookmarks) {
|
||||||
|
GutterIconInfoTabs bookmark = new GutterIconInfoTabs();
|
||||||
|
bookmark.file = tab.getSketchFile();
|
||||||
|
bookmark.bookmark = element;
|
||||||
|
bookmark.textArea = tab.getTextArea();
|
||||||
|
bookmarks.add(bookmark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bookmarks.size()==0) {
|
||||||
|
UIManager.getLookAndFeel().
|
||||||
|
provideErrorFeedback(textArea);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GutterIconInfoTabs moveTo = null;
|
||||||
|
int curLine = textArea.getCaretLineNumber();
|
||||||
|
|
||||||
|
for (int i=0; i<bookmarks.size(); i++) {
|
||||||
|
GutterIconInfo bookmark = bookmarks.get(i).bookmark;
|
||||||
|
int offs = bookmark.getMarkedOffset();
|
||||||
|
int line = 0;
|
||||||
|
int curTabIndex = editor.getCurrentTabIndex();
|
||||||
|
int bookmarkTabIndex = editor.findTabIndex(bookmarks.get(i).file);
|
||||||
|
if (curTabIndex == bookmarkTabIndex) {
|
||||||
|
line = textArea.getLineOfOffset(offs);
|
||||||
|
}
|
||||||
|
if ((curTabIndex == bookmarkTabIndex && line>curLine) || (curTabIndex < bookmarkTabIndex)) {
|
||||||
|
moveTo = bookmarks.get(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (moveTo==null) { // Loop back to beginning
|
||||||
|
moveTo = bookmarks.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.selectTab(editor.findTabIndex(moveTo.file));
|
||||||
|
|
||||||
|
int offs = moveTo.bookmark.getMarkedOffset();
|
||||||
|
if (moveTo.textArea instanceof RSyntaxTextArea) {
|
||||||
|
RSyntaxTextArea rsta = (RSyntaxTextArea)moveTo.textArea;
|
||||||
|
if (rsta.isCodeFoldingEnabled()) {
|
||||||
|
rsta.getFoldManager().
|
||||||
|
ensureOffsetNotInClosedFold(offs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int line = moveTo.textArea.getLineOfOffset(offs);
|
||||||
|
offs = moveTo.textArea.getLineStartOffset(line);
|
||||||
|
moveTo.textArea.setCaretPosition(offs);
|
||||||
|
|
||||||
|
} catch (BadLocationException ble) { // Never happens
|
||||||
|
UIManager.getLookAndFeel().
|
||||||
|
provideErrorFeedback(textArea);
|
||||||
|
ble.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMacroID() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private SketchTextArea createTextArea(RSyntaxDocument document)
|
private SketchTextArea createTextArea(RSyntaxDocument document)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final SketchTextArea textArea = new SketchTextArea(document, editor.base.getPdeKeywords());
|
final SketchTextArea textArea = new SketchTextArea(document, editor.base.getPdeKeywords());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user