Example #1
0
    def Draw(self, grid, dc, rect, row):
        rect.y -= 1
        if row == grid.actions.cursor[0]:
            color = get_color(config["selection_color"])
        else:
            color = get_color(config["label_color"])

        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.SetBrush(wx.Brush(color))
        dc.DrawRectangleRect(rect)
        hAlign, vAlign = grid.GetRowLabelAlignment()
        text = grid.GetRowLabelValue(row)
        if row != grid.actions.cursor[0]:
            self.DrawBorder(grid, dc, rect)
        self.DrawText(grid, dc, rect, text, hAlign, vAlign)
Example #2
0
    def Draw(self, grid, dc, rect, row):
        rect.y -= 1
        if row == grid.actions.cursor[0]:
            color = get_color(config["selection_color"])
        else:
            color = get_color(config["label_color"])

        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.SetBrush(wx.Brush(color))
        dc.DrawRectangleRect(rect)
        hAlign, vAlign = grid.GetRowLabelAlignment()
        text = grid.GetRowLabelValue(row)
        if row != grid.actions.cursor[0]:
            self.DrawBorder(grid, dc, rect)
        self.DrawText(grid, dc, rect, text, hAlign, vAlign)
Example #3
0
    def __init__(self, parent, main_window, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)

        try:
            self.SetBackgroundColour(get_color(wx.SYS_COLOUR_FRAMEBK))
        except AttributeError:
            # Does not work on wx 2.x
            pass
        self.parent = parent
        self.main_window = main_window

        style = wx.TE_PROCESS_ENTER | wx.TE_MULTILINE
        self.entry_line = EntryLine(self, main_window, style=style)
        self.selection_toggle_button = \
            wx.ToggleButton(self, -1, size=(24, -1), label=u"\u25F0")

        tooltip = wx.ToolTip(_("Toggles link insertion mode."))
        self.selection_toggle_button.SetToolTip(tooltip)
        self.selection_toggle_button.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggle)

        if not is_gtk():
            # TODO: Selections still do not work right on Windows
            self.selection_toggle_button.Disable()

        self.__do_layout()
Example #4
0
    def __init__(self, parent, main_window, no_tabs):
        self.parent = parent
        self.main_window = main_window
        self.no_tabs = no_tabs

        IntCtrl.__init__(self,
                         parent,
                         allow_long=True,
                         style=wx.NO_BORDER,
                         default_color=get_color(config["text_color"]))

        self.last_change_s = time.clock()

        tipmsg = _("For switching tables enter the table number or "
                   "use the mouse wheel.")
        self.SetToolTip(wx.ToolTip(tipmsg))

        # State for preventing to post GridActionTableSwitchMsg
        self.switching = False
        self.cursor_pos = 0

        self.Bind(EVT_INT, self.OnInt)
        self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
        self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
        self.main_window.Bind(self.EVT_CMD_RESIZE_GRID, self.OnResizeGrid)
        self.main_window.Bind(self.EVT_CMD_TABLE_CHANGED, self.OnTableChanged)
Example #5
0
    def OnDrawBackground(self, dc, rect, item, flags):
        """Called for drawing the background area of each item

        Overridden from OwnerDrawnComboBox

        """

        # If the item is selected, or its item is even,
        # or if we are painting the combo control itself
        # then use the default rendering.

        if (item & 1 == 0 or flags & (wx.combo.ODCB_PAINTING_CONTROL
                                      | wx.combo.ODCB_PAINTING_SELECTED)):
            try:
                wx.combo.OwnerDrawnComboBox.OnDrawBackground(
                    self, dc, rect, item, flags)
            finally:
                return

        # Otherwise, draw every other background with
        # different color.

        bg_color = get_color(wx.SYS_COLOUR_BACKGROUND)
        dc.SetBrush(wx.Brush(bg_color))
        dc.SetPen(wx.Pen(bg_color))
        dc.DrawRectangleRect(rect)
Example #6
0
    def OnDrawItem(self, dc, rect, item, flags):

        if item == wx.NOT_FOUND:
            return

        default_font_size = get_default_font().GetPointSize()

        context = wx.lib.wxcairo.ContextFromDC(dc)

        context.rectangle(*rect)
        context.clip()

        pangocairo_context = pangocairo.CairoContext(context)
        pangocairo_context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)

        layout = pangocairo_context.create_layout()
        fontname = self.GetString(item)
        font = pango.FontDescription("{} {}".format(fontname,
                                                    default_font_size))
        layout.set_font_description(font)

        layout.set_text(fontname)

        color = tuple(
            [c / 255.0 for c in get_color(config["text_color"]).Get()])
        context.set_source_rgb(*color)

        height = layout.get_pixel_extents()[1][3]

        y_adjust = int((rect.height - height) / 2.0)
        context.translate(rect.x + 3, rect.y + y_adjust)

        pangocairo_context.update_layout(layout)
        pangocairo_context.show_layout(layout)
Example #7
0
    def __init__(self, parent, main_window, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)

        try:
            self.SetBackgroundColour(get_color(wx.SYS_COLOUR_FRAMEBK))
        except AttributeError:
            # Does not work on wx 2.x
            pass
        self.parent = parent
        self.main_window = main_window

        style = wx.TE_PROCESS_ENTER | wx.TE_MULTILINE
        self.entry_line = EntryLine(self, main_window, style=style)
        self.selection_toggle_button = \
            wx.ToggleButton(self, -1, size=(24, -1), label=u"\u25F0")

        tooltip = wx.ToolTip(_("Toggles link insertion mode."))
        self.selection_toggle_button.SetToolTip(tooltip)
        self.selection_toggle_button.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggle)

        if not is_gtk():
            # TODO: Selections still do not work right on Windows
            self.selection_toggle_button.Disable()

        self.__do_layout()
Example #8
0
    def OnDrawBackground(self, dc, rect, item, flags):
        """Called for drawing the background area of each item

        Overridden from OwnerDrawnComboBox

        """

        # If the item is selected, or its item is even,
        # or if we are painting the combo control itself
        # then use the default rendering.

        if (item & 1 == 0 or flags & (wx.combo.ODCB_PAINTING_CONTROL |
                                      wx.combo.ODCB_PAINTING_SELECTED)):
            try:
                wx.combo.OwnerDrawnComboBox.OnDrawBackground(self, dc,
                                                             rect, item, flags)
            finally:
                return

        # Otherwise, draw every other background with
        # different color.

        bg_color = get_color(config["label_color"])
        dc.SetBrush(wx.Brush(bg_color))
        dc.SetPen(wx.Pen(bg_color))
        dc.DrawRectangleRect(rect)
Example #9
0
    def Draw(self, grid, dc, rect, col):
        if col == grid.actions.cursor[1]:
            rect.x += 1
            rect.width -= 1
            pen_color = get_color(wx.SYS_COLOUR_MENUHILIGHT)
            pen = wx.Pen(pen_color, 2, wx.SOLID)
            dc.SetPen(pen)
        else:
            dc.SetPen(wx.TRANSPARENT_PEN)

        color = get_color(wx.SYS_COLOUR_BACKGROUND)
        dc.SetBrush(wx.Brush(color))
        dc.DrawRectangleRect(rect)
        hAlign, vAlign = grid.GetColLabelAlignment()
        text = grid.GetColLabelValue(col)
        self.DrawBorder(grid, dc, rect)
        self.DrawText(grid, dc, rect, text, hAlign, vAlign)
Example #10
0
    def Draw(self, grid, dc, rect, col):
        if col == grid.actions.cursor[1]:
            rect.x += 1
            rect.width -= 1
            pen_color = get_color(wx.SYS_COLOUR_MENUHILIGHT)
            pen = wx.Pen(pen_color, 2, wx.SOLID)
            dc.SetPen(pen)
        else:
            dc.SetPen(wx.TRANSPARENT_PEN)

        color = get_color(wx.SYS_COLOUR_MENUBAR)
        dc.SetBrush(wx.Brush(color))
        dc.DrawRectangleRect(rect)
        hAlign, vAlign = grid.GetColLabelAlignment()
        text = grid.GetColLabelValue(col)
        self.DrawBorder(grid, dc, rect)
        self.DrawText(grid, dc, rect, text, hAlign, vAlign)
Example #11
0
    def Draw(self, grid, dc, rect, row):

        if row == grid.actions.cursor[0]:
            rect.y += 1
            rect.height -= 1
            pen_color = get_color(wx.SYS_COLOUR_MENUHILIGHT)
            pen = wx.Pen(pen_color, 2, wx.SOLID)
            dc.SetPen(pen)
        else:
            dc.SetPen(wx.TRANSPARENT_PEN)

        color = get_color(wx.SYS_COLOUR_MENUBAR)
        dc.SetBrush(wx.Brush(color))
        dc.DrawRectangleRect(rect)
        hAlign, vAlign = grid.GetRowLabelAlignment()
        text = grid.GetRowLabelValue(row)
        self.DrawBorder(grid, dc, rect)
        self.DrawText(grid, dc, rect, text, hAlign, vAlign)
Example #12
0
    def update_cursor(self, dc, grid, row, col):
        """Whites out the old cursor and draws the new one"""

        old_row, old_col = self.old_cursor_row_col

        bgcolor = get_color(config["background_color"])

        self._draw_cursor(dc, grid, old_row, old_col,
                          pen=wx.Pen(bgcolor), brush=wx.Brush(bgcolor))
        self._draw_cursor(dc, grid, row, col)
Example #13
0
    def update_cursor(self, dc, grid, row, col):
        """Whites out the old cursor and draws the new one"""

        old_row, old_col = self.old_cursor_row_col

        bgcolor = get_color(config["background_color"])

        self._draw_cursor(dc, grid, old_row, old_col,
                          pen=wx.Pen(bgcolor), brush=wx.Brush(bgcolor))
        self._draw_cursor(dc, grid, row, col)
Example #14
0
    def draw_background(self, dc):
        """Draws the background of the background"""

        attr = self.data_array.cell_attributes[self.key]

        if self.selection:
            color = get_color(config["selection_color"])
        else:
            rgb = attr["bgcolor"]
            color = wx.Colour()
            color.SetRGB(rgb)
        bgbrush = wx.Brush(color, wx.SOLID)
        dc.SetBrush(bgbrush)
        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.DrawRectangle(0, 0, self.rect.width, self.rect.height)

        # Draw frozen cell background rect
        if self.grid._view_frozen and attr['frozen']:
            style = wx.FDIAGONAL_HATCH
            freeze_color = get_color(config['freeze_color'])
            freeze_brush = wx.Brush(freeze_color, style)
            dc.SetBrush(freeze_brush)
            dc.DrawRectangle(0, 0, self.rect.width, self.rect.height)
Example #15
0
    def draw_background(self, dc):
        """Draws the background of the background"""

        attr = self.data_array.cell_attributes[self.key]

        if self.selection:
            color = get_color(config["selection_color"])
        else:
            rgb = attr["bgcolor"]
            color = wx.Colour()
            color.SetRGB(rgb)
        bgbrush = wx.Brush(color, wx.SOLID)
        dc.SetBrush(bgbrush)
        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.DrawRectangle(0, 0, self.rect.width, self.rect.height)

        # Draw frozen cell background rect
        if self.grid._view_frozen and attr['frozen']:
            style = wx.FDIAGONAL_HATCH
            freeze_color = get_color(config['freeze_color'])
            freeze_brush = wx.Brush(freeze_color, style)
            dc.SetBrush(freeze_brush)
            dc.DrawRectangle(0, 0, self.rect.width, self.rect.height)
Example #16
0
    def __init__(self, parent, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)
        try:
            self.SetBackgroundColour(get_color(wx.SYS_COLOUR_FRAMEBK))
        except AttributeError:
            # Does not work on wx 2.x
            pass

        self.parent = parent
        # Panel with EntryLine and button
        self.entry_line_panel = EntryLinePanel(self, parent, style=wx.NO_BORDER)

        # IntCtrl for table choice
        self.table_choice = TableChoiceIntCtrl(self, parent, config["grid_tables"])

        self.__do_layout()
Example #17
0
        def _get_color_idx(color):
            """Converts wx.Colour to Excel color index

            Differs from self.color2idx because it maps
            the pyspread default grid color to the Excel default color

            Parameters
            ----------
            color: wx.Colour
            \tColor to be converted

            """

            if color == get_color(config["grid_color"]):
                return DEFAULT_COLOR_IDX
            else:
                return self.color2idx(*color.Get())
Example #18
0
        def _get_color_idx(color):
            """Converts wx.Colour to Excel color index

            Differs from self.color2idx because it maps
            the pyspread default grid color to the Excel default color

            Parameters
            ----------
            color: wx.Colour
            \tColor to be converted

            """

            if color == get_color(config["grid_color"]):
                return DEFAULT_COLOR_IDX
            else:
                return self.color2idx(*color.Get())
Example #19
0
    def __init__(self, parent, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)
        try:
            self.SetBackgroundColour(get_color(wx.SYS_COLOUR_FRAMEBK))
        except AttributeError:
            # Does not work on wx 2.x
            pass

        self.parent = parent
        # Panel with EntryLine and button
        self.entry_line_panel = EntryLinePanel(self, parent,
                                               style=wx.NO_BORDER)

        # IntCtrl for table choice
        self.table_choice = TableChoiceIntCtrl(self, parent,
                                               config["grid_tables"])

        self.__do_layout()
Example #20
0
    def __init__(self, parent, main_window, no_tabs):
        self.parent = parent
        self.main_window = main_window
        self.no_tabs = no_tabs

        IntCtrl.__init__(self, parent, allow_long=True, style=wx.NO_BORDER,
                         default_color=get_color(config["text_color"]))

        self.last_change_s = time.clock()

        tipmsg = _("For switching tables enter the table number or "
                   "use the mouse wheel.")
        self.SetToolTip(wx.ToolTip(tipmsg))

        # State for preventing to post GridActionTableSwitchMsg
        self.switching = False
        self.cursor_pos = 0

        self.Bind(EVT_INT, self.OnInt)
        self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
        self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
        self.main_window.Bind(self.EVT_CMD_RESIZE_GRID, self.OnResizeGrid)
        self.main_window.Bind(self.EVT_CMD_TABLE_CHANGED, self.OnTableChanged)
Example #21
0
    def OnDrawItem(self, dc, rect, item, flags):

        if item == wx.NOT_FOUND:
            return

        default_font_size = get_default_font().GetPointSize()

        context = wx.lib.wxcairo.ContextFromDC(dc)

        context.rectangle(*rect)
        context.clip()

        pangocairo_context = pangocairo.CairoContext(context)
        pangocairo_context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)

        layout = pangocairo_context.create_layout()
        fontname = self.GetString(item)
        font = pango.FontDescription("{} {}".format(fontname,
                                                    default_font_size))
        layout.set_font_description(font)

        layout.set_text(fontname)

        color = tuple([c / 255.0 for c in get_color(config["text_color"]).Get()])
        context.set_source_rgb(*color)

        height = layout.get_pixel_extents()[1][3]

        y_adjust = int((rect.height - height) / 2.0)
        context.save()
        context.translate(rect.x + 3, rect.y + y_adjust)

        pangocairo_context.update_layout(layout)
        pangocairo_context.show_layout(layout)

        context.restore()
Example #22
0
    def _do_layout(self):
        """Adds widgets to the aui manager and controls the layout"""

        # Set background color for the toolbar via the manager
        ap = self._mgr.GetArtProvider()
        ap.SetColour(aui.AUI_DOCKART_BACKGROUND_GRADIENT_COLOUR,
                     get_color(config["background_color"]))

        # Add the toolbars to the manager

        self._mgr.AddPane(self.main_toolbar, aui.AuiPaneInfo().
                          Name("main_window_toolbar").
                          Caption(_("Main toolbar")).
                          ToolbarPane().Top().Row(0))

        self._mgr.AddPane(self.find_toolbar, aui.AuiPaneInfo().
                          Name("find_toolbar").Caption(_("Find toolbar")).
                          ToolbarPane().Top().Row(0))

        self._mgr.AddPane(self.attributes_toolbar, aui.AuiPaneInfo().
                          Name("attributes_toolbar").
                          Caption(_("Format toolbar")).
                          ToolbarPane().Top().Row(1))

        self._mgr.AddPane(self.macro_toolbar, aui.AuiPaneInfo().
                          Name("macro_toolbar").Caption(_("Macro toolbar")).
                          Gripper(True).ToolbarPane().Top().Row(1))

        self._mgr.AddPane(self.widget_toolbar, aui.AuiPaneInfo().
                          Name("widget_toolbar").Caption(_("Widget toolbar")).
                          Gripper(True).ToolbarPane().Top().Row(1))

        self._mgr.AddPane(self.entry_line_panel, aui.AuiPaneInfo().
                          Name("entry_line_panel").Caption(_("Entry line")).
                          Gripper(False).CenterPane().Top().Row(2).
                          BestSize(400, 30).PaneBorder(False))

        self._mgr.AddPane(self.table_list_panel, aui.AuiPaneInfo().
                          Name("table_list_panel").Caption(_("Table")).
                          CenterPane().Left().BestSize(50, 300))

        self._mgr.AddPane(self.macro_panel, aui.AuiPaneInfo().
                          Name("macro_panel").Caption(_("Macro panel")).
                          Gripper(False).CenterPane().Right().
                          BestSize(200, 200))

        # Load perspective from config
        window_layout = config["window_layout"]

        if window_layout:
            self._mgr.LoadPerspective(window_layout)

        # Add the main grid
        self._mgr.AddPane(self.grid, aui.AuiPaneInfo().
                          Name("grid").Caption(_("Main grid")).CentrePane())

        # Tell the manager to 'commit' all the changes just made
        self._mgr.Update()
        self._mgr.GetPane("attributes_toolbar")
        self._mgr.Update()

        self._set_menu_toggles()

        # Set initial size to config value
        self.SetInitialSize(config["window_size"])
        self.SetMinSize((10, 10))

        # TODO: Set window position fix --> different positions for
        # different window managers prevent this

        self.SetPosition(config["window_position"])
Example #23
0
class CellAttributes(list):
    """Stores cell formatting attributes in a list of 3 - tuples

    The first element of each tuple is a Selection.
    The second element is the table
    The third element is a dict of attributes that are altered.

    The class provides attribute read access to single cells via __getitem__
    Otherwise it behaves similar to a list.

    The following methods mave been made undoable:
    * __setitem__
    * append

    List methods that may alter the list have been removed

    """
    def __init__(self, *args, **kwargs):
        self.__add__ = None
        self.__delattr__ = None
        self.__delitem__ = None
        self.__delslice__ = None
        self.__iadd__ = None
        self.__imul__ = None
        self.__rmul__ = None
        self.__setattr__ = None
        self.__setslice__ = None
        self.insert = None
        self.pop = None
        self.remove = None
        self.reverse = None
        self.sort = None

    default_cell_attributes = {
        "borderwidth_bottom": 1,
        "borderwidth_right": 1,
        "bordercolor_bottom": get_color(config["grid_color"]).GetRGB(),
        "bordercolor_right": get_color(config["grid_color"]).GetRGB(),
        "bgcolor": get_color(config["background_color"]).GetRGB(),
        "textfont": get_font_string(config["font"]),
        "pointsize": 10,
        "fontweight": wx.NORMAL,
        "fontstyle": wx.NORMAL,
        "textcolor": get_color(config["text_color"]).GetRGB(),
        "underline": False,
        "strikethrough": False,
        "locked": False,
        "angle": 0.0,
        "column-width": 75,
        "row-height": 26,
        "vertical_align": "top",
        "justification": "left",
        "frozen": False,
        "merge_area": None,
        "markup": False,
        "button_cell": False,
        "panel_cell": False,
        "video_volume": None,
    }

    # Cache for __getattr__ maps key to tuple of len and attr_dict

    _attr_cache = {}
    _table_cache = {}

    @undoable
    def append(self, value):
        list.append(self, value)
        self._attr_cache.clear()
        self._table_cache.clear()

        yield "append"

        # Undo actions

        list.pop(self)
        self._attr_cache.clear()
        self._table_cache.clear()

    def __getitem__(self, key):
        """Returns attribute dict for a single key"""

        assert not any(type(key_ele) is SliceType for key_ele in key)

        if key in self._attr_cache:
            cache_len, cache_dict = self._attr_cache[key]

            # Use cache result only if no new attrs have been defined
            if cache_len == len(self):
                return cache_dict

        # Update table cache if it is outdated (e.g. when creating a new grid)
        if len(self) != self._len_table_cache():
            self._update_table_cache()

        row, col, tab = key

        result_dict = copy(self.default_cell_attributes)

        try:
            for selection, attr_dict in self._table_cache[tab]:
                if (row, col) in selection:
                    result_dict.update(attr_dict)
        except KeyError:
            pass

        # Upddate cache with current length and dict
        self._attr_cache[key] = (len(self), result_dict)

        return result_dict

    @undoable
    def __setitem__(self, key, value):
        """Undoable version of list.__setitem__"""

        try:
            old_value = list.__getitem__(self, key)
        except IndexError:
            old_value = None

        list.__setitem__(self, key, value)

        self._attr_cache.clear()
        self._table_cache.clear()

        yield "__setitem__"

        if old_value is None:
            self.pop(key)
        else:
            list.__setitem__(self, key, old_value)

        self._attr_cache.clear()
        self._table_cache.clear()

    def _len_table_cache(self):
        """Returns the length of the table cache"""

        length = 0

        for table in self._table_cache:
            length += len(self._table_cache[table])

        return length

    def _update_table_cache(self):
        """Clears and updates the table cache to be in sync with self"""

        self._table_cache.clear()
        for sel, tab, val in self:
            try:
                self._table_cache[tab].append((sel, val))
            except KeyError:
                self._table_cache[tab] = [(sel, val)]

        assert len(self) == self._len_table_cache()

    def get_merging_cell(self, key):
        """Returns key of cell that merges the cell key

        or None if cell key not merged

        Parameters
        ----------
        key: 3-tuple of Integer
        \tThe key of the cell that is merged

        """

        row, col, tab = key

        # Is cell merged
        merge_area = self[key]["merge_area"]

        if merge_area:
            return merge_area[0], merge_area[1], tab
Example #24
0
    def __init__(self, main_window, *args, **kwargs):
        S = kwargs.pop("S")

        self.main_window = main_window

        self._states()

        self.interfaces = GuiInterfaces(self.main_window)

        if S is None:
            dimensions = kwargs.pop("dimensions")
        else:
            dimensions = S.shape
            kwargs.pop("dimensions")

        wx.grid.Grid.__init__(self, main_window, *args, **kwargs)
        glr.GridWithLabelRenderersMixin.__init__(self)

        self.SetDefaultCellBackgroundColour(
            get_color(config["background_color"]))

        # Cursor position on entering selection mode
        self.sel_mode_cursor = None

        # Set multi line editor
        self.SetDefaultEditor(GridCellEditor(main_window))

        # Create new grid
        if S is None:
            self.code_array = CodeArray(dimensions)
            post_command_event(self, self.GridActionNewMsg, shape=dimensions)
        else:
            self.code_array = S

        _grid_table = GridTable(self, self.code_array)
        self.SetTable(_grid_table, True)

        # Grid renderer draws the grid
        self.grid_renderer = GridRenderer(self.code_array)
        self.SetDefaultRenderer(self.grid_renderer)

        self.SetDefaultRowLabelRenderer(RowLabelRenderer())
        self.SetDefaultColLabelRenderer(ColLabelRenderer())

        # Context menu for quick access of important functions
        self.contextmenu = ContextMenu(parent=self)

        # Handler classes contain event handler methods
        self.handlers = GridEventHandlers(self)
        self.cell_handlers = GridCellEventHandlers(self)

        # Grid actions
        self.actions = AllGridActions(self)

        # Layout and bindings
        self._layout()
        self._bind()

        # Update toolbars
        self.update_entry_line()
        self.update_attribute_toolbar()

        # Focus on grid so that typing can start immediately
        self.SetFocus()
Example #25
0
    def _draw_cursor(self, dc, grid, row, col,
                     pen=None, brush=None):
        """Draws cursor as Rectangle in lower right corner"""

        # If in full screen mode draw no cursor
        if grid.main_window.IsFullScreen():
            return

        key = row, col, grid.current_table
        rect = grid.CellToRect(row, col)
        rect = self.get_merged_rect(grid, key, rect)

        # Check if cell is invisible
        if rect is None:
            return

        size = self.get_zoomed_size(1.0)

        caret_length = int(min([rect.width, rect.height]) / 5.0)

        color = get_color(config["text_color"])
        if pen is None:
          pen = wx.Pen(color)
        if brush is None:
          brush = wx.Brush(color)

        pen.SetWidth(size)

        # Inner right and lower borders
        border_left = rect.x + size - 1
        border_right = rect.x + rect.width - size - 1
        border_upper = rect.y + size - 1
        border_lower = rect.y + rect.height - size - 1

        points_lr = [
            (border_right, border_lower - caret_length),
            (border_right, border_lower),
            (border_right - caret_length, border_lower),
            (border_right, border_lower),
        ]

        points_ur = [
            (border_right, border_upper + caret_length),
            (border_right, border_upper),
            (border_right - caret_length, border_upper),
            (border_right, border_upper),
        ]

        points_ul = [
            (border_left, border_upper + caret_length),
            (border_left, border_upper),
            (border_left + caret_length, border_upper),
            (border_left, border_upper),
        ]

        points_ll = [
            (border_left, border_lower - caret_length),
            (border_left, border_lower),
            (border_left + caret_length, border_lower),
            (border_left, border_lower),
        ]

        point_list = [points_lr, points_ur, points_ul, points_ll]

        dc.DrawPolygonList(point_list, pens=pen, brushes=brush)

        self.old_cursor_row_col = row, col
Example #26
0
class CellAttributes(list):
    """Stores cell formatting attributes in a list of 3 - tuples

    The first element of each tuple is a Selection.
    The second element is the table
    The third element is a dict of attributes that are altered.

    The class provides attribute read access to single cells via __getitem__
    Otherwise it behaves similar to a list.

    Note that for the method undoable_append to work, unredo has to be
    defined as class attribute.

    """

    default_cell_attributes = {
        "borderwidth_bottom": 1,
        "borderwidth_right": 1,
        "bordercolor_bottom": get_color(config["grid_color"]).GetRGB(),
        "bordercolor_right": get_color(config["grid_color"]).GetRGB(),
        "bgcolor": get_color(config["background_color"]).GetRGB(),
        "textfont": get_font_string(config["font"]),
        "pointsize": 10,
        "fontweight": wx.NORMAL,
        "fontstyle": wx.NORMAL,
        "textcolor": get_color(config["text_color"]).GetRGB(),
        "underline": False,
        "strikethrough": False,
        "locked": False,
        "angle": 0.0,
        "column-width": 150,
        "row-height": 26,
        "vertical_align": "top",
        "justification": "left",
        "frozen": False,
        "merge_area": None,
    }

    # Cache for __getattr__ maps key to tuple of len and attr_dict

    _attr_cache = {}

    def undoable_append(self, value, mark_unredo=True):
        """Appends item to list and provides undo and redo functionality"""

        undo_operation = (self.pop, [])
        redo_operation = (self.undoable_append, [value, mark_unredo])

        self.unredo.append(undo_operation, redo_operation)

        if mark_unredo:
            self.unredo.mark()

        self.append(value)
        self._attr_cache.clear()

    def __getitem__(self, key):
        """Returns attribute dict for a single key"""

        assert not any(type(key_ele) is SliceType for key_ele in key)

        if key in self._attr_cache:
            cache_len, cache_dict = self._attr_cache[key]

            # Use cache result only if no new attrs have been defined
            if cache_len == len(self):
                return cache_dict

        row, col, tab = key

        result_dict = copy(self.default_cell_attributes)

        for selection, table, attr_dict in self:
            if tab == table and (row, col) in selection:
                result_dict.update(attr_dict)

        # Upddate cache with current length and dict
        self._attr_cache[key] = (len(self), result_dict)

        return result_dict

    def get_merging_cell(self, key):
        """Returns key of cell that merges the cell key

        or None if cell key not merged

        Parameters
        ----------
        key: 3-tuple of Integer
        \tThe key of the cell that is merged

        """

        row, col, tab = key

        merging_cell = None

        def is_in_merge_area(row, col, merge_area):
            top, left, bottom, right = merge_area
            return top <= row <= bottom and left <= col <= right

        for selection, table, attr_dict in self:
            try:
                merge_area = attr_dict["merge_area"]
                if table == tab and merge_area is not None:
                    # We have a merge area in the cell's table
                    if is_in_merge_area(row, col, merge_area):
                        merging_cell = merge_area[0], merge_area[1], tab
            except KeyError:
                pass

        return merging_cell

    # Allow getting and setting elements in list
    get_item = list.__getitem__
    set_item = list.__setitem__
Example #27
0
class GridRenderer(wx.grid.PyGridCellRenderer, EventMixin):
    """This renderer draws borders and text at specified font, size, color"""

    selection_color_tuple = \
        tuple([c / 255.0 for c in get_color(config["selection_color"]).Get()] +
              [0.5])

    def __init__(self, data_array):

        wx.grid.PyGridCellRenderer.__init__(self)

        self.data_array = data_array

        # Cache for cell content
        self.cell_cache = {}

        # Video cell register, contains keys
        self.video_cells = {}

        # Zoom of grid
        self.zoom = 1.0

        # Old cursor position
        self.old_cursor_row_col = 0, 0

    def get_zoomed_size(self, size):
        """Returns zoomed size as Integer

        Parameters
        ----------

        font_size: Integer
        \tOriginal font size

        """

        return max(1.0, round(size * self.zoom))

    def _draw_cursor(self, dc, grid, row, col, pen=None, brush=None):
        """Draws cursor as Rectangle in lower right corner"""

        # If in full screen mode draw no cursor
        if grid.main_window.IsFullScreen():
            return

        key = row, col, grid.current_table
        rect = grid.CellToRect(row, col)
        rect = self.get_merged_rect(grid, key, rect)

        # Check if cell is invisible
        if rect is None:
            return

        size = self.get_zoomed_size(1.0)

        caret_length = int(min([rect.width, rect.height]) / 5.0)

        color = get_color(config["text_color"])
        if pen is None:
            pen = wx.Pen(color)
        if brush is None:
            brush = wx.Brush(color)

        pen.SetWidth(size)

        # Inner right and lower borders
        border_left = rect.x + size - 1
        border_right = rect.x + rect.width - size - 1
        border_upper = rect.y + size - 1
        border_lower = rect.y + rect.height - size - 1

        points_lr = [
            (border_right, border_lower - caret_length),
            (border_right, border_lower),
            (border_right - caret_length, border_lower),
            (border_right, border_lower),
        ]

        points_ur = [
            (border_right, border_upper + caret_length),
            (border_right, border_upper),
            (border_right - caret_length, border_upper),
            (border_right, border_upper),
        ]

        points_ul = [
            (border_left, border_upper + caret_length),
            (border_left, border_upper),
            (border_left + caret_length, border_upper),
            (border_left, border_upper),
        ]

        points_ll = [
            (border_left, border_lower - caret_length),
            (border_left, border_lower),
            (border_left + caret_length, border_lower),
            (border_left, border_lower),
        ]

        point_list = [points_lr, points_ur, points_ul, points_ll]

        dc.DrawPolygonList(point_list, pens=pen, brushes=brush)

        self.old_cursor_row_col = row, col

    def update_cursor(self, dc, grid, row, col):
        """Whites out the old cursor and draws the new one"""

        old_row, old_col = self.old_cursor_row_col

        bgcolor = get_color(config["background_color"])

        self._draw_cursor(dc,
                          grid,
                          old_row,
                          old_col,
                          pen=wx.Pen(bgcolor),
                          brush=wx.Brush(bgcolor))
        self._draw_cursor(dc, grid, row, col)

    def get_merging_cell(self, grid, key):
        """Returns row, col, tab of merging cell if the cell key is merged"""

        return grid.code_array.cell_attributes.get_merging_cell(key)

    def get_merged_rect(self, grid, key, rect):
        """Returns cell rect for normal or merged cells and None for merged"""

        row, col, tab = key

        # Check if cell is merged:
        cell_attributes = grid.code_array.cell_attributes
        merge_area = cell_attributes[(row, col, tab)]["merge_area"]

        if merge_area is None:
            return rect

        else:
            # We have a merged cell
            top, left, bottom, right = merge_area

            # Are we drawing the top left cell?
            if top == row and left == col:
                # Set rect to merge area
                ul_rect = grid.CellToRect(row, col)
                br_rect = grid.CellToRect(bottom, right)

                width = br_rect.x - ul_rect.x + br_rect.width
                height = br_rect.y - ul_rect.y + br_rect.height

                rect = wx.Rect(ul_rect.x, ul_rect.y, width, height)

                return rect

    def _get_drawn_rect(self, grid, key, rect):
        """Replaces drawn rect if the one provided by wx is incorrect

        This handles merged rects including those that are partly off screen.

        """

        rect = self.get_merged_rect(grid, key, rect)
        if rect is None:
            # Merged cell is drawn
            if grid.is_merged_cell_drawn(key):
                # Merging cell is outside view
                row, col, __ = key = self.get_merging_cell(grid, key)
                rect = grid.CellToRect(row, col)
                rect = self.get_merged_rect(grid, key, rect)
            else:
                return

        return rect

    def _get_draw_cache_key(self, grid, key, drawn_rect, is_selected):
        """Returns key for the screen draw cache"""

        row, col, tab = key
        cell_attributes = grid.code_array.cell_attributes

        zoomed_width = drawn_rect.width / self.zoom
        zoomed_height = drawn_rect.height / self.zoom

        # Button cells shall not be executed for preview
        if grid.code_array.cell_attributes[key]["button_cell"]:
            cell_preview = repr(grid.code_array(key))[:100]
        else:
            cell_preview = repr(grid.code_array[key])[:100]

        sorted_keys = sorted(grid.code_array.cell_attributes[key].iteritems())

        key_above_left = row - 1, col - 1, tab
        key_above = row - 1, col, tab
        key_above_right = row - 1, col + 1, tab
        key_left = row, col - 1, tab
        key_right = row, col + 1, tab
        key_below_left = row + 1, col - 1, tab
        key_below = row + 1, col, tab

        borders = []

        for k in [
                key, key_above_left, key_above, key_above_right, key_left,
                key_right, key_below_left, key_below
        ]:
            borders.append(cell_attributes[k]["borderwidth_bottom"])
            borders.append(cell_attributes[k]["borderwidth_right"])
            borders.append(cell_attributes[k]["bordercolor_bottom"])
            borders.append(cell_attributes[k]["bordercolor_right"])

        return (zoomed_width, zoomed_height, is_selected, cell_preview,
                tuple(sorted_keys), tuple(borders))

    def _get_cairo_bmp(self, mdc, key, rect, is_selected, view_frozen):
        """Returns a wx.Bitmap of cell key in size rect"""

        bmp = wx.EmptyBitmap(rect.width, rect.height)
        mdc.SelectObject(bmp)
        mdc.SetBackgroundMode(wx.SOLID)
        mdc.SetBackground(wx.WHITE_BRUSH)
        mdc.Clear()
        mdc.SetDeviceOrigin(0, 0)

        context = wx.lib.wxcairo.ContextFromDC(mdc)

        context.save()

        # Zoom context
        zoom = self.zoom
        context.scale(zoom, zoom)

        # Set off cell renderer by 1/2 a pixel to avoid blurry lines
        rect_tuple = \
            -0.5, -0.5, rect.width / zoom + 0.5, rect.height / zoom + 0.5
        spell_check = config["check_spelling"]
        cell_renderer = GridCellCairoRenderer(context,
                                              self.data_array,
                                              key,
                                              rect_tuple,
                                              view_frozen,
                                              spell_check=spell_check)
        # Draw cell
        cell_renderer.draw()

        # Draw selection if present
        if is_selected:
            context.set_source_rgba(*self.selection_color_tuple)
            context.rectangle(*rect_tuple)
            context.fill()

        context.restore()

        return bmp

    def Draw(self, grid, attr, dc, rect, row, col, isSelected):
        """Draws the cell border and content using pycairo"""

        key = row, col, grid.current_table

        # If cell is merge draw the merging cell if invisibile
        if grid.code_array.cell_attributes[key]["merge_area"]:
            key = self.get_merging_cell(grid, key)

        drawn_rect = self._get_drawn_rect(grid, key, rect)
        if drawn_rect is None:
            return

        cell_cache_key = self._get_draw_cache_key(grid, key, drawn_rect,
                                                  isSelected)

        mdc = wx.MemoryDC()

        if vlc is not None and key in self.video_cells and \
           grid.code_array.cell_attributes[key]["panel_cell"]:
            # Update video position of previously created video panel
            self.video_cells[key].SetClientRect(drawn_rect)

        elif cell_cache_key in self.cell_cache:
            mdc.SelectObject(self.cell_cache[cell_cache_key])

        else:
            code = grid.code_array(key)
            if vlc is not None and code is not None and \
               grid.code_array.cell_attributes[key]["panel_cell"]:
                try:
                    # A panel is to be displayed
                    panel_cls = grid.code_array[key]

                    # Assert that we have a subclass of a wxPanel that we
                    # can instantiate
                    assert issubclass(panel_cls, wx.Panel)

                    video_panel = panel_cls(grid)
                    video_panel.SetClientRect(drawn_rect)
                    # Register video cell
                    self.video_cells[key] = video_panel

                    return

                except Exception, err:
                    # Someting is wrong with the panel to be displayed
                    post_command_event(grid.main_window,
                                       self.StatusBarMsg,
                                       text=unicode(err))
                    bmp = self._get_cairo_bmp(mdc, key, drawn_rect, isSelected,
                                              grid._view_frozen)
            else:
Example #28
0
    def _draw_cursor(self, dc, grid, row, col, pen=None, brush=None):
        """Draws cursor as Rectangle in lower right corner"""

        # If in full screen mode draw no cursor
        if grid.main_window.IsFullScreen():
            return

        key = row, col, grid.current_table
        rect = grid.CellToRect(row, col)
        rect = self.get_merged_rect(grid, key, rect)

        # Check if cell is invisible
        if rect is None:
            return

        size = self.get_zoomed_size(1.0)

        caret_length = int(min([rect.width, rect.height]) / 5.0)

        color = get_color(config["text_color"])
        if pen is None:
            pen = wx.Pen(color)
        if brush is None:
            brush = wx.Brush(color)

        pen.SetWidth(size)

        # Inner right and lower borders
        border_left = rect.x + size - 1
        border_right = rect.x + rect.width - size - 1
        border_upper = rect.y + size - 1
        border_lower = rect.y + rect.height - size - 1

        points_lr = [
            (border_right, border_lower - caret_length),
            (border_right, border_lower),
            (border_right - caret_length, border_lower),
            (border_right, border_lower),
        ]

        points_ur = [
            (border_right, border_upper + caret_length),
            (border_right, border_upper),
            (border_right - caret_length, border_upper),
            (border_right, border_upper),
        ]

        points_ul = [
            (border_left, border_upper + caret_length),
            (border_left, border_upper),
            (border_left + caret_length, border_upper),
            (border_left, border_upper),
        ]

        points_ll = [
            (border_left, border_lower - caret_length),
            (border_left, border_lower),
            (border_left + caret_length, border_lower),
            (border_left, border_lower),
        ]

        point_list = [points_lr, points_ur, points_ul, points_ll]

        dc.DrawPolygonList(point_list, pens=pen, brushes=brush)

        self.old_cursor_row_col = row, col