masaccio/numbers-parser

Add support for pop-up menus

Closed this issue · 11 comments

Is there a way to add a pop-up menu?

Screenshot 2024-02-22 at 22 41 31

I have tried to open a Numbers file with a pop-up menu, and after saving the pop-up is removed:

Screenshot 2024-02-22 at 22 42 24

This has been published in v4.9.0. There's an example in this test. Error handling is a bit ropey at the moment. For example there's no check that values written match the available popup values. You can mix types in the menu, but currently only float and str are supported. Numbers detects percentages and currencies, but I think that will be fragile in python.

It's working thanks. The only problem that I see is that it's also removing pop-up menu when the value is None.
Original file:
Screenshot 2024-02-25 at 19 38 46
After saving:
Screenshot 2024-02-25 at 19 39 35

As in you have a popup with an empty first value, load the document in numbers-parser, re-save and the resulting popup is removed?

Correct, I have a document with many popups. Some popups have a non-empty default value and some have default value None. After loading this document into number-parser and re-saving, it keeps popups where the first value isn't empty but for those where the default value is None it removes popup definition and the cell ends up with empty value. I'm using 4.9.1 version, tested also on 4.9.0 with no difference.

v4.9.2 adds support for empty cells with popup menus.

Works perfectly, thanks!

I have one more problem with pop-ups when reading existing Numbers file. Here is how to reproduce the error:

  1. Create a new Numbers file and save it to template.numbers file
  2. Execute
from numbers_parser import Document

doc = Document("./template.numbers")
table = doc.sheets[0].tables[0]
table.write(0, 1, "Dog")
table.set_cell_formatting(0, 1, "popup", popup_values=["Cat", "Dog", "Rabbit"], allow_none=True)

Error:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "test.py", line 22, in <module>
    table.set_cell_formatting(0, 1, "popup", popup_values=["Cat", "Dog", "Rabbit"], allow_none=True)
  File "venv/lib/python3.11/site-packages/numbers_parser/document.py", line 1384, in set_cell_formatting
    self._set_cell_data_format(row, col, format_type, **kwargs)
  File "venv/lib/python3.11/site-packages/numbers_parser/document.py", line 1426, in _set_cell_data_format
    control_id = self._model.control_cell_archive(self._table_id, format_type, format)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "venv/lib/python3.11/site-packages/numbers_parser/model.py", line 418, in control_cell_archive
    popup_id = self.cell_popup_model(self._control_specs.id(table_id), format)
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "venv/lib/python3.11/site-packages/numbers_parser/model.py", line 161, in id
    return self._datalists[table_id]["id"]
           ~~~~~~~~~~~~~~~^^^^^^^^^^
KeyError: 904538

Tested on numbers-parser==4.10.0

I tested also without template.numbers file and I'm also getting error. This doesn't work:

doc = Document()
table = doc.sheets[0].tables[0]

table.write(1, 0, "Dog")
table.set_cell_formatting(1, 0, "popup", popup_values=["Cat", "Dog", "Rabbit"], allow_none=True)

This works:

doc = Document()
table = doc.sheets[0].tables[0]

table.write(0, 0, False)
table.set_cell_formatting(0, 0, "tickbox")

table.write(1, 0, "Dog")
table.set_cell_formatting(1, 0, "popup", popup_values=["Cat", "Dog", "Rabbit"], allow_none=True)

Also, what is the best way to add pop-up with None value? I tried:

table.set_cell_formatting(0, 1, "popup", popup_values=["Test"], allow_none=True)

And I'm getting TypeError: cannot use popup formatting for cells of type EmptyCell
I tried also:

table.write(0, 1, "")
table.set_cell_formatting(0, 1, "popup", popup_values=["Test"], allow_none=True)

And I'm getting IndexError: current cell value '' does not match any popup values

Thanks for spotting that using a different control before the popup hid the bug -- the popup code was not calling an init method.

I've added checks for empty cells and popups. Empty values are only allowed if allow_none is True:

    table.write(0, 0, "")
    # Valid
    table.set_cell_formatting(0, 0, "popup", popup_values=["Cat", "Dog", "Rabbit"], allow_none=True)
    # raises IndexError
    table.set_cell_formatting(0, 0, "popup", popup_values=["Cat", "Dog", "Rabbit"])

All published in v4.10.1.

Works perfect, thanks!