mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
Merge pull request #2382 from GKFX/mnem-patch
Dynamically add menu mnemonics to all menus
This commit is contained in:
@@ -51,8 +51,8 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
protected EditorState state;
|
||||
protected Mode mode;
|
||||
|
||||
// otherwise, if the window is resized with the message label
|
||||
// set to blank, it's preferredSize() will be fukered
|
||||
// Otherwise, if the window is resized with the message label
|
||||
// set to blank, its preferredSize() will be fuckered
|
||||
static protected final String EMPTY =
|
||||
" " +
|
||||
" " +
|
||||
@@ -66,7 +66,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
private PageFormat pageFormat;
|
||||
private PrinterJob printerJob;
|
||||
|
||||
// file and sketch menus for re-inserting items
|
||||
// File and sketch menus for re-inserting items
|
||||
private JMenu fileMenu;
|
||||
// private JMenuItem saveMenuItem;
|
||||
// private JMenuItem saveAsMenuItem;
|
||||
@@ -148,7 +148,10 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
// fileMenu.insert(base.getSketchbookMenu(), 2);
|
||||
fileMenu.insert(base.getRecentMenu(), 2);
|
||||
// fileMenu.insert(mode.getExamplesMenu(), 3);
|
||||
Toolkit.setMenuMnemsInside(fileMenu);
|
||||
|
||||
sketchMenu.insert(mode.getImportMenu(), 4);
|
||||
Toolkit.setMenuMnemsInside(sketchMenu);
|
||||
mode.insertToolbarRecentMenu();
|
||||
}
|
||||
|
||||
@@ -398,7 +401,6 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (!sketch.isModified()) {
|
||||
base.changeMode(m);
|
||||
|
||||
} else {
|
||||
Base.showWarning("Save",
|
||||
"Please save the sketch before changing the mode.",
|
||||
@@ -433,6 +435,8 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
}
|
||||
});
|
||||
modeMenu.add(addLib);
|
||||
|
||||
Toolkit.setMenuMnemsInside(modeMenu);
|
||||
}
|
||||
|
||||
|
||||
@@ -557,7 +561,6 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
protected void buildMenuBar() {
|
||||
JMenuBar menubar = new JMenuBar();
|
||||
menubar = new JMenuBar();
|
||||
fileMenu = buildFileMenu();
|
||||
menubar.add(fileMenu);
|
||||
menubar.add(buildEditMenu());
|
||||
@@ -573,6 +576,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
menubar.add(getToolMenu());
|
||||
|
||||
menubar.add(buildHelpMenu());
|
||||
Toolkit.setMenuMnemonics(menubar);
|
||||
setJMenuBar(menubar);
|
||||
}
|
||||
|
||||
@@ -734,11 +738,11 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
cutItems = Toolkit.newJMenuItem("Cut", 'X');
|
||||
cutItems = Toolkit.newJMenuItem(Language.text("menu.edit.cut"), 'X');
|
||||
cutItems.addActionListener(cutAction = new CutAction());
|
||||
menu.add(cutItems);
|
||||
|
||||
copyItems = Toolkit.newJMenuItem("Copy", 'C');
|
||||
copyItems = Toolkit.newJMenuItem(Language.text("menu.edit.copy"), 'C');
|
||||
copyItems.addActionListener(copyAction = new CopyAction());
|
||||
menu.add(copyItems);
|
||||
|
||||
@@ -933,7 +937,9 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
});
|
||||
sketchMenu.add(item);
|
||||
|
||||
sketchMenu.addSeparator();
|
||||
if (runItems != null && runItems.length != 0) {
|
||||
sketchMenu.addSeparator();
|
||||
}
|
||||
|
||||
// final Editor editorName = this;
|
||||
|
||||
@@ -957,7 +963,6 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
// Action listener to bring the appropriate sketch in front
|
||||
item.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
editor.setState(Frame.NORMAL);
|
||||
@@ -967,6 +972,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
});
|
||||
sketchMenu.add(item);
|
||||
menuList.add(item);
|
||||
Toolkit.setMenuMnemsInside(sketchMenu);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1296,7 +1302,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
class CutAction extends AbstractAction {
|
||||
public CutAction() {
|
||||
super("Cut");
|
||||
super(Language.text("menu.edit.cut"));
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -1306,11 +1312,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
}
|
||||
|
||||
public void updateCutState() {
|
||||
if (canCut()) {
|
||||
cutItems.setEnabled(true);
|
||||
} else {
|
||||
cutItems.setEnabled(false);
|
||||
}
|
||||
cutItems.setEnabled(canCut());
|
||||
}
|
||||
|
||||
public boolean canCut() {
|
||||
@@ -1320,7 +1322,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
class CopyAction extends AbstractAction {
|
||||
public CopyAction() {
|
||||
super("Copy");
|
||||
super(Language.text("menu.edit.copy"));
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -1329,11 +1331,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
}
|
||||
|
||||
public void updateCopyState() {
|
||||
if (canCopy()) {
|
||||
copyItems.setEnabled(true);
|
||||
} else {
|
||||
copyItems.setEnabled(false);
|
||||
}
|
||||
copyItems.setEnabled(canCopy());
|
||||
}
|
||||
|
||||
public boolean canCopy() {
|
||||
@@ -2933,11 +2931,9 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
* Returns the edit popup menu.
|
||||
*/
|
||||
class TextAreaPopup extends JPopupMenu {
|
||||
JMenuItem cutItem;
|
||||
JMenuItem copyItem;
|
||||
JMenuItem discourseItem;
|
||||
JMenuItem referenceItem;
|
||||
|
||||
JMenuItem cutItem, copyItem, discourseItem, pasteItem,
|
||||
selectAllItem, commUncommItem, incIndItem, decIndItem,
|
||||
referenceItem;
|
||||
|
||||
public TextAreaPopup() {
|
||||
JMenuItem item;
|
||||
@@ -2992,7 +2988,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
});
|
||||
this.add(item);
|
||||
|
||||
item = new JMenuItem("\u2192 "+Language.text("menu.edit.increase_indent"));
|
||||
item = new JMenuItem("\u2192 " + Language.text("menu.edit.increase_indent"));
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleIndentOutdent(true);
|
||||
@@ -3000,7 +2996,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
});
|
||||
this.add(item);
|
||||
|
||||
item = new JMenuItem("\u2190 "+Language.text("menu.edit.decrease_indent"));
|
||||
item = new JMenuItem("\u2190 " + Language.text("menu.edit.decrease_indent"));
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleIndentOutdent(false);
|
||||
@@ -3017,6 +3013,8 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
}
|
||||
});
|
||||
this.add(referenceItem);
|
||||
|
||||
Toolkit.setMenuMnemonics(this);
|
||||
}
|
||||
|
||||
// if no text is selected, disable copy and cut menu items
|
||||
|
||||
@@ -615,6 +615,8 @@ public class EditorHeader extends JComponent {
|
||||
menu.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
Toolkit.setMenuMnemonics(menu);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
|
||||
package processing.app;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
@@ -45,14 +47,18 @@ import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
@@ -130,6 +136,251 @@ public class Toolkit {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all mnemonics, then sets a mnemonic for each menu and menu item
|
||||
* recursively by these rules:
|
||||
* <ol>
|
||||
* <li> It tries to assign one of <a href="http://techbase.kde.org/Projects/Usability/HIG/Keyboard_Accelerators">
|
||||
* KDE's defaults</a>.</li>
|
||||
* <li> Failing that, it loops through the first letter of each word, where a word
|
||||
* is a block of Unicode "alphabetical" chars, looking for an upper-case ASCII mnemonic
|
||||
* that is not taken. This is to try to be relevant, by using a letter well-associated
|
||||
* with the command. (MS guidelines) </li>
|
||||
* <li> Ditto, but with lowercase. </li>
|
||||
* <li> Next, it tries the second ASCII character, if its width >= half the width of
|
||||
* 'A'. </li>
|
||||
* <li> If the first letters are all taken/non-ASCII, then it loops through the
|
||||
* ASCII letters in the item, widest to narrowest, seeing if any of them is not taken.
|
||||
* To improve readability, it discriminates against decenders (qypgj), imagining they
|
||||
* have 2/3 their actual width. (MS guidelines: avoid decenders). It also discriminates
|
||||
* against vowels, imagining they have 2/3 their actual width. (MS and Gnome guidelines:
|
||||
* avoid vowels. </li>
|
||||
* <li>Failing that, it will loop left-to-right for an available digit. This is a last
|
||||
* resort because the normal setMnemonic dislikes them.</li>
|
||||
* <li> If that doesn't work, it doesn't assign a mnemonic. </li>
|
||||
* </ol>
|
||||
*
|
||||
* As a special case, strings starting "sketchbook \u2192 " have that bit ignored
|
||||
* because otherwise the Recent menu looks awful. However, the name <tt>"sketchbook \u2192
|
||||
* Sketch"</tt>, for example, will have the 'S' of "Sketch" chosen, but the 's' of 'sketchbook
|
||||
* will get underlined.
|
||||
* No letter by an underscore will be assigned.
|
||||
* Disabled on Mac, per Apple guidelines.
|
||||
* <tt>menu</tt> may contain nulls.
|
||||
*
|
||||
* Author: George Bateman. Initial work Myer Nore.
|
||||
* @param menu
|
||||
* A menu, a list of menus or an array of menu items to set mnemonics for.
|
||||
*/
|
||||
public static void setMenuMnemonics(JMenuItem... menu) {
|
||||
if (Base.isMacOS()) return;
|
||||
if (menu.length == 0) return;
|
||||
|
||||
// This list is (mostly) the contents of http://techbase.kde.org/Projects/Usability/HIG/
|
||||
// Keyboard_Accelerators, made lowercase, with nothing but letters left except
|
||||
// for ampersands before mnemonics and ".+" for changable text. (They are regexs.)
|
||||
// Note that every ampersand MUST be followed by a lowercase ASCII letter.
|
||||
final String[] kdePreDefStrs = { "&file", "&new", "&open", "open&recent", "&save",
|
||||
"save&as", "saveacop&y", "saveas&template", "savea&ll", "reloa&d", "&print",
|
||||
"printpre&view", "&import", "e&xport", "&closefile", "clos&eallfiles", "&quit",
|
||||
"&edit", "&undo", "re&do", "cu&t&", "©", "&paste", "&delete", "select&all",
|
||||
"dese&lect", "&find", "find&next", "findpre&vious", "&replace", "&gotoline",
|
||||
"&view", "&newview", "close&allviews", "&splitview", "&removeview",
|
||||
"splitter&orientation", "&horizontal", "&vertical", "view&mode", "&fullscreenmode",
|
||||
"&zoom", "zoom&in", "zoom&out", "zoomtopage&width", "zoomwhole&page", "zoom&factor",
|
||||
"&insert", "&format", "&go", "&up", "&back", "&forward", "&home", "&go", "&previouspage",
|
||||
"&nextpage", "&firstpage", "&lastpage", "read&updocument", "read&downdocument", "&back",
|
||||
"&forward", "&gotopage", "&bookmarks", "&addbookmark", "bookmark&tabsasfolder",
|
||||
"&editbookmarks", "&newbookmarksfolder", "&tools", "&settings", "&toolbars",
|
||||
"configure&shortcuts", "configuretool&bars", "&configure*", "&help", ".+&handbook",
|
||||
"&whatsthis", "report&bug", "&aboutprocessing", "about&kde", "&beenden" };
|
||||
Pattern[] kdePreDefPats = new Pattern[kdePreDefStrs.length];
|
||||
for (int i = 0; i < kdePreDefStrs.length; i++)
|
||||
kdePreDefPats[i] = Pattern.compile(kdePreDefStrs[i].replace("&",""));
|
||||
|
||||
final Pattern nonAAlpha = Pattern.compile("[^A-Za-z]");
|
||||
FontMetrics fmTmp = null;
|
||||
for (JMenuItem m : menu) {
|
||||
if (m != null) fmTmp = m.getFontMetrics(m.getFont());
|
||||
}
|
||||
if (fmTmp == null) return; // All null menuitems; comparator would fail.
|
||||
final FontMetrics fm = fmTmp; // Hack for accessing variable in comparator.
|
||||
|
||||
final Comparator<Character> charComparator = new Comparator<Character>() {
|
||||
char[] baddies = "qypgjaeiouQYPGJAEIOU".toCharArray();
|
||||
public int compare(Character ch1, Character ch2) {
|
||||
// Descriminates against decenders for readability, per MS
|
||||
// Human Interface Guide, and vowels per MS and Gnome.
|
||||
float w1 = fm.charWidth(ch1), w2 = fm.charWidth(ch2);
|
||||
for (char bad : baddies) {
|
||||
if (bad == ch1) w1 *= 0.66f;
|
||||
if (bad == ch2) w2 *= 0.66f;
|
||||
}
|
||||
return (int)Math.signum(w2 - w1);
|
||||
}
|
||||
};
|
||||
|
||||
// Holds only [0-9a-z], not uppercase.
|
||||
// Prevents X != x, so "Save" and "Save As" aren't both given 'a'.
|
||||
final List<Character> taken = new ArrayList<Character>(menu.length);
|
||||
char firstChar;
|
||||
char[] cleanChars;
|
||||
Character[] cleanCharas;
|
||||
|
||||
// METHOD 1: attempt to assign KDE defaults.
|
||||
for (JMenuItem jmi : menu) {
|
||||
if (jmi == null) continue;
|
||||
if (jmi.getText() == null) continue;
|
||||
jmi.setMnemonic(0); // Reset.
|
||||
for (int i = 0; i < kdePreDefStrs.length; i++) {
|
||||
// To ASCII lowercase letters.
|
||||
String lASCIIName = nonAAlpha.matcher(jmi.getText()).replaceAll("").toLowerCase();
|
||||
if (kdePreDefPats[i].matcher(lASCIIName).matches()) {
|
||||
char mnem = kdePreDefStrs[i].charAt(1+kdePreDefStrs[i].indexOf("&"));
|
||||
jmi.setMnemonic(mnem);
|
||||
taken.add(mnem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Where KDE defaults fail, use an algorithm.
|
||||
algorithmicAssignment:
|
||||
for (JMenuItem jmi : menu) {
|
||||
if (jmi == null) continue;
|
||||
if (jmi.getText() == null) continue;
|
||||
if (jmi.getMnemonic() != 0) continue; // Already assigned.
|
||||
|
||||
// The string can't be made lower-case as that would spoil
|
||||
// the width comparison.
|
||||
String cleanString = jmi.getText();
|
||||
if (cleanString.startsWith("sketchbook \u2192 "))
|
||||
cleanString = cleanString.substring(13);
|
||||
|
||||
if (cleanString.length() == 0) continue;
|
||||
|
||||
// First, ban letters by underscores.
|
||||
final List<Character> banned = new ArrayList<Character>();
|
||||
for (int i = 0; i < cleanString.length(); i++) {
|
||||
if (cleanString.charAt(i) == '_') {
|
||||
if (i > 0)
|
||||
banned.add(Character.toLowerCase(cleanString.charAt(i-1)));
|
||||
if (i+1 < cleanString.length())
|
||||
banned.add(Character.toLowerCase(cleanString.charAt(i+1)));
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD 2: Uppercase starts of words.
|
||||
// Splitting into blocks of ASCII letters wouldn't work
|
||||
// because there could be non-ASCII letters in a word.
|
||||
for (String wd : cleanString.split("[^\\p{IsAlphabetic}]")) {
|
||||
if (wd.length() == 0) continue;
|
||||
firstChar = wd.charAt(0);
|
||||
if (taken.contains(Character.toLowerCase(firstChar))) continue;
|
||||
if (banned.contains(Character.toLowerCase(firstChar))) continue;
|
||||
if ('A' <= firstChar && firstChar <= 'Z') {
|
||||
jmi.setMnemonic(firstChar);
|
||||
taken.add((char)(firstChar | 32)); // tolowercase
|
||||
continue algorithmicAssignment;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD 3: Lowercase starts of words.
|
||||
for (String wd : cleanString.split("[^\\p{IsAlphabetic}]")) {
|
||||
if (wd.length() == 0) continue;
|
||||
firstChar = wd.charAt(0);
|
||||
if (taken.contains(Character.toLowerCase(firstChar))) continue;
|
||||
if (banned.contains(Character.toLowerCase(firstChar))) continue;
|
||||
if ('a' <= firstChar && firstChar <= 'z') {
|
||||
jmi.setMnemonic(firstChar);
|
||||
taken.add(firstChar); // is lowercase
|
||||
continue algorithmicAssignment;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD 4: Second wide-enough ASCII letter.
|
||||
cleanString = nonAAlpha.matcher(jmi.getText()).replaceAll("");
|
||||
if (cleanString.length() >= 2) {
|
||||
char ascii2nd = cleanString.charAt(1);
|
||||
if (!taken.contains((char)(ascii2nd|32)) &&
|
||||
!banned.contains((char)(ascii2nd|32)) &&
|
||||
fm.charWidth('A') <= 2*fm.charWidth(ascii2nd)) {
|
||||
jmi.setMnemonic(ascii2nd);
|
||||
taken.add((char)(ascii2nd|32));
|
||||
continue algorithmicAssignment;
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD 5: charComparator over all ASCII letters.
|
||||
cleanChars = cleanString.toCharArray();
|
||||
cleanCharas = new Character[cleanChars.length];
|
||||
for (int i = 0; i < cleanChars.length; i++) {
|
||||
cleanCharas[i] = new Character(cleanChars[i]);
|
||||
}
|
||||
Arrays.sort(cleanCharas, charComparator); // sorts in increasing order
|
||||
for (char mnem : cleanCharas) {
|
||||
if (taken.contains(Character.toLowerCase(mnem))) continue;
|
||||
if (banned.contains(Character.toLowerCase(mnem))) continue;
|
||||
// NB: setMnemonic(char) doesn't want [^A-Za-z]
|
||||
jmi.setMnemonic(mnem);
|
||||
taken.add(Character.toLowerCase(mnem));
|
||||
continue algorithmicAssignment;
|
||||
}
|
||||
|
||||
// METHOD 6: Digits as last resort.
|
||||
for (char digit : jmi.getText().replaceAll("[^0-9]", "").toCharArray()) {
|
||||
if (taken.contains(digit)) continue;
|
||||
if (banned.contains(digit)) continue;
|
||||
jmi.setMnemonic(KeyEvent.VK_0 + digit - '0');
|
||||
taken.add(digit);
|
||||
continue algorithmicAssignment;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, RECURSION.
|
||||
for (JMenuItem jmi : menu) {
|
||||
if (jmi instanceof JMenu) setMenuMnemsInside((JMenu) jmi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* As setMenuMnemonics(JMenuItem...).
|
||||
*/
|
||||
public static void setMenuMnemonics(JMenuBar menubar) {
|
||||
JMenuItem[] items = new JMenuItem[menubar.getMenuCount()];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = menubar.getMenu(i);
|
||||
}
|
||||
setMenuMnemonics(items);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* As setMenuMnemonics(JMenuItem...).
|
||||
*/
|
||||
public static void setMenuMnemonics(JPopupMenu menu) {
|
||||
ArrayList<JMenuItem> items = new ArrayList<JMenuItem>();
|
||||
|
||||
for (Component c : menu.getComponents()) {
|
||||
if (c instanceof JMenuItem) items.add((JMenuItem)c);
|
||||
}
|
||||
setMenuMnemonics(items.toArray(new JMenuItem[items.size()]));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls setMenuMnemonics(JMenuItem...) on the sub-elements only.
|
||||
*/
|
||||
public static void setMenuMnemsInside(JMenu menu) {
|
||||
JMenuItem[] items = new JMenuItem[menu.getItemCount()];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = menu.getItem(i);
|
||||
}
|
||||
setMenuMnemonics(items);
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
|
||||
@@ -250,6 +250,8 @@ public class DebugEditor extends JavaEditor implements ActionListener {
|
||||
// }
|
||||
// });
|
||||
|
||||
Toolkit.setMenuMnemonics(ta.getRightClickPopup());
|
||||
|
||||
// load settings from theme.txt
|
||||
ExperimentalMode theme = dmode;
|
||||
breakpointColor = theme.getThemeColor("breakpoint.bgcolor", breakpointColor);
|
||||
@@ -377,26 +379,27 @@ public class DebugEditor extends JavaEditor implements ActionListener {
|
||||
* Writes all error messages to a csv file.
|
||||
* For analytics purposes only.
|
||||
*/
|
||||
private void writeErrorsToFile(){
|
||||
if (errorCheckerService.tempErrorLog.size() == 0)
|
||||
return;
|
||||
try {
|
||||
System.out.println("Writing errors");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
private void writeErrorsToFile() {
|
||||
if (errorCheckerService.tempErrorLog.size() == 0) return;
|
||||
|
||||
try {
|
||||
System.out.println("Writing errors");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Sketch: " + getSketch().getFolder() + ", "
|
||||
+ new java.sql.Timestamp(new java.util.Date().getTime())
|
||||
+ new java.sql.Timestamp(new java.util.Date().getTime())
|
||||
+ "\nComma in error msg is substituted with ^ symbol\nFor separating arguments in error args | symbol is used\n");
|
||||
sb.append("ERROR TYPE, ERROR ARGS, ERROR MSG\n");
|
||||
for (String errMsg : errorCheckerService.tempErrorLog.keySet()) {
|
||||
IProblem ip = errorCheckerService.tempErrorLog.get(errMsg);
|
||||
if(ip != null){
|
||||
sb.append(ErrorMessageSimplifier.getIDName(ip.getID()));
|
||||
sb.append(',');
|
||||
sb.append("{");
|
||||
for (int i = 0; i < ip.getArguments().length; i++) {
|
||||
sb.append(ip.getArguments()[i]);
|
||||
if(i < ip.getArguments().length - 1)
|
||||
sb.append("| ");
|
||||
|
||||
for (String errMsg : errorCheckerService.tempErrorLog.keySet()) {
|
||||
IProblem ip = errorCheckerService.tempErrorLog.get(errMsg);
|
||||
if (ip != null) {
|
||||
sb.append(ErrorMessageSimplifier.getIDName(ip.getID()));
|
||||
sb.append(',');
|
||||
sb.append("{");
|
||||
for (int i = 0; i < ip.getArguments().length; i++) {
|
||||
sb.append(ip.getArguments()[i]);
|
||||
if (i < ip.getArguments().length-1)
|
||||
sb.append("| ");
|
||||
}
|
||||
sb.append("}");
|
||||
sb.append(',');
|
||||
@@ -1005,6 +1008,7 @@ public class DebugEditor extends JavaEditor implements ActionListener {
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
private boolean viewingAutosaveBackup;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user