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):
|
if key == Qt.Key.Key_Home and smart_home(editor, ev):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if key == Qt.Key.Key_Tab:
|
if key in (Qt.Key.Key_Tab, Qt.Key.Key_Backtab):
|
||||||
mods = ev.modifiers()
|
mods = ev.modifiers()
|
||||||
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
||||||
return True
|
return True
|
||||||
|
@ -732,7 +732,7 @@ class Smarts(NullSmarts):
|
|||||||
if key == Qt.Key.Key_Home and smart_home(editor, ev):
|
if key == Qt.Key.Key_Home and smart_home(editor, ev):
|
||||||
return True
|
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):
|
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class Smarts(NullSmarts):
|
|||||||
def handle_key_press(self, ev, editor):
|
def handle_key_press(self, ev, editor):
|
||||||
key = ev.key()
|
key = ev.key()
|
||||||
|
|
||||||
if key == Qt.Key.Key_Tab:
|
if key in (Qt.Key.Key_Tab, Qt.Key.Key_Backtab):
|
||||||
mods = ev.modifiers()
|
mods = ev.modifiers()
|
||||||
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
if not mods & Qt.KeyboardModifier.ControlModifier and smart_tab(editor, ev):
|
||||||
return True
|
return True
|
||||||
|
@ -74,19 +74,73 @@ def expand_tabs(text, tw):
|
|||||||
return text.replace('\t', ' ' * 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)
|
cursor, text = get_text_before_cursor(editor)
|
||||||
if not text.lstrip():
|
if not text.lstrip():
|
||||||
# cursor is preceded by only whitespace
|
# cursor is preceded by only whitespace
|
||||||
tw = editor.tw
|
tw = editor.tw
|
||||||
text = expand_tabs(text, tw)
|
text = expand_tabs(text, tw)
|
||||||
spclen = len(text) - (len(text) % tw) + tw
|
if backwards:
|
||||||
cursor.insertText(' ' * spclen)
|
if leading := len(text):
|
||||||
editor.setTextCursor(cursor)
|
new_leading = max(0, leading - tw)
|
||||||
return True
|
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
|
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):
|
def smart_backspace(editor, ev):
|
||||||
if editor.textCursor().hasSelection():
|
if editor.textCursor().hasSelection():
|
||||||
return False
|
return False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user