InputDialog: add search (#7701)

Searches for a string in the edited text.
Available in the Text editor and other input dialogs with the navigation bar enabled.

Find first searches from the beginning of the text.
Find next searches from the next to cursor position, used for continious search.
By now, the Search input window is closed after the search. You need to press the Find button again for continious search, the search string is kept in the input.
Is it better to keep the dialog open for the comfortable continious search? And close it with the Cancel only?

Case insensitive. Cursor jumps to the beginning of the found string.
Notifications are shown for better results visibility.

Unfortunately, violated our standartization to "search", couldn't invent better short wordings.
reviewable/pr7711/r1
hius07 3 years ago committed by GitHub
parent 4afcca9d6e
commit f3fe643d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -724,8 +724,73 @@ function InputDialog:_addScrollButtons(nav_bar)
end,
})
end
-- Add a button to go to the line by its number in the file
if self.fullscreen then
-- Add a button to search for a string in the edited text
table.insert(row, {
text = _("Find"),
callback = function()
local input_dialog
input_dialog = InputDialog:new{
title = _("Enter text to search for"),
stop_events_propagation = true, -- avoid interactions with upper InputDialog
input = self.search_value,
buttons = {
{
{
text = _("Cancel"),
callback = function()
UIManager:close(input_dialog)
end,
},
{
text = _("Find first"),
callback = function()
self.search_value = input_dialog:getInputText()
if self.search_value ~= "" then
UIManager:close(input_dialog)
local msg
local char_pos = self._input_widget:searchString(self.search_value, 1)
if char_pos > 0 then
self._input_widget:moveCursorToCharPos(char_pos)
msg = T(_("Found in line %1"), self._input_widget:getLineNums())
else
msg = _("Not found")
end
UIManager:show(Notification:new{
text = msg,
})
end
end,
},
{
text = _("Find next"),
is_enter_default = true,
callback = function()
self.search_value = input_dialog:getInputText()
if self.search_value ~= "" then
UIManager:close(input_dialog)
local msg
local char_pos = self._input_widget:searchString(self.search_value)
if char_pos > 0 then
self._input_widget:moveCursorToCharPos(char_pos)
msg = T(_("Found in line %1."), self._input_widget:getLineNums())
else
msg = _("Not found.")
end
UIManager:show(Notification:new{
text = msg,
})
end
end,
},
},
},
}
UIManager:show(input_dialog)
input_dialog:onShowKeyboard()
end,
})
-- Add a button to go to the line by its number in the file
table.insert(row, {
text = _("Go"),
callback = function()

@ -533,6 +533,29 @@ function InputText:getLineCharPos(line_num)
return char_pos
end
--- Search for a string.
-- if start_pos not set, starts a search from the next to cursor position
-- returns first found position or 0 if not found
function InputText:searchString(str, start_pos)
local str_len = string.len(str)
local char_pos, found = 0, 0
start_pos = start_pos and (start_pos - 1) or self.charpos
for i = start_pos, #self.charlist - str_len do
for j = 1, str_len do
if string.lower(self.charlist[i + j]) ~= string.lower(string.sub(str, j, j)) then
found = 0
break
end
found = found + 1
end
if found == str_len then
char_pos = i + 1
break
end
end
return char_pos
end
function InputText:addChars(chars)
if not chars then
-- VirtualKeyboard:addChar(key) gave us 'nil' once (?!)

Loading…
Cancel
Save