/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
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.
*/
package org.geogebra.desktop.gui.dialog;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.geogebra.common.GeoGebraConstants;
import org.geogebra.common.gui.dialog.ToolManagerDialogModel;
import org.geogebra.common.gui.dialog.ToolManagerDialogModel.ToolManagerDialogListener;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.Macro;
import org.geogebra.common.util.FileExtensions;
import org.geogebra.desktop.export.GeoGebraTubeExportD;
import org.geogebra.desktop.gui.MyImageD;
import org.geogebra.desktop.gui.ToolNameIconPanelD;
import org.geogebra.desktop.gui.app.GeoGebraFrame;
import org.geogebra.desktop.main.AppD;
import org.geogebra.desktop.main.LocalizationD;
/**
* Dialog to manage existing user defined tools (macros).
*
* @author Markus Hohenwarter
*/
public class ToolManagerDialogD extends javax.swing.JDialog
implements ToolManagerDialogListener {
private static final long serialVersionUID = 1L;
AppD app;
final LocalizationD loc;
private DefaultListModel toolsModel;
private ToolManagerDialogModel model;
public ToolManagerDialogD(AppD app) {
super(app.getFrame());
setModal(true);
model = new ToolManagerDialogModel(app, this);
this.app = app;
this.loc = app.getLocalization();
initGUI();
}
@Override
public void setVisible(boolean flag) {
if (flag) {
app.setMoveMode();
} else {
// recreate tool bar of application window
updateToolBar(toolsModel);
}
super.setVisible(flag);
}
/**
* Updates the order of macros using the listModel.
*/
private void updateToolBar(DefaultListModel listModel) {
model.addMacros(listModel.toArray());
app.updateToolBar();
}
/**
* Deletes all selected tools that are not used in the construction.
*/
private void deleteTools(JList toolList, DefaultListModel listModel) {
Object[] sel = toolList.getSelectedValuesList().toArray();
if (sel == null || sel.length == 0) {
return;
}
// ARE YOU SURE ?
Object[] options = { loc.getMenu("DeleteTool"),
loc.getMenu("DontDeleteTool") };
int returnVal = JOptionPane.showOptionDialog(this,
loc.getMenu("Tool.DeleteQuestion"), loc.getPlain("Question"),
JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null,
options, options[1]);
if (returnVal == 1) {
return;
}
if (model.deleteTools(sel)) {
updateToolBar(listModel);
}
for (Macro macro : model.getDeletedMacros()) {
listModel.removeElement(macro);
}
}
private void initGUI() {
try {
setTitle(loc.getMenu("Tool.Manage"));
JPanel panel = new JPanel(new BorderLayout(5, 5));
setContentPane(panel);
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel toolListPanel = new JPanel(new BorderLayout(5, 5));
toolListPanel.setBorder(
BorderFactory.createTitledBorder(loc.getMenu("Tools")));
getContentPane().add(toolListPanel, BorderLayout.NORTH);
toolsModel = new DefaultListModel();
insertTools(toolsModel);
final JList toolList = new JList(toolsModel);
toolList.setCellRenderer(new MacroCellRenderer());
toolList.setVisibleRowCount(6);
JPanel centerPanel = ToolCreationDialogD
.createListUpDownRemovePanel(loc, toolList, null, false,
true, false, null);
// JScrollPane jScrollPane1 = new JScrollPane(toolList);
// jScrollPane1.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED
// ));
// toolListPanel.add(jScrollPane1, BorderLayout.CENTER);
toolListPanel.add(centerPanel, BorderLayout.CENTER);
JPanel toolButtonPanel = new JPanel(
new FlowLayout(FlowLayout.LEFT));
toolListPanel.add(toolButtonPanel, BorderLayout.SOUTH);
final JButton btDelete = new JButton();
toolButtonPanel.add(btDelete);
btDelete.setText(loc.getPlain("Delete"));
final JButton btOpen = new JButton();
toolButtonPanel.add(btOpen);
btOpen.setText(loc.getPlain("Open"));
final JButton btSave = new JButton();
toolButtonPanel.add(btSave);
btSave.setText(loc.getMenu("SaveAs") + " ...");
final JButton btShare = new JButton();
toolButtonPanel.add(btShare);
btShare.setText(loc.getMenu("Share") + " ...");
// name & icon
final ToolNameIconPanelD namePanel = new ToolNameIconPanelD(app,
true);
namePanel.setBorder(
BorderFactory.createTitledBorder(loc.getMenu("NameIcon")));
panel.add(namePanel, BorderLayout.CENTER);
JPanel closePanel = new JPanel();
FlowLayout closePanelLayout = new FlowLayout();
closePanelLayout.setAlignment(FlowLayout.RIGHT);
closePanel.setLayout(closePanelLayout);
final JButton btClose = new JButton(loc.getMenu("Close"));
closePanel.add(btClose);
panel.add(closePanel, BorderLayout.SOUTH);
// action listener for buttone
ActionListener ac = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if (src == btClose) {
// ensure to set macro properties from namePanel
namePanel.init(null, null);
// make sure new macro command gets into dictionary
app.updateCommandDictionary();
// destroy dialog
setVisible(false);
dispose();
} else if (src == btDelete) {
deleteTools(toolList, toolsModel);
} else if (src == btOpen) {
openTools(toolList);
} else if (src == btSave) {
saveTools(toolList);
} else if (src == btShare) {
uploadToGeoGebraTube(toolList);
}
}
};
btShare.addActionListener(ac);
btSave.addActionListener(ac);
btDelete.addActionListener(ac);
btOpen.addActionListener(ac);
btClose.addActionListener(ac);
// add selection listener for list
final ListSelectionModel selModel = toolList.getSelectionModel();
ListSelectionListener selListener = new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (selModel.getValueIsAdjusting()) {
return;
}
int[] selIndices = toolList.getSelectedIndices();
if (selIndices == null || selIndices.length != 1) {
// no or several tools selected
namePanel.init(null, null);
} else {
Macro macro = (Macro) toolsModel
.getElementAt(selIndices[0]);
namePanel.init(ToolManagerDialogD.this, macro);
}
}
};
selModel.addListSelectionListener(selListener);
// select first tool in list
if (toolsModel.size() > 0) {
toolList.setSelectedIndex(0);
} else {
namePanel.init(null, null);
}
setResizable(true);
namePanel.setPreferredSize(new Dimension(400, 200));
app.setComponentOrientation(this);
pack();
setLocationRelativeTo(app.getFrame()); // center
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Opens tools in different windows
*
* @author Zbynek Konecny
* @param toolList
* Tools to be opened
*/
private void openTools(JList toolList) {
Object[] sel = toolList.getSelectedValuesList().toArray();
if (sel == null || sel.length == 0) {
return;
}
for (int i = 0; i < sel.length; i++) {
final Macro macro = (Macro) sel[i];
Thread runner = new Thread() {
@Override
public void run() {
app.setWaitCursor();
// avoid deadlock with current app
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GeoGebraFrame newframe = ((GeoGebraFrame) app
.getFrame()).createNewWindow(null, macro);
newframe.setTitle(macro.getCommandName());
byte[] byteArray = app.getMacroFileAsByteArray();
newframe.getApplication()
.loadMacroFileFromByteArray(byteArray,
false);
newframe.getApplication().openMacro(macro);
app.setDefaultCursor();
}
});
}
};
runner.start();
this.setVisible(false);
this.dispose();
}
}
private void insertTools(DefaultListModel listModel) {
Kernel kernel = app.getKernel();
int size = kernel.getMacroNumber();
for (int i = 0; i < size; i++) {
Macro macro = kernel.getMacro(i);
listModel.addElement(macro);
}
}
private class MacroCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
/*
* This is the only method defined by ListCellRenderer. We just
* reconfigure the Jlabel each time we're called.
*/
@Override
public Component getListCellRendererComponent(JList list, Object value, // value
// to
// display
int index, // cell index
boolean iss, // is the cell selected
boolean chf) // the list and the cell have the focus
{
/*
* The DefaultListCellRenderer class will take care of the JLabels
* text property, it's foreground and background colors, and so on.
*/
super.getListCellRendererComponent(list, value, index, iss, chf);
if (value != null) {
Macro macro = (Macro) value;
StringBuilder sb = new StringBuilder();
sb.append("<html><b>");
sb.append(macro.getToolName());
sb.append("</b>: ");
sb.append(macro.getNeededTypesString());
sb.append("</html>");
setText(sb.toString());
MyImageD img = app.getExternalImage(macro.getIconFileName());
if (img != null) {
setIcon(new ImageIcon(img.getImage()));
Dimension dim = getPreferredSize();
dim.height = img.getHeight();
setPreferredSize(dim);
setMinimumSize(dim);
}
}
return this;
}
}
/*
* upload selected Tools to GeoGebraTube
*/
private void uploadToGeoGebraTube(final JList toolList) {
Thread runner = new Thread() {
@Override
public void run() {
model.uploadToGeoGebraTube(
toolList.getSelectedValuesList().toArray());
}
};
runner.start();
}
/**
* Saves all selected tools in a new file.
*/
private void saveTools(JList toolList) {
Object[] sel = toolList.getSelectedValuesList().toArray();
if (sel == null || sel.length == 0) {
return;
}
File file = app.getGuiManager().showSaveDialog(
FileExtensions.GEOGEBRA_TOOL, null,
GeoGebraConstants.APPLICATION_NAME + " " + loc.getMenu("Tools"),
true, false);
if (file == null) {
return;
}
// save selected macros
app.saveMacroFile(file, model.getAllTools(sel));
}
@Override
public void removeMacroFromToolbar(int i) {
app.getGuiManager().removeFromToolbarDefinition(i);
}
@Override
public void refreshCustomToolsInToolBar() {
app.getGuiManager().refreshCustomToolsInToolBar();
}
@Override
public void uploadWorksheet(ArrayList<Macro> macros) {
// create new exporter
GeoGebraTubeExportD exporter = new GeoGebraTubeExportD(app);
exporter.uploadWorksheet(macros);
}
}