diff --git a/frontend/ui/widget/inputtext.lua b/frontend/ui/widget/inputtext.lua index 297ded7f4..5cb66b0a3 100644 --- a/frontend/ui/widget/inputtext.lua +++ b/frontend/ui/widget/inputtext.lua @@ -59,6 +59,8 @@ local InputText = InputContainer:new{ is_text_editable = true, -- whether text is utf8 reversible and editing won't mess content is_text_edited = false, -- whether text has been updated for_measurement_only = nil, -- When the widget is a one-off used to compute text height + do_select = false, -- to start text selection + selection_start_pos = nil, -- selection start position } -- only use PhysicalKeyboard if the device does not have touch screen @@ -134,15 +136,105 @@ if Device:isTouchDevice() or Device:hasDPad() then if self.parent.onSwitchFocus then self.parent:onSwitchFocus(self) end - if #self.charlist > 0 then -- Avoid cursor moving within a hint. - local textwidget_offset = self.margin + self.bordersize + self.padding - local x = ges.pos.x - self._frame_textwidget.dimen.x - textwidget_offset - local y = ges.pos.y - self._frame_textwidget.dimen.y - textwidget_offset - self.text_widget:moveCursorToXY(x, y, true) -- restrict_to_view=true - self.charpos, self.top_line_num = self.text_widget:getCharPos() - end - if Device:hasClipboard() and Device.input.hasClipboardText() then - self:addChars(Device.input.getClipboardText()) + -- clipboard dialog + if Device:hasClipboard() then + if self.do_select then -- select mode on + if self.selection_start_pos then -- select end + local selection_end_pos = self.charpos - 1 + if self.selection_start_pos > selection_end_pos then + self.selection_start_pos, selection_end_pos = selection_end_pos + 1, self.selection_start_pos - 1 + end + local txt = table.concat(self.charlist, "", self.selection_start_pos, selection_end_pos) + Device.input.setClipboardText(txt) + UIManager:show(Notification:new{ + text = _("Selection copied to clipboard."), + }) + self.selection_start_pos = nil + self.do_select = false + return true + else -- select start + self.selection_start_pos = self.charpos + UIManager:show(Notification:new{ + text = _("Set cursor to end of selection, then hold."), + }) + return true + end + end + local input_dialog + input_dialog = require("ui/widget/inputdialog"):new{ + title = _("Clipboard"), + stop_events_propagation = true, + input_hint = _("empty"), + input = Device.input.getClipboardText(), + buttons = { + { + { + text = _("All"), + callback = function() + UIManager:close(input_dialog) + Device.input.setClipboardText(table.concat(self.charlist)) + UIManager:show(Notification:new{ + text = _("All text copied to clipboard."), + }) + end, + }, + { + text = _("Line"), + callback = function() + UIManager:close(input_dialog) + local txt = table.concat(self.charlist, "", self:getStringPos({"\n", "\r"}, {"\n", "\r"})) + Device.input.setClipboardText(txt) + UIManager:show(Notification:new{ + text = _("Line copied to clipboard."), + }) + end, + }, + { + text = _("Word"), + callback = function() + UIManager:close(input_dialog) + local txt = table.concat(self.charlist, "", self:getStringPos({"\n", "\r", " "}, {"\n", "\r", " "})) + Device.input.setClipboardText(txt) + UIManager:show(Notification:new{ + text = _("Word copied to clipboard."), + }) + end, + }, + }, + { + { + text = _("Cancel"), + callback = function() + UIManager:close(input_dialog) + end, + }, + { + text = _("Select"), + callback = function() + UIManager:close(input_dialog) + UIManager:show(Notification:new{ + text = _("Set cursor to start of selection, then hold."), + }) + self.do_select = true + end, + }, + { + text = _("Paste"), + is_enter_default = true, + callback = function() + local paste_value = input_dialog:getInputText() + if paste_value ~= "" then + UIManager:close(input_dialog) + Device.input.setClipboardText(paste_value) + self:addChars(paste_value) + end + end, + }, + }, + }, + } + UIManager:show(input_dialog) + input_dialog:onShowKeyboard(true) end return true end @@ -536,6 +628,41 @@ function InputText:getLineCharPos(line_num) return char_pos end +-- Get start and end positions of the substring +-- delimited with the delimiters and containing char_pos. +-- If char_pos not set, current charpos assumed. +function InputText:getStringPos(left_delimiter, right_delimiter, char_pos) + char_pos = char_pos and char_pos or self.charpos + local start_pos, end_pos = 1, #self.charlist + local done = false + if char_pos > 1 then + for i = char_pos, 2, -1 do + for j = 1, #left_delimiter do + if self.charlist[i-1] == left_delimiter[j] then + start_pos = i + done = true + break + end + end + if done then break end + end + end + done = false + if char_pos < #self.charlist then + for i = char_pos, #self.charlist do + for j = 1, #right_delimiter do + if self.charlist[i] == right_delimiter[j] then + end_pos = i - 1 + done = true + break + end + end + if done then break end + end + end + return start_pos, end_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