mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
efa95ceb0b
commit
7a04279803
@ -430,6 +430,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
s = gprefs.get('template_editor_break_on_print', False)
|
s = gprefs.get('template_editor_break_on_print', False)
|
||||||
self.go_button.setEnabled(s)
|
self.go_button.setEnabled(s)
|
||||||
self.remove_all_button.setEnabled(s)
|
self.remove_all_button.setEnabled(s)
|
||||||
|
self.set_all_button.setEnabled(s)
|
||||||
self.toggle_button.setEnabled(s)
|
self.toggle_button.setEnabled(s)
|
||||||
self.breakpoint_line_box.setEnabled(s)
|
self.breakpoint_line_box.setEnabled(s)
|
||||||
self.breakpoint_line_box_label.setEnabled(s)
|
self.breakpoint_line_box_label.setEnabled(s)
|
||||||
@ -440,6 +441,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
self.set_up_font_boxes()
|
self.set_up_font_boxes()
|
||||||
self.toggle_button.clicked.connect(self.toggle_button_pressed)
|
self.toggle_button.clicked.connect(self.toggle_button_pressed)
|
||||||
self.remove_all_button.clicked.connect(self.remove_all_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.load_button.clicked.connect(self.load_template)
|
||||||
self.save_button.clicked.connect(self.save_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
|
gprefs['template_editor_break_on_print'] = new_state != 0
|
||||||
self.go_button.setEnabled(new_state != 0)
|
self.go_button.setEnabled(new_state != 0)
|
||||||
self.remove_all_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.toggle_button.setEnabled(new_state != 0)
|
||||||
self.breakpoint_line_box.setEnabled(new_state != 0)
|
self.breakpoint_line_box.setEnabled(new_state != 0)
|
||||||
self.breakpoint_line_box_label.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):
|
def remove_all_button_pressed(self):
|
||||||
self.textbox.set_clicked_line_numbers(set())
|
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):
|
def toggle_button_pressed(self):
|
||||||
ln = self.breakpoint_line_box.value()
|
ln = self.breakpoint_line_box.value()
|
||||||
if ln > self.textbox.blockCount():
|
if ln > self.textbox.blockCount():
|
||||||
|
@ -170,7 +170,9 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0" colspan="4">
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
<widget class="QLabel">
|
<widget class="QLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>T&emplate:</string>
|
<string>T&emplate:</string>
|
||||||
@ -183,8 +185,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1" colspan="3">
|
|
||||||
<layout class="QHBoxLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -232,6 +232,9 @@ you the value as well as all the local variables</p></string>
|
|||||||
<iconset resource="../../../../resources/images.qrc">
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
<normaloff>:/images/sync-right.png</normaloff>:/images/sync-right.png</iconset>
|
<normaloff>:/images/sync-right.png</normaloff>:/images/sync-right.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">padding: 5; padding-left: 1;</string>
|
||||||
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>If 'Enable breakpoints' is checked then click this button to run your template</string>
|
<string>If 'Enable breakpoints' is checked then click this button to run your template</string>
|
||||||
</property>
|
</property>
|
||||||
@ -287,6 +290,9 @@ you the value as well as all the local variables</p></string>
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Toggle</string>
|
<string>&Toggle</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">padding: 5; padding-left: 1;</string>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../../../resources/images.qrc">
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
<normaloff>:/images/swap.png</normaloff>:/images/swap.png</iconset>
|
<normaloff>:/images/swap.png</normaloff>:/images/swap.png</iconset>
|
||||||
@ -314,6 +320,9 @@ you the value as well as all the local variables</p></string>
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Remove all</string>
|
<string>&Remove all</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">padding: 5; padding-left: 1;</string>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../../../resources/images.qrc">
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
<normaloff>:/images/list_remove.png</normaloff>:/images/list_remove.png</iconset>
|
<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</p></string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="set_all_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>&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>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="4">
|
<item row="2" column="0" colspan="4">
|
||||||
@ -590,13 +616,26 @@ you the value as well as all the local variables</p></string>
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="save_button">
|
<widget class="QToolButton" name="save_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Save</string>
|
<string>Sa&ve</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Save the template in a file</string>
|
<string>Save the template in a file</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -8,7 +8,8 @@ License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
from qt.core import (
|
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
|
from calibre.gui2.tweak_book.editor.text import LineNumbers
|
||||||
@ -91,6 +92,9 @@ class CodeEditor(QPlainTextEdit):
|
|||||||
self.clicked_line_numbers.add(line)
|
self.clicked_line_numbers.add(line)
|
||||||
self.update(self.line_number_area.geometry())
|
self.update(self.line_number_area.geometry())
|
||||||
|
|
||||||
|
def number_of_lines(self):
|
||||||
|
return self.blockCount()
|
||||||
|
|
||||||
def set_clicked_line_numbers(self, new_set):
|
def set_clicked_line_numbers(self, new_set):
|
||||||
self.clicked_line_numbers = new_set
|
self.clicked_line_numbers = new_set
|
||||||
self.update(self.line_number_area.geometry())
|
self.update(self.line_number_area.geometry())
|
||||||
@ -131,3 +135,86 @@ class CodeEditor(QPlainTextEdit):
|
|||||||
top = bottom
|
top = bottom
|
||||||
bottom = top + int(self.blockBoundingRect(block).height())
|
bottom = top + int(self.blockBoundingRect(block).height())
|
||||||
num += 1
|
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)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user