<filename>desktop/core/ext-py/openpyxl-2.6.4/openpyxl/worksheet/_write_only.py
from __future__ import absolute_import
# Copyright (c) 2010-2019 openpyxl


"""Write worksheets to xml representations in an optimized way"""

from inspect import isgenerator

from openpyxl.cell import Cell, WriteOnlyCell
from openpyxl.workbook.child import _WorkbookChild
from .worksheet import Worksheet
from openpyxl.utils.exceptions import WorkbookAlreadySaved

from ._writer import WorksheetWriter


class WriteOnlyWorksheet(_WorkbookChild):
    """
    Streaming worksheet. Optimised to reduce memory by writing rows just in
    time.
    Cells can be styled and have comments Styles for rows and columns
    must be applied before writing cells
    """

    __saved = False
    _writer = None
    _rows = None
    _rel_type = Worksheet._rel_type
    _path = Worksheet._path
    mime_type = Worksheet.mime_type


    def __init__(self, parent, title):
        super(WriteOnlyWorksheet, self).__init__(parent, title)
        self._max_col = 0
        self._max_row = 0

        # Methods from Worksheet
        self._add_row = Worksheet._add_row.__get__(self)
        self._add_column = Worksheet._add_column.__get__(self)
        self.add_chart = Worksheet.add_chart.__get__(self)
        self.add_image = Worksheet.add_image.__get__(self)
        self.add_table = Worksheet.add_table.__get__(self)

        setup = Worksheet._setup.__get__(self)
        setup()

        self.print_titles = Worksheet.print_titles.__get__(self)
        self.sheet_view = Worksheet.sheet_view.__get__(self)


    @property
    def freeze_panes(self):
        return Worksheet.freeze_panes.__get__(self)


    @freeze_panes.setter
    def freeze_panes(self, value):
        Worksheet.freeze_panes.__set__(self, value)


    @property
    def print_title_cols(self):
        return Worksheet.print_title_cols.__get__(self)


    @print_title_cols.setter
    def print_title_cols(self, value):
        Worksheet.print_title_cols.__set__(self, value)


    @property
    def print_title_rows(self):
        return Worksheet.print_title_rows.__get__(self)


    @print_title_rows.setter
    def print_title_rows(self, value):
        Worksheet.print_title_rows.__set__(self, value)


    @property
    def print_area(self):
        return Worksheet.print_area.__get__(self)


    @print_area.setter
    def print_area(self, value):
        Worksheet.print_area.__set__(self, value)


    @property
    def closed(self):
        return self.__saved


    def _write_rows(self):
        """
        Send rows to the writer's stream
        """
        try:
            xf = self._writer.xf.send(True)
        except StopIteration:
            self._already_saved()

        with xf.element("sheetData"):
            row_idx = 1
            try:
                while True:
                    row = (yield)
                    row = self._values_to_row(row, row_idx)
                    self._writer.write_row(xf, row, row_idx)
                    row_idx += 1
            except GeneratorExit:
                pass

        self._writer.xf.send(None)


    def _get_writer(self):
        if self._writer is None:
            self._writer = WorksheetWriter(self)
            self._writer.write_top()


    def close(self):
        if self.__saved:
            self._already_saved()

        self._get_writer()

        if self._rows is None:
            self._writer.write_rows()
        else:
            self._rows.close()

        self._writer.write_tail()

        self._writer.close()
        self.__saved = True


    def append(self, row):
        """
        :param row: iterable containing values to append
        :type row: iterable
        """

        if (not isgenerator(row) and
            not isinstance(row, (list, tuple, range))
            ):
            self._invalid_row(row)

        self._get_writer()

        if self._rows is None:
            self._rows = self._write_rows()
            next(self._rows)

        self._rows.send(row)


    def _values_to_row(self, values, row_idx):
        """
        Convert whatever has been appended into a form suitable for work_rows
        """
        cell = WriteOnlyCell(self)

        for col_idx, value in enumerate(values, 1):
            if value is None:
                continue
            try:
                cell.value = value
            except ValueError:
                if isinstance(value, Cell):
                    cell = value
                else:
                    raise ValueError

            cell.column = col_idx
            cell.row = row_idx

            if cell.hyperlink is not None:
                cell.hyperlink.ref = cell.coordinate

            yield cell

            # reset cell if style applied
            if cell.has_style or cell.hyperlink:
                cell = WriteOnlyCell(self)


    def _already_saved(self):
        raise WorkbookAlreadySaved('Workbook has already been saved and cannot be modified or saved anymore.')


    def _invalid_row(self, iterable):
        raise TypeError('Value must be a list, tuple, range or a generator Supplied value is {0}'.format(
            type(iterable))
                        )
