Exemple #1
0
    def _code_convert_1_2(self, key: Tuple[int, int, int], code: str) -> str:
        """Converts chart and image code from v1.0 to v2.0

        :param key: Key of cell with code
        :param code: Code in cell to be converted

        """
        def get_image_code(image_data: str, width: int, height: int) -> str:
            """Returns code string for v2.0

            :param image_data: b85encoded image data
            :param width: Image width
            :param height: Image height

            """

            image_buffer_tpl = 'bz2.decompress(base64.b85decode({data}))'
            image_array_tpl = 'numpy.frombuffer({buffer}, dtype="uint8")'
            image_matrix_tpl = '{array}.reshape({height}, {width}, 3)'

            image_buffer = image_buffer_tpl.format(data=image_data)
            image_array = image_array_tpl.format(buffer=image_buffer)
            image_matrix = image_matrix_tpl.format(array=image_array,
                                                   height=height,
                                                   width=width)

            return image_matrix

        start_str = "bz2.decompress(base64.b64decode('"
        size_start_str = "wx.ImageFromData("
        if size_start_str in code and start_str in code:
            size_start = code.index(size_start_str) + len(size_start_str)
            size_str_list = code[size_start:].split(",")[:2]
            width, height = tuple(map(int, size_str_list))

            # We have a cell that displays a bitmap
            data_start = code.index(start_str) + len(start_str)
            data_stop = code.find("'", data_start)
            enc_data = bytes(code[data_start:data_stop], encoding='utf-8')
            compressed_image_data = b64decode(enc_data)
            reenc_data = b85encode(compressed_image_data)
            code = get_image_code(repr(reenc_data), width, height)

            selection = Selection([], [], [], [], [(key[0], key[1])])
            tab = key[2]
            attr_dict = AttrDict([("renderer", "image")])
            attr = CellAttribute(selection, tab, attr_dict)
            self.cell_attributes_postfixes.append(attr)

        elif "charts.ChartFigure(" in code:
            # We have a matplotlib figure
            selection = Selection([], [], [], [], [(key[0], key[1])])
            tab = key[2]
            attr_dict = AttrDict([("renderer", "matplotlib")])
            attr = CellAttribute(selection, tab, attr_dict)
            self.cell_attributes_postfixes.append(attr)

        return code
Exemple #2
0
    def redo(self):
        """Redo column deletion, updates screen"""

        # Store content of deleted columns
        self.old_col_widths = copy(self.model.code_array.col_widths)
        self.old_cell_attributes = copy(self.model.code_array.cell_attributes)
        self.old_code = {}
        columns = list(range(self.first, self.last + 1))
        selection = Selection([], [], [], columns, [])
        for key in selection.cell_generator(self.model.shape, self.grid.table):
            self.old_code[key] = self.model.code_array(key)

        with self.model.removing_columns(self.index, self.first, self.last):
            self.model.removeColumns(self.column, self.count)
        self.grid.table_choice.on_table_changed(self.grid.current)
Exemple #3
0
    def redo(self):
        """Redo row deletion, updates screen"""

        # Store content of deleted rows
        self.old_row_heights = copy(self.model.code_array.row_heights)
        self.old_cell_attributes = copy(self.model.code_array.cell_attributes)
        self.old_code = {}
        rows = list(range(self.first, self.last + 1))
        selection = Selection([], [], rows, [], [])
        for key in selection.cell_generator(self.model.shape, self.grid.table):
            self.old_code[key] = self.model.code_array(key)

        with self.model.removing_rows(self.index, self.first, self.last):
            self.model.removeRows(self.row, self.count)
        self.grid.table_choice.on_table_changed(self.grid.current)
Exemple #4
0
    def _pys2attributes_10(self, line: str):
        """Updates attributes in code_array - for save file version 1.0

        :param line: Pys file line to be parsed

        """

        splitline = self._split_tidy(line)

        selection_data = list(map(ast.literal_eval, splitline[:5]))
        selection = Selection(*selection_data)

        tab = int(splitline[5])

        attr_dict = AttrDict()

        old_merged_cells = {}

        for col, ele in enumerate(splitline[6:]):
            if not (col % 2):
                # Odd entries are keys
                key = ast.literal_eval(ele)

            else:
                # Even cols are values
                value = ast.literal_eval(ele)

                # Convert old wx color values and merged cells
                key_, value_ = self._attr_convert_1to2(key, value)

                if key_ is None and value_ is not None:
                    # We have a merged cell
                    old_merged_cells[value_[:2]] = value_
                try:
                    attr_dict.pop("merge_area")
                except KeyError:
                    pass
                attr_dict[key_] = value_

        attr = CellAttribute(selection, tab, attr_dict)
        self.code_array.cell_attributes.append(attr)

        for key in old_merged_cells:
            selection = Selection([], [], [], [], [key])
            attr_dict = AttrDict([("merge_area", old_merged_cells[key])])
            attr = CellAttribute(selection, tab, attr_dict)
            self.code_array.cell_attributes.append(attr)
        old_merged_cells.clear()
Exemple #5
0
    def _pys2attributes(self, line: str):
        """Updates attributes in code_array

        :param line: Pys file line to be parsed

        """

        splitline = self._split_tidy(line)

        selection_data = list(map(ast.literal_eval, splitline[:5]))
        selection = Selection(*selection_data)

        tab = int(splitline[5])

        attr_dict = AttrDict()

        for col, ele in enumerate(splitline[6:]):
            if not (col % 2):
                # Odd entries are keys
                key = ast.literal_eval(ele)

            else:
                # Even cols are values
                value = ast.literal_eval(ele)
                attr_dict[key] = value

        attr = CellAttribute(selection, tab, attr_dict)
        self.code_array.cell_attributes.append(attr)
Exemple #6
0
    def redo(self):
        """Redo cell thawing"""

        row, column, table = current = self.current

        # Remove and store frozen cache content
        self.res_obj = self.model.code_array.frozen_cache.pop(repr(current))

        # Remove the frozen state
        selection = Selection([], [], [], [], [(row, column)])
        attr_dict = AttrDict([("frozen", False)])
        attr = CellAttribute(selection, table, attr_dict)
        self.model.setData([], attr, Qt.DecorationRole)
        self.model.dataChanged.emit(QModelIndex(), QModelIndex())
Exemple #7
0
    def undo(self):
        """Undo button cell removal"""

        row, column, table = self.key
        selection = Selection([], [], [], [], [(row, column)])
        attr_dict = AttrDict([("button_cell", self.text)])
        ca = CellAttribute(selection, table, attr_dict)
        self.grid.model.setData([self.index], ca, Qt.DecorationRole)

        if table == self.grid.table:
            # Only add widget if we are in the right table
            button = CellButton(self.text, self.grid, self.key)
            self.grid.setIndexWidget(self.index, button)
            self.grid.widget_indices.append(self.index)
        self.grid.model.dataChanged.emit(self.index, self.index)
Exemple #8
0
    def redo(self):
        """Redo cell freezing"""

        row, column, table = self.current

        # Add frozen cache content
        res_obj = self.model.code_array[self.current]
        self.model.code_array.frozen_cache[repr(self.current)] = res_obj

        # Set the frozen state
        selection = Selection([], [], [], [], [(row, column)])
        attr_dict = AttrDict([("frozen", True)])
        attr = CellAttribute(selection, table, attr_dict)
        self.model.setData([], attr, Qt.DecorationRole)
        self.model.dataChanged.emit(QModelIndex(), QModelIndex())
Exemple #9
0
    def undo(self):
        """Undo button cell making"""

        if self.index not in self.grid.widget_indices:
            return

        row, column, table = self.key
        selection = Selection([], [], [], [], [(row, column)])
        attr_dict = AttrDict([("button_cell", False)])
        ca = CellAttribute(selection, table, attr_dict)
        self.grid.model.setData([self.index], ca, Qt.DecorationRole)

        if table == self.grid.table:
            # Only remove widget if we are in the right table
            self.grid.setIndexWidget(self.index, None)
            self.grid.widget_indices.remove(self.index)
        self.grid.model.dataChanged.emit(self.index, self.index)
Exemple #10
0
    def redo(self):
        """Redo grid size change and deletion of cell code outside new shape

        Cell formats are not deleted.

        """

        model = self.grid.model
        code_array = model.code_array

        rows, columns, tables = self.new_shape
        shapeselection = Selection([(0, 0)], [(rows - 1, columns - 1)], [], [],
                                   [])

        for row, column, table in code_array.keys():
            if not (table < tables and (row, column) in shapeselection):
                # Code outside grid shape. Delete it and store cell data
                key = row, column, table
                self.deleted_cells[key] = code_array.pop(key)

        # Now change the shape
        self.grid.model.shape = self.new_shape
Exemple #11
0
    def _adjust_merge_area(self, attrs: AttrDict, insertion_point: int,
                           no_to_insert: int,
                           axis: int) -> Tuple[int, int, int, int]:
        """Returns an updated merge area

        :param attrs: Cell attribute dictionary that shall be adjusted
        :param insertion_point: Point on axis at which insertion takes place
        :param no_to_insert: Number of rows/cols/tabs to be inserted (>=0)
        :param axis: Row insertion if 0, column insertion if 1, must be in 0, 1

        """

        if axis not in (0, 1):
            raise Warning("Axis {} not in (0, 1)".format(axis))
            return

        if "merge_area" not in attrs or attrs["merge_area"] is None:
            return

        top, left, bottom, right = attrs["merge_area"]
        selection = Selection([(top, left)], [(bottom, right)], [], [], [])

        selection.insert(insertion_point, no_to_insert, axis)

        __top, __left = selection.block_tl[0]
        __bottom, __right = selection.block_br[0]

        # Adjust merge area if it is beyond the grid shape
        rows, cols, tabs = self.shape

        if __top < 0 and __bottom < 0:
            return
        if __top >= rows and __bottom >= rows:
            return
        if __left < 0 and __right < 0:
            return
        if __left >= cols and __right >= cols:
            return

        if __top < 0:
            __top = 0

        if __top >= rows:
            __top = rows - 1

        if __bottom < 0:
            __bottom = 0

        if __bottom >= rows:
            __bottom = rows - 1

        if __left < 0:
            __left = 0

        if __left >= cols:
            __left = cols - 1

        if __right < 0:
            __right = 0

        if __right >= cols:
            __right = cols - 1

        return __top, __left, __bottom, __right