2024-12-04 13:35:57 +05:00

212 lines
5.6 KiB
Python

# Copyright (c) 2010-2024 openpyxl
## Incomplete!
from openpyxl.descriptors.serialisable import Serialisable
from openpyxl.descriptors import (
Typed,
Integer,
Set,
String,
Bool,
)
from openpyxl.descriptors.excel import Guid, ExtensionList
from openpyxl.descriptors.sequence import NestedSequence
from openpyxl.utils.indexed_list import IndexedList
from openpyxl.xml.constants import SHEET_MAIN_NS
from openpyxl.cell.text import Text
from .author import AuthorList
from .comments import Comment
from .shape_writer import ShapeWriter
class Properties(Serialisable):
locked = Bool(allow_none=True)
defaultSize = Bool(allow_none=True)
_print = Bool(allow_none=True)
disabled = Bool(allow_none=True)
uiObject = Bool(allow_none=True)
autoFill = Bool(allow_none=True)
autoLine = Bool(allow_none=True)
altText = String(allow_none=True)
textHAlign = Set(values=(['left', 'center', 'right', 'justify', 'distributed']))
textVAlign = Set(values=(['top', 'center', 'bottom', 'justify', 'distributed']))
lockText = Bool(allow_none=True)
justLastX = Bool(allow_none=True)
autoScale = Bool(allow_none=True)
rowHidden = Bool(allow_none=True)
colHidden = Bool(allow_none=True)
# anchor = Typed(expected_type=ObjectAnchor, )
__elements__ = ('anchor',)
def __init__(self,
locked=None,
defaultSize=None,
_print=None,
disabled=None,
uiObject=None,
autoFill=None,
autoLine=None,
altText=None,
textHAlign=None,
textVAlign=None,
lockText=None,
justLastX=None,
autoScale=None,
rowHidden=None,
colHidden=None,
anchor=None,
):
self.locked = locked
self.defaultSize = defaultSize
self._print = _print
self.disabled = disabled
self.uiObject = uiObject
self.autoFill = autoFill
self.autoLine = autoLine
self.altText = altText
self.textHAlign = textHAlign
self.textVAlign = textVAlign
self.lockText = lockText
self.justLastX = justLastX
self.autoScale = autoScale
self.rowHidden = rowHidden
self.colHidden = colHidden
self.anchor = anchor
class CommentRecord(Serialisable):
tagname = "comment"
ref = String()
authorId = Integer()
guid = Guid(allow_none=True)
shapeId = Integer(allow_none=True)
text = Typed(expected_type=Text)
commentPr = Typed(expected_type=Properties, allow_none=True)
author = String(allow_none=True)
__elements__ = ('text', 'commentPr')
__attrs__ = ('ref', 'authorId', 'guid', 'shapeId')
def __init__(self,
ref="",
authorId=0,
guid=None,
shapeId=0,
text=None,
commentPr=None,
author=None,
height=79,
width=144
):
self.ref = ref
self.authorId = authorId
self.guid = guid
self.shapeId = shapeId
if text is None:
text = Text()
self.text = text
self.commentPr = commentPr
self.author = author
self.height = height
self.width = width
@classmethod
def from_cell(cls, cell):
"""
Class method to convert cell comment
"""
comment = cell._comment
ref = cell.coordinate
self = cls(ref=ref, author=comment.author)
self.text.t = comment.content
self.height = comment.height
self.width = comment.width
return self
@property
def content(self):
"""
Remove all inline formatting and stuff
"""
return self.text.content
class CommentSheet(Serialisable):
tagname = "comments"
authors = Typed(expected_type=AuthorList)
commentList = NestedSequence(expected_type=CommentRecord, count=0)
extLst = Typed(expected_type=ExtensionList, allow_none=True)
_id = None
_path = "/xl/comments/comment{0}.xml"
mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
_rel_type = "comments"
_rel_id = None
__elements__ = ('authors', 'commentList')
def __init__(self,
authors=None,
commentList=None,
extLst=None,
):
self.authors = authors
self.commentList = commentList
def to_tree(self):
tree = super().to_tree()
tree.set("xmlns", SHEET_MAIN_NS)
return tree
@property
def comments(self):
"""
Return a dictionary of comments keyed by coord
"""
authors = self.authors.author
for c in self.commentList:
yield c.ref, Comment(c.content, authors[c.authorId], c.height, c.width)
@classmethod
def from_comments(cls, comments):
"""
Create a comment sheet from a list of comments for a particular worksheet
"""
authors = IndexedList()
# dedupe authors and get indexes
for comment in comments:
comment.authorId = authors.add(comment.author)
return cls(authors=AuthorList(authors), commentList=comments)
def write_shapes(self, vml=None):
"""
Create the VML for comments
"""
sw = ShapeWriter(self.comments)
return sw.write(vml)
@property
def path(self):
"""
Return path within the archive
"""
return self._path.format(self._id)