mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Edit book: When text is selected allow changing the indentation of all lines in the selection by pressing Tab to increase one level or Shift+Tab to decrease one level. Fixes #2076251 [[Edit Book][Enhancement] Allow to indent all selected lines at once](https://bugs.launchpad.net/calibre/+bug/2076251)
This commit is contained in:
parent
3d477b904c
commit
5fc10a7af1
@ -72,7 +72,7 @@ class Smarts(NullSmarts):
|
||||
if key == Qt.Key.Key_Home and smart_home(editor, ev):
|
||||
return True
|
||||
|
||||
if key == Qt.Key.Key_Tab:
|
||||
if key in (Qt.Key.Key_Tab, Qt.Key.Key_Backtab):
|
||||
mods = ev.modifiers()
|
||||
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
||||
return True
|
||||
|
@ -732,7 +732,7 @@ class Smarts(NullSmarts):
|
||||
if key == Qt.Key.Key_Home and smart_home(editor, ev):
|
||||
return True
|
||||
|
||||
if key == Qt.Key.Key_Tab:
|
||||
if key in (Qt.Key.Key_Tab, Qt.Key.Key_Backtab):
|
||||
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
||||
return True
|
||||
|
||||
|
@ -36,7 +36,7 @@ class Smarts(NullSmarts):
|
||||
def handle_key_press(self, ev, editor):
|
||||
key = ev.key()
|
||||
|
||||
if key == Qt.Key.Key_Tab:
|
||||
if key in (Qt.Key.Key_Tab, Qt.Key.Key_Backtab):
|
||||
mods = ev.modifiers()
|
||||
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
||||
return True
|
||||
|
@ -74,19 +74,73 @@ def expand_tabs(text, tw):
|
||||
return text.replace('\t', ' ' * tw)
|
||||
|
||||
|
||||
def smart_tab(editor, ev):
|
||||
def smart_tab_if_whitespace_only_before_cursor(editor, backwards):
|
||||
cursor, text = get_text_before_cursor(editor)
|
||||
if not text.lstrip():
|
||||
# cursor is preceded by only whitespace
|
||||
tw = editor.tw
|
||||
text = expand_tabs(text, tw)
|
||||
spclen = len(text) - (len(text) % tw) + tw
|
||||
cursor.insertText(' ' * spclen)
|
||||
editor.setTextCursor(cursor)
|
||||
return True
|
||||
if backwards:
|
||||
if leading := len(text):
|
||||
new_leading = max(0, leading - tw)
|
||||
extra = new_leading % tw
|
||||
if extra:
|
||||
new_leading += tw - extra
|
||||
cursor.insertText(' ' * new_leading)
|
||||
return True
|
||||
else:
|
||||
spclen = len(text) - (len(text) % tw) + tw
|
||||
cursor.insertText(' ' * spclen)
|
||||
editor.setTextCursor(cursor)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def smart_tab_all_blocks_in_selection(editor, backwards):
|
||||
cursor = editor.textCursor()
|
||||
c = QTextCursor(cursor)
|
||||
c.clearSelection()
|
||||
c.setPosition(cursor.selectionStart())
|
||||
tab_width = editor.tw
|
||||
changed = False
|
||||
while not c.atEnd() and c.position() <= cursor.selectionEnd():
|
||||
c.clearSelection()
|
||||
c.movePosition(QTextCursor.MoveOperation.EndOfBlock)
|
||||
c.movePosition(QTextCursor.MoveOperation.StartOfBlock, QTextCursor.MoveMode.KeepAnchor)
|
||||
c.movePosition(QTextCursor.MoveOperation.StartOfBlock)
|
||||
# select leading whitespace
|
||||
while not c.atEnd() and c.document().characterAt(c.position()).isspace():
|
||||
c.movePosition(QTextCursor.MoveOperation.NextCharacter, QTextCursor.MoveMode.KeepAnchor)
|
||||
text = expand_tabs(editor.selected_text_from_cursor(c), tab_width)
|
||||
leading = len(text)
|
||||
replaced = False
|
||||
if backwards:
|
||||
if leading:
|
||||
new_leading = max(0, leading - tab_width)
|
||||
extra = new_leading % tab_width
|
||||
if extra:
|
||||
new_leading += tab_width - extra
|
||||
replaced = True
|
||||
else:
|
||||
new_leading = leading + tab_width
|
||||
new_leading -= new_leading % tab_width
|
||||
replaced = True
|
||||
if replaced:
|
||||
c.insertText(' ' * new_leading)
|
||||
changed = True
|
||||
c.movePosition(QTextCursor.MoveOperation.NextBlock)
|
||||
c.movePosition(QTextCursor.MoveOperation.StartOfBlock)
|
||||
return changed
|
||||
|
||||
|
||||
def smart_tab(editor, ev):
|
||||
cursor = editor.textCursor()
|
||||
backwards = ev.key() == Qt.Key.Key_Backtab or (ev.key() == Qt.Key.Key_Tab and bool(ev.modifiers() & Qt.KeyboardModifier.ShiftModifier))
|
||||
if cursor.hasSelection():
|
||||
return smart_tab_all_blocks_in_selection(editor, backwards)
|
||||
return smart_tab_if_whitespace_only_before_cursor(editor, backwards)
|
||||
|
||||
|
||||
def smart_backspace(editor, ev):
|
||||
if editor.textCursor().hasSelection():
|
||||
return False
|
||||
|
Loading…
x
Reference in New Issue
Block a user