mirror of https://github.com/KLayout/klayout.git
2546 lines
52 KiB
C++
2546 lines
52 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2024 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
#ifndef HDR_rdb
|
|
#define HDR_rdb
|
|
|
|
#include "rdbCommon.h"
|
|
|
|
#include "dbTrans.h"
|
|
#include "gsi.h"
|
|
#include "tlObject.h"
|
|
#include "tlObjectCollection.h"
|
|
#include "tlPixelBuffer.h"
|
|
|
|
#include <string>
|
|
#include <list>
|
|
#include <map>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
#if defined(HAVE_QT)
|
|
class QImage;
|
|
#endif
|
|
|
|
namespace tl
|
|
{
|
|
class Extractor;
|
|
}
|
|
|
|
namespace db
|
|
{
|
|
class Shape;
|
|
class Layout;
|
|
}
|
|
|
|
namespace rdb
|
|
{
|
|
|
|
typedef size_t id_type;
|
|
|
|
class References;
|
|
class Categories;
|
|
class Database;
|
|
class Cells;
|
|
class Cell;
|
|
class Items;
|
|
|
|
/**
|
|
* @brief A report item's category
|
|
*
|
|
* An item is member of exactly one category. This can be a check for example.
|
|
* A category is described by a name and a description string. An Id is provided
|
|
* to reference this category from actual report items.
|
|
* Categories can be organized hierarchically for which a category collection
|
|
* is provided and member of the individual category.
|
|
*
|
|
* A category can only be created by the database object, since the
|
|
* database object issues id's.
|
|
*/
|
|
class RDB_PUBLIC Category
|
|
: public tl::Object
|
|
{
|
|
public:
|
|
/**
|
|
* @brief The default constructor with a category reference
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
* Use Database::create_category instead.
|
|
*/
|
|
Category (Categories *categories);
|
|
|
|
/**
|
|
* @brief The default constructor
|
|
*/
|
|
Category ();
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
~Category ();
|
|
|
|
/**
|
|
* @brief The Id of the category (getter)
|
|
*/
|
|
id_type id () const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
/**
|
|
* @brief The Id of the category (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_id (id_type id)
|
|
{
|
|
m_id = id;
|
|
}
|
|
|
|
/**
|
|
* @brief The name string (getter)
|
|
*/
|
|
const std::string &name () const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/**
|
|
* @brief The the name string (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_name (const std::string &d)
|
|
{
|
|
m_name = d;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the path of this category
|
|
*
|
|
* The path contains all components leading to this category starting from a top level
|
|
* category. The path string can be used with category_by_name to localize the current
|
|
* category.
|
|
*/
|
|
std::string path () const;
|
|
|
|
/**
|
|
* @brief The description string (getter)
|
|
*/
|
|
const std::string &description () const
|
|
{
|
|
return m_description;
|
|
}
|
|
|
|
/**
|
|
* @brief The description string (setter)
|
|
*/
|
|
void set_description (const std::string &d)
|
|
{
|
|
m_description = d;
|
|
}
|
|
|
|
/**
|
|
* @brief The collection of sub-categories (const access)
|
|
*/
|
|
const Categories &sub_categories () const;
|
|
|
|
/**
|
|
* @brief The collection of sub-categories
|
|
*/
|
|
Categories &sub_categories ();
|
|
|
|
/**
|
|
* @brief The parent (owner) of this category (getter)
|
|
*/
|
|
const Category *parent () const
|
|
{
|
|
return mp_parent;
|
|
}
|
|
|
|
/**
|
|
* @brief The parent (owner) of this category (getter)
|
|
*/
|
|
Category *parent ()
|
|
{
|
|
return mp_parent;
|
|
}
|
|
|
|
/**
|
|
* @brief Import categories as sub categories.
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
* The Category object will take over ownership over the sub categories.
|
|
*/
|
|
void import_sub_categories (Categories *categories);
|
|
|
|
/**
|
|
* @brief Report the number of items
|
|
*/
|
|
size_t num_items () const
|
|
{
|
|
return m_num_items;
|
|
}
|
|
|
|
/**
|
|
* @brief Report the number of items visited
|
|
*/
|
|
size_t num_items_visited () const
|
|
{
|
|
return m_num_items_visited;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference (const version)
|
|
*/
|
|
const Database *database () const
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
private:
|
|
friend class Database;
|
|
friend class Categories;
|
|
|
|
id_type m_id;
|
|
std::string m_name, m_description;
|
|
Category *mp_parent;
|
|
Categories *mp_sub_categories;
|
|
size_t m_num_items;
|
|
size_t m_num_items_visited;
|
|
Database *mp_database;
|
|
|
|
/**
|
|
* @brief Default constructor
|
|
*
|
|
* Creates a category object with empty name and description.
|
|
* This constructor is private to allow only the database to produce a
|
|
* category object.
|
|
*/
|
|
Category (const std::string &name);
|
|
|
|
/**
|
|
* @brief The parent (owner) of this category (setter)
|
|
*/
|
|
void set_parent (Category *parent_category)
|
|
{
|
|
mp_parent = parent_category;
|
|
}
|
|
|
|
/**
|
|
* @brief Add an offset to the number of items visited
|
|
*/
|
|
void add_to_num_items_visited (int d)
|
|
{
|
|
m_num_items_visited += d;
|
|
}
|
|
|
|
/**
|
|
* @brief Add an offset to the number of items
|
|
*/
|
|
void add_to_num_items (int d)
|
|
{
|
|
m_num_items += d;
|
|
}
|
|
|
|
/**
|
|
* @brief Reset the number of items
|
|
*/
|
|
void reset_num_items ()
|
|
{
|
|
m_num_items = 0;
|
|
m_num_items_visited = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the database reference
|
|
*/
|
|
void set_database (Database *database);
|
|
|
|
// no copying, no default ctor
|
|
Category (const Category &d);
|
|
Category &operator= (const Category &d);
|
|
};
|
|
|
|
/**
|
|
* @brief The collection of categories
|
|
*
|
|
* A generic collection of categories used for the root node and
|
|
* sub-category nodes.
|
|
*/
|
|
class RDB_PUBLIC Categories
|
|
{
|
|
public:
|
|
typedef tl::shared_collection<Category>::const_iterator const_iterator;
|
|
typedef tl::shared_collection<Category>::iterator iterator;
|
|
|
|
/**
|
|
* @brief Constructor with a database reference
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Categories (Database *database)
|
|
: mp_database (database)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Constructor with a parent category reference
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Categories (Category *category)
|
|
: mp_database (category->database ())
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the categories inside this collection (begin iterator)
|
|
*/
|
|
const_iterator begin () const
|
|
{
|
|
return m_categories.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the categories inside this collection (end iterator)
|
|
*/
|
|
const_iterator end () const
|
|
{
|
|
return m_categories.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the categories inside this collection (begin iterator)
|
|
*/
|
|
iterator begin ()
|
|
{
|
|
return m_categories.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the categories inside this collection (end iterator)
|
|
*/
|
|
iterator end ()
|
|
{
|
|
return m_categories.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Find a category by name
|
|
*
|
|
* The name is actually a path expression which specifies the category starting from the given
|
|
* node with a '.' separated path notation. I.e. 'a.b' is the sub-category 'b' of category 'a'.
|
|
* If no such category can be found, 0 is returned.
|
|
*/
|
|
const Category *category_by_name (const char *path) const
|
|
{
|
|
return (const_cast <Categories *> (this)->category_by_name (path));
|
|
}
|
|
|
|
/**
|
|
* @brief Find a category by name (non-const version)
|
|
*
|
|
* The name is actually a path expression which specifies the category starting from the given
|
|
* node with a '.' separated path notation. I.e. 'a.b' is the sub-category 'b' of category 'a'.
|
|
* If no such category can be found, 0 is returned.
|
|
*/
|
|
Category *category_by_name (const char *path);
|
|
|
|
/**
|
|
* @brief Clear the collection of categories
|
|
*/
|
|
void clear ();
|
|
|
|
/**
|
|
* @brief Import a category
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
* This will take over ownership over the category.
|
|
*/
|
|
void import_category (Category *category);
|
|
|
|
/**
|
|
* @brief Gets the database reference
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database.get ();
|
|
}
|
|
|
|
public:
|
|
friend class Database;
|
|
friend class Category;
|
|
|
|
tl::shared_collection<Category> m_categories;
|
|
std::map <std::string, Category *> m_categories_by_name;
|
|
tl::weak_ptr<Database> mp_database;
|
|
|
|
Categories ()
|
|
: mp_database (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
void add_category (Category *cath);
|
|
|
|
void set_database (Database *database);
|
|
};
|
|
|
|
/**
|
|
* @brief This is the base class of any value associated with a marker item
|
|
* A value has a value (as the name says) and an optional tag id. Tag id's identify
|
|
* the value and make the value a named one.
|
|
*/
|
|
class RDB_PUBLIC ValueBase
|
|
{
|
|
public:
|
|
ValueBase ()
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
virtual ~ValueBase ()
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
virtual std::string to_string () const = 0;
|
|
|
|
virtual std::string to_display_string () const = 0;
|
|
|
|
virtual bool is_shape () const = 0;
|
|
|
|
virtual ValueBase *clone () const = 0;
|
|
|
|
virtual int type_index () const = 0;
|
|
|
|
virtual bool compare (const ValueBase *other) const = 0;
|
|
|
|
static bool compare (const ValueBase *a, const ValueBase *b);
|
|
|
|
static ValueBase *create_from_string (const std::string &s);
|
|
|
|
static ValueBase *create_from_string (tl::Extractor &ex);
|
|
|
|
static ValueBase *create_from_shape (const db::Shape &shape, const db::CplxTrans &trans);
|
|
};
|
|
|
|
/**
|
|
* @brief A type identifier
|
|
*
|
|
* This template function associates a type with an integer for the value.
|
|
*/
|
|
template <class T>
|
|
int type_index_of ();
|
|
|
|
/**
|
|
* @brief A generic class wrapped into a ValueBase
|
|
*
|
|
* Using this class, any value can be stored inside the collection of Values.
|
|
*/
|
|
template <class C>
|
|
class RDB_PUBLIC_TEMPLATE Value
|
|
: public ValueBase
|
|
{
|
|
public:
|
|
Value ()
|
|
: m_value ()
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
Value (const C &value)
|
|
: m_value (value)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
void set_value (const C &value)
|
|
{
|
|
m_value = value;
|
|
}
|
|
|
|
const C &value () const
|
|
{
|
|
return m_value;
|
|
}
|
|
|
|
C &value ()
|
|
{
|
|
return m_value;
|
|
}
|
|
|
|
int type_index () const
|
|
{
|
|
return type_index_of<C> ();
|
|
}
|
|
|
|
bool compare (const ValueBase *other) const;
|
|
|
|
bool is_shape () const;
|
|
|
|
std::string to_string () const;
|
|
|
|
std::string to_display_string () const;
|
|
|
|
ValueBase *clone () const
|
|
{
|
|
return new Value<C> (m_value);
|
|
}
|
|
|
|
private:
|
|
C m_value;
|
|
};
|
|
|
|
/**
|
|
* @brief Type bindings
|
|
*/
|
|
template <class T>
|
|
RDB_PUBLIC_TEMPLATE ValueBase *make_value (const T &value)
|
|
{
|
|
return new Value<T> (value);
|
|
}
|
|
|
|
/**
|
|
* @brief A class encapsulating ValueBase pointer
|
|
*/
|
|
class RDB_PUBLIC ValueWrapper
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Default constructor
|
|
*/
|
|
ValueWrapper ()
|
|
: mp_ptr (0), m_tag_id (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Constructor from an existing object
|
|
*/
|
|
ValueWrapper (ValueBase *ptr)
|
|
: mp_ptr (ptr), m_tag_id (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Copy constructor
|
|
*/
|
|
ValueWrapper (const ValueWrapper &d)
|
|
: mp_ptr (d.mp_ptr ? d.mp_ptr->clone () : 0), m_tag_id (d.m_tag_id)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
~ValueWrapper ()
|
|
{
|
|
set (0);
|
|
}
|
|
|
|
/**
|
|
* @brief Assignment
|
|
*/
|
|
ValueWrapper &operator= (const ValueWrapper &d)
|
|
{
|
|
if (this != &d) {
|
|
if (mp_ptr) {
|
|
delete mp_ptr;
|
|
}
|
|
mp_ptr = (d.mp_ptr ? d.mp_ptr->clone () : 0);
|
|
m_tag_id = d.m_tag_id;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the pointer
|
|
*/
|
|
ValueBase *get ()
|
|
{
|
|
return mp_ptr;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the pointer (const)
|
|
*/
|
|
const ValueBase *get () const
|
|
{
|
|
return mp_ptr;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the pointer
|
|
*/
|
|
void set (ValueBase *ptr)
|
|
{
|
|
if (mp_ptr) {
|
|
delete mp_ptr;
|
|
}
|
|
mp_ptr = ptr;
|
|
}
|
|
|
|
void set_tag_id (id_type id)
|
|
{
|
|
m_tag_id = id;
|
|
}
|
|
|
|
id_type tag_id () const
|
|
{
|
|
return m_tag_id;
|
|
}
|
|
|
|
/**
|
|
* @brief Convert the values collection to a string
|
|
*/
|
|
std::string to_string () const;
|
|
|
|
/**
|
|
* @brief Fill the values collection from the string
|
|
*/
|
|
void from_string (const std::string &s);
|
|
|
|
/**
|
|
* @brief Fill the values collection from an extractor
|
|
*/
|
|
void from_string (tl::Extractor &ex);
|
|
|
|
private:
|
|
ValueBase *mp_ptr;
|
|
id_type m_tag_id;
|
|
};
|
|
|
|
/**
|
|
* @brief A collection of value objects for a RDB item
|
|
*/
|
|
class RDB_PUBLIC Values
|
|
{
|
|
public:
|
|
typedef std::list<ValueWrapper>::const_iterator const_iterator;
|
|
typedef std::list<ValueWrapper>::iterator iterator;
|
|
|
|
/**
|
|
* @brief The default constructor
|
|
*/
|
|
Values ()
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Copy constructor
|
|
*/
|
|
Values (const Values &d)
|
|
{
|
|
operator= (d);
|
|
}
|
|
|
|
/**
|
|
* @brief Assignment
|
|
*/
|
|
Values &operator= (const Values &d);
|
|
|
|
/**
|
|
* @brief Compare two value sets (less operator)
|
|
*
|
|
* This compare function will use the tag mapping provided by tag map ("this" tag id to "other" tag id).
|
|
* Values with tags not listed in the tag map will not be compared.
|
|
* Untagged values (tag_id 0) will be compared always.
|
|
*
|
|
* "rev_tag_map" needs to be the reverse of "tag_map".
|
|
*
|
|
* The order of the values matters.
|
|
*/
|
|
bool compare (const Values &other, const std::set<id_type> &common_tags) const;
|
|
|
|
/**
|
|
* @brief The const iterator (begin)
|
|
*/
|
|
const_iterator begin () const
|
|
{
|
|
return m_values.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief The const iterator (end)
|
|
*/
|
|
const_iterator end () const
|
|
{
|
|
return m_values.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief The non-const iterator (begin)
|
|
*/
|
|
iterator begin ()
|
|
{
|
|
return m_values.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief The non-const iterator (end)
|
|
*/
|
|
iterator end ()
|
|
{
|
|
return m_values.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Add a new value
|
|
*
|
|
* The values collection will become owner of the pointer given.
|
|
*/
|
|
void add (ValueBase *value, id_type tag_id = 0)
|
|
{
|
|
m_values.push_back (ValueWrapper ());
|
|
m_values.back ().set (value);
|
|
m_values.back ().set_tag_id (tag_id);
|
|
}
|
|
|
|
/**
|
|
* @brief Add a new value from a wrapper
|
|
*/
|
|
void add (const ValueWrapper &value)
|
|
{
|
|
m_values.push_back (value);
|
|
}
|
|
|
|
/**
|
|
* @brief Swaps the values with other values
|
|
*/
|
|
void swap (Values &other)
|
|
{
|
|
m_values.swap (other.m_values);
|
|
}
|
|
|
|
/**
|
|
* @brief Clears the values
|
|
*/
|
|
void clear ()
|
|
{
|
|
m_values.clear ();
|
|
}
|
|
|
|
/**
|
|
* @brief Convert the values collection to a string
|
|
*/
|
|
std::string to_string () const;
|
|
|
|
/**
|
|
* @brief Fill the values collection from the string
|
|
*/
|
|
void from_string (const std::string &s);
|
|
|
|
private:
|
|
std::list <ValueWrapper> m_values;
|
|
};
|
|
|
|
/**
|
|
* @brief A report item
|
|
*
|
|
* A report item is one information item in the report.
|
|
* The value of a report item is manyfold. Values can be keyed,
|
|
* i.e. multiple values can be present with different keys.
|
|
* Each value can be of different types where the type is specified by a type Id.
|
|
*/
|
|
class RDB_PUBLIC Item
|
|
: public tl::Object
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Construct an item from a items reference
|
|
*/
|
|
Item (Items *items);
|
|
|
|
/**
|
|
* @brief Copy constructor
|
|
*/
|
|
Item (const Item &d);
|
|
|
|
/**
|
|
* @brief Assignment
|
|
*/
|
|
Item &operator= (const Item &d);
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
~Item ();
|
|
|
|
/**
|
|
* @brief Get the cell that this item is located inside (by id)
|
|
*/
|
|
id_type cell_id () const
|
|
{
|
|
return m_cell_id;
|
|
}
|
|
|
|
/**
|
|
* @brief The cell id (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_cell_id (id_type id)
|
|
{
|
|
m_cell_id = id;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the cell that this item is located inside (by name or name:variant combination)
|
|
*/
|
|
std::string cell_qname () const;
|
|
|
|
/**
|
|
* @brief The cell name or name:variant combination (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_cell_qname (const std::string &qname);
|
|
|
|
/**
|
|
* @brief Get the category that this item is located inside (by id)
|
|
*/
|
|
id_type category_id () const
|
|
{
|
|
return m_category_id;
|
|
}
|
|
|
|
/**
|
|
* @brief The category Id of the category (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_category_id (id_type id)
|
|
{
|
|
m_category_id = id;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the category that this item is located inside (by name)
|
|
*/
|
|
std::string category_name () const;
|
|
|
|
/**
|
|
* @brief The category name (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_category_name (const std::string &name);
|
|
|
|
/**
|
|
* @brief The list of values of this item
|
|
*/
|
|
const Values &values () const
|
|
{
|
|
return m_values;
|
|
}
|
|
|
|
/**
|
|
* @brief The list of values of this item (non-const version)
|
|
*/
|
|
Values &values ()
|
|
{
|
|
return m_values;
|
|
}
|
|
|
|
/**
|
|
* @brief Add a value in a generic way
|
|
*/
|
|
template <class V>
|
|
ValueBase *add_value (const V &v, id_type tag_id = 0)
|
|
{
|
|
ValueBase *value = new Value<V> (v);
|
|
values ().add (value, tag_id);
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the list of values
|
|
*/
|
|
void set_values (const Values &values)
|
|
{
|
|
m_values = values;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the multiplicity of the item
|
|
*/
|
|
void set_multiplicity (size_t n)
|
|
{
|
|
m_multiplicity = n;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the multiplicity of this item
|
|
*/
|
|
size_t multiplicity () const
|
|
{
|
|
return m_multiplicity;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns true if the item was visited already.
|
|
*
|
|
* This property should be changed with rdb::Database::set_item_visited.
|
|
*/
|
|
bool visited () const
|
|
{
|
|
return m_visited;
|
|
}
|
|
|
|
/**
|
|
* @brief Directly set the visited flag
|
|
*
|
|
* This method must not be used for items already in the database to keep
|
|
* the database consistent. Use rdb::Database::set_item_visited instead.
|
|
*/
|
|
void set_visited (bool v)
|
|
{
|
|
m_visited = v;
|
|
}
|
|
|
|
/**
|
|
* @brief Add a tag to this item
|
|
*/
|
|
void add_tag (id_type tag_id);
|
|
|
|
/**
|
|
* @brief Remove a tag from this item
|
|
*/
|
|
void remove_tag (id_type tag_id);
|
|
|
|
/**
|
|
* @brief Remove all tags of this item
|
|
*/
|
|
void remove_tags ();
|
|
|
|
/**
|
|
* @brief Check, if this item has the given tag
|
|
*/
|
|
bool has_tag (id_type tag_id) const;
|
|
|
|
/**
|
|
* @brief Get the tags for this item by string
|
|
*/
|
|
std::string tag_str () const;
|
|
|
|
/**
|
|
* @brief Set the tags for this item from a string
|
|
*/
|
|
void set_tag_str (const std::string &tags);
|
|
|
|
#if defined(HAVE_QT)
|
|
/**
|
|
* @brief Gets the image object attached to this item
|
|
*
|
|
* @return The image object or an empty image if no image is attached
|
|
*/
|
|
QImage image () const;
|
|
|
|
/**
|
|
* @brief Set the image for this item
|
|
*/
|
|
void set_image (const QImage &image);
|
|
#endif
|
|
|
|
#if defined(HAVE_PNG)
|
|
/**
|
|
* @brief Gets the image as a tl::PixelBuffer object
|
|
*/
|
|
tl::PixelBuffer image_pixels () const;
|
|
|
|
/**
|
|
* @brief Sets the image from a tl::PixelBuffer object
|
|
*/
|
|
void set_image (const tl::PixelBuffer &image);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Gets a value indicating whether the item has an image
|
|
*/
|
|
bool has_image () const;
|
|
|
|
/**
|
|
* @brief Gets the image as a string (PNG, base64 coded)
|
|
*
|
|
* Note: if neither PNG support for Qt are compiled in, this string will be empty
|
|
*/
|
|
std::string image_str () const;
|
|
|
|
/**
|
|
* @brief Gets the image from a string (PNG, base64 coded)
|
|
*
|
|
* If the image string is empty, the image will be cleared.
|
|
* If the image string is not valid, the image will also be cleared.
|
|
*/
|
|
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
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference (const version)
|
|
*/
|
|
const Database *database () const
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
private:
|
|
friend class Database;
|
|
friend class Items;
|
|
|
|
Values m_values;
|
|
id_type m_cell_id;
|
|
id_type m_category_id;
|
|
size_t m_multiplicity;
|
|
std::string m_comment;
|
|
bool m_visited;
|
|
std::set <id_type> m_tag_ids;
|
|
Database *mp_database;
|
|
std::string m_image_str;
|
|
|
|
Item ();
|
|
|
|
/**
|
|
* @brief Set the database reference
|
|
*/
|
|
void set_database (Database *database)
|
|
{
|
|
mp_database = database;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief An item reference
|
|
*
|
|
* This is basically a wrapper for a pointer that correctly
|
|
* maps const * and non-const * values through the operator->
|
|
* overloads.
|
|
*/
|
|
class RDB_PUBLIC ItemRef
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*/
|
|
ItemRef (Item *item)
|
|
: mp_item (item)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief non-const access
|
|
*/
|
|
Item *operator-> ()
|
|
{
|
|
return mp_item;
|
|
}
|
|
|
|
/**
|
|
* @brief non-const reference access
|
|
*/
|
|
Item &operator* ()
|
|
{
|
|
return *mp_item;
|
|
}
|
|
|
|
/**
|
|
* @brief const access
|
|
*/
|
|
const Item *operator-> () const
|
|
{
|
|
return mp_item;
|
|
}
|
|
|
|
/**
|
|
* @brief const reference access
|
|
*/
|
|
const Item &operator* () const
|
|
{
|
|
return *mp_item;
|
|
}
|
|
|
|
public:
|
|
Item *mp_item;
|
|
};
|
|
|
|
/**
|
|
* @brief A container for items
|
|
*
|
|
* This container is owned by the database.
|
|
*/
|
|
class RDB_PUBLIC Items
|
|
{
|
|
public:
|
|
typedef std::list<Item>::const_iterator const_iterator;
|
|
typedef std::list<Item>::iterator iterator;
|
|
|
|
/**
|
|
* @brief Construct an item list with a database reference
|
|
*/
|
|
Items (Database *database)
|
|
: mp_database (database)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the items inside this collection (begin iterator)
|
|
*/
|
|
const_iterator begin () const
|
|
{
|
|
return m_items.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the items inside this collection (end iterator)
|
|
*/
|
|
const_iterator end () const
|
|
{
|
|
return m_items.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the items inside this collection (non-const begin iterator)
|
|
*/
|
|
iterator begin ()
|
|
{
|
|
return m_items.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterate the items inside this collection (non-const end iterator)
|
|
*/
|
|
iterator end ()
|
|
{
|
|
return m_items.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Add an item
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void add_item (const Item &item)
|
|
{
|
|
m_items.push_back (item);
|
|
m_items.back ().set_database (mp_database);
|
|
}
|
|
|
|
/**
|
|
* @brief Get a reference to the last item
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Item &back ()
|
|
{
|
|
return m_items.back ();
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
private:
|
|
friend class Cell;
|
|
friend class Database;
|
|
|
|
std::list <Item> m_items;
|
|
Database *mp_database;
|
|
|
|
Items (const Items &d);
|
|
Items &operator= (const Items &d);
|
|
|
|
Items ()
|
|
: mp_database (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
void set_database (Database *database)
|
|
{
|
|
mp_database = database;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief A reference description
|
|
*
|
|
* A reference describes how a cell is located inside a parent cell.
|
|
* The reference is not meant to replace a full hierarchy graph. Instead
|
|
* it is intended as a hint how to display a marker in a top level context
|
|
*/
|
|
class RDB_PUBLIC Reference
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructs a reference with a unit transformation and a empty parent cell id
|
|
*/
|
|
Reference ()
|
|
: m_trans (), m_parent_cell_id (0), mp_database (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Constructs a reference in the context of a References collection
|
|
*/
|
|
Reference (References *references);
|
|
|
|
/**
|
|
* @brief Constructs a reference with the given transformation and the given parent cell id
|
|
*
|
|
* @param trans The transformation which transforms anything of this cell into the parent cell.
|
|
*/
|
|
Reference (const db::DCplxTrans &trans, id_type parent_cell_id)
|
|
: m_trans (trans), m_parent_cell_id (parent_cell_id), mp_database (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Set the parent cell id
|
|
*/
|
|
void set_parent_cell_id (id_type id)
|
|
{
|
|
m_parent_cell_id = id;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the parent cell id
|
|
*/
|
|
id_type parent_cell_id () const
|
|
{
|
|
return m_parent_cell_id;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the parent cell name (plus optionally the variant id separated by a colon - i.e. cell:var1)
|
|
*/
|
|
void set_parent_cell_qname (const std::string &qname);
|
|
|
|
/**
|
|
* @brief Get the transformation as string (plus optionally the variant id separated by a colon - i.e. cell:var1)
|
|
*/
|
|
std::string parent_cell_qname () const;
|
|
|
|
/**
|
|
* @brief Set the transformation
|
|
*/
|
|
void set_trans (const db::DCplxTrans &trans)
|
|
{
|
|
m_trans = trans;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the transformation
|
|
*/
|
|
const db::DCplxTrans &trans () const
|
|
{
|
|
return m_trans;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the transformation as string
|
|
*/
|
|
void set_trans_str (const std::string &str);
|
|
|
|
/**
|
|
* @brief Get the transformation as string
|
|
*/
|
|
std::string trans_str () const;
|
|
|
|
/**
|
|
* @brief Get the database reference
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference (const version)
|
|
*/
|
|
const Database *database () const
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
private:
|
|
friend class References;
|
|
|
|
db::DCplxTrans m_trans;
|
|
id_type m_parent_cell_id;
|
|
Database *mp_database;
|
|
|
|
/**
|
|
* @brief Set the database reference
|
|
*/
|
|
void set_database (Database *database)
|
|
{
|
|
mp_database = database;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief A collection of references
|
|
*/
|
|
class RDB_PUBLIC References
|
|
{
|
|
public:
|
|
typedef std::vector<Reference>::const_iterator const_iterator;
|
|
typedef std::vector<Reference>::iterator iterator;
|
|
|
|
/**
|
|
* @brief Create a References object for a cell
|
|
*/
|
|
References (Cell *cell);
|
|
|
|
/**
|
|
* @brief Add a reference to this collection
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void insert (const Reference &ref)
|
|
{
|
|
m_references.push_back (ref);
|
|
m_references.back ().set_database (mp_database);
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator (const)
|
|
*/
|
|
const_iterator begin () const
|
|
{
|
|
return m_references.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator (const)
|
|
*/
|
|
const_iterator end () const
|
|
{
|
|
return m_references.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator (non-const)
|
|
*/
|
|
iterator begin ()
|
|
{
|
|
return m_references.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator (non-const)
|
|
*/
|
|
iterator end ()
|
|
{
|
|
return m_references.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Clear this collection
|
|
*/
|
|
void clear ()
|
|
{
|
|
m_references.clear ();
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
private:
|
|
friend class Database;
|
|
friend class Cell;
|
|
|
|
std::vector<Reference> m_references;
|
|
Database *mp_database;
|
|
|
|
/**
|
|
* @brief Set the database reference
|
|
*/
|
|
void set_database (Database *database);
|
|
|
|
References ();
|
|
|
|
// no copying, no default ctor
|
|
References (const References &d);
|
|
References &operator= (const References &d);
|
|
};
|
|
|
|
/**
|
|
* @brief A class describing a cell
|
|
*
|
|
* A cell has a collection of items, a unique id and a name.
|
|
* A cell can only be create by the database.
|
|
*/
|
|
class RDB_PUBLIC Cell
|
|
: public tl::Object
|
|
{
|
|
public:
|
|
typedef std::vector<Reference> references_list_type;
|
|
typedef std::vector<Reference>::const_iterator reference_iterator;
|
|
|
|
/**
|
|
* @brief The default constructor
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Cell ();
|
|
|
|
/**
|
|
* @brief The constructor taking the database reference from the Cells collection
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Cell (Cells *cells);
|
|
|
|
/**
|
|
* @brief the constructor from an id and a name
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Cell (id_type id, const std::string &name);
|
|
|
|
/**
|
|
* @brief the constructor from an id and a name and a variant id
|
|
*
|
|
* 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, const std::string &layout_name);
|
|
|
|
/**
|
|
* @brief Cell destructor
|
|
*/
|
|
~Cell ();
|
|
|
|
/**
|
|
* @brief Get the cell id
|
|
*/
|
|
id_type id () const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
/**
|
|
* @brief The Id of the category (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_id (id_type id)
|
|
{
|
|
m_id = id;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the cell name
|
|
*/
|
|
const std::string &name () const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the name string
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_name (const std::string &d)
|
|
{
|
|
m_name = d;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the variant id
|
|
*/
|
|
const std::string &variant () const
|
|
{
|
|
return m_variant;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the variant string
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_variant (const std::string &v)
|
|
{
|
|
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)
|
|
*/
|
|
std::string qname () const;
|
|
|
|
/**
|
|
* @brief Report the number of items in total
|
|
*/
|
|
size_t num_items () const
|
|
{
|
|
return m_num_items;
|
|
}
|
|
|
|
/**
|
|
* @brief Report the number of items visited
|
|
*/
|
|
size_t num_items_visited () const
|
|
{
|
|
return m_num_items_visited;
|
|
}
|
|
|
|
/**
|
|
* @brief The reference collection (const)
|
|
*/
|
|
const References &references () const
|
|
{
|
|
return m_references;
|
|
}
|
|
|
|
/**
|
|
* @brief The reference collection (non-const)
|
|
*/
|
|
References &references ()
|
|
{
|
|
return m_references;
|
|
}
|
|
|
|
/**
|
|
* @brief Import a set of references
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void import_references (const References &references);
|
|
|
|
/**
|
|
* @brief Get one example transformation leading from this cell to a given parent cell
|
|
*
|
|
* This method will try to determine one path from the given cell to the given parent
|
|
* cell and return the accumulated transformation for this path.
|
|
* If no path is found, the first parameter of the returned pair is false, otherwise it's
|
|
* true.
|
|
*/
|
|
std::pair<bool, db::DCplxTrans> path_to (id_type parent_cell_id, const rdb::Database *db) const;
|
|
|
|
/**
|
|
* @brief Get the database reference
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference (const version)
|
|
*/
|
|
const Database *database () const
|
|
{
|
|
return mp_database;
|
|
}
|
|
|
|
private:
|
|
friend class Database;
|
|
friend class Cells;
|
|
|
|
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;
|
|
Database *mp_database;
|
|
|
|
Cell (const Cell &d);
|
|
Cell &operator= (const Cell &d);
|
|
|
|
/**
|
|
* @brief Add an offset to the number of items visited
|
|
*/
|
|
void add_to_num_items_visited (int d)
|
|
{
|
|
m_num_items_visited += d;
|
|
}
|
|
|
|
/**
|
|
* @brief Add an offset to the number of items
|
|
*/
|
|
void add_to_num_items (int d)
|
|
{
|
|
m_num_items += d;
|
|
}
|
|
|
|
/**
|
|
* @brief Reset the number of items
|
|
*/
|
|
void reset_num_items ()
|
|
{
|
|
m_num_items = 0;
|
|
m_num_items_visited = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the database reference
|
|
*/
|
|
void set_database (Database *database)
|
|
{
|
|
mp_database = database;
|
|
m_references.set_database (database);
|
|
}
|
|
|
|
std::pair<bool, db::DCplxTrans> path_to (id_type parent_cell_id, const Database *db, std::set <id_type> &visited, const db::DCplxTrans &trans) const;
|
|
};
|
|
|
|
/**
|
|
* @brief A collection of cells
|
|
*/
|
|
class RDB_PUBLIC Cells
|
|
{
|
|
public:
|
|
typedef tl::shared_collection<Cell>::const_iterator const_iterator;
|
|
typedef tl::shared_collection<Cell>::iterator iterator;
|
|
|
|
/**
|
|
* @brief The default Constructor
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Cells ()
|
|
: mp_database (0)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief The default Constructor
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Cells (Database *database)
|
|
: mp_database (database)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Add a cell to this collection
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void add_cell (Cell *cell)
|
|
{
|
|
m_cells.push_back (cell);
|
|
cell->set_database (mp_database.get ());
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator (const)
|
|
*/
|
|
const_iterator begin () const
|
|
{
|
|
return m_cells.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator (const)
|
|
*/
|
|
const_iterator end () const
|
|
{
|
|
return m_cells.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator (non-const)
|
|
*/
|
|
iterator begin ()
|
|
{
|
|
return m_cells.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator (non-const)
|
|
*/
|
|
iterator end ()
|
|
{
|
|
return m_cells.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Clear this collection
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void clear ()
|
|
{
|
|
m_cells.clear ();
|
|
}
|
|
|
|
/**
|
|
* @brief Import a cell
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void import_cell (const Cell &cell);
|
|
|
|
/**
|
|
* @brief Get the database reference
|
|
*/
|
|
const Database *database () const
|
|
{
|
|
return mp_database.get ();
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database reference (non-const)
|
|
*/
|
|
Database *database ()
|
|
{
|
|
return mp_database.get ();
|
|
}
|
|
|
|
private:
|
|
friend class Database;
|
|
|
|
tl::shared_collection<Cell> m_cells;
|
|
tl::weak_ptr<Database> mp_database;
|
|
|
|
/**
|
|
* @brief Set the database reference
|
|
*/
|
|
void set_database (Database *database)
|
|
{
|
|
mp_database = database;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief Represents a tag
|
|
*
|
|
* A tag has a name and a description. A tag is identifies with an Id.
|
|
*/
|
|
class RDB_PUBLIC Tag
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Default constructor
|
|
*/
|
|
Tag ()
|
|
: m_id (0), m_is_user_tag (false)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief The constructor
|
|
*/
|
|
Tag (id_type id, const std::string &name, bool user_tag = false)
|
|
: m_id (id), m_is_user_tag (user_tag), m_name (name)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
/**
|
|
* @brief Set the description
|
|
*/
|
|
void set_description (const std::string &d)
|
|
{
|
|
m_description = d;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the description
|
|
*/
|
|
const std::string &description () const
|
|
{
|
|
return m_description;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets a flag indicating whether the tag is a user tag or a system tag
|
|
*
|
|
* If this flag is false, the tag is a system tag used for tagging "waived" and
|
|
* similar conditions. Otherwise it is a user tag which can be used freely to
|
|
* tag arbitrary conditions.
|
|
*/
|
|
bool is_user_tag () const
|
|
{
|
|
return m_is_user_tag;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets a flag indicating whether the tag is a user tag or a system tag
|
|
*
|
|
* See \is_user_tag for details.
|
|
*/
|
|
void set_user_tag (bool user)
|
|
{
|
|
m_is_user_tag = user;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the id
|
|
*/
|
|
id_type id () const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
/**
|
|
* @brief The Id of the category (setter)
|
|
*
|
|
* This method must not be used for items in the database to keep the database consistent.
|
|
*/
|
|
void set_id (id_type id)
|
|
{
|
|
m_id = id;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the name
|
|
*/
|
|
const std::string &name () const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the name
|
|
*
|
|
* The name of the tag must not be changed when the tag is already part of a Tags collection.
|
|
* Otherwise, the tag collection becomes inconsistent.
|
|
*/
|
|
void set_name (const std::string &name)
|
|
{
|
|
m_name = name;
|
|
}
|
|
|
|
private:
|
|
id_type m_id;
|
|
bool m_is_user_tag;
|
|
std::string m_name, m_description;
|
|
};
|
|
|
|
/**
|
|
* @brief Represents a tag collection
|
|
*/
|
|
class RDB_PUBLIC Tags
|
|
{
|
|
public:
|
|
typedef std::vector <rdb::Tag> tag_list_type;
|
|
typedef tag_list_type::const_iterator const_iterator;
|
|
|
|
/**
|
|
* @brief Default constructor for the tags list
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
Tags ();
|
|
|
|
/**
|
|
* @brief Get the tag for a name (const version)
|
|
*/
|
|
const Tag &tag (const std::string &name, bool user_tag = false) const;
|
|
|
|
/**
|
|
* @brief Get the tag for a name (non-const version)
|
|
*/
|
|
Tag &tag (const std::string &name, bool user_tag = false);
|
|
|
|
/**
|
|
* @brief Get the tag for an id
|
|
*/
|
|
const Tag &tag (id_type id) const;
|
|
|
|
/**
|
|
* @brief Get the tag for an id
|
|
*/
|
|
Tag &tag (id_type id);
|
|
|
|
/**
|
|
* @brief Determine if a tag with that name already exists
|
|
*/
|
|
bool has_tag (const std::string &name, bool user_tag = false) const;
|
|
|
|
/**
|
|
* @brief Get the tag iterator (begin)
|
|
*/
|
|
const_iterator begin_tags () const
|
|
{
|
|
return m_tags.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Get the tag iterator (end)
|
|
*/
|
|
const_iterator end_tags () const
|
|
{
|
|
return m_tags.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Import a tag
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
* This will assign a new id to the tag and replace any tag with that
|
|
* name.
|
|
*/
|
|
void import_tag (const Tag &tag);
|
|
|
|
/**
|
|
* @brief Clear the collection of tags
|
|
*/
|
|
void clear ();
|
|
|
|
/**
|
|
* @brief Gets the name and user flag for a tag ID
|
|
*
|
|
* This method will assert if the tag ID is not valid in the global namespace.
|
|
*/
|
|
static const std::pair<std::string, bool> &name_for_id (id_type tag_id);
|
|
|
|
/**
|
|
* @brief Gets the id for a given name and user flag
|
|
*
|
|
* This will pull the ID from the global namespace.
|
|
*/
|
|
static id_type id_for_name (const std::string &name, bool user_flag);
|
|
|
|
/**
|
|
* @brief Gets a tag object for a given name and user flag
|
|
*
|
|
* This will create the tag from the global namespace.
|
|
*/
|
|
static Tag tag_for_name (const std::string &name, bool user_flag);
|
|
|
|
private:
|
|
friend class Database;
|
|
|
|
mutable std::map<id_type, size_t> m_tags_per_id;
|
|
mutable std::vector<Tag> m_tags;
|
|
};
|
|
|
|
/**
|
|
* @brief The database object
|
|
*/
|
|
class RDB_PUBLIC Database
|
|
: public gsi::ObjectBase,
|
|
public tl::Object
|
|
{
|
|
public:
|
|
typedef Items::const_iterator const_item_iterator;
|
|
typedef Items::iterator item_iterator;
|
|
typedef std::list<ItemRef>::const_iterator const_item_ref_iterator;
|
|
typedef std::list<ItemRef>::iterator item_ref_iterator;
|
|
typedef Cells::const_iterator const_cell_iterator;
|
|
typedef Cells::iterator cell_iterator;
|
|
|
|
/**
|
|
* @brief Default constructor
|
|
*/
|
|
Database ();
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
~Database ();
|
|
|
|
/**
|
|
* @brief Get the database description
|
|
*/
|
|
const std::string &description () const
|
|
{
|
|
return m_description;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the database description
|
|
*/
|
|
void set_description (const std::string &description)
|
|
{
|
|
set_modified ();
|
|
m_description = description;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database original file
|
|
*
|
|
* The original file describes what original file the marker database
|
|
* was derived from.
|
|
*/
|
|
const std::string &original_file () const
|
|
{
|
|
return m_original_file;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the database original file
|
|
*/
|
|
void set_original_file (const std::string &original_file)
|
|
{
|
|
set_modified ();
|
|
m_original_file = original_file;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the database name
|
|
*/
|
|
const std::string &name () const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the database name
|
|
*/
|
|
void set_name (const std::string &name)
|
|
{
|
|
m_name = name;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the file name
|
|
*/
|
|
const std::string &filename () const
|
|
{
|
|
return m_filename;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the file name
|
|
*/
|
|
void set_filename (const std::string &filename)
|
|
{
|
|
set_modified ();
|
|
m_filename = filename;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the generator name
|
|
*/
|
|
const std::string &generator () const
|
|
{
|
|
return m_generator;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the generator name
|
|
*/
|
|
void set_generator (const std::string &generator)
|
|
{
|
|
set_modified ();
|
|
m_generator = generator;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the top cell name
|
|
*/
|
|
void set_top_cell_name (const std::string &topcell)
|
|
{
|
|
set_modified ();
|
|
m_topcell = topcell;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the top cell name
|
|
*/
|
|
const std::string &top_cell_name () const
|
|
{
|
|
return m_topcell;
|
|
}
|
|
|
|
/*
|
|
* @brief Get the reference to the tags collection (const version)
|
|
*/
|
|
const Tags &tags () const
|
|
{
|
|
return m_tags;
|
|
}
|
|
|
|
/**
|
|
* @brief Import tags
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void import_tags (const Tags &tags);
|
|
|
|
/**
|
|
* @brief Get the reference to the categories collection (const version)
|
|
*/
|
|
const Categories &categories () const
|
|
{
|
|
return *mp_categories;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the reference to the categories collection (non-const version)
|
|
*/
|
|
Categories &categories_non_const ()
|
|
{
|
|
return *mp_categories;
|
|
}
|
|
|
|
/**
|
|
* @brief Import categories
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
* This will take over the ownership over the Categories object.
|
|
*/
|
|
void import_categories (Categories *categories);
|
|
|
|
/**
|
|
* @brief Create a category and register it
|
|
*/
|
|
Category *create_category (const std::string &name);
|
|
|
|
/**
|
|
* @brief Create a category as a subcategory and register it
|
|
*/
|
|
Category *create_category (Category *parent, const std::string &name);
|
|
|
|
/**
|
|
* @brief Create a category as a subcategory in the container and register it
|
|
*
|
|
* Hint: this method does not set the parent properly and must not be used
|
|
* under normal circumstances. It is provided as a internal method and
|
|
* to be used in the persistency code.
|
|
*/
|
|
Category *create_category (Categories *container, const std::string &name);
|
|
|
|
/**
|
|
* @brief Get the category pointer for a category name (const version)
|
|
*
|
|
* This method returns 0 if the category name is invalid.
|
|
*/
|
|
const Category *category_by_name (const std::string &name) const
|
|
{
|
|
return const_cast<Database *> (this)->category_by_name_non_const (name);
|
|
}
|
|
|
|
/**
|
|
* @brief Get the category pointer for a category id (const version)
|
|
*
|
|
* This method returns 0 if the category is invalid.
|
|
*/
|
|
const Category *category_by_id (id_type id) const
|
|
{
|
|
return const_cast<Database *> (this)->category_by_id_non_const (id);
|
|
}
|
|
|
|
/**
|
|
* @brief Get the category pointer for a category name (non-const version)
|
|
*
|
|
* This method returns 0 if the category name is invalid.
|
|
*/
|
|
Category *category_by_name_non_const (const std::string &name);
|
|
|
|
/**
|
|
* @brief Get the category pointer for a category id (non-const version)
|
|
*
|
|
* This method returns 0 if the category is invalid.
|
|
*/
|
|
Category *category_by_id_non_const (id_type id);
|
|
|
|
/**
|
|
* @brief Access to the cell collection (const)
|
|
*/
|
|
const Cells &cells () const
|
|
{
|
|
return m_cells;
|
|
}
|
|
|
|
/**
|
|
* @brief Access to the cell collection
|
|
*/
|
|
Cells &cells_non_const ()
|
|
{
|
|
return m_cells;
|
|
}
|
|
|
|
/**
|
|
* @brief Import cells
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
*/
|
|
void import_cells (const Cells &cells);
|
|
|
|
/**
|
|
* @brief Create a cell and register it
|
|
*
|
|
* If a cell with that name already exists, a variant is created
|
|
*/
|
|
Cell *create_cell (const std::string &name)
|
|
{
|
|
return create_cell (name, std::string (), std::string ());
|
|
}
|
|
|
|
/**
|
|
* @brief Create a cell variant and register it
|
|
*
|
|
* 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, const std::string &layout_name);
|
|
|
|
/**
|
|
* @brief Get all variants registered for a given cell name (not qname!)
|
|
*
|
|
* @return a vector of id's corresponding to the given variants or an empty vector if the name is not valid or the cell has no variants
|
|
*/
|
|
const std::vector <id_type> &variants (const std::string &name);
|
|
|
|
/**
|
|
* @brief Get the cell pointer for a cell name or name:variant combination (const version)
|
|
*
|
|
* This method returns 0 if the cell name or name:variant combination is invalid.
|
|
*/
|
|
const Cell *cell_by_qname (const std::string &name) const
|
|
{
|
|
return const_cast<Database *> (this)->cell_by_qname_non_const (name);
|
|
}
|
|
|
|
/**
|
|
* @brief Get the cell pointer for a cell id (const version)
|
|
*
|
|
* This method returns 0 if the cell id is invalid.
|
|
*/
|
|
const Cell *cell_by_id (id_type id) const
|
|
{
|
|
return const_cast<Database *> (this)->cell_by_id_non_const (id);
|
|
}
|
|
|
|
/**
|
|
* @brief Get the cell pointer for a cell name or name:variant combination (non-const version)
|
|
*
|
|
* This method returns 0 if the cell name or name:variant combination is invalid.
|
|
*/
|
|
Cell *cell_by_qname_non_const (const std::string &qname);
|
|
|
|
/**
|
|
* @brief Get the cell pointer for a cell id (non-const version)
|
|
*
|
|
* This method returns 0 if the cell id is invalid.
|
|
*/
|
|
Cell *cell_by_id_non_const (id_type id);
|
|
|
|
/**
|
|
* @brief Report the number of items in total
|
|
*/
|
|
size_t num_items () const
|
|
{
|
|
return m_num_items;
|
|
}
|
|
|
|
/**
|
|
* @brief Report the number of items visited
|
|
*/
|
|
size_t num_items_visited () const
|
|
{
|
|
return m_num_items_visited;
|
|
}
|
|
|
|
/**
|
|
* @brief Report the number of items for a given cell and category id
|
|
*/
|
|
size_t num_items (id_type cell_id, id_type category_id) const;
|
|
|
|
/**
|
|
* @brief Report the number of items visited
|
|
*/
|
|
size_t num_items_visited (id_type cell_id, id_type category_id) const;
|
|
|
|
/**
|
|
* @brief Create a new item for the given cell and category (both given by id)
|
|
*/
|
|
Item *create_item (id_type cell_id, id_type category_id);
|
|
|
|
/**
|
|
* @brief Set a tag's description
|
|
*/
|
|
void set_tag_description (id_type tag_id, const std::string &description);
|
|
|
|
/**
|
|
* @brief Set an item to visited state or reset the state
|
|
*/
|
|
void set_item_visited (const Item *item, bool visited);
|
|
|
|
/**
|
|
* @brief Add a tag to the given item
|
|
*/
|
|
void add_item_tag (const Item *item, id_type tag);
|
|
|
|
/**
|
|
* @brief Remove a tag from the given item
|
|
*/
|
|
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
|
|
*/
|
|
void set_item_image (const Item *item, const QImage &image);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Set the image string of an item
|
|
*/
|
|
void set_item_image_str (const Item *item, const std::string &image_str);
|
|
|
|
/**
|
|
* @brief Set the multiplicity of an item
|
|
*/
|
|
void set_item_multiplicity (const Item *item, size_t n);
|
|
|
|
/**
|
|
* @brief Get the items collection (const version)
|
|
*/
|
|
const Items &items () const
|
|
{
|
|
return *mp_items;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the items collection (non-const version)
|
|
*/
|
|
Items &items_non_const ()
|
|
{
|
|
return *mp_items;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the items collection
|
|
*
|
|
* This method is provided for persistency application only. It should not be used otherwise.
|
|
* This will take ownership over the items collection.
|
|
*/
|
|
void set_items (Items *items);
|
|
|
|
/**
|
|
* @brief Get an iterator pair that delivers the const items (ItemRef) for a given cell
|
|
*/
|
|
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell (id_type cell_id) const;
|
|
|
|
/**
|
|
* @brief Get an iterator pair that delivers the non-const items (ItemRef) for a given cell
|
|
*/
|
|
std::pair<item_ref_iterator, item_ref_iterator> items_by_cell (id_type cell_id);
|
|
|
|
/**
|
|
* @brief Get an iterator that delivers the const items (ItemRef) for a given category
|
|
*/
|
|
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_category (id_type category_id) const;
|
|
|
|
/**
|
|
* @brief Get an iterator that delivers the non-const items (ItemRef) for a given category
|
|
*/
|
|
std::pair<item_ref_iterator, item_ref_iterator> items_by_category (id_type category_id);
|
|
|
|
/**
|
|
* @brief Get an iterator that delivers the const items (ItemRef) for a given cell and category
|
|
*/
|
|
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell_and_category (id_type cell_id, id_type category_id) const;
|
|
|
|
/**
|
|
* @brief Get an iterator that delivers the non-const items (ItemRef) for a given cell and category
|
|
*/
|
|
std::pair<item_ref_iterator, item_ref_iterator> items_by_cell_and_category (id_type cell_id, id_type category_id);
|
|
|
|
/**
|
|
* @brief Returns true, if the database was modified
|
|
*/
|
|
bool is_modified () const
|
|
{
|
|
return m_modified;
|
|
}
|
|
|
|
/**
|
|
* @brief Reset the modified file
|
|
*/
|
|
void reset_modified ()
|
|
{
|
|
m_modified = false;
|
|
}
|
|
|
|
/**
|
|
* @brief Save the database to a file
|
|
*/
|
|
void save (const std::string &filename);
|
|
|
|
/**
|
|
* @brief Write the database to a file
|
|
*
|
|
* This function is like "save", but does not update the file name attribute.
|
|
*/
|
|
void write (const std::string &filename);
|
|
|
|
/**
|
|
* @brief Load the database from a file
|
|
*
|
|
* Note: This clears the existing database.
|
|
* The argument intentionally is a copy, so we can call
|
|
* "load (this->filename ())" for reloading.
|
|
*/
|
|
void load (std::string filename);
|
|
|
|
/**
|
|
* @brief Applies the attributes from a different database
|
|
*
|
|
* Attributes are waived flags, images etc.
|
|
* The attributes are applied to markers with identical value(s), category and cell context.
|
|
*/
|
|
void apply (const rdb::Database &other);
|
|
|
|
/**
|
|
* @brief Scans a layout into this RDB
|
|
*
|
|
* @param layout The layout to scan
|
|
* @param cell_index The top cell to scan
|
|
* @param layers_and_descriptions The layers and (optional) descriptions/names of the layer to scan
|
|
* @param flat True, to perform a flat scan
|
|
*/
|
|
void scan_layout (const db::Layout &layout, db::cell_index_type cell_index, const std::vector<std::pair<unsigned int, std::string> > &layers_and_descriptions, bool flat);
|
|
|
|
private:
|
|
std::string m_generator;
|
|
std::string m_filename;
|
|
std::string m_description;
|
|
std::string m_original_file;
|
|
std::string m_name;
|
|
std::string m_topcell;
|
|
id_type m_next_id;
|
|
Categories *mp_categories;
|
|
Tags m_tags;
|
|
std::map <std::string, Cell *> m_cells_by_qname;
|
|
std::map <std::string, std::vector <id_type> > m_cell_variants;
|
|
std::map <id_type, Cell *> m_cells_by_id;
|
|
std::map <id_type, Category *> m_categories_by_id;
|
|
std::map <std::pair <id_type, id_type>, std::list<ItemRef> > m_items_by_cell_and_category_id;
|
|
std::map <std::pair <id_type, id_type>, size_t> m_num_items_by_cell_and_category;
|
|
std::map <std::pair <id_type, id_type>, size_t> m_num_items_visited_by_cell_and_category;
|
|
std::map <id_type, std::list<ItemRef> > m_items_by_cell_id;
|
|
std::map <id_type, std::list<ItemRef> > m_items_by_category_id;
|
|
Items *mp_items;
|
|
Cells m_cells;
|
|
size_t m_num_items;
|
|
size_t m_num_items_visited;
|
|
bool m_modified;
|
|
|
|
void clear ();
|
|
|
|
void set_modified ()
|
|
{
|
|
m_modified = true;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the reference to the tags collection (non-const version)
|
|
*/
|
|
Tags &tags_non_const ()
|
|
{
|
|
return m_tags;
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|