X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2FTEditorWidget.java;h=9236da2a89a57afd06cd62e3463c800bcd573df2;hb=bff0df27562e1cca8e6be47e7ace9bd5bb1adbfa;hp=a329dfa347b770dcb279140a1c5ef170f72aab64;hpb=20c416a0cb63ad5d2e3f14eae42d2d7b2f13e946;p=fanfix.git diff --git a/src/jexer/TEditorWidget.java b/src/jexer/TEditorWidget.java index a329dfa..9236da2 100644 --- a/src/jexer/TEditorWidget.java +++ b/src/jexer/TEditorWidget.java @@ -165,8 +165,10 @@ public class TEditorWidget extends TWidget implements EditMenuUser { if (mouse.isMouse1()) { // Selection. inSelection = true; - selectionColumn0 = leftColumn + mouse.getX(); selectionLine0 = topLine + mouse.getY(); + selectionColumn0 = leftColumn + mouse.getX(); + selectionColumn0 = Math.max(0, Math.min(selectionColumn0, + document.getLine(selectionLine0).getDisplayLength() - 1)); selectionColumn1 = selectionColumn0; selectionLine1 = selectionLine0; @@ -221,21 +223,25 @@ public class TEditorWidget extends TWidget implements EditMenuUser { public void onMouseMotion(final TMouseEvent mouse) { if (mouse.isMouse1()) { + // Set the row and column + int newLine = topLine + mouse.getY(); + int newX = leftColumn + mouse.getX(); + if ((newLine < 0) || (newX < 0)) { + return; + } + // Selection. if (inSelection) { - selectionColumn1 = leftColumn + mouse.getX(); - selectionLine1 = topLine + mouse.getY(); + selectionColumn1 = newX; + selectionLine1 = newLine; } else { inSelection = true; - selectionColumn0 = leftColumn + mouse.getX(); - selectionLine0 = topLine + mouse.getY(); + selectionColumn0 = newX; + selectionLine0 = newLine; selectionColumn1 = selectionColumn0; selectionLine1 = selectionLine0; } - // Set the row and column - int newLine = topLine + mouse.getY(); - int newX = leftColumn + mouse.getX(); if (newLine > document.getLineCount() - 1) { // Go to the end document.setLineNumber(document.getLineCount() - 1); @@ -252,7 +258,6 @@ public class TEditorWidget extends TWidget implements EditMenuUser { } return; } - document.setLineNumber(newLine); setCursorY(mouse.getY()); if (newX >= document.getCurrentLine().getDisplayLength()) { @@ -510,23 +515,27 @@ public class TEditorWidget extends TWidget implements EditMenuUser { public void draw() { CellAttributes selectedColor = getTheme().getColor("teditor.selected"); + boolean drawSelection = true; + int startCol = selectionColumn0; int startRow = selectionLine0; int endCol = selectionColumn1; int endRow = selectionLine1; if (((selectionColumn1 < selectionColumn0) - && (selectionLine1 <= selectionLine0)) - || ((selectionColumn1 <= selectionColumn0) - && (selectionLine1 < selectionLine0)) + && (selectionLine1 == selectionLine0)) + || (selectionLine1 < selectionLine0) ) { - // The user selected from bottom-right to top-left. Reverse the - // coordinates for the inverted section. + // The user selected from bottom-to-top and/or right-to-left. + // Reverse the coordinates for the inverted section. startCol = selectionColumn1; startRow = selectionLine1; endCol = selectionColumn0; endRow = selectionLine0; } + if ((startCol == endCol) && (startRow == endRow)) { + drawSelection = false; + } for (int i = 0; i < getHeight(); i++) { // Background line @@ -548,7 +557,7 @@ public class TEditorWidget extends TWidget implements EditMenuUser { } // Highlight selected region - if (inSelection) { + if (inSelection && drawSelection) { if (startRow == endRow) { if (topLine + i == startRow) { for (x = startCol; x <= endCol; x++) { @@ -789,6 +798,17 @@ public class TEditorWidget extends TWidget implements EditMenuUser { return document.getLineLengthMax() + 1; } + /** + * Get the current editing row plain text. 1-based. + * + * @param row the editing row number. Row 1 is the first row. + * @return the plain text of the row + */ + public String getEditingRawLine(final int row) { + Line line = document.getLine(row - 1); + return line.getRawString(); + } + /** * Get the dirty value. * @@ -798,6 +818,13 @@ public class TEditorWidget extends TWidget implements EditMenuUser { return document.isDirty(); } + /** + * Unset the dirty flag. + */ + public void setNotDirty() { + document.setNotDirty(); + } + /** * Save contents to file. * @@ -812,7 +839,7 @@ public class TEditorWidget extends TWidget implements EditMenuUser { * Delete text within the selection bounds. */ private void deleteSelection() { - if (inSelection == false) { + if (!inSelection) { return; } inSelection = false; @@ -822,26 +849,74 @@ public class TEditorWidget extends TWidget implements EditMenuUser { int endCol = selectionColumn1; int endRow = selectionLine1; + /* + System.err.println("INITIAL: " + startRow + " " + startCol + " " + + endRow + " " + endCol + " " + + document.getLineNumber() + " " + document.getCursor()); + */ + if (((selectionColumn1 < selectionColumn0) - && (selectionLine1 <= selectionLine0)) - || ((selectionColumn1 <= selectionColumn0) - && (selectionLine1 < selectionLine0)) + && (selectionLine1 == selectionLine0)) + || (selectionLine1 < selectionLine0) ) { - // The user selected from bottom-right to top-left. Reverse the - // coordinates for the inverted section. + // The user selected from bottom-to-top and/or right-to-left. + // Reverse the coordinates for the inverted section. startCol = selectionColumn1; startRow = selectionLine1; endCol = selectionColumn0; endRow = selectionLine0; + + if (endRow >= document.getLineCount()) { + // The selection started beyond EOF, trim it to EOF. + endRow = document.getLineCount() - 1; + endCol = document.getLine(endRow).getDisplayLength(); + } else if (endRow == document.getLineCount() - 1) { + // The selection started beyond EOF, trim it to EOF. + if (endCol >= document.getLine(endRow).getDisplayLength()) { + endCol = document.getLine(endRow).getDisplayLength() - 1; + } + } + } + /* + System.err.println("FLIP: " + startRow + " " + startCol + " " + + endRow + " " + endCol + " " + + document.getLineNumber() + " " + document.getCursor()); + System.err.println(" --END: " + endRow + " " + document.getLineCount() + + " " + document.getLine(endRow).getDisplayLength()); + */ + + assert (endRow < document.getLineCount()); + if (endCol >= document.getLine(endRow).getDisplayLength()) { + endCol = document.getLine(endRow).getDisplayLength() - 1; + } + if (endCol < 0) { + endCol = 0; + } + if (startCol >= document.getLine(startRow).getDisplayLength()) { + startCol = document.getLine(startRow).getDisplayLength() - 1; + } + if (startCol < 0) { + startCol = 0; } // Place the cursor on the selection end, and "press backspace" until // the cursor matches the selection start. + /* + System.err.println("BEFORE: " + startRow + " " + startCol + " " + + endRow + " " + endCol + " " + + document.getLineNumber() + " " + document.getCursor()); + */ document.setLineNumber(endRow); document.setCursor(endCol + 1); while (!((document.getLineNumber() == startRow) && (document.getCursor() == startCol)) ) { + /* + System.err.println("DURING: " + startRow + " " + startCol + " " + + endRow + " " + endCol + " " + + document.getLineNumber() + " " + document.getCursor()); + */ + document.backspace(); } alignTopLine(true); @@ -851,9 +926,42 @@ public class TEditorWidget extends TWidget implements EditMenuUser { * Copy text within the selection bounds to clipboard. */ private void copySelection() { - if (inSelection == false) { + if (!inSelection) { return; } + getClipboard().copyText(getSelection()); + } + + /** + * Set the selection. + * + * @param startRow the starting row number. 0-based: row 0 is the first + * row. + * @param startColumn the starting column number. 0-based: column 0 is + * the first column. + * @param endRow the ending row number. 0-based: row 0 is the first row. + * @param endColumn the ending column number. 0-based: column 0 is the + * first column. + */ + public void setSelection(final int startRow, final int startColumn, + final int endRow, final int endColumn) { + + inSelection = true; + selectionLine0 = startRow; + selectionColumn0 = startColumn; + selectionLine1 = endRow; + selectionColumn1 = endColumn; + } + + /** + * Copy text within the selection bounds to a string. + * + * @return the selection as a string, or null if there is no selection + */ + public String getSelection() { + if (!inSelection) { + return null; + } int startCol = selectionColumn0; int startRow = selectionLine0; @@ -861,12 +969,11 @@ public class TEditorWidget extends TWidget implements EditMenuUser { int endRow = selectionLine1; if (((selectionColumn1 < selectionColumn0) - && (selectionLine1 <= selectionLine0)) - || ((selectionColumn1 <= selectionColumn0) - && (selectionLine1 < selectionLine0)) + && (selectionLine1 == selectionLine0)) + || (selectionLine1 < selectionLine0) ) { - // The user selected from bottom-right to top-left. Reverse the - // coordinates for the inverted section. + // The user selected from bottom-to-top and/or right-to-left. + // Reverse the coordinates for the inverted section. startCol = selectionColumn1; startRow = selectionLine1; endCol = selectionColumn0; @@ -927,8 +1034,186 @@ public class TEditorWidget extends TWidget implements EditMenuUser { i += Character.charCount(ch); } } + return sb.toString(); + } + + /** + * Get the selection starting row number. + * + * @return the starting row number, or -1 if there is no selection. + * 0-based: row 0 is the first row. + */ + public int getSelectionStartRow() { + if (!inSelection) { + return -1; + } + + int startCol = selectionColumn0; + int startRow = selectionLine0; + int endCol = selectionColumn1; + int endRow = selectionLine1; + + if (((selectionColumn1 < selectionColumn0) + && (selectionLine1 == selectionLine0)) + || (selectionLine1 < selectionLine0) + ) { + // The user selected from bottom-to-top and/or right-to-left. + // Reverse the coordinates for the inverted section. + startCol = selectionColumn1; + startRow = selectionLine1; + endCol = selectionColumn0; + endRow = selectionLine0; + } + return startRow; + } + + /** + * Get the selection starting column number. + * + * @return the starting column number, or -1 if there is no selection. + * 0-based: column 0 is the first column. + */ + public int getSelectionStartColumn() { + if (!inSelection) { + return -1; + } + + int startCol = selectionColumn0; + int startRow = selectionLine0; + int endCol = selectionColumn1; + int endRow = selectionLine1; - getClipboard().copyText(sb.toString()); + if (((selectionColumn1 < selectionColumn0) + && (selectionLine1 == selectionLine0)) + || (selectionLine1 < selectionLine0) + ) { + // The user selected from bottom-to-top and/or right-to-left. + // Reverse the coordinates for the inverted section. + startCol = selectionColumn1; + startRow = selectionLine1; + endCol = selectionColumn0; + endRow = selectionLine0; + } + return startCol; + } + + /** + * Get the selection ending row number. + * + * @return the ending row number, or -1 if there is no selection. + * 0-based: row 0 is the first row. + */ + public int getSelectionEndRow() { + if (!inSelection) { + return -1; + } + + int startCol = selectionColumn0; + int startRow = selectionLine0; + int endCol = selectionColumn1; + int endRow = selectionLine1; + + if (((selectionColumn1 < selectionColumn0) + && (selectionLine1 == selectionLine0)) + || (selectionLine1 < selectionLine0) + ) { + // The user selected from bottom-to-top and/or right-to-left. + // Reverse the coordinates for the inverted section. + startCol = selectionColumn1; + startRow = selectionLine1; + endCol = selectionColumn0; + endRow = selectionLine0; + } + return endRow; + } + + /** + * Get the selection ending column number. + * + * @return the ending column number, or -1 if there is no selection. + * 0-based: column 0 is the first column. + */ + public int getSelectionEndColumn() { + if (!inSelection) { + return -1; + } + + int startCol = selectionColumn0; + int startRow = selectionLine0; + int endCol = selectionColumn1; + int endRow = selectionLine1; + + if (((selectionColumn1 < selectionColumn0) + && (selectionLine1 == selectionLine0)) + || (selectionLine1 < selectionLine0) + ) { + // The user selected from bottom-to-top and/or right-to-left. + // Reverse the coordinates for the inverted section. + startCol = selectionColumn1; + startRow = selectionLine1; + endCol = selectionColumn0; + endRow = selectionLine0; + } + return endCol; + } + + /** + * Unset the selection. + */ + public void unsetSelection() { + inSelection = false; + } + + /** + * Replace whatever is being selected with new text. If not in + * selection, nothing is replaced. + * + * @param text the new replacement text + */ + public void replaceSelection(final String text) { + if (!inSelection) { + return; + } + + // Delete selected text, then paste text from clipboard. + deleteSelection(); + + for (int i = 0; i < text.length(); ) { + int ch = text.codePointAt(i); + onKeypress(new TKeypressEvent(false, 0, ch, false, false, + false)); + i += Character.charCount(ch); + } + } + + /** + * Check if selection is available. + * + * @return true if a selection has been made + */ + public boolean hasSelection() { + return inSelection; + } + + /** + * Get the entire contents of the editor as one string. + * + * @return the editor contents + */ + public String getText() { + return document.getText(); + } + + /** + * Set the entire contents of the editor from one string. + * + * @param text the new contents + */ + public void setText(final String text) { + document = new Document(text, defaultColor); + unsetSelection(); + topLine = 0; + leftColumn = 0; } // ------------------------------------------------------------------------