Template tester changes:

1) Add button to set breakpoints on every line
2) Make using Tab and Shift-Tab do indenting
This commit is contained in:
Charles Haley 2021-04-01 14:25:00 +01:00
parent efa95ceb0b
commit 7a04279803
3 changed files with 148 additions and 16 deletions

View File

@ -430,6 +430,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
s = gprefs.get('template_editor_break_on_print', False)
self.go_button.setEnabled(s)
self.remove_all_button.setEnabled(s)
self.set_all_button.setEnabled(s)
self.toggle_button.setEnabled(s)
self.breakpoint_line_box.setEnabled(s)
self.breakpoint_line_box_label.setEnabled(s)
@ -440,6 +441,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
self.set_up_font_boxes()
self.toggle_button.clicked.connect(self.toggle_button_pressed)
self.remove_all_button.clicked.connect(self.remove_all_button_pressed)
self.set_all_button.clicked.connect(self.set_all_button_pressed)
self.load_button.clicked.connect(self.load_template)
self.save_button.clicked.connect(self.save_template)
@ -511,6 +513,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
gprefs['template_editor_break_on_print'] = new_state != 0
self.go_button.setEnabled(new_state != 0)
self.remove_all_button.setEnabled(new_state != 0)
self.set_all_button.setEnabled(new_state != 0)
self.toggle_button.setEnabled(new_state != 0)
self.breakpoint_line_box.setEnabled(new_state != 0)
self.breakpoint_line_box_label.setEnabled(new_state != 0)
@ -521,6 +524,9 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
def remove_all_button_pressed(self):
self.textbox.set_clicked_line_numbers(set())
def set_all_button_pressed(self):
self.textbox.set_clicked_line_numbers({i for i in range(1, self.textbox.blockCount()+1)})
def toggle_button_pressed(self):
ln = self.breakpoint_line_box.value()
if ln > self.textbox.blockCount():

View File

@ -170,21 +170,21 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel">
<property name="text">
<string>T&amp;emplate:</string>
</property>
<property name="buddy">
<cstring>textbox</cstring>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<item row="1" column="0" colspan="4">
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>T&amp;emplate:</string>
</property>
<property name="buddy">
<cstring>textbox</cstring>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
@ -232,6 +232,9 @@ you the value as well as all the local variables&lt;/p&gt;</string>
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/sync-right.png</normaloff>:/images/sync-right.png</iconset>
</property>
<property name="styleSheet">
<string notr="true">padding: 5; padding-left: 1;</string>
</property>
<property name="toolTip">
<string>If 'Enable breakpoints' is checked then click this button to run your template</string>
</property>
@ -287,6 +290,9 @@ you the value as well as all the local variables&lt;/p&gt;</string>
<property name="text">
<string>&amp;Toggle</string>
</property>
<property name="styleSheet">
<string notr="true">padding: 5; padding-left: 1;</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/swap.png</normaloff>:/images/swap.png</iconset>
@ -314,6 +320,9 @@ you the value as well as all the local variables&lt;/p&gt;</string>
<property name="text">
<string>&amp;Remove all</string>
</property>
<property name="styleSheet">
<string notr="true">padding: 5; padding-left: 1;</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/list_remove.png</normaloff>:/images/list_remove.png</iconset>
@ -323,6 +332,23 @@ you the value as well as all the local variables&lt;/p&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="set_all_button">
<property name="text">
<string>&amp;Set all</string>
</property>
<property name="styleSheet">
<string notr="true">padding: 5; padding-left: 1;</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/plus.png</normaloff>:/images/plus.png</iconset>
</property>
<property name="toolTip">
<string>Set breakpoint on every line</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="4">
@ -590,13 +616,26 @@ you the value as well as all the local variables&lt;/p&gt;</string>
<item>
<widget class="QToolButton" name="save_button">
<property name="text">
<string>&amp;Save</string>
<string>Sa&amp;ve</string>
</property>
<property name="toolTip">
<string>Save the template in a file</string>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::VLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="lineWidth">
<number>3</number>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">

View File

@ -8,7 +8,8 @@ License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
'''
from qt.core import (
QFont, QPainter, QPalette, QPlainTextEdit, QRect, Qt, QTextEdit, QTextFormat
QFont, QPainter, QPalette, QPlainTextEdit, QRect, Qt, QTextEdit,
QTextFormat, QTextCursor
)
from calibre.gui2.tweak_book.editor.text import LineNumbers
@ -91,6 +92,9 @@ class CodeEditor(QPlainTextEdit):
self.clicked_line_numbers.add(line)
self.update(self.line_number_area.geometry())
def number_of_lines(self):
return self.blockCount()
def set_clicked_line_numbers(self, new_set):
self.clicked_line_numbers = new_set
self.update(self.line_number_area.geometry())
@ -131,3 +135,86 @@ class CodeEditor(QPlainTextEdit):
top = bottom
bottom = top + int(self.blockBoundingRect(block).height())
num += 1
def keyPressEvent(self, ev):
if ev.key() == Qt.Key.Key_Insert:
self.setOverwriteMode(self.overwriteMode() ^ True)
ev.accept()
return
key = ev.key()
if key == Qt.Key_Tab or key == Qt.Key_Backtab:
'''
Handle indenting usingTab and Shift Tab. This is remarkably
difficult because of the way Qt represents the edit buffer.
Selections represent the start and end as character positions in the
buffer. To convert a position into a line number we must get the
block number containing that position. You so this by setting a
cursor to that position.
To get the text of a line we must convert the line number (the
block number) to a block and then fetch the text from that.
To change text we must create a cursor that selects all the text on
the line. Because cursors use document positions, not block numbers
or blocks, we must convert line numbers to blocks then get the
position of the first character of the block. We then "extend" the
selection to the end by computing the end position: the start + the
length of the text on the line. We then uses that cursor to
"insert" the new text, which magically replaces the selected text.
'''
# Get the position of the start and end of the selection.
cursor = self.textCursor()
start_position = cursor.selectionStart()
end_position = cursor.selectionEnd()
# Now convert positions into block (line) numbers
cursor.setPosition(start_position)
start_block = cursor.block().blockNumber()
cursor.setPosition(end_position)
end_block = cursor.block().blockNumber()
def select_block(block_number, curs):
# Note the side effect: 'curs' is changed to select the line
blk = self.document().findBlockByNumber(block_number)
txt = blk.text()
pos = blk.position()
curs.setPosition(pos)
curs.setPosition(pos+len(txt), QTextCursor.KeepAnchor)
return txt
# Check if there is a selection. If not then only Shift-Tab is valid
if start_position == end_position:
if key == Qt.Key_Backtab:
txt = select_block(start_block, cursor)
if txt.startswith('\t'):
# This works because of the side effect in select_block()
cursor.insertText(txt[1:])
cursor.setPosition(start_position-1)
self.setTextCursor(cursor)
ev.accept()
else:
QPlainTextEdit.keyPressEvent(self, ev)
return
# There is a selection so both Tab and Shift-Tab do indenting operations
for bn in range(start_block, end_block+1):
txt = select_block(bn, cursor)
if key == Qt.Key_Backtab:
if txt.startswith('\t'):
cursor.insertText(txt[1:])
if bn == start_block:
start_position -= 1
end_position -= 1
else:
cursor.insertText('\t' + txt)
if bn == start_block:
start_position += 1
end_position += 1
# Restore the selection, adjusted for the added or deleted tabs
cursor.setPosition(start_position)
cursor.setPosition(end_position, QTextCursor.KeepAnchor)
self.setTextCursor(cursor)
ev.accept()
return
QPlainTextEdit.keyPressEvent(self, ev)