package de.uni_passau.fim.infosun.prophet.experimentEditor; import java.awt.Component; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.tree.TreePath; import de.uni_passau.fim.infosun.prophet.experimentEditor.macroEditor.MacroEditor; import de.uni_passau.fim.infosun.prophet.experimentEditor.qTree.QTree; import de.uni_passau.fim.infosun.prophet.experimentEditor.qTree.QTreeModel; import de.uni_passau.fim.infosun.prophet.experimentEditor.tabbedPane.ExperimentEditorTabbedPane; import de.uni_passau.fim.infosun.prophet.experimentEditor.tabbedPane.editorTabs.ContentEditorPanel; import de.uni_passau.fim.infosun.prophet.util.qTree.QTreeNode; import de.uni_passau.fim.infosun.prophet.util.qTree.handlers.QTreeCSVHandler; import de.uni_passau.fim.infosun.prophet.util.qTree.handlers.QTreeHTMLHandler; import de.uni_passau.fim.infosun.prophet.util.qTree.handlers.QTreeXMLHandler; import org.jsoup.nodes.Element; import org.jsoup.parser.Tag; import static de.uni_passau.fim.infosun.prophet.util.language.UIElementNames.getLocalized; import static de.uni_passau.fim.infosun.prophet.util.qTree.QTreeNode.Type.EXPERIMENT; import static javax.swing.JFileChooser.APPROVE_OPTION; /** * The menu bar used by the <code>ExperimentEditor</code>. * * @author Andreas Hasselberg * @author Markus Köppen */ public class ExperimentEditorMenuBar extends JMenuBar { private File currentFile; private QTreeModel qTreeModel; private ExperimentEditorTabbedPane tabbedPane; private JFrame owner; private JMenuItem saveMenuItem; private JMenuItem saveAsMenuItem; private JMenuItem nameCheckMenuItem; private JMenuItem exportCSVMenuItem; private JMenu exportMenu; private FileNameExtensionFilter extensionFilter = new FileNameExtensionFilter("Experiment XML", "xml"); private class XMLToCSVActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { JFileChooser dirChooser = new JFileChooser(); dirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); JFileChooser saveFileChooser = new JFileChooser(); saveFileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Comma Separated Values", "csv")); saveFileChooser.setFileFilter(saveFileChooser.getChoosableFileFilters()[1]); if (dirChooser.showOpenDialog(owner) == APPROVE_OPTION) { File answerDir = dirChooser.getSelectedFile(); if (saveFileChooser.showSaveDialog(owner) == APPROVE_OPTION) { File saveFile = saveFileChooser.getSelectedFile(); if (saveFile.exists() && !confirmOverwrite(saveFile)) { return; } new Thread(() -> QTreeCSVHandler.exportCSV(answerDir, saveFile)).start(); } } } } private ActionListener searchActionListener = event -> { Component current = tabbedPane.getSelectedComponent(); if (current instanceof ContentEditorPanel) { ((ContentEditorPanel) current).search(); } }; private ActionListener closeActionListener = event -> { WindowEvent closeEvent = new WindowEvent(owner, WindowEvent.WINDOW_CLOSING); Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closeEvent); }; private ActionListener newActionListener = event -> { currentFile = null; qTreeModel.setRoot(new QTreeNode(null, EXPERIMENT, "Experiment")); }; private ActionListener loadActionListener = event -> { JFileChooser fileChooser = new JFileChooser(currentFile == null ? new File(".") : currentFile); fileChooser.setFileFilter(extensionFilter); if (fileChooser.showOpenDialog(owner) != APPROVE_OPTION) { return; } currentFile = fileChooser.getSelectedFile(); QTreeNode treeRoot = QTreeXMLHandler.loadExperimentXML(currentFile); if (treeRoot == null) { JOptionPane.showMessageDialog(owner, getLocalized("MESSAGE_NO_VALID_EXPERIMENT_FILE")); return; } qTreeModel.setRoot(treeRoot); owner.setTitle(ExperimentEditor.class.getSimpleName() + " - " + currentFile.getAbsolutePath()); }; private ActionListener saveActionListener = event -> { if (currentFile != null) { tabbedPane.save(); try { QTreeXMLHandler.saveExperimentXML(qTreeModel.getRoot(), currentFile); confirmSave(); } catch (IOException e) { JOptionPane.showMessageDialog(owner, getLocalized("MESSAGE_SAVE_ERROR"), getLocalized("MESSAGE_ERROR"), JOptionPane.ERROR_MESSAGE); } } else { saveAsMenuItem.doClick(); } }; private ActionListener saveAsActionListener = event -> { JFileChooser fileChooser = new JFileChooser(currentFile == null ? new File(".") : currentFile); fileChooser.setFileFilter(extensionFilter); if (fileChooser.showSaveDialog(owner) != APPROVE_OPTION) { return; } File chosenFile = fileChooser.getSelectedFile(); String path = chosenFile.getPath(); String suffix = ".xml"; if (!path.endsWith(suffix)) { chosenFile = new File(path + suffix); } if (chosenFile.exists() && !confirmOverwrite(chosenFile)) { return; } currentFile = chosenFile; owner.setTitle(ExperimentEditor.class.getSimpleName() + " - " + currentFile.getAbsolutePath()); saveMenuItem.doClick(); }; private class ExportHTMLFileActionListener implements ActionListener { public void actionPerformed(ActionEvent arg0) { JFileChooser fc = new JFileChooser(currentFile); fc.addChoosableFileFilter(new FileNameExtensionFilter("HyperText Markup Language", "htm", "html")); fc.setFileFilter(fc.getChoosableFileFilters()[1]); if (fc.showSaveDialog(owner) == APPROVE_OPTION) { File file = fc.getSelectedFile(); if (!file.getPath().endsWith(".htm") && !file.getPath().endsWith(".html")) { file = new File(file.getAbsolutePath() + ".html"); } if (file.exists()) { int n = JOptionPane.showConfirmDialog(owner, file.getName() + getLocalized("MESSAGE_REPLACE_FILE"), getLocalized("MESSAGE_REPLACE_FILE_TITLE"), JOptionPane.YES_NO_OPTION); if (n == JOptionPane.NO_OPTION) { return; } } try { QTreeHTMLHandler.saveExperimentHTML(qTreeModel.getRoot(), file); } catch (IOException e) { JOptionPane.showMessageDialog(owner, getLocalized("MESSAGE_SAVE_ERROR"), getLocalized("MESSAGE_ERROR"), JOptionPane.ERROR_MESSAGE); } } } } private ActionListener nameCheckActionListener = event -> { Map<String, List<TreePath>> duplicates = QTreeHTMLHandler.checkNames(qTreeModel.getRoot()); if (duplicates.isEmpty()) { JOptionPane.showMessageDialog(null, getLocalized("MESSAGE_DUPLICATE_TITLE_NO_DUPLICATES_EXIST")); return; } // build a html table containing the returned duplicates String tableRow = "tr"; String tableHeader = "th"; String tableData = "td"; Element html = new Element(Tag.valueOf("html"), ""); Element table = html.appendElement("table"); Element header = table.appendElement(tableRow); Element row; table.attr("border", "1"); header.appendElement(tableHeader).text(getLocalized("MULTILINEDIALOG_NAME")); header.appendElement(tableHeader).text(getLocalized("MESSAGE_DUPLICATE_APPEARANCE")); boolean first; for (Map.Entry<String, List<TreePath>> entry : duplicates.entrySet()) { first = true; for (TreePath tPath : entry.getValue()) { row = table.appendElement(tableRow); if (first) { row.appendElement(tableData).text(entry.getKey()); } else { row.appendElement(tableData); } row.appendElement(tableData).text(tPath.toString()); first = false; } } JScrollPane sPane = new JScrollPane(new JLabel(html.toString())); sPane.setPreferredSize(new Dimension(sPane.getPreferredSize().width + 20, 500)); JOptionPane.showMessageDialog(null, sPane, getLocalized("MESSAGE_DUPLICATE_TITLE_DUPLICATES_EXIST"), JOptionPane.INFORMATION_MESSAGE); }; /** * Constructs a new <code>ExperimentEditorMenuBar</code>. * * @param qTree * the <code>QTree</code> used in the <code>ExperimentEditor</code> * @param tabbedPane * the <code>ExperimentEditorTabbedPane</code> in the <code>ExperimentEditor</code> */ public ExperimentEditorMenuBar(QTree qTree, ExperimentEditorTabbedPane tabbedPane) { this.owner = (JFrame) SwingUtilities.getWindowAncestor(qTree); this.qTreeModel = (QTreeModel) qTree.getModel(); this.tabbedPane = tabbedPane; MenuListener enableListener = new MenuListener() { @Override public void menuSelected(MenuEvent e) { boolean treeExists = qTreeModel.getRoot() != null; saveMenuItem.setEnabled(treeExists); saveAsMenuItem.setEnabled(treeExists); nameCheckMenuItem.setEnabled(treeExists); } @Override public void menuDeselected(MenuEvent e) { } @Override public void menuCanceled(MenuEvent e) { } }; //DATEI JMenu fileMenu = new JMenu(getLocalized("MENU_FILE")); add(fileMenu); fileMenu.addMenuListener(enableListener); JMenuItem newMenuItem = new JMenuItem(getLocalized("MENU_FILE_NEW")); newMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK)); fileMenu.add(newMenuItem); newMenuItem.addActionListener(newActionListener); JMenuItem loadMenuItem = new JMenuItem(getLocalized("MENU_FILE_OPEN")); loadMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.CTRL_MASK)); fileMenu.add(loadMenuItem); loadMenuItem.addActionListener(loadActionListener); saveMenuItem = new JMenuItem(getLocalized("MENU_FILE_SAVE")); saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK)); fileMenu.add(saveMenuItem); saveMenuItem.addActionListener(saveActionListener); saveAsMenuItem = new JMenuItem(getLocalized("MENU_FILE_SAVE_AS")); saveAsMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0)); fileMenu.add(saveAsMenuItem); saveAsMenuItem.addActionListener(saveAsActionListener); fileMenu.addSeparator(); exportMenu = new JMenu(getLocalized("MENU_EXPORT")); fileMenu.add(exportMenu); JMenuItem exportHTMLFileMenuItem = new JMenuItem(getLocalized("MENU_ITEM_HTML_OF_QUESTIONS")); exportMenu.add(exportHTMLFileMenuItem); exportHTMLFileMenuItem.addActionListener(new ExportHTMLFileActionListener()); JMenuItem xmlToCsvAllInDir = new JMenuItem(getLocalized("MENU_ITEM_XML_TO_CSV")); exportMenu.add(xmlToCsvAllInDir); xmlToCsvAllInDir.addActionListener(new XMLToCSVActionListener()); fileMenu.addSeparator(); JMenuItem closeMenuItem = new JMenuItem(getLocalized("MENU_FILE_QUIT")); fileMenu.add(closeMenuItem); // BEARBEITEN JMenu editMenu = new JMenu(getLocalized("MENU_EDIT")); add(editMenu); JMenuItem searchMenuItem = new JMenuItem(getLocalized("MENU_EDIT_FIND")); searchMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK)); editMenu.add(searchMenuItem); searchMenuItem.addActionListener(searchActionListener); // EXTRAS JMenu extrasMenu = new JMenu(getLocalized("MENU_PLAUSIBILITY_FEATURES")); add(extrasMenu); extrasMenu.addMenuListener(enableListener); nameCheckMenuItem = new JMenuItem(getLocalized("MENU_ITEM_CHECK_FORM_NAMES")); extrasMenu.add(nameCheckMenuItem); nameCheckMenuItem.addActionListener(nameCheckActionListener); JMenuItem macroEd = new JMenuItem(MacroEditor.class.getSimpleName()); extrasMenu.add(macroEd); macroEd.addActionListener(event -> MacroEditor.main(null)); closeMenuItem.addActionListener(closeActionListener); } /** * Display a OK dialog confirming that the current experiment was saved. */ private void confirmSave() { JOptionPane.showMessageDialog(owner, getLocalized("MESSAGE_SAVE_SUCCESSFUL"), null, JOptionPane.INFORMATION_MESSAGE); } /** * Displays a YES/NO dialog asking whether the user would like to overwrite an existing file. * * @param saveFile * the <code>File</code> that would be overridden * * @return true iff the user clicked YES */ private boolean confirmOverwrite(File saveFile) { return JOptionPane.showConfirmDialog(owner, saveFile.getName() + ' ' + getLocalized("MESSAGE_REPLACE_FILE"), getLocalized("MESSAGE_REPLACE_FILE_TITLE"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION; } }