1from __future__ import absolute_import
2# Copyright (c) 2010-2019 openpyxl
3
4from openpyxl.cell import Cell
5from openpyxl.utils import get_column_letter
6from openpyxl.utils.datetime import from_excel
7from openpyxl.styles import is_date_format
8from openpyxl.styles.numbers import BUILTIN_FORMATS, BUILTIN_FORMATS_MAX_SIZE
9
10
11class ReadOnlyCell(object):
12
13    __slots__ =  ('parent', 'row', 'column', '_value', 'data_type', '_style_id')
14
15    def __init__(self, sheet, row, column, value, data_type='n', style_id=0):
16        self.parent = sheet
17        self._value = None
18        self.row = row
19        self.column = column
20        self.data_type = data_type
21        self.value = value
22        self._style_id = style_id
23
24
25    def __eq__(self, other):
26        for a in self.__slots__:
27            if getattr(self, a) != getattr(other, a):
28                return
29        return True
30
31    def __ne__(self, other):
32        return not self.__eq__(other)
33
34
35    def __repr__(self):
36        return "<ReadOnlyCell {0!r}.{1}>".format(self.parent.title, self.coordinate)
37
38
39    @property
40    def coordinate(self):
41        column = get_column_letter(self.column)
42        return "{1}{0}".format(self.row, column)
43
44
45    @property
46    def coordinate(self):
47        return Cell.coordinate.__get__(self)
48
49
50    @property
51    def column_letter(self):
52        return Cell.column_letter.__get__(self)
53
54
55    @property
56    def style_array(self):
57        return self.parent.parent._cell_styles[self._style_id]
58
59    @property
60    def number_format(self):
61        _id = self.style_array.numFmtId
62        if _id < BUILTIN_FORMATS_MAX_SIZE:
63            return BUILTIN_FORMATS.get(_id, "General")
64        else:
65            return self.parent.parent._number_formats[
66                _id - BUILTIN_FORMATS_MAX_SIZE]
67
68    @property
69    def font(self):
70        _id = self.style_array.fontId
71        return self.parent.parent._fonts[_id]
72
73    @property
74    def fill(self):
75        _id = self.style_array.fillId
76        return self.parent.parent._fills[_id]
77
78    @property
79    def border(self):
80        _id = self.style_array.borderId
81        return self.parent.parent._borders[_id]
82
83    @property
84    def alignment(self):
85        _id = self.style_array.alignmentId
86        return self.parent.parent._alignments[_id]
87
88    @property
89    def protection(self):
90        _id = self.style_array.protectionId
91        return self.parent.parent._protections[_id]
92
93
94    @property
95    def is_date(self):
96        return Cell.is_date.__get__(self)
97
98
99    @property
100    def internal_value(self):
101        return self._value
102
103    @property
104    def value(self):
105        return self._value
106
107    @value.setter
108    def value(self, value):
109        if self._value is not None:
110            raise AttributeError("Cell is read only")
111        self._value = value
112
113
114class EmptyCell(object):
115
116    __slots__ = ()
117
118    value = None
119    is_date = False
120    font = None
121    border = None
122    fill = None
123    number_format = None
124    alignment = None
125    data_type = 'n'
126
127
128    def __repr__(self):
129        return "<EmptyCell>"
130
131EMPTY_CELL = EmptyCell()
132