Skip to content

Commit

Permalink
fix the table displayed functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
jdum committed Sep 22, 2024
1 parent 0de73c6 commit e3f8f2b
Show file tree
Hide file tree
Showing 5 changed files with 284 additions and 41 deletions.
101 changes: 87 additions & 14 deletions odfdo/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
)
from .container import Container
from .content import Content
from .datatype import Boolean
from .element import Element
from .manifest import Manifest
from .meta import Meta
Expand Down Expand Up @@ -1130,26 +1131,20 @@ def get_style_properties(
return None
return style.get_properties(area=area) # type: ignore

def _get_table(self, table: int | str) -> Table | None:
if not (isinstance(table, int) or isinstance(table, str)):
raise TypeError(f"Table parameter must be int or str: {table!r}")
if isinstance(table, int):
return self.body.get_table(position=table) # type: ignore
return self.body.get_table(name=table) # type: ignore

def get_cell_style_properties( # noqa: C901
self, table: str | int, coord: tuple | list | str
) -> dict[str, str]: # type: ignore
"""Return the style properties of a table cell of a .ods document,
from the cell style or from the row style."""

def _get_table(table: int | str) -> Table | None:
table_pos = 0
table_name = None
if isinstance(table, int):
table_pos = table
elif isinstance(table, str):
table_name = table_name
else:
raise TypeError(f"Table parameter must be int or str: {table!r}")
return self.body.get_table(
position=table_pos, name=table_name # type: ignore
)

if not (sheet := _get_table(table)):
if not (sheet := self._get_table(table)):
return {}
cell = sheet.get_cell(coord, clone=False)
if cell.style:
Expand Down Expand Up @@ -1186,3 +1181,81 @@ def get_cell_background_color(
If color is not defined, return default value.."""
found = self.get_cell_style_properties(table, coord).get("fo:background-color")
return found or default

def get_table_style( # noqa: C901
self,
table: str | int,
) -> Style | None: # type: ignore
"""Return the Style instance the table.
Arguments:
table -- name or index of the table
"""
if not (sheet := self._get_table(table)):
return None
return self.get_style("table", sheet.style)

def get_table_displayed(self, table: str | int) -> bool:
"""Return the table:display property of the style of the table, ie if
the table should be displayed in a graphical interface.
Note: that method replaces the broken Table.displayd() method from previous
odfdo versions.
Arguments:
table -- name or index of the table
"""
style = self.get_table_style(table)
if not style:
# should not happen, but assume that a table without style is
# displayed by default
return True
properties = style.get_properties() or {}
property_str = str(properties.get("table:display", "true"))
return Boolean.decode(property_str)

def _unique_style_name(self, base: str) -> str:
current = {style.name for style in self.get_styles()}
idx = 0
while True:
name = f"{base}_{idx}"
if name in current:
idx += 1
continue
return name

def set_table_displayed(self, table: str | int, displayed: bool) -> None:
"""Set the table:display property of the style of the table, ie if
the table should be displayed in a graphical interface.
Note: that method replaces the broken Table.displayd() method from previous
odfdo versions.
Arguments:
table -- name or index of the table
displayed -- boolean flag
"""
orig_style = self.get_table_style(table)
if not orig_style:
name = self._unique_style_name("ta")
orig_style = Element.from_tag(
(
f'<style:style style:name="{name}" style:family="table" '
'style:master-page-name="Default">'
'<style:table-properties table:display="true" '
'style:writing-mode="lr-tb"/></style:style>'
)
)
self.insert_style(orig_style, automatic=True) # type:ignore
new_style = orig_style.clone
new_name = self._unique_style_name("ta")
new_style.name = new_name # type:ignore
self.insert_style(new_style, automatic=True) # type:ignore
sheet = self._get_table(table)
sheet.style = new_name # type: ignore
properties = {"table:display": Boolean.encode(displayed)}
new_style.set_properties(properties) # type: ignore
15 changes: 0 additions & 15 deletions odfdo/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ def __init__(
height: int | None = None,
protected: bool = False,
protection_key: str | None = None,
display: bool = True,
printable: bool = True,
print_ranges: list[str] | None = None,
style: str | None = None,
Expand All @@ -334,8 +333,6 @@ def __init__(
If the table is to be protected, a protection key must be provided,
i.e. a hash value of the password.
If the table must not be displayed, set "display" to False.
If the table must not be printed, set "printable" to False. The table
will not be printed when it is not displayed, whatever the value of
this argument.
Expand Down Expand Up @@ -363,8 +360,6 @@ def __init__(
protection_key -- str
display -- bool
printable -- bool
print_ranges -- list
Expand All @@ -380,8 +375,6 @@ def __init__(
if protected:
self.protected = protected
self.set_protection_key = protection_key
if not display:
self.displayed = display
if not printable:
self.printable = printable
if print_ranges:
Expand Down Expand Up @@ -841,14 +834,6 @@ def protection_key(self) -> str | None:
def protection_key(self, key: str) -> None:
self.set_attribute("table:protection-key", key)

@property
def displayed(self) -> bool:
return bool(self.get_attribute("table:display"))

@displayed.setter
def displayed(self, display: bool) -> None:
self.set_attribute("table:display", display)

@property
def printable(self) -> bool:
printable = self.get_attribute("table:print")
Expand Down
Binary file added tests/samples/minimal_hidden.ods
Binary file not shown.
12 changes: 0 additions & 12 deletions tests/test_table_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,6 @@ def test_width_height():
assert table.serialize() == expected


def test_display():
table = Table("Displayed")
expected = '<table:table table:name="Displayed"/>'
assert table.serialize() == expected


def test_display_false():
table = Table("Hidden", display=False)
expected = '<table:table table:name="Hidden" table:display="false"/>'
assert table.serialize() == expected


def test_print():
table = Table("Printable")
expected = '<table:table table:name="Printable"/>'
Expand Down
197 changes: 197 additions & 0 deletions tests/test_table_display.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Copyright 2018-2024 Jérôme Dumonteil
# Copyright (c) 2009-2010 Ars Aperta, Itaapy, Pierlis, Talend.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Authors (odfdo project): [email protected]
# The odfdo project is a derivative work of the lpod-python project:
# https://github.com/lpod/lpod-python

from pathlib import Path

from odfdo.document import Document
from odfdo.table import Table

SAMPLES = Path(__file__).parent / "samples"
FILE_HIDDEN_ODS = SAMPLES / "minimal_hidden.ods"


def test_display_default():
table = Table("A Table")
expected = '<table:table table:name="A Table"/>'
assert table.serialize() == expected


def test_table_style_get_table_name():
doc = Document("spreadsheet")
body = doc.body
body.clear()
table = Table("Table0")
body.append(table)
table = doc._get_table("Table0")
assert table.name == "Table0"


def test_table_style_table_display_default():
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table("Table0"))
assert doc.get_table_displayed("Table0")


def test_table_style_table_display_default_idx():
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table("Table0"))
assert doc.get_table_displayed(0)


def test_table_style_table_display_change1():
name0 = "Table0"
name1 = "Table1"
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table(name0))
doc.body.append(Table(name1))
doc.set_table_displayed(name0, True)
assert doc.get_table_displayed(name0)
assert doc.get_table_displayed(name1)


def test_table_style_table_display_change2():
name0 = "Table0"
name1 = "Table1"
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table(name0))
doc.body.append(Table(name1))
doc.set_table_displayed(name0, False)
assert not doc.get_table_displayed(name0)
assert doc.get_table_displayed(name1)


def test_table_style_table_display_change3():
name0 = "Table0"
name1 = "Table1"
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table(name0))
doc.body.append(Table(name1))
doc.set_table_displayed(name0, True)
doc.set_table_displayed(name1, False)
assert doc.get_table_displayed(name0)
assert not doc.get_table_displayed(name1)


def test_table_style_table_display_change1_idx():
name0 = "Table0"
name1 = "Table1"
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table(name0))
doc.body.append(Table(name1))
doc.set_table_displayed(0, True)
assert doc.get_table_displayed(0)
assert doc.get_table_displayed(1)


def test_table_style_table_display_change2_idx():
name0 = "Table0"
name1 = "Table1"
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table(name0))
doc.body.append(Table(name1))
doc.set_table_displayed(0, False)
assert not doc.get_table_displayed(0)
assert doc.get_table_displayed(1)


def test_table_style_table_display_change3_idx():
name0 = "Table0"
name1 = "Table1"
doc = Document("spreadsheet")
doc.body.clear()
doc.body.append(Table(name0))
doc.body.append(Table(name1))
doc.set_table_displayed(0, True)
doc.set_table_displayed(1, False)
assert doc.get_table_displayed(0)
assert not doc.get_table_displayed(1)


def test_table_style_get_table_name_file():
doc = Document(FILE_HIDDEN_ODS)
table = doc._get_table("Tab 1")
assert table.name == "Tab 1"


def test_table_style_table_display_file1():
doc = Document(FILE_HIDDEN_ODS)
assert doc.get_table_displayed("Tab 1")


def test_table_style_table_display_file2():
doc = Document(FILE_HIDDEN_ODS)
assert not doc.get_table_displayed("Tab 2")


def test_table_style_table_display_3_idx_file():
doc = Document(FILE_HIDDEN_ODS)
doc.body.append(Table("Table 3"))
assert doc.get_table_displayed(2)


def test_table_style_table_display_change1_file():
doc = Document(FILE_HIDDEN_ODS)
doc.set_table_displayed("Tab 1", True)
assert doc.get_table_displayed("Tab 1")
assert not doc.get_table_displayed("Tab 2")


def test_table_style_table_display_change2_file():
doc = Document(FILE_HIDDEN_ODS)
doc.set_table_displayed("Tab 1", False)
assert not doc.get_table_displayed("Tab 1")
assert not doc.get_table_displayed("Tab 2")


def test_table_style_table_display_change3_file():
doc = Document(FILE_HIDDEN_ODS)
doc.set_table_displayed("Tab 1", False)
doc.set_table_displayed("Tab 2", True)
assert not doc.get_table_displayed("Tab 1")
assert doc.get_table_displayed("Tab 2")


def test_table_style_table_display_change1_idx_file():
doc = Document(FILE_HIDDEN_ODS)
doc.set_table_displayed(0, True)
assert doc.get_table_displayed(0)
assert not doc.get_table_displayed(1)


def test_table_style_table_display_change2_idx_file():
doc = Document(FILE_HIDDEN_ODS)
doc.set_table_displayed(0, False)
assert not doc.get_table_displayed(0)
assert not doc.get_table_displayed(1)


def test_table_style_table_display_change3_idx_file():
doc = Document(FILE_HIDDEN_ODS)
doc.set_table_displayed(0, False)
doc.set_table_displayed(1, True)
assert not doc.get_table_displayed(0)
assert doc.get_table_displayed(1)

0 comments on commit e3f8f2b

Please sign in to comment.