584 lines
20 KiB
Java
584 lines
20 KiB
Java
/*
|
|
|
|
Copyright 2006 Eric Hakenholz
|
|
|
|
This file is part of C.a.R. software.
|
|
|
|
C.a.R. is a 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, version 3 of the License.
|
|
|
|
C.a.R. 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
package eric.macros;
|
|
|
|
import eric.GUI.themes;
|
|
import eric.JGeneralMenuBar;
|
|
import eric.JZirkelCanvas;
|
|
import java.awt.Color;
|
|
import java.awt.Component;
|
|
import java.awt.Dimension;
|
|
import java.awt.Font;
|
|
import java.awt.FontMetrics;
|
|
import java.awt.Graphics;
|
|
import java.awt.event.KeyAdapter;
|
|
import java.awt.event.KeyEvent;
|
|
import java.awt.event.MouseAdapter;
|
|
import java.awt.event.MouseEvent;
|
|
import java.util.Vector;
|
|
|
|
import javax.swing.BorderFactory;
|
|
import javax.swing.DefaultCellEditor;
|
|
import javax.swing.ImageIcon;
|
|
import javax.swing.JButton;
|
|
import javax.swing.JComponent;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JMenu;
|
|
import eric.JEricPanel;
|
|
import javax.swing.JPopupMenu;
|
|
import javax.swing.JScrollPane;
|
|
import javax.swing.JTable;
|
|
import javax.swing.JTextField;
|
|
import javax.swing.JTree;
|
|
import javax.swing.SwingUtilities;
|
|
import javax.swing.event.TreeModelEvent;
|
|
import javax.swing.event.TreeModelListener;
|
|
import javax.swing.tree.DefaultTreeModel;
|
|
import javax.swing.tree.TreeCellRenderer;
|
|
import javax.swing.tree.TreeNode;
|
|
import javax.swing.tree.TreePath;
|
|
import javax.swing.tree.TreeSelectionModel;
|
|
import rene.gui.Global;
|
|
|
|
import rene.gui.MyMenu;
|
|
import rene.zirkel.ZirkelFrame;
|
|
import rene.zirkel.macro.Macro;
|
|
import rene.zirkel.macro.MacroItem;
|
|
|
|
// Toute ce qui touche à l'arbre de macros et à sa gestion :
|
|
public class MacrosList extends JEricPanel {
|
|
|
|
private final int CONTROLHEIGHT=25;
|
|
private final ImageIcon JTreefoldclosed;
|
|
private final ImageIcon JTreefoldopened;
|
|
private final ImageIcon[] JTreeleaf;
|
|
private CTree MacrosTree;
|
|
private JDefaultMutableTreeNode MacroTreeTopNode=new JDefaultMutableTreeNode("Macros");
|
|
private ZirkelFrame ZF;
|
|
private JScrollPane jscrolls;
|
|
private JControls controls;
|
|
// private Jcreatemacro createmacropanel;
|
|
|
|
public MacrosList(ZirkelFrame zf) {
|
|
ZF=zf;
|
|
JTreefoldclosed=themes.getIcon("JTreefoldclosed.gif");
|
|
JTreefoldopened=themes.getIcon("JTreefoldopened.gif");
|
|
JTreeleaf=new ImageIcon[4];
|
|
JTreeleaf[0]=themes.getIcon("JTreeleaf_0.gif");
|
|
JTreeleaf[1]=themes.getIcon("JTreeleaf_1.gif");
|
|
JTreeleaf[2]=themes.getIcon("JTreeleaf_2.gif");
|
|
JTreeleaf[3]=themes.getIcon("JTreeleaf_3.gif");
|
|
this.setLayout(new javax.swing.BoxLayout(this,
|
|
javax.swing.BoxLayout.Y_AXIS));
|
|
|
|
// uncomment this line to obtain gray conection lines between leaves :
|
|
// UIManager.put("Tree.hash",new ColorUIResource(Color.lightGray));
|
|
|
|
MacroTreeTopNode=new JDefaultMutableTreeNode("Macros");
|
|
MacrosTree=new CTree(this) {
|
|
|
|
/**
|
|
*
|
|
*/
|
|
@Override
|
|
public void paint(final Graphics g) {
|
|
final ImageIcon backimage=themes.getIcon("macrospanelback.gif");
|
|
g.drawImage(backimage.getImage(), 0, 0, this.getSize().width,
|
|
backimage.getIconHeight(), this);
|
|
super.paint(g);
|
|
}
|
|
};
|
|
MacrosTree.setFocusable(false);
|
|
MacrosTree.setModel(new MyTreeModel(MacroTreeTopNode));
|
|
MacrosTree.getSelectionModel().setSelectionMode(
|
|
TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
|
|
final MyCellRenderer renderer=new MyCellRenderer();
|
|
MacrosTree.setCellRenderer(renderer);
|
|
MacrosTree.setCellEditor(new MyDefaultCellEditor());
|
|
MacrosTree.setOpaque(false);
|
|
MacrosTree.setFont(new Font(Global.GlobalFont, 0, 12));
|
|
MacrosTree.setForeground(new Color(70, 70, 70));
|
|
MacrosTree.setDragEnabled(false);
|
|
MacrosTree.setEditable(false);
|
|
|
|
jscrolls=new JScrollPane(MacrosTree);
|
|
jscrolls.setAlignmentX(0F);
|
|
jscrolls.setBorder(BorderFactory.createEmptyBorder());
|
|
this.add(jscrolls);
|
|
|
|
controls=new JControls(this);
|
|
this.add(controls);
|
|
// createmacropanel=new Jcreatemacro(this);
|
|
// this.add(createmacropanel);
|
|
}
|
|
|
|
public JDefaultMutableTreeNode getTopNode() {
|
|
return MacroTreeTopNode;
|
|
}
|
|
|
|
public CTree getMacrosTree() {
|
|
return MacrosTree;
|
|
}
|
|
|
|
// Utilise le Vector de macros pour initialiser l'arbre :
|
|
public void initTreeFromZCMacros() {
|
|
|
|
Vector mc;
|
|
// JMacrosTools.setDefaultMacros();
|
|
MacroTreeTopNode.removeAllChildren();
|
|
// removeAll();
|
|
// MacroTreeTopNode=new JDefaultMutableTreeNode("Macros");
|
|
|
|
mc=ZF.ZC.getMacros();
|
|
for (int i=0; i<mc.size(); i++) {
|
|
// if (((MacroItem) mc.elementAt(i)).M!=null) {
|
|
Macro m=((MacroItem) mc.elementAt(i)).M;
|
|
if ((ZF.ZC.isLibraryMacrosVisible())||(!m.isProtected())) {
|
|
AddMacroToTree(m);
|
|
}
|
|
// AddMacroToTree(((MacroItem) mc.elementAt(i)).M);
|
|
// }
|
|
}
|
|
|
|
MacrosTree.setModel(new MyTreeModel(MacroTreeTopNode));
|
|
MacrosTree.getSelectionModel().setSelectionMode(
|
|
TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
|
|
final MyCellRenderer renderer=new MyCellRenderer();
|
|
MacrosTree.setCellRenderer(renderer);
|
|
MacrosTree.setCellEditor(new MyDefaultCellEditor());
|
|
|
|
ActualiseMacroPopupMenu();
|
|
}
|
|
|
|
|
|
// Only called by LeftPanelContent init method :
|
|
public void fixPanelSize(int w, int h) {
|
|
fixsize(this, w, h);
|
|
fixsize(jscrolls, w, h-CONTROLHEIGHT);
|
|
jscrolls.revalidate();
|
|
//fixsize(MacrosTree,w,h-CONTROLHEIGHT);
|
|
fixsize(controls,w,CONTROLHEIGHT);
|
|
controls.revalidate();
|
|
}
|
|
|
|
private static void fixsize(final JComponent cp, final int w, final int h) {
|
|
final Dimension d=new Dimension(w, h);
|
|
cp.setMaximumSize(d);
|
|
cp.setMinimumSize(d);
|
|
cp.setPreferredSize(d);
|
|
cp.setSize(d);
|
|
}
|
|
|
|
class MyDefaultCellEditor extends DefaultCellEditor {
|
|
|
|
/**
|
|
*
|
|
*/
|
|
JTextField jtf;
|
|
|
|
public MyDefaultCellEditor() {
|
|
super(new JTextField());
|
|
jtf=(JTextField) this.getComponent();
|
|
jtf.setFocusTraversalKeysEnabled(false);
|
|
jtf.setBorder(BorderFactory.createLineBorder(Color.BLACK));
|
|
jtf.addKeyListener(new KeyAdapter() {
|
|
|
|
@Override
|
|
public void keyTyped(final KeyEvent e) {
|
|
adjust(e.getKeyChar());
|
|
}
|
|
|
|
@Override
|
|
public void keyPressed(final KeyEvent e) {
|
|
if ((e.getKeyCode()==KeyEvent.VK_ESCAPE)
|
|
||(e.getKeyCode()==KeyEvent.VK_TAB)) {
|
|
fireEditingStopped();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private void adjust(final char ad) {
|
|
final FontMetrics fm=getFontMetrics(jtf.getFont());
|
|
jtf.setSize(fm.stringWidth(jtf.getText()+ad)+5, jtf.getHeight());
|
|
}
|
|
|
|
@Override
|
|
protected void fireEditingCanceled() {
|
|
super.fireEditingStopped();
|
|
}
|
|
|
|
@Override
|
|
protected void fireEditingStopped() {
|
|
super.fireEditingStopped();
|
|
}
|
|
|
|
@Override
|
|
public Object getCellEditorValue() {
|
|
return super.getCellEditorValue();
|
|
}
|
|
|
|
@Override
|
|
public Component getTableCellEditorComponent(final JTable table,
|
|
final Object value, final boolean isSelected, final int row,
|
|
final int column) {
|
|
return super.getTableCellEditorComponent(table, value, isSelected,
|
|
row, column);
|
|
|
|
}
|
|
}
|
|
|
|
public void AddMacroToTree(final Macro m) {
|
|
if (m.getName().startsWith("@builtin@")) {
|
|
return;
|
|
}
|
|
String[] mypath;
|
|
mypath=m.getName().split("/");
|
|
JDefaultMutableTreeNode mother=MacroTreeTopNode;
|
|
for (int i=0; i<mypath.length-1; i++) {
|
|
mother=getFolder(mother, mypath[i]);
|
|
}
|
|
final JDefaultMutableTreeNode node=new JDefaultMutableTreeNode(ZF, m);
|
|
mother.add(node);
|
|
}
|
|
|
|
private JDefaultMutableTreeNode getFolder(
|
|
final JDefaultMutableTreeNode father, final String name) {
|
|
for (int i=0; i<father.getChildCount(); i++) {
|
|
if (name.equals((String) ((JDefaultMutableTreeNode) father.getChildAt(i)).getUserObject())) {
|
|
return ((JDefaultMutableTreeNode) father.getChildAt(i));
|
|
}
|
|
}
|
|
final JDefaultMutableTreeNode node=new JDefaultMutableTreeNode(name);
|
|
father.add(node);
|
|
return node;
|
|
}
|
|
|
|
// Actualisation du PopupMenu de macro, du menu principal "Macros", et du vector librarymacros
|
|
// Appelée à chaque modification de l'arbre (Drag and Drop, Rename, ...)
|
|
// appelée aussi à la fin de initMacrosTreeFromPopup :
|
|
public void ActualiseMacroPopupMenu() {
|
|
|
|
final MyMenu pm=new MyMenu("root");
|
|
final JMenu jm=new JMenu("root");
|
|
|
|
if (MacroTreeTopNode.getChildCount()>0) {
|
|
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
|
|
|
|
ParseMacroTree(pm, jm, MacroTreeTopNode, "root");
|
|
|
|
ZF.ZC.PM.removeAll();
|
|
JGeneralMenuBar.s_InitMacrosMenu();
|
|
|
|
final JMenu jmroot=(JMenu) jm.getItem(0);
|
|
final MyMenu pmroot=(MyMenu) pm.getItem(0);
|
|
while (pmroot.getItemCount()>0) {
|
|
ZF.ZC.PM.add(pmroot.getItem(0));
|
|
JGeneralMenuBar.addMacrosMenu(jmroot.getItem(0));
|
|
|
|
|
|
// if (ZF.ZC.isLibraryMacrosVisible()) {
|
|
// ZF.ZC.PM.add(pmroot.getItem(0));
|
|
// JGeneralMenuBar.addMacrosMenu(jmroot.getItem(0));
|
|
// } else {
|
|
// pmroot.remove(0);
|
|
// jmroot.remove(0);
|
|
//
|
|
// }
|
|
}
|
|
|
|
} else {
|
|
ZF.ZC.PM.removeAll();
|
|
JGeneralMenuBar.s_InitMacrosMenu();
|
|
}
|
|
MacroTools.updateLibraryMacros();
|
|
}
|
|
|
|
// Procédure recursive appelée uniquement par ActualiseMacroPopupMenu.
|
|
// Parcours de l'arbre de macros :
|
|
private void ParseMacroTree(final MyMenu PMmenu, final JMenu JMmenu,
|
|
final JDefaultMutableTreeNode node, final String path) {
|
|
final String mypath=path;
|
|
if (!(node.isLeaf())) {
|
|
final MyMenu mymenu=new MyMenu((String) node.getUserObject());
|
|
final JMenu myjmenu=new JMenu((String) node.getUserObject());
|
|
myjmenu.setFont(new java.awt.Font("System", 0, 13));
|
|
for (int i=0; i<node.getChildCount(); i++) {
|
|
ParseMacroTree(mymenu, myjmenu, (JDefaultMutableTreeNode) node.getChildAt(i), mypath+"/"+mymenu.getLabel());
|
|
}
|
|
PMmenu.add(mymenu);
|
|
JMmenu.add(myjmenu);
|
|
} else {
|
|
final String myname=(String) node.getUserObject();
|
|
if (!(myname.startsWith("-- "))) {
|
|
node.ActualisePath();
|
|
PMmenu.add(node.PMmenuitem);
|
|
JMmenu.add(node.MainMenuItem);
|
|
} else {
|
|
if (node.getParent().getChildCount()>1) {
|
|
((DefaultTreeModel) MacrosTree.getModel()).removeNodeFromParent(node);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Les noeuds de l'arbre sont considérés comme des JLabels
|
|
// Cette classe se charge de leurs look :
|
|
class MyCellRenderer extends JLabel implements TreeCellRenderer {
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public MyCellRenderer() {
|
|
setOpaque(false);
|
|
setBackground(null);
|
|
}
|
|
|
|
public Component getTreeCellRendererComponent(final JTree tree,
|
|
final Object value, final boolean sel, final boolean expanded,
|
|
final boolean leaf, final int row, final boolean hasFocus) {
|
|
final String stringValue=tree.convertValueToText(value, sel,
|
|
expanded, leaf, row, hasFocus);
|
|
|
|
setText(stringValue);
|
|
setEnabled(tree.isEnabled());
|
|
setFont(tree.getFont());
|
|
setForeground(Color.black);
|
|
setOpaque(sel);
|
|
|
|
// Couleur de sélection :
|
|
setBackground(Color.lightGray);
|
|
final JDefaultMutableTreeNode mynode=(JDefaultMutableTreeNode) value;
|
|
if (leaf) {
|
|
setIcon((stringValue.startsWith(("-- ")))?null
|
|
:JTreeleaf[mynode.macrotype]);
|
|
if (mynode.macrotype==0) {
|
|
setForeground(new Color(68, 84, 131));
|
|
}
|
|
} else {
|
|
setIcon((expanded)?JTreefoldopened:JTreefoldclosed);
|
|
}
|
|
|
|
|
|
return this;
|
|
}
|
|
}
|
|
|
|
// Le modèle sur lequel est basé l'arbre
|
|
// Se charge de l'édition des noeuds et contient les TreeModelListeners :
|
|
class MyTreeModel extends DefaultTreeModel implements TreeModelListener {
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public MyTreeModel(final TreeNode node) {
|
|
super(node);
|
|
this.addTreeModelListener(this);
|
|
|
|
}
|
|
|
|
@Override
|
|
public void valueForPathChanged(final TreePath path,
|
|
final Object newValue) {
|
|
final JDefaultMutableTreeNode tn=(JDefaultMutableTreeNode) path.getLastPathComponent();
|
|
super.valueForPathChanged(path, newValue);
|
|
tn.ActualisePath();
|
|
}
|
|
|
|
public void treeNodesChanged(final TreeModelEvent e) {
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
public void run() {
|
|
ActualiseMacroPopupMenu();
|
|
}
|
|
});
|
|
}
|
|
|
|
public void treeNodesInserted(final TreeModelEvent e) {
|
|
// System.out.println("treeNodesInserted");
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
public void run() {
|
|
ActualiseMacroPopupMenu();
|
|
}
|
|
});
|
|
}
|
|
|
|
public void treeNodesRemoved(final TreeModelEvent e) {
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
public void run() {
|
|
ActualiseMacroPopupMenu();
|
|
}
|
|
});
|
|
}
|
|
|
|
public void treeStructureChanged(final TreeModelEvent e) {
|
|
// System.out.println("treeStructureChanged");
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
public void run() {
|
|
ActualiseMacroPopupMenu();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**************************************************************************************
|
|
*** N'oublions pas que JMacrosList est un JPanel qui contient d'autres
|
|
* JPanels La class Jcontrols contient les boutons d'édition de l'arbre et
|
|
* leurs listeners
|
|
***************************************************************************************/
|
|
class JControls extends JEricPanel {
|
|
|
|
/**
|
|
*
|
|
*/
|
|
private JButton addbtn;
|
|
private JButton delbtn;
|
|
private JButton renbtn;
|
|
private JButton createbtn;
|
|
private String message="";
|
|
private MacrosList MI;
|
|
|
|
@Override
|
|
public void paintComponent(final java.awt.Graphics g) {
|
|
super.paintComponent(g);
|
|
final java.awt.Dimension d=this.getSize();
|
|
g.drawImage(themes.getImage("tab_bottom.gif"), 0, 0, d.width,
|
|
d.height, this);
|
|
}
|
|
|
|
public void setButtonsIcons() {
|
|
addbtn.setIcon(themes.getIcon("addmacrofolder.png"));
|
|
addbtn.setRolloverIcon(themes.getIcon("addmacrofoldersel.png"));
|
|
delbtn.setIcon(themes.getIcon("delmacro.png"));
|
|
delbtn.setToolTipText(Global.Loc("macros.deleteselected"));
|
|
renbtn.setIcon(themes.getIcon("renamemacro.png"));
|
|
renbtn.setRolloverIcon(themes.getIcon("renamemacrosel.png"));
|
|
createbtn.setIcon(themes.getIcon("createmacro.png"));
|
|
createbtn.setRolloverIcon(themes.getIcon("createmacroover.png"));
|
|
|
|
}
|
|
|
|
public JControls(MacrosList mi) {
|
|
MI=mi;
|
|
this.setLayout(new javax.swing.BoxLayout(this,
|
|
javax.swing.BoxLayout.X_AXIS));
|
|
this.setAlignmentX(0F);
|
|
addbtn=new JButton();
|
|
addbtn.setToolTipText(Global.Loc("macros.addfolder"));
|
|
addbtn.setOpaque(false);
|
|
addbtn.setContentAreaFilled(false);
|
|
addbtn.setBorder(BorderFactory.createEmptyBorder());
|
|
addbtn.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
public void mouseClicked(final MouseEvent e) {
|
|
MacrosTree.nodepopup.addfolder();
|
|
}
|
|
});
|
|
|
|
delbtn=new JButton();
|
|
delbtn.setOpaque(false);
|
|
delbtn.setContentAreaFilled(false);
|
|
delbtn.setBorder(BorderFactory.createEmptyBorder());
|
|
delbtn.setRolloverIcon(themes.getIcon("delmacrosel.png"));
|
|
delbtn.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
public void mouseClicked(final MouseEvent e) {
|
|
// MacrosTree.nodepopup.deletenodes();
|
|
System.out.println("size="+JZirkelCanvas.getCurrentZC().getMacros().size());
|
|
}
|
|
});
|
|
|
|
renbtn=new JButton();
|
|
renbtn.setToolTipText(Global.Loc("macros.renamemacro"));
|
|
renbtn.setOpaque(false);
|
|
renbtn.setContentAreaFilled(false);
|
|
renbtn.setBorder(BorderFactory.createEmptyBorder());
|
|
renbtn.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
public void mouseClicked(final MouseEvent e) {
|
|
MacrosTree.nodepopup.renamenode();
|
|
}
|
|
});
|
|
|
|
createbtn=new JButton();
|
|
createbtn.setToolTipText(Global.Loc("macros.recordmacro"));
|
|
createbtn.setSelectedIcon(themes.getIcon("createmacrosel.png"));
|
|
createbtn.setBorder(BorderFactory.createEmptyBorder());
|
|
createbtn.setOpaque(false);
|
|
createbtn.setContentAreaFilled(false);
|
|
createbtn.setSelected(false);
|
|
|
|
setButtonsIcons();
|
|
|
|
createbtn.addMouseListener(new MouseAdapter() {
|
|
|
|
@Override
|
|
public void mouseEntered(final MouseEvent e) {
|
|
// if (createbtn.isSelected()) {
|
|
// message=createmacropanel.getComment().getText();
|
|
// createmacropanel.getComment().setText(Global.Loc("macros.cancel"));
|
|
// }
|
|
}
|
|
|
|
@Override
|
|
public void mouseExited(final MouseEvent e) {
|
|
// if (createbtn.isSelected()) {
|
|
// if (message!="") {
|
|
// createmacropanel.getComment().setText(message);
|
|
// }
|
|
// }
|
|
}
|
|
|
|
@Override
|
|
public void mousePressed(final MouseEvent e) {
|
|
if (createbtn.isSelected()) {
|
|
createbtn.setSelected(false);
|
|
// createmacropanel.disappeargently();
|
|
// PaletteManager.setSelected("point", true);
|
|
} else {
|
|
createbtn.setSelected(true);
|
|
new CreateMacroDialog(MI);
|
|
// createmacropanel.appeargently();
|
|
// PaletteManager.deselectgeomgroup();
|
|
}
|
|
|
|
}
|
|
});
|
|
|
|
final JEricPanel spacer=new JEricPanel();
|
|
spacer.setOpaque(false);
|
|
|
|
this.add(addbtn);
|
|
this.add(delbtn);
|
|
this.add(renbtn);
|
|
this.add(spacer);
|
|
this.add(createbtn);
|
|
}
|
|
}
|
|
}
|