/* XLogo4Schools - A Logo Interpreter specialized for use in schools, based on XLogo by Loïc Le Coq
* Copyright (C) 2013 Marko Zivkovic
*
* Contact Information: marko88zivkovic at gmail dot com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version. This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the
* GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
* This Java source code belongs to XLogo4Schools, written by Marko Zivkovic
* during his Bachelor thesis at the computer science department of ETH Zürich,
* in the year 2013 and/or during future work.
*
* It is a reengineered version of XLogo written by Loïc Le Coq, published
* under the GPL License at http://xlogo.tuxfamily.org/
*
* Contents of this file were initially written by Loïc Le Coq,
* modifications, extensions, refactorings might have been applied by Marko Zivkovic
*/
package xlogo.gui;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.JTextComponent;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.undo.UndoManager;
import javax.swing.undo.UndoableEdit;
import xlogo.Popup;
/**
*
* @author loic
* This class is the generic component to display the text in the editor
* If there are too many characters, it is a JTextArea
* Else it's a JtextPane that allows Syntax Highlighting
*/
public abstract class EditorTextZone implements Searchable, Printable {
private Editor editor;
private StringBuffer text;
protected JTextComponent jtc;
private Popup jpop;
private boolean highlightWasSet = false;
// When printing the text area, this stack stores each page
private Stack pages=null;
// To remember undoable edits
private UndoManager undoManager;
private int startOffset,endOffset;
/**
* Default constructor for this generic constructor
*
* @param editor The parent editor
*/
EditorTextZone(Editor editor){
this.editor=editor;
}
protected void initGui(){
// Adds the JPopup Menu
jpop=new Popup(editor,jtc);
MouseListener popupListener = new PopupListener();
jtc.addMouseListener(popupListener);
jtc.addMouseListener(new MouseListener(){
@Override
public void mouseReleased(MouseEvent e) { }
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e) { }
@Override
public void mouseEntered(MouseEvent e) { }
@Override
public void mouseClicked(MouseEvent e) {
if (highlightWasSet)
{
removeHighlight();
highlightWasSet = false;
}
}
});
undoManager=new UndoManager();
}
/**
* Erase all text
*/
protected void clearText(){
jtc.setText("");
}
public boolean find(String searchText,boolean forward){
try
{
int index;
String element = searchText.toLowerCase();
text = new StringBuffer(jtc.getText().toLowerCase());
// Find forward
if (forward)
index = text.indexOf(element, jtc.getCaretPosition());
else
index = text.lastIndexOf(element, jtc.getCaretPosition());
if (index == -1)
{
startOffset = 0;
endOffset = 0;
return false;
}
else
{
jtc.getHighlighter().removeAllHighlights();
startOffset = index;
endOffset = index + element.length();
jtc.getHighlighter().addHighlight(startOffset, endOffset, DefaultHighlighter.DefaultPainter);
if (forward)
jtc.setCaretPosition(index + element.length());
else if (index > 1)
jtc.setCaretPosition(index - 1);
highlightWasSet = true;
return true;
}
}
catch(NullPointerException e){} // If the combo is empty
catch(BadLocationException e){}
return false;
}
public void replace(String element, boolean forward){
text.delete(startOffset, endOffset);
try{
text.insert(startOffset,element );
}
catch(NullPointerException err){}
jtc.setText(text.toString());
if (forward) jtc.setCaretPosition(endOffset);
else if (startOffset>1) jtc.setCaretPosition(startOffset-1);
}
public void replaceAll(String element, String substitute){
try {
String string=jtc.getText().toString();
string=string.replaceAll(element, substitute);
jtc.setText(string);
}
catch(NullPointerException e2){}
}
public void removeHighlight(){
jtc.getHighlighter().removeAllHighlights();
}
class MyUndoableEditListener implements UndoableEditListener{
public void undoableEditHappened(UndoableEditEvent e){
UndoableEdit edit = e.getEdit();
// Include this method to ignore syntax changes
if (edit instanceof AbstractDocument.DefaultDocumentEvent &&
((AbstractDocument.DefaultDocumentEvent)edit).getType() ==
AbstractDocument.DefaultDocumentEvent.EventType.CHANGE) {
return;
}
// Remember the edit
undoManager.addEdit(edit);
// System.out.println(e.getEdit().getPresentationName());
editor.updateUndoRedoButtons();
}
}
protected UndoManager getUndoManager(){
return undoManager;
}
protected String getText(){
return jtc.getText();
}
public void requestFocus(){
jtc.requestFocus();
}
protected JTextComponent getTextComponent(){
return jtc;
}
protected boolean supportHighlighting(){
return false;
}
protected void setFont(Font f){
jtc.setFont(f);
}
protected Font getFont(){
return jtc.getFont();
}
// To print the text Area
public int print(Graphics g,PageFormat pf, int pi) throws PrinterException{
if(pi();
StringTokenizer st = new StringTokenizer(txt, "\n");
String page="";
// System.out.println("hauteur "+fm.getHeight()+" "+h_imp);
int compteur=0;
while (st.hasMoreTokens()) {
String element = st.nextToken();
compteur+=fm.getHeight();
if (compteur>h_imp) {
pages.push(page);
page = element;
compteur=fm.getHeight();
}
else page+= element+"\n";
}
if (!page.equals("")) pages.push(page);
if (job.printDialog()) {
try {
job.print();
}
catch (PrinterException ex) {
System.out.println(ex.getMessage());
}
}
font=jtc.getFont();
jtc.setFont(new Font(font.getFontName(),Font.PLAIN,12));
jtc.setText(txt);
}
// Edit Actions
protected void copy(){
jtc.copy();
}
protected void cut(){
jtc.cut();
}
protected void paste(){
jtc.paste();
}
// setText Method for Text Zone
protected void setText(String s){
jtc.setText(s);
}
protected abstract void ecris(String s);
protected abstract void append(String s);
abstract void setActive(boolean b);
class PopupListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
jpop.show(e.getComponent(), e.getX(), e.getY());
}
}
}
}