Modify

Opened 2 years ago

Last modified 6 months ago

#15051 new enhancement

Add help button to "Search for Objects by Preset"

Reported by: jidanni Owned by: team
Priority: normal Milestone:
Component: Core Version:
Keywords: search preset help focus traversal Cc: Klumbumbus, stoecker, GerdP

Description

Search has a Help button, but "Search for Objects by Preset" doesn't.
Some people's first search is Search for Objects by Preset, not plain Search. So Help is needed.

Attachments (0)

Change History (14)

comment:1 Changed 10 months ago by simon04

Milestone: 19.01

comment:2 Changed 10 months ago by simon04

Cc: help added
Summary: Search has a Help button, but Search for Objects by Preset doesn'tAdd help button to "Search for Objects by Preset"

The problem is: we do not yet have a help page for this action. The closest one is Help/Action/TaggingPresetSearch.

comment:3 Changed 10 months ago by Klumbumbus

I wonder if the "Search for Objects by Preset" window is still needed since it was integrated in the default search window too.

Last edited 10 months ago by Klumbumbus (previous) (diff)

comment:4 Changed 10 months ago by simon04

Good point. The only argument I found after some testing is that "Search for Objects by Preset" can be operated quickly using the keyboard only:

  • [Ctrl]+F3tree[Enter]
  • [Ctrl]+F – 6×[Tab]tree[Enter] – does not work (i.e., select everything) since a preset must be double-clicked in order to obtain the search phrase preset:"Geography/Nature/Tree"

We could try to address this issue (tabindex, respect selected preset items for empty search phrase) and then remove "Search for Objects by Preset".

comment:5 Changed 10 months ago by Don-vip

Milestone: 19.0119.02

comment:6 Changed 9 months ago by Don-vip

Cc: help removed
Keywords: search preset help added
Milestone: 19.0219.03
Priority: trivialnormal

comment:7 Changed 8 months ago by Don-vip

In 14927/josm:

see #15051 - refactoring: extract SearchDialog from SearchAction

comment:8 Changed 8 months ago by Don-vip

Cc: Klumbumbus stoecker GerdP added
Keywords: focus traversal added

@team: I spent an hour trying to customize focus traversal without success, I think it's a lot simpler to put the preset list on the left side of the search dialog instead of on the right. This way the focus will work by itself. Any objection?

Below my (failed) attempt:

  • SearchDialog.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.Component;
     7import java.awt.Container;
    68import java.awt.Cursor;
    79import java.awt.Dimension;
    810import java.awt.FlowLayout;
     11import java.awt.FocusTraversalPolicy;
    912import java.awt.GridBagLayout;
    1013import java.awt.event.ActionEvent;
    1114import java.awt.event.MouseAdapter;
    1215import java.awt.event.MouseEvent;
     16import java.util.ArrayList;
    1317import java.util.Arrays;
    1418import java.util.Collections;
    1519import java.util.List;
     
    5256    private final SearchSetting searchSettings;
    5357
    5458    private final HistoryComboBox hcbSearchString = new HistoryComboBox();
     59    private final TaggingPresetSelector selector = new TaggingPresetSelector(false, false);
    5560    private final JCheckBox addOnToolbar = new JCheckBox(tr("add toolbar button"), false);
    5661
    5762    private JCheckBox caseSensitive;
     
    8388        setContent(buildPanel(searchExpressionHistory, expertMode));
    8489    }
    8590
     91    private static void addFocusableComponents(List<Component> order, Component c) {
     92        if (c.isFocusable()) {
     93            order.add(c);
     94        }
     95        if (c instanceof Container) {
     96            for (Component child : ((Container) c).getComponents()) {
     97                addFocusableComponents(order, child);
     98            }
     99        }
     100    }
     101
     102    private static void setFocusTraversalOrder(Container container, List<Component> components) {
     103
     104        List<Component> order = new ArrayList<>();
     105        components.forEach(c -> addFocusableComponents(order, c));
     106
     107        container.setFocusCycleRoot(true);
     108        container.setFocusTraversalPolicy(new FocusTraversalPolicy() {
     109
     110            @Override
     111            public Component getFirstComponent(Container aContainer) {
     112                return order.get(0);
     113            }
     114
     115            @Override
     116            public Component getLastComponent(Container aContainer) {
     117                return order.get(order.size() - 1);
     118            }
     119
     120            @Override
     121            public Component getDefaultComponent(Container aContainer) {
     122                return order.get(0);
     123            }
     124
     125            @Override
     126            public Component getComponentBefore(Container aContainer, Component aComponent) {
     127                int idx = order.indexOf(aComponent) - 1;
     128                return order.get(idx < 0 ? order.size() - 1 : idx);
     129            }
     130
     131            @Override
     132            public Component getComponentAfter(Container aContainer, Component aComponent) {
     133                return order.get((order.indexOf(aComponent) + 1) % order.size());
     134            }
     135        });
     136    }
     137
    86138    private JPanel buildPanel(List<String> searchExpressionHistory, boolean expertMode) {
    87139
    88140        // prepare the combo box with the search expressions
     
    194246         * selected preset by the user. Every query is of the form ' group/sub-group/.../presetName'
    195247         * if the corresponding group of the preset exists, otherwise it is simply ' presetName'.
    196248         */
    197         TaggingPresetSelector selector = new TaggingPresetSelector(false, false);
    198249        selector.setBorder(BorderFactory.createTitledBorder(tr("Search by preset")));
    199250        selector.setDblClickListener(ev -> setPresetDblClickListener(selector, editorComponent));
    200251
     
    204255        p.add(right, GBC.std().fill(GBC.BOTH).insets(0, 10, 0, 0));
    205256        p.add(selector, GBC.eol().fill(GBC.BOTH).insets(0, 10, 0, 0));
    206257
     258        setFocusTraversalOrder(p, Arrays.asList(top, selector, left, right));
     259
    207260        return p;
    208261    }
    209262
     
    244297        searchSettings.regexSearch = regexSearch.isSelected();
    245298        searchSettings.mapCSSSearch = mapCSSSearch.isSelected();
    246299
     300        if (searchSettings.text.isEmpty()) {
     301            searchSettings.text = presetSearchQuery(selector.getSelectedPreset());
     302        }
     303
    247304        if (inSelection.isSelected()) {
    248305            searchSettings.mode = SearchMode.in_selection;
    249306        } else if (replace.isSelected()) {
     
    364421    }
    365422
    366423    /**
    367      *
     424     * Sets the preset list double-click handler that generates the associated search query
    368425     * @param selector Selector component that the user interacts with
    369426     * @param searchEditor Editor for search queries
    370427     */
     
    384441        // invokeLater allows us to defer the selection until waiting for focus.
    385442        SwingUtilities.invokeLater(() -> {
    386443            int textOffset = searchEditor.getCaretPosition();
    387             String presetSearchQuery = " preset:" +
    388                     "\"" + selectedPreset.getRawName() + "\"";
    389444            try {
    390                 searchEditor.getDocument().insertString(textOffset, presetSearchQuery, null);
     445                searchEditor.getDocument().insertString(textOffset, presetSearchQuery(selectedPreset), null);
    391446            } catch (BadLocationException e1) {
    392447                throw new JosmRuntimeException(e1.getMessage(), e1);
    393448            }
    394449        });
    395450    }
    396451
     452    private static String presetSearchQuery(TaggingPreset selectedPreset) {
     453        return selectedPreset != null ? " preset:\"" + selectedPreset.getRawName() + "\"" : "";
     454    }
     455
    397456    private static class SearchKeywordRow extends JPanel {
    398457
    399458        private final HistoryComboBox hcb;

comment:9 Changed 8 months ago by GerdP

I think I don't like the idea to reorder this often used dialog. Up to now I did not even recognize the "search by preset" stuff.
With
[Ctrl]+F – 6×[Tab]tree - [Down][Enter]
you get into the list. Would it be possible to bind a hotkey - e.g. [Tab]or [Space] - so that it creates the corresponding search entry?

comment:10 Changed 8 months ago by Don-vip

In 14932/josm:

see #15051, fix #17522 - crash in filter dialog caused by r14927 (patch by taylor.smock)

comment:11 Changed 8 months ago by Don-vip

Milestone: 19.0319.04

comment:12 Changed 7 months ago by Don-vip

In 14976/josm:

see #15051 - add a new method to get search text from SearchTextResultListPanel

comment:13 Changed 7 months ago by Don-vip

Milestone: 19.0419.05

comment:14 Changed 6 months ago by Don-vip

Milestone: 19.05

Modify Ticket

Change Properties
Set your email in Preferences
Action
as new The owner will remain team.
as The resolution will be set.
to The owner will be changed from team to the specified user.
The owner will change to jidanni
as duplicate The resolution will be set to duplicate.The specified ticket will be cross-referenced with this ticket
The owner will be changed from team to anonymous.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.