Block Selection

Questions on using RSyntaxTextArea should go here.

Moderator: robert

Block Selection

Postby Deepak » Wed Feb 03, 2010 1:17 pm

Hi,

I need the Block selection in RSyntaxTextArea. kindly guide me.
Deepak
 

Re: Block Selection

Postby robert » Wed Feb 03, 2010 1:52 pm

HI Deepak,

RSTA currently does not support block selection. Please add a Feature Request if you'd like to see this feature added in a future release.

Thanks!
User avatar
robert
 
Posts: 802
Joined: Sat May 10, 2008 5:16 pm

Re: Block Selection

Postby nenopera » Wed Aug 29, 2012 10:49 am

There is a block_selection branch created in 2010

Despite of implement keyboard selection is completely functional (I use java 1.4 for test)

Cut, copy, paste and edit al block selection at time is working in this example (last post about these topics in the blog says they didn't at that time)

java code:

import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.plaf.TextUI;
import javax.swing.plaf.basic.BasicTextUI;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.MouseEvent;


/**
* Resaltado de paréntesis ( [ { y block selection
*/
public class BlockSelectionTest implements CaretListener {

public static void main(String a[]) {
JFrame f = new JFrame();
final JEditorPane p = new JEditorPane() {
public String getSelectedText() {
String text = null;
BlockCaret cc = (BlockCaret) getCaret();

if (cc.isBlockSelectionHighlighted()) {
StringBuffer sb = new StringBuffer();
Highlighter.Highlight[] h = getHighlighter().getHighlights();
try {
for (int i = 0; i < h.length; i++) {
int offs = h[i].getStartOffset();
int len = h[i].getEndOffset() - offs;
String line = getText(offs, len);
sb.append(line);
if (i < h.length - 1) {
sb.append('\n');
}
}
} catch (BadLocationException ble) { // Never happens
ble.printStackTrace();
}
text = sb.toString();
} else {
text = super.getSelectedText();
}

return text;
}
};
p.setDocument(new PlainDocument() {
public void remove(int offs, int len) throws BadLocationException {
BlockCaret cc = (BlockCaret) p.getCaret();

if (cc.isBlockSelectionHighlighted()) {
Highlighter.Highlight[] h = p.getHighlighter().getHighlights();
try {
for (int i = 0; i < h.length; i++) {
int offsTemp = h[i].getStartOffset();
int lenTemp = h[i].getEndOffset() - offsTemp;
super.remove(offsTemp, lenTemp);
}
} catch (BadLocationException ble) {
ble.printStackTrace();
}
} else {
super.remove(offs, len);
}
}

public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
BlockCaret cc = (BlockCaret) p.getCaret();

if (cc.isBlockSelectionHighlighted()) {
Highlighter.Highlight[] h = p.getHighlighter().getHighlights();
try {
for (int i = 0; i < h.length; i++) {
int offsTemp = h[i].getStartOffset();
super.insertString(offsTemp, str, a);
}
} catch (BadLocationException ble) {
ble.printStackTrace();
}
} else {
super.insertString(offs, str, a);
}
}
});
p.setCaret(new BlockCaret(p));
f.getContentPane().add(new JScrollPane(p));
p.setFont(new Font("Monospaced", 0, 12));

f.setSize(400, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}

private static class BlockCaret extends BasicTextUI.BasicCaret {

JTextComponent component;

/**
* Used to help with block selections.
*/
private Point lastPoint = new Point();

/**
* Whether a block selection is currently taking place.
*/
private boolean isBlockSelection;

public boolean isBlockSelectionHighlighted() {
return blockSelectionHighlighted;
}

/**
* Whether a block selection exists.
*/
private boolean blockSelectionHighlighted;

/**
* The dot of the block selection. Only valid if
* {@link #isBlockSelection} is <code>true</code>.
*/
private int blockSelectionDot;

/**
* The mark of the block selection. Only valid if
* {@link #isBlockSelection} is <code>true</code> and
*/
private int blockSelectionMark;

private BlockCaret(JTextComponent component) {
this.component = component;
}

private void removeHighlights() {
if (blockSelectionHighlighted) {
getComponent().getHighlighter().removeAllHighlights();
blockSelectionHighlighted = false;
}
}

public int getDot() {
return blockSelectionDot != blockSelectionMark ? blockSelectionDot : super.getDot();
}


public int getMark() {
return blockSelectionDot != blockSelectionMark ? blockSelectionMark : super.getMark();
}

protected void customHighlight(Point start, Point end) {
blockSelectionHighlighted = true;
Highlighter h = getComponent().getHighlighter();
TextUI ui = getComponent().getUI();
h.removeAllHighlights();
int y = start.y;
int firstX = start.x;
int lastX = end.x;
int pos1 = ui.viewToModel(getComponent(), new Point(firstX, y));
int pos2 = ui.viewToModel(getComponent(), new Point(lastX, y));
try {
h.addHighlight(pos1, pos2, getSelectionPainter());
} catch (Exception ex) {
ex.printStackTrace();
}

for (int i = y + 1; i < end.y; i++) {
int pos1new = ui.viewToModel(getComponent(), new Point(firstX, i));
int pos2new = ui.viewToModel(getComponent(), new Point(lastX, i));
if (pos1 != pos1new) {
pos1 = pos1new;
pos2 = pos2new;
try {
h.addHighlight(pos1, pos2, getSelectionPainter());
} catch (Exception e) {
}
}
}
}

public void mousePressed(MouseEvent e) {
removeHighlights();
isBlockSelection = e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1 && e.isShiftDown();
blockSelectionDot = blockSelectionMark = getComponent().viewToModel(e.getPoint());
super.mousePressed(e);
}


public void mouseMoved(MouseEvent e) {
lastPoint = e.getPoint();
super.mouseMoved(e);
}


public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
isBlockSelection = false;
lastPoint.setLocation(0, 0);
}

protected void moveCaret(MouseEvent e) {
if (isBlockSelection) {
Point p = e.getPoint();
int pos = getComponent().getUI().viewToModel(getComponent(), p);
blockSelectionMark = getComponent().viewToModel(p);
if (pos >= 0) {
setDot(pos);
Point start = new Point(Math.min(lastPoint.x, p.x), Math.min(lastPoint.y, p.y));
Point end = new Point(Math.max(lastPoint.x, p.x), Math.max(lastPoint.y, p.y));
customHighlight(start, end);
}
} else {
removeHighlights();
}
super.moveCaret(e);
}
}
}


For sake of simplicity I use JEditorPane here, but you could use RSyntaxTextArea and Undo/Redo will work as expected

About keyboard selection I personally use a IDE which uses Alt-Shift-Insert to toggle line selection to block selection, so the only pending work is extend the default actions on up, down, left, right if that toggle is on.

I hope you fifesoft find that useful and commit it to the project or at least to the block_selection branch
nenopera
 

Re: Block Selection

Postby robert » Thu Aug 30, 2012 3:36 am

Thanks neonpara! I'll take a look at this soon.
User avatar
robert
 
Posts: 802
Joined: Sat May 10, 2008 5:16 pm


Return to Help

Who is online

Users browsing this forum: No registered users and 5 guests