Here is the current version of the script, after some cleanup and 
reorganization, and one change to get it to work under PyQt6.11 as well as 
PyQt5.

On Thursday, August 26, 2021 at 6:49:14 PM UTC-4 [email protected] wrote:

> I now have reasonable colors for highlighting of very dark and very light 
> themes, as well as for no-theme color schemes that forgot to set the 
> background color.
>
> On Thursday, August 26, 2021 at 5:25:26 PM UTC-4 [email protected] wrote:
>
>> @ekr asked me to see about getting Leo's body editor to highlight the 
>> current line.  This was in response to a request in Issue 2150 
>> <https://github.com/leo-editor/leo-editor/issues/2150>.  I've made some 
>> progress, which I report here.  I'd say it's about 3/4 of the way there.
>>
>> I have a working script that, when run, highlights the cursor line in the 
>> visible node's body.  Here's what is left to do:
>>
>> 1. The highlight color isn't visible for very dark or very light 
>> background colors.  Currently the highlight color is a modification of the 
>> text background color as specified in the theme's stylesheet.  The way this 
>> color is arrived at needs to be improved .  And I'm not yet sure how to 
>> handle the case where no theme at all is in use (some people have tweaked 
>> Leo's colors without using a theme).
>>
>> The highlight color scheme works well with the three 
>> tbp_xxx_solarized.leo themes.
>>
>> 2. The code needs to have a proper home.  Presumably this will be in the 
>> qt_text.py plugin.
>>
>> 3. The code needs to be hooked up to the body's cursor events so that the 
>> highlight code knows that it has to change lines.
>>
>> Also, as a longer term matter, the code does not use any wrappers or 
>> abstractions, so it will only work for Qt-based Guis.  This can be 
>> addressed later, if it appears that there might be a viable non-Qt Gui 
>> version of Leo.
>>
>> I've attached the current version of the code.  Open it in Leo.  Select a 
>> line in the top node.  Run the script by pressing CTRL-b.  The current line 
>> should highlight, although you may not be able to see it if you are using a 
>> very dark or light theme, including Leo's default theme.  Put the cursor on 
>> a different line in the same body.  Press CTRL-b again.  The highlight 
>> should shift to the new cursor line.
>>
>> Please let me know if you find any problems (apart from the actual 
>> highlight color).
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/01ea5c1f-1b8a-40cf-abe6-6ea24b543dfen%40googlegroups.com.
<?xml version="1.0" encoding="utf-8"?>
<!-- Created by Leo: http://leoeditor.com/leo_toc.html -->
<leo_file xmlns:leo="http://leoeditor.com/namespaces/leo-python-editor/1.1"; >
<leo_header file_format="2"/>
<vnodes>
<v t="tom.20210825084838.1"><vh>Highlight Current Line</vh>
<v t="tom.20210826153820.1"><vh>highlightCurrentLine</vh>
<v t="tom.20210826153508.1"><vh>parse_css</vh></v>
<v t="tom.20210827002358.1"><vh>assign_bg</vh></v>
<v t="tom.20210827091401.1"><vh>calc_bg</vh></v>
</v>
</v>
</vnodes>
<tnodes>
<t tx="tom.20210825084838.1">@language python
from leo.core.leoQt import QtGui, QtWidgets
QColor = QtGui.QColor
QTextFormat = QtGui.QTextFormat
QTextEdit = QtWidgets.QTextEdit
FullWidthSelection = 0x06000 # works for both Qt5 and Qt6

w = c.frame.body.wrapper
editor = w.widget

ssm = c.styleSheetManager
sheet = ssm.expand_css_constants(c.active_stylesheet)

@others

highlightCurrentLine(editor, sheet)</t>
<t tx="tom.20210826153508.1">@language python
def parse_css(css_string, clas=''):
    """Extract colors from a css stylesheet string. 
    
    This is an extremely simple-minded function. It assumes
    that no quotation marks are being used, and that the
    first block in braces with the name clas is the controlling
    css for our widget.
    
    Returns a tuple of strings (foregound, background).
    """
    # Get first block with name matching "clas'
    block = css_string.split(clas, 1)
    block = block[1].split('{', 1)
    block = block[1].split('}', 1)

    # Split into styles separated by ";"
    styles = block[0].split(';')

    # Split into fields separated by ":"
    fields = [style.split(':') for style in styles if style.strip()]

    # Only get fields whose names are "color" and "background"
    color = bg = ''
    for style, val in fields:
        style = style.strip()
        if style == 'color':
            color = val.strip()
        elif style == 'background':
            bg = val.strip()
    return color, bg

</t>
<t tx="tom.20210826153820.1">@language python
def highlightCurrentLine(ed, css):
    """Highlight cursor line.
    
    Based in part on code from
    https://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html
    
    ARGUMENTS
    ed -- current editor widget
    css -- css stylesheet string
    """
    fg, bg = parse_css(css, 'QTextEdit')
    if not bg:
        bg = assign_bg(fg)
    bg_color = calc_bg(bg)

    selection = QTextEdit.ExtraSelection()
    selection.format.setBackground(bg_color)
    selection.format.setProperty(FullWidthSelection, True)
    selection.cursor = ed.textCursor()
    selection.cursor.clearSelection()

    ed.setExtraSelections([selection])

</t>
<t tx="tom.20210827002358.1">@language python
def assign_bg(fg):
    # If fg or bg colors are missing, assign
    # reasonable values.  Can happen with incorrectly
    # constructed themes, or no-theme color schemes.
    if not fg:
        fg = 'black' # QTextEdit default
        bg = 'white' # QTextEdit default
    if fg == 'black':
        bg = 'white' # QTextEdit default
    else:
        fg_color = QColor(fg)
        h, s, v, a = fg_color.getHsv()
        if v &lt; 128: # dark foreground
            bg = 'white'
        else:
            bg = 'black'
    return bg
</t>
<t tx="tom.20210827091401.1">@language python
def calc_bg(bg):
    """Return the background color for highlighting.
    
    ARGUMENT
    bg -- the string background stylesheet value
    
    RETURNS
    a QColor object for the highlight color
    """
    bg_color = QColor(bg)
    h, s, v, a = bg_color.getHsv()

    if v &lt; 24:
        v = 50
        bg_color.setHsv(h, s, v, a)
    elif v &gt; 240:
        v = 220
        bg_color.setHsv(h, s, v, a)
    elif v &lt; 128:
        bg_color = bg_color.lighter(130)
    else:
        bg_color = bg_color.darker(120)

    return bg_color
</t>
</tnodes>
</leo_file>

Reply via email to