package net.atlanticbb.tantlinger.ui.text;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
/**
* {@link DocumentFilter} which manages auto indentation and soft tabs.
*
*
* @author Bob Tantlinger
*
*/
public class IndentationFilter extends DocumentFilter
{
private boolean isSoftTabs;
private boolean isAutoIndent;
/**
* Creates a filter that uses regular tabs and that auto indents
*
*/
public IndentationFilter()
{
this(false, true);
}
public IndentationFilter(boolean isSoftTabs, boolean isAutoIndent)
{
this.isSoftTabs = isSoftTabs;
this.isAutoIndent = isAutoIndent;
}
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
throws BadLocationException
{
Document doc = fb.getDocument();
if(text != null && length == 0)
{
if(isSoftTabs)
text = convertTabsToSpaces(text, doc);
if(isAutoIndent && text.startsWith("\n"))
text += getLineIndentation(offset, doc);
}
super.replace(fb, offset, length, text, attrs);
}
private String convertTabsToSpaces(String text, Document doc)
{
try
{
AbstractDocument adoc = (AbstractDocument)doc;
int tabSize = ((Integer)adoc.getProperty("tabSize")).intValue();
String softTab = "";
for(int i = 1; i <= tabSize; i++)
softTab += ' ';
StringBuffer sb = new StringBuffer(text);
int pos = 0;
while((pos = sb.indexOf("\t", pos)) != -1)
{
sb.replace(pos, pos + 1, softTab);
pos += softTab.length();
}
return sb.toString();
}
catch(Exception ex){}
return text;
}
private String getLineIndentation(int offs, Document doc)
throws BadLocationException
{
StringBuffer ws = new StringBuffer();
if(doc instanceof AbstractDocument)
{
AbstractDocument adoc = (AbstractDocument)doc;
int s = adoc.getParagraphElement(offs).getStartOffset();
String line = adoc.getText(s, offs - s);
for(int i = 0; i < line.length(); i++)
{
char c = line.charAt(i);
if(c == '\n' || !Character.isWhitespace(c))
break;
ws.append(c);
}
}
return ws.toString();
}
/**
* @return the isAutoIndent
*/
public boolean isAutoIndent()
{
return isAutoIndent;
}
/**
* @param isAutoIndent the isAutoIndent to set
*/
public void setAutoIndent(boolean isAutoIndent)
{
this.isAutoIndent = isAutoIndent;
}
/**
* @return the isSoftTabs
*/
public boolean isSoftTabs()
{
return isSoftTabs;
}
/**
* @param isSoftTabs the isSoftTabs to set
*/
public void setSoftTabs(boolean isSoftTabs)
{
this.isSoftTabs = isSoftTabs;
}
}