<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Urwid graphics widgets
#    Copyright (C) 2004-2007  <NAME>
#
#    This library is free software; you can redistribute it and/or
#    modify it under the terms of the GNU Lesser General Public
#    License as published by the Free Software Foundation; either
#    version 2.1 of the License, or (at your option) any later version.
#
#    This library is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#    Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public
#    License along with this library; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Urwid web site: http://excess.org/urwid/

from urwid.util import decompose_tagmarkup, get_encoding_mode
from urwid.canvas import CompositeCanvas, CanvasJoin, TextCanvas, CanvasCombine
from urwid.widget import WidgetMeta, BoxWidget, FlowWidget, FixedWidget, \
    nocache_widget_render, nocache_widget_render_instance, fixed_size, \
    WidgetWrap, Divider, SolidFill, Text
from urwid.container import Pile, Columns
from urwid.escape import utf8decode
from urwid.display_common import AttrSpec
from urwid.decoration import WidgetDecoration, AttrWrap

class BigText(FixedWidget):
    def __init__(self, markup, font):
        """
        markup -- same as Text widget markup
        font -- instance of a Font class
        """
        self.set_font(font)
        self.set_text(markup)
    
    def set_text(self, markup):
        self.text, self.attrib = decompose_tagmarkup(markup)
        self._invalidate()
    
    def get_text(self):
        """
        Returns (text, attributes).
        """
        return self.text, self.attrib
    
    def set_font(self, font):
        self.font = font
        self._invalidate()
    
    def pack(self, size=None, focus=False):
        rows = self.font.height
        cols = 0
        for c in self.text:
            cols += self.font.char_width(c)
        return cols, rows
    
    def render(self, size, focus=False):
        fixed_size(size) # complain if parameter is wrong
        a = None
        ai = ak = 0
        o = []
        rows = self.font.height
        attrib = self.attrib+[(None,len(self.text))]
        for ch in self.text:
            if not ak:
                a, ak = attrib[ai]
                ai += 1
            ak -= 1
            width = self.font.char_width(ch)
            if not width: 
                # ignore invalid characters
                continue
            c = self.font.render(ch)
            if a is not None:
                c = CompositeCanvas(c)
                c.fill_attr(a)
            o.append((c, None, False, width))
        if o:
            canv = CanvasJoin(o)
        else:
            canv = TextCanvas([""]*rows, maxcol=0, 
                check_width=False)
            canv = CompositeCanvas(canv)
        canv.set_depends([])
        return canv
        

class LineBox(WidgetDecoration, WidgetWrap):
    def __init__(self, original_widget):
        """Draw a line around original_widget."""
        
        tlcorner=None; tline=None; lline=None
        trcorner=None; blcorner=None; rline=None
        bline=None; brcorner=None
        
        def use_attr( a, t ):
            if a is not None:
                t = AttrWrap(t, a)
            return t
            
        tline = use_attr( tline, Divider(utf8decode("─")))
        bline = use_attr( bline, Divider(utf8decode("─")))
        lline = use_attr( lline, SolidFill(utf8decode("│")))
        rline = use_attr( rline, SolidFill(utf8decode("│")))
        tlcorner = use_attr( tlcorner, Text(utf8decode("┌")))
        trcorner = use_attr( trcorner, Text(utf8decode("┐")))
        blcorner = use_attr( blcorner, Text(utf8decode("└")))
        brcorner = use_attr( brcorner, Text(utf8decode("┘")))
        top = Columns([ ('fixed', 1, tlcorner),
            tline, ('fixed', 1, trcorner) ])
        middle = Columns( [('fixed', 1, lline),
            original_widget, ('fixed', 1, rline)], box_columns = [0,2],
            focus_column = 1)
        bottom = Columns([ ('fixed', 1, blcorner),
            bline, ('fixed', 1, brcorner) ])
        pile = Pile([('flow',top),middle,('flow',bottom)],
            focus_item = 1)
        
        WidgetDecoration.__init__(self, original_widget)
        WidgetWrap.__init__(self, pile)


class BarGraphMeta(WidgetMeta):
    """
    Detect subclass get_data() method and dynamic change to
    get_data() method and disable caching in these cases.

    This is for backwards compatibility only, new programs
    should use set_data() instead of overriding get_data().
    """
    def __init__(cls, name, bases, d):
        super(BarGraphMeta, cls).__init__(name, bases, d)

        if "get_data" in d:
            cls.render = nocache_widget_render(cls)
            cls._get_data = cls.get_data
        cls.get_data = property(
            lambda self: self._get_data,
            nocache_bargraph_get_data)

def nocache_bargraph_get_data(self, get_data_fn):
    """
    Disable caching on this bargraph because get_data_fn needs
    to be polled to get the latest data.
    """<commit_msg>Use kwargs lines/edges in LineBox to allow for easy overriding.<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Urwid graphics widgets
#    Copyright (C) 2004-2007  <NAME>
#
#    This library is free software; you can redistribute it and/or
#    modify it under the terms of the GNU Lesser General Public
#    License as published by the Free Software Foundation; either
#    version 2.1 of the License, or (at your option) any later version.
#
#    This library is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#    Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public
#    License along with this library; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Urwid web site: http://excess.org/urwid/

from urwid.util import decompose_tagmarkup, get_encoding_mode
from urwid.canvas import CompositeCanvas, CanvasJoin, TextCanvas, CanvasCombine
from urwid.widget import WidgetMeta, BoxWidget, FlowWidget, FixedWidget, \
    nocache_widget_render, nocache_widget_render_instance, fixed_size, \
    WidgetWrap, Divider, SolidFill, Text
from urwid.container import Pile, Columns
from urwid.escape import utf8decode
from urwid.display_common import AttrSpec
from urwid.decoration import WidgetDecoration, AttrWrap

class BigText(FixedWidget):
    def __init__(self, markup, font):
        """
        markup -- same as Text widget markup
        font -- instance of a Font class
        """
        self.set_font(font)
        self.set_text(markup)
    
    def set_text(self, markup):
        self.text, self.attrib = decompose_tagmarkup(markup)
        self._invalidate()
    
    def get_text(self):
        """
        Returns (text, attributes).
        """
        return self.text, self.attrib
    
    def set_font(self, font):
        self.font = font
        self._invalidate()
    
    def pack(self, size=None, focus=False):
        rows = self.font.height
        cols = 0
        for c in self.text:
            cols += self.font.char_width(c)
        return cols, rows
    
    def render(self, size, focus=False):
        fixed_size(size) # complain if parameter is wrong
        a = None
        ai = ak = 0
        o = []
        rows = self.font.height
        attrib = self.attrib+[(None,len(self.text))]
        for ch in self.text:
            if not ak:
                a, ak = attrib[ai]
                ai += 1
            ak -= 1
            width = self.font.char_width(ch)
            if not width: 
                # ignore invalid characters
                continue
            c = self.font.render(ch)
            if a is not None:
                c = CompositeCanvas(c)
                c.fill_attr(a)
            o.append((c, None, False, width))
        if o:
            canv = CanvasJoin(o)
        else:
            canv = TextCanvas([""]*rows, maxcol=0, 
                check_width=False)
            canv = CompositeCanvas(canv)
        canv.set_depends([])
        return canv
        

class LineBox(WidgetDecoration, WidgetWrap):
    ACS_HLINE = utf8decode("─")
    ACS_VLINE = utf8decode("│")

    ACS_ULCORNER = utf8decode("┌")
    ACS_URCORNER = utf8decode("┐")
    ACS_LLCORNER = utf8decode("└")
    ACS_LRCORNER = utf8decode("┘")

    def __init__(self, original_widget,
                 tlcorner=None, tline=None, lline=None,
                 trcorner=None, blcorner=None, rline=None,
                 bline=None, brcorner=None):
        """Draw a line around original_widget."""

        def use_attr( a, t ):
            if a is not None:
                return a
            else:
                return t

        tline = use_attr( tline, Divider(self.ACS_HLINE))
        bline = use_attr( bline, Divider(self.ACS_HLINE))
        lline = use_attr( lline, SolidFill(self.ACS_VLINE))
        rline = use_attr( rline, SolidFill(self.ACS_VLINE))
        tlcorner = use_attr( tlcorner, Text(self.ACS_ULCORNER))
        trcorner = use_attr( trcorner, Text(self.ACS_URCORNER))
        blcorner = use_attr( blcorner, Text(self.ACS_LLCORNER))
        brcorner = use_attr( brcorner, Text(self.ACS_LRCORNER))
        top = Columns([ ('fixed', 1, tlcorner),
            tline, ('fixed', 1, trcorner) ])
        middle = Columns( [('fixed', 1, lline),
            original_widget, ('fixed', 1, rline)], box_columns = [0,2],
            focus_column = 1)
        bottom = Columns([ ('fixed', 1, blcorner),
            bline, ('fixed', 1, brcorner) ])
        pile = Pile([('flow',top),middle,('flow',bottom)],
            focus_item = 1)

        WidgetDecoration.__init__(self, original_widget)
        WidgetWrap.__init__(self, pile)


class BarGraphMeta(WidgetMeta):
    """
    Detect subclass get_data() method and dynamic change to
    get_data() method and disable caching in these cases.

    This is for backwards compatibility only, new programs
    should use set_data() instead of overriding get_data().
    """
    def __init__(cls, name, bases, d):
        super(BarGraphMeta, cls).__init__(name, bases, d)

        if "get_data" in d:
            cls.render = nocache_widget_render(cls)
            cls._get_data = cls.get_data
        cls.get_data = property(
            lambda self: self._get_data,
            nocache_bargraph_get_data)

def nocache_bargraph_get_data(self, get_data_fn):
    """
    Disable caching on this bargraph because get_data_fn needs
    to be polled to get the latest data.
    """
{'fraction_non_alphanumeric': 0.09959183673469388, 'fraction_numerical': 0.008707482993197279, 'mean_word_length': 2.2962630792227205, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '610543', 'n_tokens_mistral': 3452, 'n_tokens_neox': 3283, 'n_words': 985}