public static SearchSetting showSearchDialog(SearchSetting initialValues) { if (initialValues == null) { initialValues = new SearchSetting(); } // -- prepare the combo box with the search expressions // JLabel label = new JLabel(initialValues instanceof Filter ? tr("Filter string:") : tr("Search string:")); final HistoryComboBox hcbSearchString = new HistoryComboBox(); final String tooltip = tr("Enter the search expression"); hcbSearchString.setText(initialValues.text); hcbSearchString.setToolTipText(tooltip); // we have to reverse the history, because ComboBoxHistory will reverse it again in addElement() // List<String> searchExpressionHistory = getSearchExpressionHistory(); Collections.reverse(searchExpressionHistory); hcbSearchString.setPossibleItems(searchExpressionHistory); hcbSearchString.setPreferredSize(new Dimension(40, hcbSearchString.getPreferredSize().height)); label.setLabelFor(hcbSearchString); JRadioButton replace = new JRadioButton(tr("replace selection"), initialValues.mode == SearchMode.replace); JRadioButton add = new JRadioButton(tr("add to selection"), initialValues.mode == SearchMode.add); JRadioButton remove = new JRadioButton(tr("remove from selection"), initialValues.mode == SearchMode.remove); JRadioButton inSelection = new JRadioButton(tr("find in selection"), initialValues.mode == SearchMode.in_selection); ButtonGroup bg = new ButtonGroup(); bg.add(replace); bg.add(add); bg.add(remove); bg.add(inSelection); final JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), initialValues.caseSensitive); JCheckBox allElements = new JCheckBox(tr("all objects"), initialValues.allElements); allElements.setToolTipText(tr("Also include incomplete and deleted objects in search.")); final JRadioButton standardSearch = new JRadioButton(tr("standard"), !initialValues.regexSearch && !initialValues.mapCSSSearch); final JRadioButton regexSearch = new JRadioButton(tr("regular expression"), initialValues.regexSearch); final JRadioButton mapCSSSearch = new JRadioButton(tr("MapCSS selector"), initialValues.mapCSSSearch); final JCheckBox addOnToolbar = new JCheckBox(tr("add toolbar button"), false); final ButtonGroup bg2 = new ButtonGroup(); bg2.add(standardSearch); bg2.add(regexSearch); bg2.add(mapCSSSearch); JPanel top = new JPanel(new GridBagLayout()); top.add(label, GBC.std().insets(0, 0, 5, 0)); top.add(hcbSearchString, GBC.eol().fill(GBC.HORIZONTAL)); JPanel left = new JPanel(new GridBagLayout()); left.add(replace, GBC.eol()); left.add(add, GBC.eol()); left.add(remove, GBC.eol()); left.add(inSelection, GBC.eop()); left.add(caseSensitive, GBC.eol()); if (Main.pref.getBoolean("expert", false)) { left.add(allElements, GBC.eol()); left.add(addOnToolbar, GBC.eop()); left.add(standardSearch, GBC.eol()); left.add(regexSearch, GBC.eol()); left.add(mapCSSSearch, GBC.eol()); } final JPanel right; right = new JPanel(new GridBagLayout()); buildHints(right, hcbSearchString); final JTextComponent editorComponent = hcbSearchString.getEditorComponent(); editorComponent .getDocument() .addDocumentListener( new AbstractTextComponentValidator(editorComponent) { @Override public void validate() { if (!isValid()) { feedbackInvalid(tr("Invalid search expression")); } else { feedbackValid(tooltip); } } @Override public boolean isValid() { try { SearchSetting ss = new SearchSetting(); ss.text = hcbSearchString.getText(); ss.caseSensitive = caseSensitive.isSelected(); ss.regexSearch = regexSearch.isSelected(); ss.mapCSSSearch = mapCSSSearch.isSelected(); SearchCompiler.compile(ss); return true; } catch (ParseError | MapCSSException e) { return false; } } }); final JPanel p = new JPanel(new GridBagLayout()); p.add(top, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 0)); p.add(left, GBC.std().anchor(GBC.NORTH).insets(5, 10, 10, 0)); p.add(right, GBC.eol()); ExtendedDialog dialog = new ExtendedDialog( Main.parent, initialValues instanceof Filter ? tr("Filter") : tr("Search"), new String[] { initialValues instanceof Filter ? tr("Submit filter") : tr("Start Search"), tr("Cancel") }) { @Override protected void buttonAction(int buttonIndex, ActionEvent evt) { if (buttonIndex == 0) { try { SearchSetting ss = new SearchSetting(); ss.text = hcbSearchString.getText(); ss.caseSensitive = caseSensitive.isSelected(); ss.regexSearch = regexSearch.isSelected(); ss.mapCSSSearch = mapCSSSearch.isSelected(); SearchCompiler.compile(ss); super.buttonAction(buttonIndex, evt); } catch (ParseError e) { Main.debug(e); JOptionPane.showMessageDialog( Main.parent, tr("Search expression is not valid: \n\n {0}", e.getMessage()), tr("Invalid search expression"), JOptionPane.ERROR_MESSAGE); } } else { super.buttonAction(buttonIndex, evt); } } }; dialog.setButtonIcons(new String[] {"dialogs/search", "cancel"}); dialog.configureContextsensitiveHelp("/Action/Search", true /* show help button */); dialog.setContent(p); dialog.showDialog(); int result = dialog.getValue(); if (result != 1) return null; // User pressed OK - let's perform the search SearchMode mode = replace.isSelected() ? SearchAction.SearchMode.replace : (add.isSelected() ? SearchAction.SearchMode.add : (remove.isSelected() ? SearchAction.SearchMode.remove : SearchAction.SearchMode.in_selection)); initialValues.text = hcbSearchString.getText(); initialValues.mode = mode; initialValues.caseSensitive = caseSensitive.isSelected(); initialValues.allElements = allElements.isSelected(); initialValues.regexSearch = regexSearch.isSelected(); initialValues.mapCSSSearch = mapCSSSearch.isSelected(); if (addOnToolbar.isSelected()) { ToolbarPreferences.ActionDefinition aDef = new ToolbarPreferences.ActionDefinition(Main.main.menu.search); aDef.getParameters().put(SEARCH_EXPRESSION, initialValues); // Display search expression as tooltip instead of generic one aDef.setName(Utils.shortenString(initialValues.text, MAX_LENGTH_SEARCH_EXPRESSION_DISPLAY)); // parametrized action definition is now composed ActionParser actionParser = new ToolbarPreferences.ActionParser(null); String res = actionParser.saveAction(aDef); // add custom search button to toolbar preferences Main.toolbar.addCustomButton(res, -1, false); } return initialValues; }
@Test public void testCase1() { Map<String, Action> actions = new HashMap<>(); actions.put("action", new TestAction()); ActionParser parser = new ActionParser(actions); checkAction(parser.loadAction("action(param1=value1)"), "param1", "value1"); checkAction( parser.loadAction("action(param1=value1,param2=2)"), "param1", "value1", "param2", "2"); checkAction( parser.loadAction("action(param1=value1,param2=2\\(\\=\\,\\\\)"), "param1", "value1", "param2", "2(=,\\"); checkAction(parser.loadAction("action(param1=value1,"), "param1", "value1"); checkAction(parser.loadAction("action(param1=value1"), "param1", "value1"); checkAction(parser.loadAction("action(param1=")); checkAction(parser.loadAction("action(param1")); checkAction(parser.loadAction("action(")); checkAction(parser.loadAction("action")); checkAction(parser.loadAction("action(uknownParam=aa)")); Assert.assertEquals( "action(param1=value1,param2=value2)", parser.saveAction(parser.loadAction("action(param1=value1,param2=value2)"))); Assert.assertEquals( "action(param1=value1,param2=)", parser.saveAction(parser.loadAction("action(param1=value1)"))); Assert.assertEquals( "action(param1=value1,param2=2\\(\\=\\,\\\\)", parser.saveAction(parser.loadAction("action(param1=value1,param2=2\\(\\=\\,\\\\)"))); }