RdbCell#layout_name and RdbItem#comment with tests and GSI binding

This commit is contained in:
Matthias Koefferlein 2024-04-27 19:56:39 +02:00
parent 2ff06ede07
commit 9ef51ca981
6 changed files with 121 additions and 29 deletions

View File

@ -265,17 +265,25 @@ Class<rdb::Cell> decl_RdbCell ("rdb", "RdbCell",
"The cell name is an string that identifies the category in the database. "
"Additionally, a cell may carry a variant identifier which is a string that uniquely identifies a cell "
"in the context of its variants. The \"qualified name\" contains both the cell name and the variant name. "
"Cell names are also used to identify report database cell's with layout cells. "
"Cell names are also used to identify report database cells with layout cells. For variants, the layout cell name "
"can be specified explicitly with the \\layout_name attribute (see \\RdbDatabase#create_cell). The latter is available "
"since version 0.29.1.\n"
"@return The cell name\n"
) +
gsi::method ("variant", &rdb::Cell::variant,
"@brief Gets the cell variant name\n"
"A variant name additionally identifies the cell when multiple cells with the same name are present. "
"A variant name is either assigned automatically or set when creating a cell. "
"A variant name is either assigned automatically or set when creating a cell.\n"
"@return The cell variant name\n"
) +
gsi::method ("qname", &rdb::Cell::qname,
"@brief Gets the cell's qualified name\n"
gsi::method ("layout_name", &rdb::Cell::layout_name,
"@brief Gets the name of the layout cell\n"
"For variants, this string is the name of the actual layout cell. If empty, the cell is assume to be called 'name'.\n"
"@return The layout cell name\n"
"This read-only attribute has been added in version 0.29.1.\n"
) +
gsi::method ("qname", &rdb::Cell::qname,
"@brief Gets the qualified name of the cell\n"
"The qualified name is a combination of the cell name and optionally the variant name. "
"It is used to identify the cell by name in a unique way.\n"
"@return The qualified name\n"
@ -932,6 +940,19 @@ Class<rdb::Item> decl_RdbItem ("rdb", "RdbItem",
"See \\image_str how to obtain the image.\n\n"
"This method has been introduced in version 0.28.\n"
) +
gsi::method ("comment", &rdb::Item::comment,
"@brief Gets the common associated with this item as a string\n"
"@return The comment string\n"
"The comment string is an arbitrary string added by the user to the item.\n"
"\n"
"This attribute has been added in version 0.29.1.\n"
) +
gsi::method ("comment=", &rdb::Item::set_comment, gsi::arg ("comment"),
"@brief Sets the common associated with this item as a string\n"
"See \\comment for a description of that attribute.\n"
"\n"
"This attribute has been added in version 0.29.1.\n"
) +
gsi::method ("image_str", &rdb::Item::image_str,
"@brief Gets the image associated with this item as a string\n"
"@return A base64-encoded image file (in PNG format)\n"
@ -1348,10 +1369,12 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
"@brief Creates a new cell\n"
"@param name The name of the cell\n"
) +
gsi::method ("create_cell", (rdb::Cell *(rdb::Database::*) (const std::string &, const std::string &)) &rdb::Database::create_cell, gsi::arg ("name"), gsi::arg ("variant"),
gsi::method ("create_cell", (rdb::Cell *(rdb::Database::*) (const std::string &, const std::string &, const std::string &)) &rdb::Database::create_cell, gsi::arg ("name"), gsi::arg ("variant"), gsi::arg ("layout_name", std::string ()),
"@brief Creates a new cell, potentially as a variant for a cell with the same name\n"
"@param name The name of the cell\n"
"@param variant The variant name of the cell\n"
"@param layout_name For variants, this is the name of the layout cell. If empty, 'name' is used for the layout cell name.\n"
"The 'layout_name' argument has been added in version 0.29.1.\n"
) +
gsi::method ("variants", &rdb::Database::variants, gsi::arg ("name"),
"@brief Gets the variants for a given cell name\n"

View File

@ -516,7 +516,7 @@ Cells::import_cell (const Cell &c)
{
Cell *cell;
if (mp_database) {
cell = mp_database->create_cell (c.name (), c.variant ());
cell = mp_database->create_cell (c.name (), c.variant (), c.layout_name ());
} else {
cell = new Cell (0, c.name ());
add_cell (cell);
@ -548,8 +548,8 @@ Cell::Cell (id_type id, const std::string &name)
// .. nothing yet ..
}
Cell::Cell (id_type id, const std::string &name, const std::string &variant)
: m_id (id), m_name (name), m_variant (variant), m_num_items (0), m_num_items_visited (0), mp_database (0)
Cell::Cell (id_type id, const std::string &name, const std::string &variant, const std::string &layout_name = std::string ())
: m_id (id), m_name (name), m_variant (variant), m_layout_name (layout_name), m_num_items (0), m_num_items_visited (0), mp_database (0)
{
// .. nothing yet ..
}
@ -939,6 +939,7 @@ Item &Item::operator= (const Item &d)
m_category_id = d.m_category_id;
m_visited = d.m_visited;
m_multiplicity = d.m_multiplicity;
m_comment = d.m_comment;
m_tag_ids = d.m_tag_ids;
m_image_str = d.m_image_str;
}
@ -1321,7 +1322,7 @@ Database::category_by_id_non_const (id_type id)
}
Cell *
Database::create_cell (const std::string &name, const std::string &variant)
Database::create_cell (const std::string &name, const std::string &variant, const std::string &layout_name)
{
set_modified ();
@ -1358,13 +1359,13 @@ Database::create_cell (const std::string &name, const std::string &variant)
}
}
new_cell = new Cell (++m_next_id, name, tl::to_string (variant_index + 1));
new_cell = new Cell (++m_next_id, name, tl::to_string (variant_index + 1), layout_name);
variant->second.push_back (new_cell->id ());
} else {
new_cell = new Cell (++m_next_id, name);
new_cell = new Cell (++m_next_id, name, std::string (), layout_name);
}
@ -1374,7 +1375,7 @@ Database::create_cell (const std::string &name, const std::string &variant)
} else {
new_cell = new Cell (++m_next_id, name, variant);
new_cell = new Cell (++m_next_id, name, variant, layout_name);
m_cells.add_cell (new_cell);
m_cells_by_id.insert (std::make_pair (new_cell->id (), new_cell));
m_cells_by_qname.insert (std::make_pair (new_cell->qname (), new_cell));
@ -1468,6 +1469,13 @@ Database::remove_item_tag (const Item *item, id_type tag)
const_cast <Item *> (item)->remove_tag (tag);
}
void
Database::set_item_comment (const Item *item, const std::string &comment)
{
set_modified ();
const_cast <Item *> (item)->set_comment (comment);
}
#if defined(HAVE_QT)
void
Database::set_item_image (const Item *item, const QImage &image)

View File

@ -1014,6 +1014,26 @@ public:
*/
void set_image_str (const std::string &s);
/**
* @brief Gets the item comment
*
* The comment string is an arbitrary string attached to the item.
*/
const std::string &comment () const
{
return m_comment;
}
/**
* @brief Sets the item comment
*
* The comment string is an arbitrary string attached to the item.
*/
void set_comment (const std::string &s)
{
m_comment = s;
}
/**
* @brief Get the database reference
*/
@ -1038,6 +1058,7 @@ private:
id_type m_cell_id;
id_type m_category_id;
size_t m_multiplicity;
std::string m_comment;
bool m_visited;
std::vector <bool> m_tag_ids;
Database *mp_database;
@ -1462,7 +1483,7 @@ public:
*
* This method is provided for persistency application only. It should not be used otherwise.
*/
Cell (id_type id, const std::string &name, const std::string &variant);
Cell (id_type id, const std::string &name, const std::string &variant, const std::string &layout_name);
/**
* @brief Cell destructor
@ -1488,7 +1509,7 @@ public:
}
/**
* @brief Get the cell name
* @brief Gets the cell name
*/
const std::string &name () const
{
@ -1496,7 +1517,7 @@ public:
}
/**
* @brief Set the name string (setter)
* @brief Sets the name string
*
* This method must not be used for items in the database to keep the database consistent.
*/
@ -1506,7 +1527,7 @@ public:
}
/**
* @brief Get the variant id
* @brief Gets the variant id
*/
const std::string &variant () const
{
@ -1514,7 +1535,7 @@ public:
}
/**
* @brief Set the variant string (setter)
* @brief Sets the variant string
*
* This method must not be used for items in the database to keep the database consistent.
*/
@ -1523,6 +1544,24 @@ public:
m_variant = v;
}
/**
* @brief Gets the layout cell name
*/
const std::string &layout_name () const
{
return m_layout_name;
}
/**
* @brief Sets the layout cell string
*
* This method must not be used for items in the database to keep the database consistent.
*/
void set_layout_name (const std::string &s)
{
m_layout_name = s;
}
/**
* @brief Get the qualified name (name plus optionally the variant id separated by a colon)
*/
@ -1600,6 +1639,7 @@ private:
id_type m_id;
std::string m_name;
std::string m_variant;
std::string m_layout_name;
size_t m_num_items;
size_t m_num_items_visited;
References m_references;
@ -2203,7 +2243,7 @@ public:
*/
Cell *create_cell (const std::string &name)
{
return create_cell (name, std::string ());
return create_cell (name, std::string (), std::string ());
}
/**
@ -2212,8 +2252,11 @@ public:
* A cell with name name/variant combination must not exist already.
* If the variant string is empty, this method behaves the same as the
* method without variant.
*
* "layout_name" is the name of the cell in the layout. If empty, the layout
* cell is assumed to be identical to "name".
*/
Cell *create_cell (const std::string &name, const std::string &variant);
Cell *create_cell (const std::string &name, const std::string &variant, const std::string &layout_name);
/**
* @brief Get all variants registered for a given cell name (not qname!)
@ -2307,6 +2350,11 @@ public:
*/
void remove_item_tag (const Item *item, id_type tag);
/**
* @brief Sets the comment string of the item
*/
void set_item_comment (const Item *item, const std::string &comment);
#if defined(HAVE_QT)
/**
* @brief Set the image of an item

View File

@ -91,7 +91,8 @@ make_rdb_structure (rdb::Database *rdb)
tl::make_element_with_parent_ref<rdb::Cell, rdb::Cells::const_iterator, rdb::Cells> (&rdb::Cells::begin, &rdb::Cells::end, &rdb::Cells::import_cell, "cell",
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::name, &rdb::Cell::set_name, "name") +
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::variant, &rdb::Cell::set_variant, "variant") +
tl::make_element_with_parent_ref<rdb::References, rdb::Cell> (&rdb::Cell::references, &rdb::Cell::import_references, "references",
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::layout_name, &rdb::Cell::set_layout_name, "layout-name") +
tl::make_element_with_parent_ref<rdb::References, rdb::Cell> (&rdb::Cell::references, &rdb::Cell::import_references, "references",
tl::make_element_with_parent_ref<rdb::Reference, rdb::References::const_iterator, rdb::References> (&rdb::References::begin, &rdb::References::end, &rdb::References::insert, "ref",
tl::make_member<std::string, rdb::Reference> (&rdb::Reference::parent_cell_qname, &rdb::Reference::set_parent_cell_qname, "parent") +
tl::make_member<std::string, rdb::Reference> (&rdb::Reference::trans_str, &rdb::Reference::set_trans_str, "trans")
@ -106,6 +107,7 @@ make_rdb_structure (rdb::Database *rdb)
tl::make_member<std::string, rdb::Item> (&rdb::Item::cell_qname, &rdb::Item::set_cell_qname, "cell") +
tl::make_member<bool, rdb::Item> (&rdb::Item::visited, &rdb::Item::set_visited, "visited") +
tl::make_member<size_t, rdb::Item> (&rdb::Item::multiplicity, &rdb::Item::set_multiplicity, "multiplicity") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::comment, &rdb::Item::set_comment, "comment") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::image_str, &rdb::Item::set_image_str, "image") +
tl::make_element<rdb::Values, rdb::Item> (&rdb::Item::values, &rdb::Item::set_values, "values",
tl::make_member<rdb::ValueWrapper, rdb::Values::const_iterator, rdb::Values> (&rdb::Values::begin, &rdb::Values::end, &rdb::Values::add, "value", ValueConverter (rdb))

View File

@ -521,11 +521,11 @@ TEST(6)
EXPECT_EQ (db.variants ("c1")[0], c1->id ());
EXPECT_EQ (db.variants ("c1")[1], c1a->id ());
rdb::Cell *c1b = db.create_cell ("c1", "var");
rdb::Cell *c1b = db.create_cell ("c1", "var", std::string ());
EXPECT_EQ (c1b->qname (), "c1:var")
EXPECT_EQ (db.variants ("c1").size (), size_t (3));
rdb::Cell *c2 = db.create_cell ("c2", "1027");
rdb::Cell *c2 = db.create_cell ("c2", "1027", std::string ());
EXPECT_EQ (c2->qname (), "c2:1027");
EXPECT_EQ (db.variants ("c2").size (), size_t (1));
@ -534,8 +534,9 @@ TEST(6)
EXPECT_EQ (c2->qname (), "c2:1027")
EXPECT_EQ (db.variants ("c2").size (), size_t (2));
rdb::Cell *c2b = db.create_cell ("c2", "var");
rdb::Cell *c2b = db.create_cell ("c2", "var", "c2$1");
EXPECT_EQ (c2b->qname (), "c2:var")
EXPECT_EQ (c2b->layout_name (), "c2$1")
rdb::Cell *c2c = db.create_cell ("c2");
EXPECT_EQ (c2c->qname (), "c2:2");

View File

@ -76,16 +76,22 @@ class RDB_TestClass < TestBase
assert_equal(cell.name, "cell_name")
assert_equal(cell.rdb_id, 1)
cell2 = db.create_cell("cell_name", "var1")
cell2 = db.create_cell("new_cell", "var1")
assert_equal(cell2.name, "new_cell")
assert_equal(cell2.layout_name, "")
assert_equal(cell2.qname, "new_cell:var1")
cell2 = db.create_cell("cell_name", "var1", "cell_name$1")
assert_equal(cell.name, "cell_name")
assert_equal(cell.qname, "cell_name:1")
assert_equal(db.cell_by_qname("cell_name:1").rdb_id, cell.rdb_id)
assert_equal(db.cell_by_id(cell.rdb_id).rdb_id, cell.rdb_id)
assert_equal(cell2.name, "cell_name")
assert_equal(cell2.layout_name, "cell_name$1")
assert_equal(cell2.qname, "cell_name:var1")
assert_equal(db.cell_by_qname("cell_name:var1").rdb_id, cell2.rdb_id)
assert_equal(db.cell_by_id(cell2.rdb_id).rdb_id, cell2.rdb_id)
assert_equal(cell2.rdb_id, 2)
assert_equal(cell2.rdb_id, 3)
assert_equal(cell.num_items, 0)
assert_equal(cell2.num_items, 0)
assert_equal(cell.num_items_visited, 0)
@ -98,19 +104,19 @@ class RDB_TestClass < TestBase
cc = []
db.each_cell { |c| cc.push(c) }
assert_equal(cc.size, 2)
assert_equal(cc.size, 3)
assert_equal(cc[0].rdb_id, cell.rdb_id)
assert_equal(cc[1].rdb_id, cell2.rdb_id)
assert_equal(cc[2].rdb_id, cell2.rdb_id)
cat = db.create_category("cat")
assert_equal(cat.database.inspect, db.inspect)
assert_equal(cat.name, "cat")
assert_equal(cat.rdb_id, 3)
assert_equal(cat.rdb_id, 4)
assert_equal(cat.path, "cat")
cats = db.create_category(cat, "subcat")
assert_equal(cats.name, "subcat")
assert_equal(cats.rdb_id, 4)
assert_equal(cats.rdb_id, 5)
assert_equal(cats.path, "cat.subcat")
assert_equal(cats.parent.rdb_id, cat.rdb_id)
@ -425,6 +431,10 @@ class RDB_TestClass < TestBase
assert_equal(item.image_str, "")
assert_equal(item.has_image?, false)
assert_equal(item.comment, "")
item.comment = "abc"
assert_equal(item.comment, "abc")
# can actually by any string, but only base64-encoded PNG images make sense
is="iVBORw0KGgoAAAANSUhEUgAAACoAAAA0CAIAAABzfT3nAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAA0SAAANOgHo3ZneAAAA3UlEQVRYhe2WwQ3DIAxFoco8XaGZIaeO43FyYgZYgYXcQ6SWuDGgBhWq/qccIvGCEd9SbAwAAPSGaW2lFR2rfWDpXrPpSe2SP10fvnn/PZHZH9IwbKFVZZ/Z6wMtZcjW02Bn2FVpZYdWdkr2nvh23S2FyDNJuVITpwmRjTGbNr0v20U5byNtJuuJt/fO2f93+UlbEJl5UjVPr3Y71EQ/PoPPlU+lDJtWlCt3GwCMG33BuJGAcWMEMG6c1jBudCyf/nzV8nbZPRohclFLHdGbZ8eNSjN1fmf0AACA1jwA4hKxu4C6P7EAAAAASUVORK5CYII="
item.image_str=is