Applied (a sort of) decorator pattern to SketchCodeDoc.

SketchCodeDoc renamed to SketchCodeDocument.
Compiler is now independent from SketchCodeDocument.
This commit is contained in:
Cristian Maglie 2014-02-01 20:47:00 +01:00
parent bbd3782a9c
commit 54f3f538f2
6 changed files with 109 additions and 156 deletions

View File

@ -1649,7 +1649,7 @@ public class Editor extends JFrame implements RunnerListener {
// insert the program text into the document object // insert the program text into the document object
try { try {
document.insertString(0, codeDoc.getCode().getProgram(), null); document.insertString(0, codeDoc.getProgram(), null);
} catch (BadLocationException bl) { } catch (BadLocationException bl) {
bl.printStackTrace(); bl.printStackTrace();
} }

View File

@ -359,8 +359,7 @@ public class EditorHeader extends JComponent {
editor.getSketch().setCurrentCode(e.getActionCommand()); editor.getSketch().setCurrentCode(e.getActionCommand());
} }
}; };
for (SketchCodeDocument codeDoc : sketch.getCodeDocs()) { for (SketchCode code : sketch.getCodes()) {
SketchCode code = codeDoc.getCode();
item = new JMenuItem(code.isExtension(sketch.getDefaultExtension()) ? item = new JMenuItem(code.isExtension(sketch.getDefaultExtension()) ?
code.getPrettyName() : code.getFileName()); code.getPrettyName() : code.getFileName());
item.setActionCommand(code.getFileName()); item.setActionCommand(code.getFileName());

View File

@ -65,8 +65,7 @@ public class Sketch {
/** code folder location for this sketch (may not exist yet) */ /** code folder location for this sketch (may not exist yet) */
private File codeFolder; private File codeFolder;
private SketchCode current; private SketchCodeDocument current;
private SketchCodeDocument currentCodeDoc;
private int currentIndex; private int currentIndex;
private SketchData data; private SketchData data;
@ -167,7 +166,7 @@ public class Sketch {
// Don't allow people to use files with invalid names, since on load, // Don't allow people to use files with invalid names, since on load,
// it would be otherwise possible to sneak in nasty filenames. [0116] // it would be otherwise possible to sneak in nasty filenames. [0116]
if (Sketch.isSanitaryName(base)) { if (Sketch.isSanitaryName(base)) {
data.addCodeDoc(new SketchCodeDocument(new File(folder, filename))); data.addCode(new SketchCodeDocument(new File(folder, filename)));
} else { } else {
System.err.println(I18n.format("File name {0} is invalid: ignored", filename)); System.err.println(I18n.format("File name {0} is invalid: ignored", filename));
} }
@ -180,10 +179,10 @@ public class Sketch {
// move the main class to the first tab // move the main class to the first tab
// start at 1, if it's at zero, don't bother // start at 1, if it's at zero, don't bother
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
//if (code[i].file.getName().equals(mainFilename)) { //if (code[i].file.getName().equals(mainFilename)) {
if (codeDoc.getCode().getFile().equals(primaryFile)) { if (code.getFile().equals(primaryFile)) {
data.moveCodeDocToFront(codeDoc); data.moveCodeToFront(code);
break; break;
} }
} }
@ -308,7 +307,7 @@ public class Sketch {
// Don't let the user create the main tab as a .java file instead of .pde // Don't let the user create the main tab as a .java file instead of .pde
if (!isDefaultExtension(newExtension)) { if (!isDefaultExtension(newExtension)) {
if (renamingCode) { // If creating a new tab, don't show this error if (renamingCode) { // If creating a new tab, don't show this error
if (current == data.getCodeDoc(0).getCode()) { // If this is the main tab, disallow if (current == data.getCode(0)) { // If this is the main tab, disallow
Base.showWarning(_("Problem with rename"), Base.showWarning(_("Problem with rename"),
_("The main file can't use an extension.\n" + _("The main file can't use an extension.\n" +
"(It may be time for your to graduate to a\n" + "(It may be time for your to graduate to a\n" +
@ -330,12 +329,12 @@ public class Sketch {
// In Arduino, we want to allow files with the same name but different // In Arduino, we want to allow files with the same name but different
// extensions, so compare the full names (including extensions). This // extensions, so compare the full names (including extensions). This
// might cause problems: http://dev.processing.org/bugs/show_bug.cgi?id=543 // might cause problems: http://dev.processing.org/bugs/show_bug.cgi?id=543
for (SketchCodeDocument c : data.getCodeDocs()) { for (SketchCode c : data.getCodes()) {
if (newName.equalsIgnoreCase(c.getCode().getFileName())) { if (newName.equalsIgnoreCase(c.getFileName())) {
Base.showMessage(_("Nope"), Base.showMessage(_("Nope"),
I18n.format( I18n.format(
_("A file named \"{0}\" already exists in \"{1}\""), _("A file named \"{0}\" already exists in \"{1}\""),
c.getCode().getFileName(), c.getFileName(),
folder.getAbsolutePath() folder.getAbsolutePath()
)); ));
return; return;
@ -352,15 +351,13 @@ public class Sketch {
} }
if (renamingCode && currentIndex == 0) { if (renamingCode && currentIndex == 0) {
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
if (sanitaryName.equalsIgnoreCase(codeDoc.getCode().getPrettyName()) && if (sanitaryName.equalsIgnoreCase(code.getPrettyName()) &&
codeDoc.getCode().isExtension("cpp")) { code.isExtension("cpp")) {
Base.showMessage(_("Nope"), Base.showMessage(_("Nope"),
I18n.format( I18n.format(_("You can't rename the sketch to \"{0}\"\n"
_("You can't rename the sketch to \"{0}\"\n" + + "because the sketch already has a .cpp file with that name."),
"because the sketch already has a .cpp file with that name."), sanitaryName));
sanitaryName
));
return; return;
} }
} }
@ -428,8 +425,8 @@ public class Sketch {
// save each of the other tabs because this is gonna be re-opened // save each of the other tabs because this is gonna be re-opened
try { try {
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
codeDoc.getCode().save(); code.save();
} }
} catch (Exception e) { } catch (Exception e) {
Base.showWarning(_("Error"), _("Could not rename the sketch. (1)"), e); Base.showWarning(_("Error"), _("Could not rename the sketch. (1)"), e);
@ -486,10 +483,8 @@ public class Sketch {
), e); ), e);
return; return;
} }
SketchCode newCode = new SketchCode(newFile);
//System.out.println("new code is named " + newCode.getPrettyName() + " " + newCode.getFile());
ensureExistence(); ensureExistence();
data.insertCode(newCode); data.addCode(new SketchCodeDocument(newFile));
} }
// sort the entries // sort the entries
@ -601,8 +596,8 @@ public class Sketch {
protected void calcModified() { protected void calcModified() {
modified = false; modified = false;
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
if (codeDoc.getCode().isModified()) { if (code.isModified()) {
modified = true; modified = true;
break; break;
} }
@ -685,9 +680,9 @@ public class Sketch {
} }
} }
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
if (codeDoc.getCode().isModified()) if (code.isModified())
codeDoc.getCode().save(); code.save();
} }
calcModified(); calcModified();
return true; return true;
@ -695,13 +690,13 @@ public class Sketch {
protected boolean renameCodeToInoExtension(File pdeFile) { protected boolean renameCodeToInoExtension(File pdeFile) {
for (SketchCodeDocument c : data.getCodeDocs()) { for (SketchCode c : data.getCodes()) {
if (!c.getCode().getFile().equals(pdeFile)) if (!c.getFile().equals(pdeFile))
continue; continue;
String pdeName = pdeFile.getPath(); String pdeName = pdeFile.getPath();
pdeName = pdeName.substring(0, pdeName.length() - 4) + ".ino"; pdeName = pdeName.substring(0, pdeName.length() - 4) + ".ino";
return c.getCode().renameTo(new File(pdeName)); return c.renameTo(new File(pdeName));
} }
return false; return false;
} }
@ -746,9 +741,9 @@ public class Sketch {
// make sure there doesn't exist a .cpp file with that name already // make sure there doesn't exist a .cpp file with that name already
// but ignore this situation for the first tab, since it's probably being // but ignore this situation for the first tab, since it's probably being
// resaved (with the same name) to another location/folder. // resaved (with the same name) to another location/folder.
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
if (newName.equalsIgnoreCase(codeDoc.getCode().getPrettyName()) && if (newName.equalsIgnoreCase(code.getPrettyName()) &&
codeDoc.getCode().isExtension("cpp")) { code.isExtension("cpp")) {
Base.showMessage(_("Nope"), Base.showMessage(_("Nope"),
I18n.format( I18n.format(
_("You can't save the sketch as \"{0}\"\n" + _("You can't save the sketch as \"{0}\"\n" +
@ -798,10 +793,10 @@ public class Sketch {
} }
// save the other tabs to their new location // save the other tabs to their new location
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
if (data.indexOfCodeDoc(codeDoc) == 0) continue; if (data.indexOfCode(code) == 0) continue;
File newFile = new File(newFolder, codeDoc.getCode().getFileName()); File newFile = new File(newFolder, code.getFileName());
codeDoc.getCode().saveAs(newFile); code.saveAs(newFile);
} }
// re-copy the data folder (this may take a while.. add progress bar?) // re-copy the data folder (this may take a while.. add progress bar?)
@ -826,7 +821,7 @@ public class Sketch {
// save the main tab with its new name // save the main tab with its new name
File newFile = new File(newFolder, newName + ".ino"); File newFile = new File(newFolder, newName + ".ino");
data.getCodeDoc(0).getCode().saveAs(newFile); data.getCode(0).saveAs(newFile);
editor.handleOpenUnchecked(newFile, editor.handleOpenUnchecked(newFile,
currentIndex, currentIndex,
@ -989,14 +984,14 @@ public class Sketch {
} }
if (codeExtension != null) { if (codeExtension != null) {
SketchCode newCode = new SketchCode(destFile); SketchCode newCode = new SketchCodeDocument(destFile);
if (replacement) { if (replacement) {
data.replaceCode(newCode); data.replaceCode(newCode);
} else { } else {
ensureExistence(); ensureExistence();
data.insertCode(newCode); data.addCode(newCode);
data.sortCode(); data.sortCode();
} }
setCurrentCode(filename); setCurrentCode(filename);
@ -1010,7 +1005,7 @@ public class Sketch {
if (editor.untitled) { // TODO probably not necessary? problematic? if (editor.untitled) { // TODO probably not necessary? problematic?
// If a file has been added, mark the main code as modified so // If a file has been added, mark the main code as modified so
// that the sketch is properly saved. // that the sketch is properly saved.
data.getCodeDoc(0).getCode().setModified(true); data.getCode(0).setModified(true);
} }
} }
return true; return true;
@ -1071,16 +1066,15 @@ public class Sketch {
// get the text currently being edited // get the text currently being edited
if (current != null) { if (current != null) {
current.setProgram(editor.getText()); current.setProgram(editor.getText());
currentCodeDoc.setSelectionStart(editor.getSelectionStart()); current.setSelectionStart(editor.getSelectionStart());
currentCodeDoc.setSelectionStop(editor.getSelectionStop()); current.setSelectionStop(editor.getSelectionStop());
currentCodeDoc.setScrollPosition(editor.getScrollPosition()); current.setScrollPosition(editor.getScrollPosition());
} }
currentCodeDoc = data.getCodeDoc(which); current = (SketchCodeDocument) data.getCode(which);
current = currentCodeDoc.getCode();
currentIndex = which; currentIndex = which;
editor.setCode(currentCodeDoc); editor.setCode(current);
editor.header.rebuild(); editor.header.rebuild();
} }
@ -1091,10 +1085,10 @@ public class Sketch {
* @param findName the file name (not pretty name) to be shown * @param findName the file name (not pretty name) to be shown
*/ */
protected void setCurrentCode(String findName) { protected void setCurrentCode(String findName) {
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
if (findName.equals(codeDoc.getCode().getFileName()) || if (findName.equals(code.getFileName()) ||
findName.equals(codeDoc.getCode().getPrettyName())) { findName.equals(code.getPrettyName())) {
setCurrentCode(data.indexOfCodeDoc(codeDoc)); setCurrentCode(data.indexOfCode(code));
return; return;
} }
} }
@ -1527,8 +1521,8 @@ public class Sketch {
folder.mkdirs(); folder.mkdirs();
modified = true; modified = true;
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
codeDoc.getCode().save(); // this will force a save code.save(); // this will force a save
} }
calcModified(); calcModified();
@ -1562,9 +1556,8 @@ public class Sketch {
// } else if (!folder.canWrite()) { // } else if (!folder.canWrite()) {
// check to see if each modified code file can be written to // check to see if each modified code file can be written to
for (SketchCodeDocument codeDoc : data.getCodeDocs()) { for (SketchCode code : data.getCodes()) {
if (codeDoc.getCode().isModified() && codeDoc.getCode().fileReadOnly() && if (code.isModified() && code.fileReadOnly() && code.fileExists()) {
codeDoc.getCode().fileExists()) {
// System.err.println("found a read-only file " + code[i].file); // System.err.println("found a read-only file " + code[i].file);
return true; return true;
} }
@ -1702,8 +1695,8 @@ public class Sketch {
} }
public SketchCodeDocument[] getCodeDocs() { public SketchCode[] getCodes() {
return data.getCodeDocs(); return data.getCodes();
} }
@ -1713,7 +1706,7 @@ public class Sketch {
public SketchCode getCode(int index) { public SketchCode getCode(int index) {
return data.getCodeDoc(index).getCode(); return data.getCode(index);
} }

View File

@ -4,19 +4,24 @@ import java.io.File;
import javax.swing.text.Document; import javax.swing.text.Document;
public class SketchCodeDocument { public class SketchCodeDocument extends SketchCode {
SketchCode code;
private Document document; private Document document;
/** // Undo Manager for this tab, each tab keeps track of their own Editor.undo
* Undo Manager for this tab, each tab keeps track of their own // will be set to this object when this code is the tab that's currently the
* Editor.undo will be set to this object when this code is the tab // front.
* that's currently the front.
*/
private LastUndoableEditAwareUndoManager undo = new LastUndoableEditAwareUndoManager(); private LastUndoableEditAwareUndoManager undo = new LastUndoableEditAwareUndoManager();
// saved positions from last time this tab was used
private int selectionStart;
private int selectionStop;
private int scrollPosition;
public SketchCodeDocument(File file) {
super(file);
}
public LastUndoableEditAwareUndoManager getUndo() { public LastUndoableEditAwareUndoManager getUndo() {
return undo; return undo;
} }
@ -49,29 +54,6 @@ public class SketchCodeDocument {
this.scrollPosition = scrollPosition; this.scrollPosition = scrollPosition;
} }
// saved positions from last time this tab was used
private int selectionStart;
private int selectionStop;
private int scrollPosition;
public SketchCodeDocument(SketchCode sketchCode, Document doc) {
code = sketchCode;
document = doc;
}
public SketchCodeDocument(File file) {
code = new SketchCode(file);
}
public SketchCode getCode() {
return code;
}
public void setCode(SketchCode code) {
this.code = code;
}
public Document getDocument() { public Document getDocument() {
return document; return document;
} }

View File

@ -1,7 +1,5 @@
package processing.app; package processing.app;
import static processing.app.I18n._;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -15,81 +13,67 @@ public class SketchData {
*/ */
private String name; private String name;
private List<SketchCodeDocument> codeDocs = new ArrayList<SketchCodeDocument>(); private List<SketchCode> codes = new ArrayList<SketchCode>();
private static final Comparator<SketchCodeDocument> CODE_DOCS_COMPARATOR = new Comparator<SketchCodeDocument>() { private static final Comparator<SketchCode> CODE_DOCS_COMPARATOR = new Comparator<SketchCode>() {
@Override @Override
public int compare(SketchCodeDocument cd1, SketchCodeDocument cd2) { public int compare(SketchCode x, SketchCode y) {
return cd1.getCode().getFileName().compareTo(cd2.getCode().getFileName()); return x.getFileName().compareTo(y.getFileName());
} }
}; };
public int getCodeCount() { public int getCodeCount() {
return codeDocs.size(); return codes.size();
} }
public SketchCodeDocument[] getCodeDocs() { public SketchCode[] getCodes() {
return codeDocs.toArray(new SketchCodeDocument[0]); return codes.toArray(new SketchCode[0]);
} }
public void addCodeDoc(SketchCodeDocument sketchCodeDoc) { public void addCode(SketchCode sketchCode) {
codeDocs.add(sketchCodeDoc); codes.add(sketchCode);
} }
public void moveCodeDocToFront(SketchCodeDocument codeDoc) { public void moveCodeToFront(SketchCode codeDoc) {
codeDocs.remove(codeDoc); codes.remove(codeDoc);
codeDocs.add(0, codeDoc); codes.add(0, codeDoc);
} }
protected void replaceCode(SketchCode newCode) { protected void replaceCode(SketchCode newCode) {
for (SketchCodeDocument codeDoc : codeDocs) { for (SketchCode code : codes) {
if (codeDoc.getCode().getFileName().equals(newCode.getFileName())) { if (code.getFileName().equals(newCode.getFileName())) {
codeDoc.setCode(newCode); codes.set(codes.indexOf(code), newCode);
return; return;
} }
} }
} }
protected void insertCode(SketchCode sketchCode) {
addCodeDoc(new SketchCodeDocument(sketchCode, null));
}
protected void sortCode() { protected void sortCode() {
if (codeDocs.size() < 2) if (codes.size() < 2)
return; return;
SketchCodeDocument first = codeDocs.remove(0); SketchCode first = codes.remove(0);
Collections.sort(codeDocs, CODE_DOCS_COMPARATOR); Collections.sort(codes, CODE_DOCS_COMPARATOR);
codeDocs.add(0, first); codes.add(0, first);
}
public SketchCodeDocument getCodeDoc(int i) {
return codeDocs.get(i);
} }
public SketchCode getCode(int i) { public SketchCode getCode(int i) {
return codeDocs.get(i).getCode(); return codes.get(i);
} }
protected void removeCode(SketchCode which) { protected void removeCode(SketchCode which) {
for (SketchCodeDocument codeDoc : codeDocs) { for (SketchCode code : codes) {
if (codeDoc.getCode() == which) { if (code == which) {
codeDocs.remove(codeDoc); codes.remove(code);
return; return;
} }
} }
System.err.println(_("removeCode: internal error.. could not find code")); System.err.println("removeCode: internal error.. could not find code");
}
public int indexOfCodeDoc(SketchCodeDocument codeDoc) {
return codeDocs.indexOf(codeDoc);
} }
public int indexOfCode(SketchCode who) { public int indexOfCode(SketchCode who) {
for (SketchCodeDocument codeDoc : codeDocs) { for (SketchCode code : codes) {
if (codeDoc.getCode() == who) { if (code == who)
return codeDocs.indexOf(codeDoc); return codes.indexOf(code);
}
} }
return -1; return -1;
} }
@ -103,6 +87,6 @@ public class SketchData {
} }
public void clearCodeDocs() { public void clearCodeDocs() {
codeDocs.clear(); codes.clear();
} }
} }

View File

@ -40,7 +40,6 @@ import processing.app.Base;
import processing.app.I18n; import processing.app.I18n;
import processing.app.Preferences; import processing.app.Preferences;
import processing.app.SketchCode; import processing.app.SketchCode;
import processing.app.SketchCodeDocument;
import processing.app.SketchData; import processing.app.SketchData;
import processing.app.helpers.FileUtils; import processing.app.helpers.FileUtils;
import processing.app.helpers.PreferencesMap; import processing.app.helpers.PreferencesMap;
@ -50,7 +49,6 @@ import processing.app.helpers.filefilters.OnlyDirs;
import processing.app.packages.Library; import processing.app.packages.Library;
import processing.app.packages.LibraryList; import processing.app.packages.LibraryList;
import processing.app.preproc.PdePreprocessor; import processing.app.preproc.PdePreprocessor;
import processing.core.PApplet;
public class Compiler implements MessageConsumer { public class Compiler implements MessageConsumer {
@ -901,8 +899,7 @@ public class Compiler implements MessageConsumer {
StringBuffer bigCode = new StringBuffer(); StringBuffer bigCode = new StringBuffer();
int bigCount = 0; int bigCount = 0;
for (SketchCodeDocument scd : sketch.getCodeDocs()) { for (SketchCode sc : sketch.getCodes()) {
SketchCode sc = scd.getCode();
if (sc.isExtension("ino") || sc.isExtension("pde")) { if (sc.isExtension("ino") || sc.isExtension("pde")) {
sc.setPreprocOffset(bigCount); sc.setPreprocOffset(bigCount);
// These #line directives help the compiler report errors with // These #line directives help the compiler report errors with
@ -962,8 +959,7 @@ public class Compiler implements MessageConsumer {
// 3. then loop over the code[] and save each .java file // 3. then loop over the code[] and save each .java file
for (SketchCodeDocument scd : sketch.getCodeDocs()) { for (SketchCode sc : sketch.getCodes()) {
SketchCode sc = scd.getCode();
if (sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h")) { if (sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h")) {
// no pre-processing services necessary for java files // no pre-processing services necessary for java files
// just write the the contents of 'program' to a .java file // just write the the contents of 'program' to a .java file
@ -1005,8 +1001,7 @@ public class Compiler implements MessageConsumer {
// Placing errors is simple, because we inserted #line directives // Placing errors is simple, because we inserted #line directives
// into the preprocessed source. The compiler gives us correct // into the preprocessed source. The compiler gives us correct
// the file name and line number. :-) // the file name and line number. :-)
for (SketchCodeDocument codeDoc : sketch.getCodeDocs()) { for (SketchCode code : sketch.getCodes()) {
SketchCode code = codeDoc.getCode();
if (dotJavaFilename.equals(code.getFileName())) { if (dotJavaFilename.equals(code.getFileName())) {
return new RunnerException(message, sketch.indexOfCode(code), dotJavaLine); return new RunnerException(message, sketch.indexOfCode(code), dotJavaLine);
} }