/*
* Software Name : ATK
*
* Copyright (C) 2007 - 2012 France Télécom
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ------------------------------------------------------------------
* File Name : AutoCompleteJtextField.java
*
* Created : 27/10/2009
* Author(s) : France Telecom
*/
package com.orange.atk.scriptRecorder.scriptJpanel;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import com.orange.atk.interpreter.ast.FunctionDictionnary;
import com.orange.atk.scriptRecorder.ScriptController;
public class AutoCompleteJtextField extends JTextField implements KeyListener, FocusListener{
/**
*
*/
private static final long serialVersionUID = 5774469221987410017L;
private JTree tree;
private List<Integer> path;
private Boolean modify ;
private JPopupMenu menuautocompletion;
private FunctionDictionnary fd;
public AutoCompleteJtextField(JTree containertree) {
super();
addKeyListener(this);
addFocusListener(this);
tree = containertree;
fd = new FunctionDictionnary();
}
/* implement key listener
*
* used for autocompletion
*/
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
if (this.isEnabled()) {
if (menuautocompletion != null)
menuautocompletion.setVisible(false);
JTextField textField = (JTextField) e.getSource();
Point location = getLocationOnScreen();
menuautocompletion = new JPopupMenu();
//the Comment
if ("//".startsWith(textField.getText() )) {
JMenuItem jmiComment= new JMenuItem("// a comment");
jmiComment.addActionListener(new AutoCompletionActionListener("// a comment" ));
menuautocompletion.add(jmiComment);
}
//the function
for(String signature : fd.getSignaturesforautocopmpletion(textField.getText() )) {
JMenuItem jmi= new JMenuItem(signature);
jmi.addActionListener(new AutoCompletionActionListener(signature ));
menuautocompletion.add(jmi);
}
menuautocompletion.setLocation(location.x , location.y +20 );
menuautocompletion.setVisible(true);
}
}
public void keyTyped(KeyEvent e) {}
public void focusGained(FocusEvent e) {
if (isSelectionInsideInclude()) {
boolean wasEnabled = this.isEnabled();
this.setEnabled(false);
if (wasEnabled) JOptionPane.showMessageDialog(null, "Include script lines can not be modified !");
} else {
this.setEnabled(true);
//find the position of JTextfield in the tree
path = new ArrayList<Integer>();
TreePath childpath = tree.getLeadSelectionPath();
TreeNode parentnode = (TreeNode) childpath.getPathComponent(0);
for (int i=1 ; i<childpath.getPathCount() ; i++) {
TreeNode childnode = (TreeNode) childpath.getPathComponent(i);
//TODO : improve because it's a copy of ScriptJpanel function.
//Hack for loop car parent.getIndex(0) correspond to number of loop in AST
int offset=0;
if ( ((DefaultMutableTreeNode) parentnode).toString().startsWith("Loop") )
offset =1;
if ( ((DefaultMutableTreeNode) parentnode).toString().startsWith("Include") )
offset =1;
path.add(parentnode.getIndex(childnode)+offset);
parentnode = childnode;
}
if( " new ".equals(childpath.getLastPathComponent().toString() ) ) {
modify = false;
} else {
modify = true;
}
}
}
private boolean isSelectionInsideInclude() {
boolean isSelectionInsideInclude = true;
for(int i=0; i<tree.getSelectionCount() && isSelectionInsideInclude ; i++) {
int pathLength = tree.getSelectionPaths()[i].getPathCount();
boolean includeFound=false;
int j;
for (j=0; j<pathLength && !includeFound; j++) {
if (tree.getSelectionPaths()[i].getPathComponent(j).toString().startsWith("Include")) includeFound=true;
}
if (!includeFound || j==pathLength) isSelectionInsideInclude=false;
}
return isSelectionInsideInclude;
}
public void focusLost(FocusEvent e) {
if (this.isEnabled()) {
JTextField myself = (JTextField) e.getSource();
if (menuautocompletion !=null)
menuautocompletion.setVisible(false);
Boolean result = ScriptController.getScriptController().insertOrModify(
path, //the position*
myself.getText(),
modify ); //and the content
if (!result) {
TreeNode noeud =(TreeNode) tree.getModel().getRoot();
Boolean areweinloop = false;
for (int index : path)
if(areweinloop)
noeud = noeud.getChildAt(index-1);
else {
areweinloop = true;
noeud = noeud.getChildAt(index);
}
//TODO:HACKs : consequence of hacks in focusGained function
((ScriptTreeRenderer) tree.getCellRenderer()).
addToErrorList( noeud);
((DefaultTreeModel) tree.getModel()).reload();
//expand the tree
for(int i=0;i<tree.getRowCount();i++)
tree.expandRow(i);
}
}
}
/**
* To manage when user click on a item of
* Auto completion menu
*/
private class AutoCompletionActionListener implements ActionListener{
private String content;
public AutoCompletionActionListener(String signature ) {
content = signature;
};
public void actionPerformed(ActionEvent arg0) {
setText(content);
menuautocompletion.setVisible(false);
}
}
}