/*
Javier Kohen's Java Framework Classes.
Copyright (C) 2000 Javier Kohen <jkohen at tough.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package ar.com.jkohen.awt;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import ar.com.jkohen.util.Resources;
import ar.com.jkohen.irc.MircMessage;
public class TextFieldHistory extends TextField implements ActionListener, KeyListener
{
private static Frame frame;
private static Resources res;
private static TextAttributePicker pa;
private boolean focusTraversable;
// Purge entries past this number (actual entry is part of the count.)
// Twenty seems a sane number for a human being's short-term memory of what he could've written =)
// Forty either, because memory works better at night
private int history_max_size = 40;
private Vector history;
private int pos;
public TextFieldHistory(Frame f)
{
this(0);
this.frame = f;
}
public TextFieldHistory(int columns)
{
this("", columns);
}
public TextFieldHistory(String text)
{
this(text, 0);
}
public TextFieldHistory(String text, int columns)
{
super(text, columns);
// First place is for the current entry's content.
history = new Vector(1);
history.addElement("");
pos = 0;
addActionListener(this);
addKeyListener(this);
}
public int getMaximumHistorySize()
{
return history_max_size;
}
public void setMaximumHistorySize(int new_size)
{
history_max_size = new_size;
history.setSize(history_max_size);
}
private void loadItem(int n)
{
String item = (String) history.elementAt(pos);
setText(item);
setCaretPosition(item.length());
}
public void insert(String new_text)
{
int i = getSelectionStart();
int j = getSelectionEnd();
String text = getText();
if (i == j)
{
// Insert attributes at caret position.
int pos = getCaretPosition();
text = text.substring(0, pos).concat(new_text).concat(text.substring(pos));
setText(text);
setCaretPosition(pos + new_text.length());
}
else
{
// Insert attributes at start and at end of selection.
text = text.substring(0, i).concat(new_text).concat(text.substring(i, j)).concat(new_text).concat(text.substring(j));
setText(text);
setSelectionStart(i);
setSelectionEnd(j + (new_text.length() * 2));
}
}
public void pickAttr()
{
if (pa == null)
{
Dimension disposition = new Dimension(16, 1);
Dimension item_size = new Dimension(12, 16);
Dimension gap = new Dimension(2, 2);
pa = new TextAttributePicker(frame, this, disposition, item_size, gap);
// WORKAROUND: #34 something is broken in NN.
pa.addWindowListener(new WindowAdapter()
{
public void windowClosed(WindowEvent e)
{
pa = null;
}
public void windowClosing(WindowEvent windowevent)
{
windowevent.getWindow().dispose();
}
});
}
else
{
pa.setTextField(this);
pa.setVisible(true);
}
}
public void actionPerformed(ActionEvent e)
{
// Record entered lines.
String entry = e.getActionCommand();
if (entry.length() == 0)
return;
// Reset history position.
pos = 0;
history.insertElementAt(e.getActionCommand(), 1);
if (history.size() > history_max_size)
history.setSize(history_max_size);
}
public void keyPressed(KeyEvent ev)
{
if (!this.isEditable())
return;
if (ev.getModifiers() == KeyEvent.CTRL_MASK)
{
switch (ev.getKeyCode())
{
case (KeyEvent.VK_P):
pickAttr();
break;
case (KeyEvent.VK_O):
insert(String.valueOf(MircMessage.RESET));
break;
case (KeyEvent.VK_B):
insert(String.valueOf(MircMessage.BOLD));
break;
case (KeyEvent.VK_U):
insert(String.valueOf(MircMessage.UNDERLINE));
break;
case (KeyEvent.VK_I):
insert(String.valueOf(MircMessage.ITALIC));
break;
case (KeyEvent.VK_R):
insert(String.valueOf(MircMessage.REVERSE));
break;
case (KeyEvent.VK_G):
insert(String.valueOf(MircMessage.BELL));
break;
}
}
else
{
switch (ev.getKeyCode())
{
case KeyEvent.VK_UP:
if (pos == 0)
{
// Store not yet entered entry.
history.setElementAt(getText(), 0);
}
pos = (pos + 1) % history.size();
loadItem(pos);
break;
case KeyEvent.VK_DOWN:
if (pos == 0)
{
// Store not yet entered entry.
history.setElementAt(getText(), 0);
pos = history.size();
}
pos--;
loadItem(pos);
break;
case KeyEvent.VK_ESCAPE:
pos = 0;
loadItem(pos);
break;
default:
pos = 0;
break;
}
}
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
public void setFocusTraversable(boolean b)
{
this.focusTraversable = b;
}
/*
public boolean isFocusTraversable()
{
return(focusTraversable);
}
*/
public void transferFocus()
{
}
}