/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * 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 * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.properties; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.BorderFactory; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import com.rapidminer.gui.tools.SwingTools; import com.rapidminer.tools.I18N; /** * Dialog which shows a choice between two buttons how a {@link FunctionInputType#MACRO} should be * inserted into the {@link ExpressionPropertyDialog}, as a value or as an interpreted expression. * * @author Sabrina Kirstein * */ public class MacroSelectionDialog extends JDialog { private static final long serialVersionUID = 6827927054583795240L; /** * macro expression that should be inserted into the {@link ExpressionPropertyDialog}'s * expression */ private String expression = ""; /** default background color */ private Color defaultBackground; /** panel showing the 'Insert as value' part */ private JPanel valuePanel = new JPanel(); /** indicator if the value part is highlighted */ private boolean valueHighlighted = false; /** panel showing the 'Insert as evaluated expression' part */ private JPanel expressionPanel = new JPanel(); /** indicator if the expression part is highlighted */ private boolean expressionHighlighted = false; /** indicates if the old macro handling is used */ private boolean deprecated = false; /** title of the entire dialog */ private static final String DIALOG_TITLE = I18N.getGUILabel("macro_selection_dialog.title"); /** title of the value part */ private static final String VALUE_TITLE = I18N.getGUILabel("macro_selection_dialog.value.title"); /** description of the value part */ private static final String VALUE_DESCRIPTION = I18N.getGUILabel("macro_selection_dialog.value.description"); /** expression, when the user selects the expression part */ private static final String VALUE_CALL = "%{macro_name}"; /** start of the expression, when the user selects the expression part */ private static final String VALUE_CALL_START = "%{"; /** end of the expression, when the user selects the expression part */ private static final String VALUE_CALL_END = "}"; /** expression, when the user selects the expression part */ private static final String VALUE_CALL_DEPRECATED = "macro(\"macro_name\")"; /** start of the expression, when the user selects the expression part */ private static final String VALUE_CALL_START_DEPRECATED = "macro(\""; /** end of the expression, when the user selects the expression part */ private static final String VALUE_CALL_END_DEPRECATED = "\")"; /** title of the expression part */ private static final String EXPRESSION_TITLE = I18N.getGUILabel("macro_selection_dialog.expression.title"); /** description of the expression part 1 */ private static final String EXPRESSION_DESCRIPTION = I18N.getGUILabel("macro_selection_dialog.expression.description"); /** expression, when the user selects the expression part */ private static final String EXPRESSION_CALL = "eval(%{macro_name})"; /** start of the expression, when the user selects the expression part */ private static final String EXPRESSION_CALL_START = "eval(%{"; /** end of the expression, when the user selects the expression part */ private static final String EXPRESSION_CALL_END = "})"; /** expression, when the user selects the expression part */ private static final String EXPRESSION_CALL_DEPRECATED = "%{macro_name}"; /** start of the expression, when the user selects the expression part */ private static final String EXPRESSION_CALL_START_DEPRECATED = "%{"; /** end of the expression, when the user selects the expression part */ private static final String EXPRESSION_CALL_END_DEPRECATED = "}"; /** * Creates a dialog for a given {@link FunctionInputType#MACRO} to choose between inserting the * macro as a pure value or as an interpreted expression. * * @param macroPanel * @param deprecated * if deprecated, use old macro handling */ public MacroSelectionDialog(FunctionInputPanel macroPanel, boolean deprecated) { this.deprecated = deprecated; initGui(macroPanel); expressionPanel.requestFocusInWindow(); } /** * Creates a dialog for a given {@link FunctionInputType#MACRO} to choose between inserting the * macro as a pure value or as an interpreted expression. * * @param macroPanel */ public MacroSelectionDialog(FunctionInputPanel macroPanel) { this(macroPanel, false); } /** * @return the selected expression which will be added to the {@link ExpressionPropertyDialog} */ public String getExpression() { return expression; } /** * Initializes the User Interface * * @param macroPanel * {@link FunctionInputPanel} showing the macro that the user clicked on */ private void initGui(final FunctionInputPanel macroPanel) { defaultBackground = getBackground(); setResizable(false); setModalityType(ModalityType.APPLICATION_MODAL); setTitle(DIALOG_TITLE); setIconImage(SwingTools.createIcon("16/rapidminer_studio.png").getImage()); setSize(new Dimension(300, 300)); JPanel main = new JPanel(); GridBagLayout mainLayout = new GridBagLayout(); main.setLayout(mainLayout); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 1; gbc.anchor = GridBagConstraints.NORTHWEST; // VALUE PART valuePanel.setLayout(new GridBagLayout()); valuePanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); valuePanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY)); // add text if (deprecated) { valuePanel.add(new JLabel("<html><p align=\"left\"><b><font size=4>" + VALUE_TITLE + "</font></b><br><font size=3 color=\"gray\">" + VALUE_CALL_DEPRECATED + "</font><br><br>" + VALUE_DESCRIPTION + "</p></html>"), gbc); } else { valuePanel.add(new JLabel("<html><p align=\"left\"><b><font size=4>" + VALUE_TITLE + "</font></b><br><font size=3 color=\"gray\">" + VALUE_CALL + "</font><br><br>" + VALUE_DESCRIPTION + "</p></html>"), gbc); } // add highlighting behavior and store the expression if the user selects a type of // expression valuePanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (deprecated) { expression = VALUE_CALL_START_DEPRECATED + macroPanel.getInputName().replace("\\", "\\\\") + VALUE_CALL_END_DEPRECATED; } else { expression = VALUE_CALL_START + escape(macroPanel.getInputName()) + VALUE_CALL_END; } MacroSelectionDialog.this.setVisible(false); } @Override public void mouseEntered(MouseEvent e) { highlightValue(true); highlightExpression(false); } @Override public void mouseExited(MouseEvent e) { highlightValue(false); } }); main.add(valuePanel, gbc); // EVALUATED EXPRESSION PART expressionPanel.setLayout(new GridBagLayout()); expressionPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); expressionPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY)); // add text if (deprecated) { expressionPanel.add(new JLabel("<html><p align=\"left\"><b><font size=4>" + EXPRESSION_TITLE + "</font></b><br><font size=3 color=\"gray\">" + EXPRESSION_CALL_DEPRECATED + "</font><br><br>" + EXPRESSION_DESCRIPTION + "</p></html>"), gbc); } else { expressionPanel.add(new JLabel("<html><p align=\"left\"><b><font size=4>" + EXPRESSION_TITLE + "</font></b><br><font size=3 color=\"gray\">" + EXPRESSION_CALL + "</font><br><br>" + EXPRESSION_DESCRIPTION + "</p></html>"), gbc); } // add highlighting behavior and store the expression if the user selects a type of // expression expressionPanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (deprecated) { expression = EXPRESSION_CALL_START_DEPRECATED + macroPanel.getInputName() + EXPRESSION_CALL_END_DEPRECATED; } else { expression = EXPRESSION_CALL_START + escape(macroPanel.getInputName()) + EXPRESSION_CALL_END; } MacroSelectionDialog.this.setVisible(false); } @Override public void mouseEntered(MouseEvent e) { highlightExpression(true); highlightValue(false); } @Override public void mouseExited(MouseEvent e) { highlightExpression(false); } }); gbc.gridy += 1; gbc.insets = new Insets(10, 0, 0, 0); main.add(expressionPanel, gbc); // add highlighting behavior for keys and store the expression if the user selects a type of // expression addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { if (expressionHighlighted) { highlightExpression(false); highlightValue(true); } else if (!valueHighlighted) { highlightExpression(true); highlightValue(false); } } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { if (valueHighlighted) { highlightExpression(true); highlightValue(false); } else if (!expressionHighlighted) { highlightExpression(false); highlightValue(true); } } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { if (valueHighlighted) { if (deprecated) { expression = VALUE_CALL_START_DEPRECATED + macroPanel.getInputName().replace("\\", "\\\\") + VALUE_CALL_END_DEPRECATED; } else { expression = VALUE_CALL_START + escape(macroPanel.getInputName()) + VALUE_CALL_END; } MacroSelectionDialog.this.setVisible(false); } else if (expressionHighlighted) { if (deprecated) { expression = EXPRESSION_CALL_START_DEPRECATED + macroPanel.getInputName() + EXPRESSION_CALL_END_DEPRECATED; } else { expression = EXPRESSION_CALL_START + escape(macroPanel.getInputName()) + EXPRESSION_CALL_END; } MacroSelectionDialog.this.setVisible(false); } } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { setVisible(false); } } }); setLayout(new GridBagLayout()); gbc.gridx = 0; gbc.gridy = 0; gbc.insets = new Insets(10, 10, 10, 10); add(main, gbc); } /** * Escapes curly brackets and backslashes inside inputName. */ private String escape(String inputName) { return inputName.replace("\\", "\\\\").replace("{", "\\{").replace("}", "\\}"); } /** * Highlights the part to select, if the user wants to insert the value * * @param highlight * whether it should be highlighted */ private void highlightValue(boolean highlight) { valueHighlighted = highlight; if (highlight) { valuePanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, SwingTools.RAPIDMINER_ORANGE)); valuePanel.setBackground(Color.LIGHT_GRAY); } else { valuePanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY)); valuePanel.setBackground(defaultBackground); } } /** * Highlights the part to select, if the user wants to insert the evaluated expression of the * macro * * @param highlight * whether it should be highlighted */ private void highlightExpression(boolean highlight) { expressionHighlighted = highlight; if (highlight) { expressionPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, SwingTools.RAPIDMINER_ORANGE)); expressionPanel.setBackground(Color.LIGHT_GRAY); } else { expressionPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY)); expressionPanel.setBackground(defaultBackground); } } }