mirror of https://github.com/KLayout/klayout.git
commit
d14f8b0253
|
|
@ -288,6 +288,7 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
if (! var_table) {
|
||||
var_table = &var_table_intern;
|
||||
}
|
||||
tl_assert (var_table->empty ());
|
||||
|
||||
for (db::Layout::bottom_up_const_iterator c = mp_layout->begin_bottom_up (); c != mp_layout->end_bottom_up (); ++c) {
|
||||
|
||||
|
|
@ -311,6 +312,9 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
|
||||
cell.clear_insts ();
|
||||
|
||||
bool original_cell_is_variant = false;
|
||||
db::ICplxTrans original_cell_variant;
|
||||
|
||||
int index = 0;
|
||||
for (auto v = vc->second.begin (); v != vc->second.end (); ++v, ++index) {
|
||||
|
||||
|
|
@ -333,6 +337,8 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
|
||||
} else {
|
||||
ci_var = *c;
|
||||
original_cell_is_variant = true;
|
||||
original_cell_variant = *v;
|
||||
}
|
||||
|
||||
vt.insert (std::make_pair (*v, ci_var));
|
||||
|
|
@ -341,13 +347,15 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
}
|
||||
|
||||
// correct the first (remaining) entry
|
||||
if (! vt.begin ()->first.is_unity ()) {
|
||||
if (original_cell_is_variant) {
|
||||
if (! original_cell_variant.is_unity ()) {
|
||||
std::set<db::ICplxTrans> &tv = m_variants [*c];
|
||||
tv.clear ();
|
||||
tv.insert (vt.begin ()->first);
|
||||
tv.insert (original_cell_variant);
|
||||
} else {
|
||||
m_variants.erase (*c);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
|
|
|||
|
|
@ -298,28 +298,57 @@ struct DeepShapeStore::LayoutHolder
|
|||
{
|
||||
public:
|
||||
VariantsCreatedListener (DeepShapeStore::LayoutHolder *lh, db::Layout *ly)
|
||||
: mp_lh (lh)
|
||||
: mp_lh (lh), m_dbu (ly->dbu ())
|
||||
{
|
||||
ly->variants_created_event.add (this, &VariantsCreatedListener::variants_created);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string var_desc (const db::ICplxTrans &t)
|
||||
{
|
||||
std::string s;
|
||||
if (t.is_mirror ()) {
|
||||
s += "m";
|
||||
s += tl::to_string (t.angle () * 0.5);
|
||||
} else {
|
||||
s += "r";
|
||||
s += tl::to_string (t.angle ());
|
||||
}
|
||||
if (t.is_mag ()) {
|
||||
s += tl::sprintf ("*%.9g", t.mag ());
|
||||
}
|
||||
if (t.disp () != db::Vector ()) {
|
||||
s += tl::sprintf ("(%.12g,%.12g)", t.disp ().x () * m_dbu, t.disp ().y () * m_dbu);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void variants_created (const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_map)
|
||||
{
|
||||
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> >::const_iterator i = var_map->begin (); i != var_map->end (); ++i) {
|
||||
for (std::map<db::ICplxTrans, db::cell_index_type>::const_iterator j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
mp_lh->builder.register_variant (i->first, j->second);
|
||||
if (i->first != j->second) {
|
||||
mp_lh->builder.register_variant (i->first, j->second, var_desc (j->first));
|
||||
}
|
||||
}
|
||||
// NOTE: variant conversion events are registered after variant formation events, so we can
|
||||
// base the formed variants (first pass) on the originals.
|
||||
for (std::map<db::ICplxTrans, db::cell_index_type>::const_iterator j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
if (i->first == j->second) {
|
||||
mp_lh->builder.register_variant (i->first, j->second, var_desc (j->first));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeepShapeStore::LayoutHolder *mp_lh;
|
||||
double m_dbu;
|
||||
};
|
||||
|
||||
LayoutHolder (const db::ICplxTrans &trans)
|
||||
: refs (0), layout (false), builder (&layout, trans), variants_created (this, &layout)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
layout.set_hierarchy_builder (&builder);
|
||||
}
|
||||
|
||||
void add_layer_ref (unsigned int layer)
|
||||
|
|
|
|||
|
|
@ -182,14 +182,24 @@ HierarchyBuilder::reset ()
|
|||
|
||||
m_cells_to_be_filled.clear ();
|
||||
m_cell_map.clear ();
|
||||
m_variants_of_sources_map.clear ();
|
||||
m_cells_seen.clear ();
|
||||
m_cell_stack.clear ();
|
||||
m_cm_entry = null_iterator;
|
||||
m_cm_new_entry = false;
|
||||
}
|
||||
|
||||
const std::pair<db::cell_index_type, std::string> &
|
||||
HierarchyBuilder::variant_of_source (db::cell_index_type target) const
|
||||
{
|
||||
static std::pair<db::cell_index_type, std::string> def (std::numeric_limits<db::cell_index_type>::max (), std::string ());
|
||||
|
||||
auto vs = m_variants_of_sources_map.find (target);
|
||||
return vs != m_variants_of_sources_map.end () ? vs->second : def;
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_type var)
|
||||
HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_type var, const std::string &description)
|
||||
{
|
||||
// non_var (despite its name) may be a variant created previously.
|
||||
variant_to_original_target_map_type::const_iterator v = m_variants_to_original_target_map.find (non_var);
|
||||
|
|
@ -199,11 +209,23 @@ HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_
|
|||
|
||||
m_original_targets_to_variants_map [non_var].push_back (var);
|
||||
m_variants_to_original_target_map.insert (std::make_pair (var, non_var));
|
||||
|
||||
auto vs = m_variants_of_sources_map.find (non_var);
|
||||
if (vs != m_variants_of_sources_map.end ()) {
|
||||
std::string new_description = vs->second.second;
|
||||
if (! new_description.empty ()) {
|
||||
new_description += ";";
|
||||
}
|
||||
new_description += description;
|
||||
m_variants_of_sources_map [var] = std::make_pair (vs->second.first, new_description);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyBuilder::unregister_variant (db::cell_index_type var)
|
||||
{
|
||||
m_variants_of_sources_map.erase (var);
|
||||
|
||||
variant_to_original_target_map_type::iterator v = m_variants_to_original_target_map.find (var);
|
||||
if (v == m_variants_to_original_target_map.end ()) {
|
||||
return;
|
||||
|
|
@ -257,6 +279,7 @@ HierarchyBuilder::begin (const RecursiveShapeIterator *iter)
|
|||
if (m_cm_entry == m_cell_map.end ()) {
|
||||
db::cell_index_type new_top_index = mp_target->add_cell (iter->layout ()->cell_name (key.original_cell));
|
||||
m_cm_entry = m_cell_map.insert (std::make_pair (key, new_top_index)).first;
|
||||
m_variants_of_sources_map.insert (std::make_pair (new_top_index, std::make_pair (key.original_cell, std::string ())));
|
||||
}
|
||||
|
||||
db::Cell &new_top = mp_target->cell (m_cm_entry->second);
|
||||
|
|
@ -324,17 +347,34 @@ HierarchyBuilder::make_cell_variant (const HierarchyBuilder::CellMapKey &key, co
|
|||
if (m_cm_entry == m_cell_map.end ()) {
|
||||
|
||||
std::string cn = cell_name;
|
||||
std::string description;
|
||||
if (! key.clip_region.empty ()) {
|
||||
cn += "$CLIP_VAR";
|
||||
description += "CLIP";
|
||||
|
||||
}
|
||||
if (key.inactive) {
|
||||
cn += "$DIS";
|
||||
if (! description.empty ()) {
|
||||
description += "/";
|
||||
}
|
||||
description += "DISABLED";
|
||||
}
|
||||
|
||||
new_cell = mp_target->add_cell (cn.c_str ());
|
||||
|
||||
std::string new_name = mp_target->cell_name (new_cell);
|
||||
if (new_name.size () > cn.size ()) {
|
||||
// use cell name extension to uniquify the description
|
||||
description += new_name.c_str () + cn.size ();
|
||||
}
|
||||
|
||||
m_cm_entry = m_cell_map.insert (std::make_pair (key, new_cell)).first;
|
||||
m_cm_new_entry = true;
|
||||
m_cells_to_be_filled.insert (new_cell);
|
||||
|
||||
m_variants_of_sources_map.insert (std::make_pair (new_cell, std::make_pair (key.original_cell, description)));
|
||||
|
||||
} else {
|
||||
new_cell = m_cm_entry->second;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ public:
|
|||
* The first cell is either the original, non-variant target cell or itself a variant.
|
||||
* The second cell will be registered as a variant of the first one.
|
||||
*/
|
||||
void register_variant (db::cell_index_type non_var, db::cell_index_type var);
|
||||
void register_variant (db::cell_index_type non_var, db::cell_index_type var, const std::string &description);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a cell as a variant
|
||||
|
|
@ -404,8 +404,23 @@ public:
|
|||
return m_variants_to_original_target_map.find (ci) != m_variants_to_original_target_map.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the information about the target/source + variant relationship
|
||||
*
|
||||
* For a target cell, returns a pointer to a pair with the cell index of the source cell and
|
||||
* a string describing the variant this cell forms of the source cell.
|
||||
*
|
||||
* The description string is empty if the cell is not a variant.
|
||||
*/
|
||||
const std::pair<db::cell_index_type, std::string> &variant_of_source (db::cell_index_type target) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the original target for a variant cell
|
||||
*
|
||||
* The original cell is the first-generation target-space cell that variants have been created for.
|
||||
* This still can mean that the original cell is a clip variant of a source cell.
|
||||
*
|
||||
* Target-to-source variants can be derived with "variant_of_source".
|
||||
*/
|
||||
db::cell_index_type original_target_for_variant (db::cell_index_type ci) const;
|
||||
|
||||
|
|
@ -419,6 +434,7 @@ private:
|
|||
cell_map_type m_cell_map;
|
||||
original_target_to_variants_map_type m_original_targets_to_variants_map;
|
||||
variant_to_original_target_map_type m_variants_to_original_target_map;
|
||||
std::map<db::cell_index_type, std::pair<db::cell_index_type, std::string> > m_variants_of_sources_map;
|
||||
|
||||
std::set<cell_map_type::key_type> m_cells_seen;
|
||||
std::set<db::cell_index_type> m_cells_to_be_filled;
|
||||
|
|
|
|||
|
|
@ -439,6 +439,7 @@ LayoutOrCellContextInfo::has_meta_info () const
|
|||
Layout::Layout (db::Manager *manager)
|
||||
: db::Object (manager),
|
||||
mp_library (0),
|
||||
mp_builder (0),
|
||||
m_cells_size (0),
|
||||
m_invalid (0),
|
||||
m_top_cells (0),
|
||||
|
|
@ -454,6 +455,7 @@ Layout::Layout (db::Manager *manager)
|
|||
Layout::Layout (bool editable, db::Manager *manager)
|
||||
: db::Object (manager),
|
||||
mp_library (0),
|
||||
mp_builder (0),
|
||||
m_cells_size (0),
|
||||
m_invalid (0),
|
||||
m_top_cells (0),
|
||||
|
|
@ -473,6 +475,7 @@ Layout::Layout (const db::Layout &layout)
|
|||
tl::Object (),
|
||||
tl::UniqueId (),
|
||||
mp_library (0),
|
||||
mp_builder (0),
|
||||
m_cells_size (0),
|
||||
m_invalid (0),
|
||||
m_top_cells (0),
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class Technology;
|
|||
class CellMapping;
|
||||
class LayerMapping;
|
||||
class VariantsCollectorBase;
|
||||
class HierarchyBuilder;
|
||||
|
||||
template <class Coord> class generic_repository;
|
||||
typedef generic_repository<db::Coord> GenericRepository;
|
||||
|
|
@ -2113,6 +2114,24 @@ public:
|
|||
*/
|
||||
const MetaInfo &meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the hierarchy builder reference
|
||||
* Used internally
|
||||
*/
|
||||
void set_hierarchy_builder (db::HierarchyBuilder *builder)
|
||||
{
|
||||
mp_builder = builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the hierarchy builder
|
||||
* Used internally
|
||||
*/
|
||||
db::HierarchyBuilder *builder () const
|
||||
{
|
||||
return mp_builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This event is triggered when the technology changes
|
||||
*/
|
||||
|
|
@ -2138,6 +2157,7 @@ protected:
|
|||
|
||||
private:
|
||||
db::Library *mp_library;
|
||||
db::HierarchyBuilder *mp_builder;
|
||||
cell_list m_cells;
|
||||
size_t m_cells_size;
|
||||
cell_ptr_vector m_cell_ptrs;
|
||||
|
|
|
|||
|
|
@ -234,6 +234,49 @@ gate.width(min_width).output("gate_width", "Gate width violations")</pre>
|
|||
Hence such files can only be run from the macro IDE.
|
||||
</p>
|
||||
|
||||
<h2>DRC waiving flow</h2>
|
||||
|
||||
<p>
|
||||
DRC waiving is a process of signing off DRC violations that cannot be avoided.
|
||||
Usually DRC waiving is not encouraged, as manufacturability of the device cannot
|
||||
be guaranteed if DRC violations are present. Even worse, giving a non-clean layout
|
||||
into manufacturing may create a contamination risk that manufacturers will try
|
||||
to avoid. Hence, non-DRC-clean layouts are usually rejected.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Still there are some legit reasons for DRC waiving. Sometimes DRC rules do not apply
|
||||
because a specific technology option is not used by the device and corresponding
|
||||
DRC rules do not apply. Or, a certain DRC rule may be a recommended rule, and violating
|
||||
it is not forbidden. In that case, a DRC violation can be waived at your own risk.
|
||||
Waiving is not a formal process. Usually, the manufacturer will ask for a confirmation
|
||||
if DRC violations are present. KLayout can help documenting violations and copying
|
||||
the waivers from one DRC run to the next.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The DRC waiving flow of KLayout is the following:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>In the initial step, a RDB database is created by the DRC run, using the "report" command with a destination file.</li>
|
||||
<li>This report is inspected in the marker browser. You can add comments, set flags and add screenshots. This is
|
||||
also the time to waive DRC violations that you deem necessary to be waived. The marker browser has a "waive"
|
||||
button which sets or resets the waived flag of the selected markers.</li>
|
||||
<li>When finished, save the edited database to a 'waiver DB' using the marker browser's 'Save As Waiver DB' feature from
|
||||
the File menu. Technically, this will write the report database to a second file. This second file is named
|
||||
like the original one, with a ".w" added to the file name.</li>
|
||||
<li>When you run the DRC again, KLayout will find this waiver DB file and apply attributes from the waiver DB
|
||||
to the current report database. These attributes include the flags, images and comments.
|
||||
This will - among the other annotations - apply the waived flag to the report database items.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
In the waiving step, KLayout will apply attributes to items with the same value (i.e. shape), category and cell.
|
||||
This specifically means, that when you rename a cell, waivers will no longer be applied, or - in the worst case -
|
||||
be applied to the wrong cell. Hence, waiving should be done late in the process, when cell names are unlikely to change.
|
||||
</p>
|
||||
|
||||
<h2>Using KLayout as a standalone DRC engine</h2>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -115,11 +115,29 @@ module DRC
|
|||
end
|
||||
|
||||
def write
|
||||
|
||||
if @file_name
|
||||
|
||||
rdb_file = @engine._make_path(@file_name)
|
||||
|
||||
# Apply waive DB if possible
|
||||
wdb_file = rdb_file + ".w"
|
||||
if File.exists?(wdb_file)
|
||||
begin
|
||||
wdb = RBA::ReportDatabase::new
|
||||
wdb.load(wdb_file)
|
||||
@engine.info("Applying waive database: #{wdb_file} ..")
|
||||
@rdb.apply(wdb)
|
||||
wdb._destroy
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
@engine.info("Writing report database: #{rdb_file} ..")
|
||||
@rdb.save(rdb_file)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def rdb
|
||||
|
|
@ -3230,7 +3248,33 @@ CODE
|
|||
output_rdb = channel.rdb
|
||||
output_cell = channel.cell
|
||||
|
||||
cat = output_rdb.create_category(args[0].to_s)
|
||||
categories = args[0]
|
||||
if !categories.is_a?(Array)
|
||||
categories = [ categories.to_s ]
|
||||
end
|
||||
|
||||
cat = nil
|
||||
categories.each do |c|
|
||||
ccat = nil
|
||||
if cat
|
||||
cat.each_sub_category do |i|
|
||||
if i.name == c
|
||||
ccat = i
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
output_rdb.each_category do |i|
|
||||
if i.name == c
|
||||
ccat = i
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
cat = ccat ? ccat : output_rdb.create_category(cat, c)
|
||||
end
|
||||
cat ||= output_rdb.create_category("default")
|
||||
|
||||
args[1] && cat.description = args[1]
|
||||
|
||||
cat.scan_collection(output_cell, RBA::CplxTrans::new(self.dbu), data)
|
||||
|
|
@ -3347,6 +3391,7 @@ CODE
|
|||
output_rdb.generator = self._generator
|
||||
output_rdb.top_cell_name = cn
|
||||
output_rdb.description = description
|
||||
output_rdb.original_file = @def_path
|
||||
|
||||
RDBOutputChannel::new(self, output_rdb, output_rdb_index, cn, output_rdb_file)
|
||||
|
||||
|
|
|
|||
|
|
@ -5185,7 +5185,11 @@ CODE
|
|||
# This method will copy the content of the layer to the specified output.
|
||||
#
|
||||
# If a report database is selected for the output, the specification has to include a
|
||||
# category name and optionally a category description.
|
||||
# category name and optionally a category description. The category name can be an
|
||||
# array of strings - in that case, a hierarchy of categories is created
|
||||
# with the first array item being the top level category name.
|
||||
# Shapes are added to an existing category, if a category with the given
|
||||
# name already exists.
|
||||
#
|
||||
# If the layout is selected for the output, the specification can consist of
|
||||
# one to three parameters: a layer number, a data type (optional, default is 0)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "dbTestSupport.h"
|
||||
#include "dbNetlist.h"
|
||||
#include "dbNetlistSpiceReader.h"
|
||||
#include "rdb.h"
|
||||
#include "lymMacro.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
|
|
@ -1712,3 +1713,117 @@ TEST(102d_edge_modes)
|
|||
{
|
||||
run_test (_this, "102", true);
|
||||
}
|
||||
|
||||
TEST(110_RDBVariantAssignment)
|
||||
{
|
||||
std::string rs = tl::testdata ();
|
||||
rs += "/drc/drcSimpleTests_110.drc";
|
||||
|
||||
// apart from that it's a variant of 14b ...
|
||||
|
||||
std::string input = tl::testdata ();
|
||||
input += "/drc/drcSimpleTests_110.gds";
|
||||
|
||||
std::string au_report = tl::testdata ();
|
||||
au_report += "/drc/drcSimpleTests_au110.lyrdb";
|
||||
|
||||
std::string report = this->tmp_file ("tmp.lydrc");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_report = '%s'\n"
|
||||
, input, report)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro drc;
|
||||
drc.load_from (rs);
|
||||
EXPECT_EQ (drc.run (), 0);
|
||||
|
||||
compare_text_files (report, au_report);
|
||||
}
|
||||
|
||||
TEST(111_RDBCategoryHierarchy)
|
||||
{
|
||||
std::string rs = tl::testdata ();
|
||||
rs += "/drc/drcSimpleTests_111.drc";
|
||||
|
||||
// apart from that it's a variant of 14b ...
|
||||
|
||||
std::string input = tl::testdata ();
|
||||
input += "/drc/drcSimpleTests_111.gds";
|
||||
|
||||
std::string au_report = tl::testdata ();
|
||||
au_report += "/drc/drcSimpleTests_au111.lyrdb";
|
||||
|
||||
std::string report = this->tmp_file ("tmp.lydrc");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_report = '%s'\n"
|
||||
, input, report)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro drc;
|
||||
drc.load_from (rs);
|
||||
EXPECT_EQ (drc.run (), 0);
|
||||
|
||||
compare_text_files (report, au_report);
|
||||
}
|
||||
|
||||
TEST(112_Waiving)
|
||||
{
|
||||
std::string rs = tl::testdata ();
|
||||
rs += "/drc/drcSimpleTests_112.drc";
|
||||
|
||||
// apart from that it's a variant of 14b ...
|
||||
|
||||
std::string input = tl::testdata ();
|
||||
input += "/drc/drcSimpleTests_112.gds";
|
||||
|
||||
std::string au_report = tl::testdata ();
|
||||
au_report += "/drc/drcSimpleTests_au112.lyrdb";
|
||||
|
||||
std::string report = this->tmp_file ("tmp.lydrc");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_report = '%s'\n"
|
||||
, input, report)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
// prepare a waiver db
|
||||
{
|
||||
std::string report_w = this->tmp_file ("tmp.lydrc.w");
|
||||
rdb::Database rdb_w;
|
||||
rdb_w.load (au_report + ".w");
|
||||
rdb_w.write (report_w);
|
||||
}
|
||||
|
||||
lym::Macro drc;
|
||||
drc.load_from (rs);
|
||||
EXPECT_EQ (drc.run (), 0);
|
||||
|
||||
compare_text_files (report, au_report);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -292,6 +292,98 @@ to load a marker database</string>
|
|||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="open_action">
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+O</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="saveas_action">
|
||||
<property name="text">
|
||||
<string>Save As</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="reload_action">
|
||||
<property name="text">
|
||||
<string>Reload</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>F5</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="save_action">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="export_action">
|
||||
<property name="text">
|
||||
<string>Export To Layout</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="unload_action">
|
||||
<property name="text">
|
||||
<string>Unload</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="unload_all_action">
|
||||
<property name="text">
|
||||
<string>Unload All</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Unload All</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="info_action">
|
||||
<property name="text">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="saveas_waiver_db_action">
|
||||
<property name="text">
|
||||
<string>Save As Waiver DB</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="apply_waiver_db_action">
|
||||
<property name="text">
|
||||
<string>Apply Waiver DB</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
|||
|
|
@ -480,51 +480,7 @@
|
|||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="3">
|
||||
<widget class="QToolButton" name="waive_pb">
|
||||
<property name="toolTip">
|
||||
<string>Waive</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>W</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/waived_16px.png</normaloff>:/waived_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QToolButton" name="nophoto_pb">
|
||||
<property name="toolTip">
|
||||
<string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Remove snapshot</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/nophoto_16px.png</normaloff>:/nophoto_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="flags_pb">
|
||||
<property name="toolTip">
|
||||
<string>Set or reset flag</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flag</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::MenuButtonPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<item row="2" column="7">
|
||||
<widget class="QToolButton" name="photo_pb">
|
||||
<property name="toolTip">
|
||||
<string>Add snapshot</string>
|
||||
|
|
@ -538,28 +494,24 @@ p, li { white-space: pre-wrap; }
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QToolButton" name="important_pb">
|
||||
<item row="2" column="3">
|
||||
<widget class="QToolButton" name="waive_pb">
|
||||
<property name="toolTip">
|
||||
<string>Important</string>
|
||||
<string>Waive</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Imp</string>
|
||||
<string>W</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/important_16px.png</normaloff>:/important_16px.png</iconset>
|
||||
<normaloff>:/waived_16px.png</normaloff>:/waived_16px.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+W</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="info_label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="7">
|
||||
<item row="1" column="0" colspan="8">
|
||||
<widget class="QFrame" name="frame_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
|
|
@ -605,7 +557,38 @@ p, li { white-space: pre-wrap; }
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="7">
|
||||
<item row="2" column="5">
|
||||
<widget class="QToolButton" name="important_pb">
|
||||
<property name="toolTip">
|
||||
<string>Important</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Imp</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/important_16px.png</normaloff>:/important_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QToolButton" name="nophoto_pb">
|
||||
<property name="toolTip">
|
||||
<string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Remove snapshot</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/nophoto_16px.png</normaloff>:/nophoto_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="8">
|
||||
<widget class="QFrame" name="frame_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
|
|
@ -662,6 +645,43 @@ p, li { white-space: pre-wrap; }
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="info_label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="flags_pb">
|
||||
<property name="toolTip">
|
||||
<string>Set or reset flag</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flag</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::MenuButtonPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QToolButton" name="edit_pb">
|
||||
<property name="toolTip">
|
||||
<string>Edit Comment</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/edit_16px.png</normaloff>:/edit_16px.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>F2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
|
|||
|
|
@ -33,9 +33,11 @@
|
|||
#include "layConverters.h"
|
||||
#include "layQtTools.h"
|
||||
#include "layConfigurationDialog.h"
|
||||
#include "layBrowserDialog.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
#include "dbStream.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
#include "ui_MarkerBrowserDialog.h"
|
||||
|
||||
|
|
@ -84,34 +86,35 @@ MarkerBrowserDialog::MarkerBrowserDialog (lay::Dispatcher *root, lay::LayoutView
|
|||
view ()->rdb_list_changed_event.add (this, &MarkerBrowserDialog::rdbs_changed);
|
||||
}
|
||||
|
||||
m_open_action = new QAction (QObject::tr ("Open"), mp_ui->file_menu);
|
||||
m_saveas_action = new QAction (QObject::tr ("Save As"), mp_ui->file_menu);
|
||||
m_export_action = new QAction (QObject::tr ("Export To Layout"), mp_ui->file_menu);
|
||||
m_reload_action = new QAction (QObject::tr ("Reload"), mp_ui->file_menu);
|
||||
m_unload_action = new QAction (QObject::tr ("Unload"), mp_ui->file_menu);
|
||||
m_unload_all_action = new QAction (QObject::tr ("Unload All"), mp_ui->file_menu);
|
||||
connect (mp_ui->open_action, SIGNAL (triggered ()), this, SLOT (open_clicked ()));
|
||||
connect (mp_ui->save_action, SIGNAL (triggered ()), this, SLOT (save_clicked ()));
|
||||
connect (mp_ui->saveas_action, SIGNAL (triggered ()), this, SLOT (saveas_clicked ()));
|
||||
connect (mp_ui->saveas_waiver_db_action, SIGNAL (triggered ()), this, SLOT (saveas_waiver_db_clicked ()));
|
||||
connect (mp_ui->apply_waiver_db_action, SIGNAL (triggered ()), this, SLOT (apply_waiver_db_clicked ()));
|
||||
connect (mp_ui->export_action, SIGNAL (triggered ()), this, SLOT (export_clicked ()));
|
||||
connect (mp_ui->reload_action, SIGNAL (triggered ()), this, SLOT (reload_clicked ()));
|
||||
connect (mp_ui->info_action, SIGNAL (triggered ()), this, SLOT (info_clicked ()));
|
||||
connect (mp_ui->unload_action, SIGNAL (triggered ()), this, SLOT (unload_clicked ()));
|
||||
connect (mp_ui->unload_all_action, SIGNAL (triggered ()), this, SLOT (unload_all_clicked ()));
|
||||
|
||||
connect (m_open_action, SIGNAL (triggered ()), this, SLOT (open_clicked ()));
|
||||
connect (m_saveas_action, SIGNAL (triggered ()), this, SLOT (saveas_clicked ()));
|
||||
connect (m_export_action, SIGNAL (triggered ()), this, SLOT (export_clicked ()));
|
||||
connect (m_reload_action, SIGNAL (triggered ()), this, SLOT (reload_clicked ()));
|
||||
connect (m_unload_action, SIGNAL (triggered ()), this, SLOT (unload_clicked ()));
|
||||
connect (m_unload_all_action, SIGNAL (triggered ()), this, SLOT (unload_all_clicked ()));
|
||||
|
||||
mp_ui->file_menu->addAction (m_open_action);
|
||||
mp_ui->file_menu->addAction (m_saveas_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->open_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->save_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->saveas_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->saveas_waiver_db_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->apply_waiver_db_action);
|
||||
QAction *sep0 = new QAction (mp_ui->file_menu);
|
||||
sep0->setSeparator (true);
|
||||
mp_ui->file_menu->addAction (m_export_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->export_action);
|
||||
QAction *sep1 = new QAction (mp_ui->file_menu);
|
||||
sep1->setSeparator (true);
|
||||
mp_ui->file_menu->addAction (sep1);
|
||||
mp_ui->file_menu->addAction (m_reload_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->reload_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->info_action);
|
||||
QAction *sep2 = new QAction (mp_ui->file_menu);
|
||||
sep2->setSeparator (true);
|
||||
mp_ui->file_menu->addAction (sep2);
|
||||
mp_ui->file_menu->addAction (m_unload_action);
|
||||
mp_ui->file_menu->addAction (m_unload_all_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->unload_action);
|
||||
mp_ui->file_menu->addAction (mp_ui->unload_all_action);
|
||||
|
||||
connect (mp_ui->layout_cb, SIGNAL (activated (int)), this, SLOT (cv_index_changed (int)));
|
||||
connect (mp_ui->rdb_cb, SIGNAL (activated (int)), this, SLOT (rdb_index_changed (int)));
|
||||
|
|
@ -367,6 +370,99 @@ BEGIN_PROTECTED
|
|||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserDialog::save_clicked ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (m_rdb_index < int (view ()->num_rdbs ()) && m_rdb_index >= 0) {
|
||||
|
||||
rdb::Database *rdb = view ()->get_rdb (m_rdb_index);
|
||||
if (rdb) {
|
||||
|
||||
if (rdb->filename ().empty ()) {
|
||||
|
||||
saveas_clicked ();
|
||||
|
||||
} else {
|
||||
|
||||
rdb->save (rdb->filename ());
|
||||
rdb->reset_modified ();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserDialog::apply_waiver_db_clicked ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
rdb::Database *rdb = 0;
|
||||
if (m_rdb_index < int (view ()->num_rdbs ()) && m_rdb_index >= 0) {
|
||||
rdb = view ()->get_rdb (m_rdb_index);
|
||||
}
|
||||
if (! rdb) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string wdb_filename;
|
||||
if (! rdb->filename ().empty () && tl::file_exists (rdb->filename () + ".w")) {
|
||||
|
||||
wdb_filename = rdb->filename () + ".w";
|
||||
|
||||
} else {
|
||||
|
||||
// prepare and open the file dialog
|
||||
lay::FileDialog open_dialog (this, tl::to_string (QObject::tr ("Apply Waiver DB File")), "Waiver DB files (*.w)");
|
||||
|
||||
if (! rdb->filename ().empty ()) {
|
||||
wdb_filename = rdb->filename () + ".w";
|
||||
}
|
||||
|
||||
if (! open_dialog.get_open (wdb_filename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rdb::Database wdb;
|
||||
wdb.load (wdb_filename);
|
||||
|
||||
mp_ui->browser_frame->set_rdb (0);
|
||||
rdb->apply (wdb);
|
||||
mp_ui->browser_frame->set_rdb (rdb);
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserDialog::saveas_waiver_db_clicked ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
rdb::Database *rdb = 0;
|
||||
if (m_rdb_index < int (view ()->num_rdbs ()) && m_rdb_index >= 0) {
|
||||
rdb = view ()->get_rdb (m_rdb_index);
|
||||
}
|
||||
if (! rdb) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rdb->filename ().empty ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("The current report database is not saved.\nSave it to some file with 'Save As', before saving it as waiver DB.")));
|
||||
}
|
||||
|
||||
rdb->write (rdb->filename () + ".w");
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserDialog::saveas_clicked ()
|
||||
{
|
||||
|
|
@ -385,6 +481,9 @@ BEGIN_PROTECTED
|
|||
rdb->save (fn);
|
||||
rdb->reset_modified ();
|
||||
|
||||
// update the RDB title strings
|
||||
rdbs_changed ();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -394,6 +493,42 @@ BEGIN_PROTECTED
|
|||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserDialog::info_clicked ()
|
||||
{
|
||||
rdb::Database *rdb = 0;
|
||||
if (m_rdb_index < int (view ()->num_rdbs ()) && m_rdb_index >= 0) {
|
||||
rdb = view ()->get_rdb (m_rdb_index);
|
||||
}
|
||||
if (! rdb) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string html;
|
||||
html = "<html><body>\n";
|
||||
html += "<h2>" + tl::escaped_to_html (rdb->name ()) + "</h2>\n";
|
||||
if (! rdb->description ().empty ()) {
|
||||
html += "<b>" + tl::to_string (tr ("Description: ")) + "</b>" + tl::escaped_to_html (tl::escape_string (rdb->description ())) + "<br/>\n";
|
||||
}
|
||||
if (! rdb->filename ().empty ()) {
|
||||
html += "<b>" + tl::to_string (tr ("File: ")) + "</b>" + tl::escaped_to_html (rdb->filename ()) + "<br/>\n";
|
||||
}
|
||||
if (! rdb->original_file ().empty ()) {
|
||||
html += "<b>" + tl::to_string (tr ("Original File: ")) + "</b>" + tl::escaped_to_html (rdb->original_file ()) + "<br/>\n";
|
||||
}
|
||||
if (! rdb->top_cell_name ().empty ()) {
|
||||
html += "<b>" + tl::to_string (tr ("Top Cell: ")) + "</b>" + tl::escaped_to_html (rdb->top_cell_name ()) + "<br/>\n";
|
||||
}
|
||||
if (! rdb->generator ().empty ()) {
|
||||
html += "<b>" + tl::to_string (tr ("Generator: ")) + "</b>" + tl::escaped_to_html (rdb->generator ()) + "<br/>\n";
|
||||
}
|
||||
html += "</body></html>";
|
||||
|
||||
std::unique_ptr<lay::BrowserDialog> info_dialog (new lay::BrowserDialog (this, html));
|
||||
info_dialog->setWindowTitle (QObject::tr ("Marker Database Info"));
|
||||
info_dialog->exec ();
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserDialog::reload_clicked ()
|
||||
{
|
||||
|
|
@ -439,6 +574,7 @@ BEGIN_PROTECTED
|
|||
|
||||
int rdb_index = view ()->add_rdb (db.release ());
|
||||
mp_ui->rdb_cb->setCurrentIndex (rdb_index);
|
||||
|
||||
// it looks like the setCurrentIndex does not issue this signal:
|
||||
rdb_index_changed (rdb_index);
|
||||
|
||||
|
|
@ -592,9 +728,13 @@ MarkerBrowserDialog::rdbs_changed ()
|
|||
std::string text = rdb->name ();
|
||||
if (! rdb->description ().empty ()) {
|
||||
text += " (";
|
||||
text += rdb->description ();
|
||||
text += tl::escape_string (rdb->description ());
|
||||
text += ")";
|
||||
}
|
||||
if (! rdb->filename ().empty () && rdb->name () != rdb->filename ()) {
|
||||
text += " - ";
|
||||
text += rdb->filename ();
|
||||
}
|
||||
mp_ui->rdb_cb->addItem (tl::to_qstring (text));
|
||||
if (rdb->name () == m_rdb_name) {
|
||||
rdb_index = i;
|
||||
|
|
@ -688,11 +828,15 @@ MarkerBrowserDialog::update_content ()
|
|||
mp_ui->central_stack->setCurrentIndex (1);
|
||||
}
|
||||
|
||||
m_saveas_action->setEnabled (rdb != 0);
|
||||
m_export_action->setEnabled (rdb != 0);
|
||||
m_unload_action->setEnabled (rdb != 0);
|
||||
m_unload_all_action->setEnabled (rdb != 0);
|
||||
m_reload_action->setEnabled (rdb != 0);
|
||||
mp_ui->save_action->setEnabled (rdb != 0);
|
||||
mp_ui->saveas_action->setEnabled (rdb != 0);
|
||||
mp_ui->saveas_waiver_db_action->setEnabled (rdb != 0);
|
||||
mp_ui->apply_waiver_db_action->setEnabled (rdb != 0);
|
||||
mp_ui->export_action->setEnabled (rdb != 0);
|
||||
mp_ui->unload_action->setEnabled (rdb != 0);
|
||||
mp_ui->unload_all_action->setEnabled (rdb != 0);
|
||||
mp_ui->reload_action->setEnabled (rdb != 0);
|
||||
mp_ui->info_action->setEnabled (rdb != 0);
|
||||
|
||||
mp_ui->browser_frame->enable_updates (false); // Avoid building the internal lists several times ...
|
||||
mp_ui->browser_frame->set_rdb (0); // force update
|
||||
|
|
|
|||
|
|
@ -74,7 +74,11 @@ private:
|
|||
public slots:
|
||||
void cv_index_changed (int);
|
||||
void rdb_index_changed (int);
|
||||
void info_clicked ();
|
||||
void save_clicked ();
|
||||
void saveas_clicked ();
|
||||
void saveas_waiver_db_clicked ();
|
||||
void apply_waiver_db_clicked ();
|
||||
void export_clicked ();
|
||||
void reload_clicked ();
|
||||
void open_clicked ();
|
||||
|
|
@ -98,12 +102,6 @@ private:
|
|||
std::string m_rdb_name;
|
||||
int m_rdb_index;
|
||||
std::string m_open_filename;
|
||||
QAction *m_open_action;
|
||||
QAction *m_saveas_action;
|
||||
QAction *m_export_action;
|
||||
QAction *m_unload_action;
|
||||
QAction *m_unload_all_action;
|
||||
QAction *m_reload_action;
|
||||
|
||||
void update_content ();
|
||||
void scan_layer ();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <QMessageBox>
|
||||
#include <QHeaderView>
|
||||
#include <QKeyEvent>
|
||||
#include <QInputDialog>
|
||||
|
||||
namespace rdb
|
||||
{
|
||||
|
|
@ -103,13 +104,13 @@ class MarkerBrowserTreeViewModelCacheEntry
|
|||
{
|
||||
public:
|
||||
MarkerBrowserTreeViewModelCacheEntry ()
|
||||
: mp_parent (0), m_id (0), m_row (0), m_count (0)
|
||||
: mp_parent (0), m_id (0), m_row (0), m_count (0), m_waived_count (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry (rdb::id_type id, unsigned int branch)
|
||||
: mp_parent (0), m_id ((id << 3) + (branch << 1)), m_row (0), m_count (0)
|
||||
: mp_parent (0), m_id ((id << 3) + (branch << 1)), m_row (0), m_count (0), m_waived_count (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -233,6 +234,25 @@ public:
|
|||
m_count = c;
|
||||
}
|
||||
|
||||
size_t waived_count () const
|
||||
{
|
||||
return m_waived_count;
|
||||
}
|
||||
|
||||
void set_waived_count (size_t c)
|
||||
{
|
||||
m_waived_count = c;
|
||||
}
|
||||
|
||||
void waive_or_unwaive (bool w)
|
||||
{
|
||||
if (w) {
|
||||
++m_waived_count;
|
||||
} else {
|
||||
--m_waived_count;
|
||||
}
|
||||
}
|
||||
|
||||
void sort_by_key_name (bool ascending, const rdb::Database *database)
|
||||
{
|
||||
std::sort (m_ids.begin (), m_ids.end (), SortByKeyCompareFunc (ascending, database));
|
||||
|
|
@ -257,7 +277,7 @@ private:
|
|||
MarkerBrowserTreeViewModelCacheEntry *mp_parent;
|
||||
rdb::id_type m_id;
|
||||
unsigned int m_row;
|
||||
size_t m_count;
|
||||
size_t m_count, m_waived_count;
|
||||
std::vector<MarkerBrowserTreeViewModelCacheEntry *> m_ids;
|
||||
};
|
||||
|
||||
|
|
@ -267,7 +287,7 @@ SortByKeyCompareFunc::operator() (MarkerBrowserTreeViewModelCacheEntry *a, Marke
|
|||
const rdb::Cell *ca = mp_rdb->cell_by_id (a->id ());
|
||||
const rdb::Cell *cb = mp_rdb->cell_by_id (b->id ());
|
||||
if (ca && cb) {
|
||||
return m_ascending ? ca->name () < cb->name () : cb->name () < ca->name ();
|
||||
return m_ascending ? ca->qname () < cb->qname () : cb->qname () < ca->qname ();
|
||||
}
|
||||
|
||||
const rdb::Category *xa = mp_rdb->category_by_id (a->id ());
|
||||
|
|
@ -338,7 +358,7 @@ public:
|
|||
};
|
||||
|
||||
MarkerBrowserTreeViewModel ()
|
||||
: mp_database (0), m_show_empty_ones (true)
|
||||
: mp_database (0), m_show_empty_ones (true), m_waived_tag_id (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -346,6 +366,8 @@ public:
|
|||
void set_database (const rdb::Database *db)
|
||||
{
|
||||
mp_database = db;
|
||||
m_waived_tag_id = mp_database ? mp_database->tags ().tag ("waived").id () : 0;
|
||||
|
||||
invalidate ();
|
||||
}
|
||||
|
||||
|
|
@ -384,6 +406,23 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void waived_changed (const rdb::Item *item, bool waived)
|
||||
{
|
||||
const rdb::Category *cat = mp_database->category_by_id (item->category_id ());
|
||||
while (cat) {
|
||||
waive_or_unwaive (0, cat->id (), waived);
|
||||
if (item->cell_id () != 0) {
|
||||
waive_or_unwaive (item->cell_id (), cat->id (), waived);
|
||||
}
|
||||
cat = cat->parent ();
|
||||
}
|
||||
|
||||
waive_or_unwaive (0, 0, waived);
|
||||
if (item->cell_id () != 0) {
|
||||
waive_or_unwaive (item->cell_id (), 0, waived);
|
||||
}
|
||||
}
|
||||
|
||||
int columnCount (const QModelIndex & /*parent*/) const
|
||||
{
|
||||
return 2;
|
||||
|
|
@ -395,7 +434,7 @@ public:
|
|||
if (section == 0) {
|
||||
return QVariant (QObject::tr ("Cell / Category"));
|
||||
} else if (section == 1) {
|
||||
return QVariant (QObject::tr ("Count (Not Visited)"));
|
||||
return QVariant (QObject::tr ("Count (Not Visited) - Waived"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -436,13 +475,14 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool no_errors (const QModelIndex &index) const
|
||||
bool no_errors (const QModelIndex &index, bool include_waived = false) const
|
||||
{
|
||||
MarkerBrowserTreeViewModelCacheEntry *node = (MarkerBrowserTreeViewModelCacheEntry *)(index.internalPointer ());
|
||||
if (node && mp_database) {
|
||||
|
||||
rdb::id_type id = node->id ();
|
||||
bool none = false;
|
||||
size_t thr = include_waived ? node->waived_count () : 0;
|
||||
|
||||
const rdb::Cell *cell = mp_database->cell_by_id (id);
|
||||
const rdb::Category *category = mp_database->category_by_id (id);
|
||||
|
|
@ -464,13 +504,13 @@ public:
|
|||
}
|
||||
|
||||
if (cell == 0 && category == 0) {
|
||||
none = (mp_database->num_items () == 0);
|
||||
none = (mp_database->num_items () <= thr);
|
||||
} else if (category == 0) {
|
||||
none = (cell->num_items () == 0);
|
||||
none = (cell->num_items () <= thr);
|
||||
} else if (cell == 0) {
|
||||
none = (category->num_items () == 0);
|
||||
none = (category->num_items () <= thr);
|
||||
} else {
|
||||
none = (mp_database->num_items (cell->id (), category->id ()) == 0);
|
||||
none = (mp_database->num_items (cell->id (), category->id ()) <= thr);
|
||||
}
|
||||
|
||||
return none;
|
||||
|
|
@ -494,16 +534,30 @@ public:
|
|||
|
||||
if (index.column () == 1) {
|
||||
|
||||
std::string s;
|
||||
|
||||
if (node->count () > 0) {
|
||||
|
||||
size_t visited = node->visited_count (mp_database);
|
||||
size_t waived = node->waived_count ();
|
||||
|
||||
if (visited < node->count ()) {
|
||||
return QVariant (tl::to_qstring (tl::sprintf (tl::to_string (QObject::tr ("%lu (%lu)")), node->count (), node->count () - visited)));
|
||||
s = tl::sprintf (tl::to_string (tr ("%lu (%lu)")), node->count (), node->count () - visited);
|
||||
} else {
|
||||
return QVariant ((unsigned int) node->count ());
|
||||
s = tl::sprintf (tl::to_string (tr ("%lu")), node->count ());
|
||||
}
|
||||
|
||||
if (waived > 0) {
|
||||
if (waived == node->count ()) {
|
||||
s += tl::to_string (tr (" - all waived"));
|
||||
} else {
|
||||
return QVariant (QString::fromUtf8 (""));
|
||||
s += tl::sprintf (tl::to_string (tr (" - %lu")), waived);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return QVariant (tl::to_qstring (s));
|
||||
|
||||
} else if (index.column () == 0) {
|
||||
|
||||
|
|
@ -529,7 +583,7 @@ public:
|
|||
if (cell->name ().empty ()) {
|
||||
return QObject::tr ("All Cells");
|
||||
} else {
|
||||
return QVariant (QString::fromUtf8 ("[") + tl::to_qstring (cell->name ()) + QString::fromUtf8 ("]"));
|
||||
return QVariant (QString::fromUtf8 ("[") + tl::to_qstring (cell->qname ()) + QString::fromUtf8 ("]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -567,7 +621,7 @@ public:
|
|||
}
|
||||
|
||||
// Green color if no errors are present
|
||||
if (no_errors (index)) {
|
||||
if (no_errors (index, true)) {
|
||||
return QVariant (QColor (0, 192, 0));
|
||||
}
|
||||
|
||||
|
|
@ -725,22 +779,103 @@ public:
|
|||
private:
|
||||
const rdb::Database *mp_database;
|
||||
mutable MarkerBrowserTreeViewModelCacheEntry m_cache;
|
||||
mutable std::multimap<std::pair<rdb::id_type, rdb::id_type>, MarkerBrowserTreeViewModelCacheEntry *> m_cache_by_ids;
|
||||
bool m_show_empty_ones;
|
||||
id_type m_waived_tag_id;
|
||||
|
||||
void waive_or_unwaive (rdb::id_type cell_id, rdb::id_type cat_id, bool waived)
|
||||
{
|
||||
auto k = std::make_pair (cell_id, cat_id);
|
||||
auto c = m_cache_by_ids.find (k);
|
||||
while (c != m_cache_by_ids.end () && c->first == k) {
|
||||
c->second->waive_or_unwaive (waived);
|
||||
++c;
|
||||
}
|
||||
}
|
||||
|
||||
size_t num_waived () const
|
||||
{
|
||||
size_t n = 0;
|
||||
for (auto i = mp_database->items ().begin (); i != mp_database->items ().end (); ++i) {
|
||||
if (i->has_tag (m_waived_tag_id)) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t num_waived_per_cat (id_type cat_id) const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
auto ii = mp_database->items_by_category (cat_id);
|
||||
for (auto i = ii.first; i != ii.second; ++i) {
|
||||
if ((*i)->has_tag (m_waived_tag_id)) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
// include sub-categories
|
||||
const rdb::Category *cat = mp_database->category_by_id (cat_id);
|
||||
tl_assert (cat != 0);
|
||||
for (auto c = cat->sub_categories ().begin (); c != cat->sub_categories ().end (); ++c) {
|
||||
n += num_waived_per_cat (c->id ());
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t num_waived_per_cell_and_cat (id_type cell_id, id_type cat_id) const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
auto ii = mp_database->items_by_cell_and_category (cell_id, cat_id);
|
||||
for (auto i = ii.first; i != ii.second; ++i) {
|
||||
if ((*i)->has_tag (m_waived_tag_id)) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
// include sub-categories
|
||||
const rdb::Category *cat = mp_database->category_by_id (cat_id);
|
||||
tl_assert (cat != 0);
|
||||
for (auto c = cat->sub_categories ().begin (); c != cat->sub_categories ().end (); ++c) {
|
||||
n += num_waived_per_cell_and_cat (cell_id, c->id ());
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t num_waived_per_cell (id_type cell_id) const
|
||||
{
|
||||
auto ii = mp_database->items_by_cell (cell_id);
|
||||
size_t n = 0;
|
||||
for (auto i = ii.first; i != ii.second; ++i) {
|
||||
if ((*i)->has_tag (m_waived_tag_id)) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void invalidate ()
|
||||
{
|
||||
beginResetModel ();
|
||||
|
||||
m_cache.clear ();
|
||||
m_cache_by_ids.clear ();
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry *by_cell_node = new MarkerBrowserTreeViewModelCacheEntry(0, 0);
|
||||
m_cache.add_child (by_cell_node);
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (rdb::id_type (0), rdb::id_type (0)), by_cell_node));
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry *by_category_node = new MarkerBrowserTreeViewModelCacheEntry(0, 1);
|
||||
m_cache.add_child (by_category_node);
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (rdb::id_type (0), rdb::id_type (0)), by_category_node));
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry *all_node = new MarkerBrowserTreeViewModelCacheEntry(0, 2);
|
||||
m_cache.add_child (all_node);
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (rdb::id_type (0), rdb::id_type (0)), all_node));
|
||||
|
||||
m_cache.set_cache_valid (true);
|
||||
|
||||
|
|
@ -760,18 +895,22 @@ private:
|
|||
{
|
||||
const rdb::Category *category = mp_database->category_by_id (node->id ());
|
||||
if (category) {
|
||||
|
||||
for (rdb::Categories::const_iterator c = category->sub_categories ().begin (); c != category->sub_categories ().end (); ++c) {
|
||||
|
||||
node->set_cache_valid (true);
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry *child = new MarkerBrowserTreeViewModelCacheEntry (c->id (), node->branch ());
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (rdb::id_type (0), c->id ()), child));
|
||||
node->add_child (child);
|
||||
|
||||
child->set_count (mp_database->category_by_id (c->id ())->num_items ());
|
||||
child->set_waived_count (num_waived_per_cat (c->id ()));
|
||||
|
||||
add_sub_categories (child);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -781,19 +920,24 @@ private:
|
|||
|
||||
const rdb::Category *category = mp_database->category_by_id (node->id ());
|
||||
if (category) {
|
||||
|
||||
for (rdb::Categories::const_iterator c = category->sub_categories ().begin (); c != category->sub_categories ().end (); ++c) {
|
||||
|
||||
if (partial_tree.find (c->id ()) != partial_tree.end ()) {
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry *child = new MarkerBrowserTreeViewModelCacheEntry (c->id (), node->branch ());
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (cell_id, c->id ()), child));
|
||||
node->add_child (child);
|
||||
|
||||
size_t n = mp_database->num_items (cell_id, c->id ());
|
||||
child->set_count (n);
|
||||
child->set_count (mp_database->num_items (cell_id, c->id ()));
|
||||
child->set_waived_count (num_waived_per_cell_and_cat (cell_id, c->id ()));
|
||||
|
||||
add_sub_categories (cell_id, child, partial_tree);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -813,27 +957,44 @@ private:
|
|||
if (branch == 0) {
|
||||
|
||||
for (rdb::Database::const_cell_iterator c = mp_database->cells ().begin (); c != mp_database->cells ().end (); ++c) {
|
||||
|
||||
if (mp_database->cell_by_id (c->id ()) && (m_show_empty_ones || mp_database->cell_by_id (c->id ())->num_items () != 0)) {
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry *child = new MarkerBrowserTreeViewModelCacheEntry (c->id (), branch);
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (c->id (), rdb::id_type (0)), child));
|
||||
|
||||
child->set_count (mp_database->cell_by_id (c->id ())->num_items ());
|
||||
child->set_waived_count (num_waived_per_cell (c->id ()));
|
||||
|
||||
node->add_child (child);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (branch == 1) {
|
||||
|
||||
for (rdb::Categories::const_iterator c = mp_database->categories ().begin (); c != mp_database->categories ().end (); ++c) {
|
||||
|
||||
if (mp_database->category_by_id (c->id ()) && (m_show_empty_ones || mp_database->category_by_id (c->id ())->num_items () != 0)) {
|
||||
|
||||
MarkerBrowserTreeViewModelCacheEntry *child = new MarkerBrowserTreeViewModelCacheEntry (c->id (), branch);
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (rdb::id_type (0), c->id ()), child));
|
||||
|
||||
child->set_count (mp_database->category_by_id (c->id ())->num_items ());
|
||||
child->set_waived_count (num_waived_per_cat (c->id ()));
|
||||
|
||||
node->add_child (child);
|
||||
add_sub_categories (child);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
node->set_count (mp_database->num_items ());
|
||||
node->set_waived_count (num_waived ());
|
||||
|
||||
} else if (branch == 0) {
|
||||
|
||||
|
|
@ -869,9 +1030,14 @@ private:
|
|||
MarkerBrowserTreeViewModelCacheEntry *child = new MarkerBrowserTreeViewModelCacheEntry (c->id (), branch);
|
||||
|
||||
size_t n = mp_database->num_items (id, c->id ());
|
||||
|
||||
if (m_show_empty_ones || n != 0) {
|
||||
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (id, c->id ()), child));
|
||||
|
||||
child->set_count (n);
|
||||
child->set_waived_count (num_waived_per_cell_and_cat (id, c->id ()));
|
||||
|
||||
node->add_child (child);
|
||||
|
||||
add_sub_categories (id, child, category_ids);
|
||||
|
|
@ -903,8 +1069,14 @@ private:
|
|||
size_t n = mp_database->num_items (*c, id);
|
||||
|
||||
if (m_show_empty_ones || n != 0) {
|
||||
|
||||
m_cache_by_ids.insert (std::make_pair (std::make_pair (*c, id), child));
|
||||
|
||||
child->set_count (n);
|
||||
child->set_waived_count (num_waived_per_cell_and_cat (*c, id));
|
||||
|
||||
node->add_child (child);
|
||||
|
||||
} else {
|
||||
delete child;
|
||||
}
|
||||
|
|
@ -996,6 +1168,16 @@ public:
|
|||
m_sorting_order = sorting_order;
|
||||
}
|
||||
|
||||
int sorting () const
|
||||
{
|
||||
return m_sorting;
|
||||
}
|
||||
|
||||
bool sorting_order () const
|
||||
{
|
||||
return m_sorting_order;
|
||||
}
|
||||
|
||||
template <class Iter>
|
||||
bool set_items (const std::vector <std::pair<Iter, Iter> > &be_vector, size_t max_marker_count)
|
||||
{
|
||||
|
|
@ -1528,6 +1710,7 @@ MarkerBrowserPage::MarkerBrowserPage (QWidget * /*parent*/)
|
|||
connect (list_down_pb, SIGNAL (clicked ()), this, SLOT (list_down_clicked ()));
|
||||
connect (flags_pb, SIGNAL (clicked ()), this, SLOT (flag_button_clicked ()));
|
||||
connect (important_pb, SIGNAL (clicked ()), this, SLOT (important_button_clicked ()));
|
||||
connect (edit_pb, SIGNAL (clicked ()), this, SLOT (edit_button_clicked ()));
|
||||
connect (waive_pb, SIGNAL (clicked ()), this, SLOT (waived_button_clicked ()));
|
||||
connect (photo_pb, SIGNAL (clicked ()), this, SLOT (snapshot_button_clicked ()));
|
||||
connect (nophoto_pb, SIGNAL (clicked ()), this, SLOT (remove_snapshot_button_clicked ()));
|
||||
|
|
@ -1724,6 +1907,16 @@ MarkerBrowserPage::set_rdb (rdb::Database *database)
|
|||
rerun_button->setToolTip (QString ());
|
||||
}
|
||||
|
||||
// mark items visited that carry the waived flag
|
||||
if (mp_database) {
|
||||
id_type waived_tag_id = mp_database->tags ().tag ("waived").id ();
|
||||
for (auto i = mp_database->items ().begin (); i != mp_database->items ().end (); ++i) {
|
||||
if (i->has_tag (waived_tag_id)) {
|
||||
mp_database->set_item_visited (i.operator-> (), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QAbstractItemModel *tree_model = directory_tree->model ();
|
||||
|
||||
MarkerBrowserTreeViewModel *new_model = new MarkerBrowserTreeViewModel ();
|
||||
|
|
@ -1745,6 +1938,9 @@ MarkerBrowserPage::set_rdb (rdb::Database *database)
|
|||
QAbstractItemModel *list_model = markers_list->model ();
|
||||
|
||||
MarkerBrowserListViewModel *new_list_model = new MarkerBrowserListViewModel ();
|
||||
// default sorting is by waived flag
|
||||
new_list_model->set_sorting (2, true);
|
||||
markers_list->header ()->setSortIndicator (new_list_model->sorting (), new_list_model->sorting_order () ? Qt::AscendingOrder : Qt::DescendingOrder);
|
||||
new_list_model->set_database (database);
|
||||
markers_list->setModel (new_list_model);
|
||||
connect (markers_list->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (markers_selection_changed (const QItemSelection &, const QItemSelection &)));
|
||||
|
|
@ -1939,6 +2135,8 @@ MarkerBrowserPage::update_info_text ()
|
|||
size_t n_category = 0;
|
||||
const rdb::Item *item = 0;
|
||||
size_t n_item = 0;
|
||||
std::string comment;
|
||||
size_t n_comment = 0;
|
||||
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
|
||||
|
|
@ -1950,6 +2148,11 @@ MarkerBrowserPage::update_info_text ()
|
|||
item = i;
|
||||
++n_item;
|
||||
|
||||
if (! item->comment ().empty () && item->comment () != comment) {
|
||||
comment = item->comment ();
|
||||
++n_comment;
|
||||
}
|
||||
|
||||
const rdb::Cell *c = mp_database->cell_by_id (item->cell_id ());
|
||||
if (c && c != cell) {
|
||||
cell = c;
|
||||
|
|
@ -1976,11 +2179,11 @@ MarkerBrowserPage::update_info_text ()
|
|||
info += "<h3>";
|
||||
|
||||
if (category && n_category == 1) {
|
||||
info += category->name ();
|
||||
tl::escape_to_html (info, category->name ());
|
||||
}
|
||||
|
||||
if (cell && n_cell == 1 && ! cell->name ().empty ()) {
|
||||
info += " [" + cell->name () + "]";
|
||||
tl::escape_to_html (info, std::string (" [") + cell->name () + "]");
|
||||
}
|
||||
|
||||
info += "</h3>";
|
||||
|
|
@ -1997,6 +2200,12 @@ MarkerBrowserPage::update_info_text ()
|
|||
info += "</p>";
|
||||
}
|
||||
|
||||
if (! comment.empty () && n_comment == 1) {
|
||||
info += "<p style=\"color:gray\">";
|
||||
tl::escape_to_html (info, comment);
|
||||
info += "</p>";
|
||||
}
|
||||
|
||||
info += "<p/>";
|
||||
|
||||
if (item && n_item == 1) {
|
||||
|
|
@ -2085,8 +2294,6 @@ MarkerBrowserPage::do_update_markers ()
|
|||
item_index = size_t (selected_item->row ());
|
||||
++n_item;
|
||||
|
||||
std::string info;
|
||||
|
||||
const rdb::Cell *c = mp_database->cell_by_id (item->cell_id ());
|
||||
if (c && c != cell) {
|
||||
cell = c;
|
||||
|
|
@ -2736,6 +2943,60 @@ MarkerBrowserPage::flag_menu_selected ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserPage::edit_button_clicked ()
|
||||
{
|
||||
if (! mp_database) {
|
||||
return;
|
||||
}
|
||||
|
||||
MarkerBrowserListViewModel *list_model = dynamic_cast<MarkerBrowserListViewModel *> (markers_list->model ());
|
||||
if (! list_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str;
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (! i->comment ().empty ()) {
|
||||
if (str.empty ()) {
|
||||
str = i->comment ();
|
||||
} else if (str != i->comment ()) {
|
||||
str.clear ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
|
||||
#if QT_VERSION >= 0x50200
|
||||
QString new_text = QInputDialog::getMultiLineText (this, QObject::tr ("Edit Marker Comment"), QObject::tr ("Comment"), tl::to_qstring (str), &ok);
|
||||
str = tl::to_string (new_text);
|
||||
#else
|
||||
QString new_text = QInputDialog::getText (this, QObject::tr ("Edit Marker Comment"), QObject::tr ("Comment"), QLineEdit::Normal, tl::to_qstring (tl::escape_string (str)), &ok);
|
||||
str = tl::unescape_string (tl::to_string (new_text));
|
||||
#endif
|
||||
|
||||
if (ok) {
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
mp_database->set_item_comment (i, str);
|
||||
}
|
||||
}
|
||||
|
||||
update_info_text ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserPage::waived_button_clicked ()
|
||||
{
|
||||
|
|
@ -2754,7 +3015,7 @@ MarkerBrowserPage::waived_button_clicked ()
|
|||
size_t nno = 0;
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
|
@ -2792,7 +3053,7 @@ MarkerBrowserPage::important_button_clicked ()
|
|||
size_t nno = 0;
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
|
@ -2831,7 +3092,7 @@ MarkerBrowserPage::remove_snapshot_button_clicked ()
|
|||
if (msgbox.exec () == QMessageBox::Yes) {
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
|
@ -2858,7 +3119,7 @@ MarkerBrowserPage::snapshot_button_clicked ()
|
|||
}
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
|
@ -2903,6 +3164,11 @@ MarkerBrowserPage::unwaive_all ()
|
|||
return;
|
||||
}
|
||||
|
||||
MarkerBrowserTreeViewModel *tree_model = dynamic_cast<MarkerBrowserTreeViewModel *> (directory_tree->model ());
|
||||
if (! tree_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox msgbox (QMessageBox::Question,
|
||||
QObject::tr ("Remove All Waived"),
|
||||
QObject::tr ("Are you sure to remove the waived flags from all markers?"),
|
||||
|
|
@ -2912,7 +3178,10 @@ MarkerBrowserPage::unwaive_all ()
|
|||
id_type waived_tag_id = mp_database->tags ().tag ("waived").id ();
|
||||
|
||||
for (Items::const_iterator i = mp_database->items ().begin (); i != mp_database->items ().end (); ++i) {
|
||||
mp_database->remove_item_tag (&*i, waived_tag_id);
|
||||
if (i->has_tag (waived_tag_id)) {
|
||||
mp_database->remove_item_tag (i.operator-> (), waived_tag_id);
|
||||
tree_model->waived_changed (i.operator-> (), false);
|
||||
}
|
||||
}
|
||||
|
||||
list_model->mark_data_changed ();
|
||||
|
|
@ -2933,7 +3202,7 @@ MarkerBrowserPage::revisit_all ()
|
|||
}
|
||||
|
||||
for (Items::const_iterator i = mp_database->items ().begin (); i != mp_database->items ().end (); ++i) {
|
||||
mp_database->set_item_visited (&*i, false);
|
||||
mp_database->set_item_visited (i.operator-> (), false);
|
||||
}
|
||||
|
||||
list_model->mark_data_changed ();
|
||||
|
|
@ -2960,7 +3229,7 @@ MarkerBrowserPage::revisit_non_waived ()
|
|||
|
||||
for (Items::const_iterator i = mp_database->items ().begin (); i != mp_database->items ().end (); ++i) {
|
||||
if (! i->has_tag (waived_tag_id)) {
|
||||
mp_database->set_item_visited (&*i, false);
|
||||
mp_database->set_item_visited (i.operator-> (), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2988,7 +3257,7 @@ MarkerBrowserPage::revisit_important ()
|
|||
|
||||
for (Items::const_iterator i = mp_database->items ().begin (); i != mp_database->items ().end (); ++i) {
|
||||
if (i->has_tag (important_tag_id)) {
|
||||
mp_database->set_item_visited (&*i, false);
|
||||
mp_database->set_item_visited (i.operator-> (), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3015,7 +3284,7 @@ MarkerBrowserPage::mark_important ()
|
|||
id_type important_tag_id = mp_database->tags ().tag ("important").id ();
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
|
@ -3042,7 +3311,7 @@ MarkerBrowserPage::mark_unimportant ()
|
|||
id_type important_tag_id = mp_database->tags ().tag ("important").id ();
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
|
@ -3079,7 +3348,7 @@ MarkerBrowserPage::mark_visited (bool f)
|
|||
}
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
|
@ -3099,32 +3368,17 @@ MarkerBrowserPage::mark_visited (bool f)
|
|||
void
|
||||
MarkerBrowserPage::waive ()
|
||||
{
|
||||
if (! mp_database) {
|
||||
return;
|
||||
}
|
||||
|
||||
MarkerBrowserListViewModel *list_model = dynamic_cast<MarkerBrowserListViewModel *> (markers_list->model ());
|
||||
if (! list_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
id_type waived_tag_id = mp_database->tags ().tag ("waived").id ();
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
mp_database->add_item_tag (i, waived_tag_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list_model->mark_data_changed ();
|
||||
waive_or_unwaive (true);
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserPage::unwaive ()
|
||||
{
|
||||
waive_or_unwaive (false);
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBrowserPage::waive_or_unwaive (bool w)
|
||||
{
|
||||
if (! mp_database) {
|
||||
return;
|
||||
|
|
@ -3135,19 +3389,38 @@ MarkerBrowserPage::unwaive ()
|
|||
return;
|
||||
}
|
||||
|
||||
MarkerBrowserTreeViewModel *tree_model = dynamic_cast<MarkerBrowserTreeViewModel *> (directory_tree->model ());
|
||||
if (! tree_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
id_type waived_tag_id = mp_database->tags ().tag ("waived").id ();
|
||||
|
||||
QModelIndexList selected = markers_list->selectionModel ()->selectedIndexes ();
|
||||
for (QModelIndexList::const_iterator selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
for (auto selected_item = selected.begin (); selected_item != selected.end (); ++selected_item) {
|
||||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
bool was_waived = i->has_tag (waived_tag_id);
|
||||
if (w != was_waived) {
|
||||
if (w) {
|
||||
mp_database->add_item_tag (i, waived_tag_id);
|
||||
} else {
|
||||
mp_database->remove_item_tag (i, waived_tag_id);
|
||||
}
|
||||
if (w) {
|
||||
// waiving an item makes it visited (rationale: once waived, an item is no
|
||||
// longer of interest)
|
||||
mp_database->set_item_visited (i, true);
|
||||
}
|
||||
tree_model->waived_changed (i, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list_model->mark_data_changed ();
|
||||
tree_model->mark_data_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ public slots:
|
|||
void flag_menu_selected ();
|
||||
void important_button_clicked ();
|
||||
void waived_button_clicked ();
|
||||
void edit_button_clicked ();
|
||||
void snapshot_button_clicked ();
|
||||
void remove_snapshot_button_clicked ();
|
||||
void revisit_non_waived ();
|
||||
|
|
@ -238,6 +239,7 @@ private:
|
|||
void do_update_markers ();
|
||||
void update_info_text ();
|
||||
void rerun_macro ();
|
||||
void waive_or_unwaive (bool w);
|
||||
};
|
||||
|
||||
} // namespace rdb
|
||||
|
|
|
|||
|
|
@ -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 ("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 cell's qualified name\n"
|
||||
"@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"
|
||||
|
|
@ -911,6 +919,10 @@ Class<rdb::Item> decl_RdbItem ("rdb", "RdbItem",
|
|||
"@brief Remove the tag with the given id from the item\n"
|
||||
"If a tag with that ID does not exists on this item, this method does nothing."
|
||||
) +
|
||||
gsi::method ("remove_tags", &rdb::Item::remove_tags,
|
||||
"@brief Removes all tags from the item\n"
|
||||
"This method has been introduced in version 0.29.1."
|
||||
) +
|
||||
gsi::method ("has_tag?", &rdb::Item::has_tag, gsi::arg ("tag_id"),
|
||||
"@brief Returns a value indicating whether the item has a tag with the given ID\n"
|
||||
"@return True, if the item has a tag with the given ID\n"
|
||||
|
|
@ -928,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"
|
||||
|
|
@ -1317,6 +1342,7 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
|
|||
"@brief Creates a new sub-category\n"
|
||||
"@param parent The category under which the category should be created\n"
|
||||
"@param name The name of the category\n"
|
||||
"Since version 0.29.1, 'parent' can be nil. In that case, a top-level category is created."
|
||||
) +
|
||||
gsi::method ("category_by_path", &rdb::Database::category_by_name, gsi::arg ("path"),
|
||||
"@brief Gets a category by path\n"
|
||||
|
|
@ -1344,10 +1370,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"
|
||||
|
|
@ -1562,6 +1590,36 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
|
|||
"@param trans The transformation to apply\n"
|
||||
"@param edge_pairs The list of edge_pairs for which the items are created\n"
|
||||
) +
|
||||
gsi::method ("apply", &rdb::Database::apply, gsi::arg ("other"),
|
||||
"@brief Transfers item attributes from one database to another for identical items\n"
|
||||
"This method will identify items that are identical between the two databases and transfer "
|
||||
"item attributes from the 'other' database to this database. Transferable attributes are:\n"
|
||||
"\n"
|
||||
"@ul\n"
|
||||
"@li Images @/li\n"
|
||||
"@li Item tags @/li\n"
|
||||
"@/ul\n"
|
||||
"\n"
|
||||
"Existing attributes in this database are overwritten.\n"
|
||||
"\n"
|
||||
"Items are identical if\n"
|
||||
"\n"
|
||||
"@ul\n"
|
||||
"@li They belong to the same cell (by qname) @/li\n"
|
||||
"@li They belong to the same category (by name) @/li\n"
|
||||
"@li Their values are identical @/li\n"
|
||||
"@/ul\n"
|
||||
"\n"
|
||||
"Values are identical if their individual values and (optional) value tags are identical. "
|
||||
"Values tagged with a tag unknown to the other database are ignored. "
|
||||
"The order of values matters during the compare. So the value pair (17.0, 'abc') is different from ('abc', 17.0).\n"
|
||||
"\n"
|
||||
"The intended application for this method is use for error waiving: as the waived attribute is a transferable "
|
||||
"attribute, it is possible to apply the waived flag from from a waiver database (the 'other' database) using this "
|
||||
"method.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.29.1."
|
||||
) +
|
||||
gsi::method ("is_modified?", &rdb::Database::is_modified,
|
||||
"@brief Returns a value indicating whether the database has been modified\n"
|
||||
) +
|
||||
|
|
|
|||
|
|
@ -60,16 +60,18 @@ namespace rdb
|
|||
// type index specializations
|
||||
|
||||
template <> RDB_PUBLIC int type_index_of<double> () { return 0; }
|
||||
template <> RDB_PUBLIC int type_index_of<std::string> () { return 1; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DPolygon> () { return 2; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DEdge> () { return 3; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DEdgePair> () { return 4; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DBox> () { return 5; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DPath> () { return 6; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DText> () { return 7; }
|
||||
template <> RDB_PUBLIC int type_index_of<int> () { return 1; }
|
||||
template <> RDB_PUBLIC int type_index_of<std::string> () { return 2; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DPolygon> () { return 3; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DEdge> () { return 4; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DEdgePair> () { return 5; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DBox> () { return 6; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DPath> () { return 7; }
|
||||
template <> RDB_PUBLIC int type_index_of<db::DText> () { return 8; }
|
||||
|
||||
// Explicit instantiations to make VC++ happy in debug mode
|
||||
template class RDB_PUBLIC Value<double>;
|
||||
template class RDB_PUBLIC Value<int>;
|
||||
template class RDB_PUBLIC Value<std::string>;
|
||||
template class RDB_PUBLIC Value<db::DPolygon>;
|
||||
template class RDB_PUBLIC Value<db::DEdge>;
|
||||
|
|
@ -85,6 +87,11 @@ template <> RDB_PUBLIC std::string Value<double>::to_string () const
|
|||
return "float: " + tl::to_string (m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC std::string Value<int>::to_string () const
|
||||
{
|
||||
return "int: " + tl::to_string (m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC std::string Value<std::string>::to_string () const
|
||||
{
|
||||
return "text: " + tl::to_word_or_quoted_string (m_value);
|
||||
|
|
@ -127,6 +134,11 @@ template <> RDB_PUBLIC std::string Value<double>::to_display_string () const
|
|||
return tl::to_string (m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC std::string Value<int>::to_display_string () const
|
||||
{
|
||||
return tl::to_string (m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC std::string Value<std::string>::to_display_string () const
|
||||
{
|
||||
return m_value;
|
||||
|
|
@ -162,6 +174,62 @@ template <> RDB_PUBLIC std::string Value<db::DText>::to_display_string () const
|
|||
return to_string ();
|
||||
}
|
||||
|
||||
// compare implementations
|
||||
|
||||
template <> RDB_PUBLIC bool Value<double>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<double> *other = static_cast<const Value<double> *> (o);
|
||||
return m_value < other->m_value - db::epsilon;
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<int>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<int> *other = static_cast<const Value<int> *> (o);
|
||||
return m_value < other->m_value;
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<std::string>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<std::string> *other = static_cast<const Value<std::string> *> (o);
|
||||
return m_value < other->m_value;
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<db::DPolygon>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<db::DPolygon> *other = static_cast<const Value<db::DPolygon> *> (o);
|
||||
return m_value.less (other->m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<db::DEdge>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<db::DEdge> *other = static_cast<const Value<db::DEdge> *> (o);
|
||||
return m_value.less (other->m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<db::DEdgePair>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<db::DEdgePair> *other = static_cast<const Value<db::DEdgePair> *> (o);
|
||||
return m_value.less (other->m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<db::DBox>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<db::DBox> *other = static_cast<const Value<db::DBox> *> (o);
|
||||
return m_value.less (other->m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<db::DPath>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<db::DPath> *other = static_cast<const Value<db::DPath> *> (o);
|
||||
return m_value.less (other->m_value);
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<db::DText>::compare (const ValueBase *o) const
|
||||
{
|
||||
const Value<db::DText> *other = static_cast<const Value<db::DText> *> (o);
|
||||
return m_value.less (other->m_value);
|
||||
}
|
||||
|
||||
// is_shape implementations
|
||||
|
||||
template <> RDB_PUBLIC bool Value<double>::is_shape () const
|
||||
|
|
@ -169,6 +237,11 @@ template <> RDB_PUBLIC bool Value<double>::is_shape () const
|
|||
return false;
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<int>::is_shape () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> RDB_PUBLIC bool Value<std::string>::is_shape () const
|
||||
{
|
||||
return false;
|
||||
|
|
@ -403,6 +476,58 @@ Values::operator= (const Values &d)
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
Values::compare (const Values &other, const std::map<id_type, id_type> &tag_map, const std::map<id_type, id_type> &rev_tag_map) const
|
||||
{
|
||||
Values::const_iterator a = begin (), b = other.begin ();
|
||||
while (a != end () && b != other.end ()) {
|
||||
|
||||
id_type t12 = 0;
|
||||
while (a != end () && a->tag_id () != 0) {
|
||||
auto j = tag_map.find (a->tag_id ());
|
||||
if (j != tag_map.end ()) {
|
||||
t12 = j->second;
|
||||
break;
|
||||
}
|
||||
++a;
|
||||
}
|
||||
|
||||
id_type t2 = 0;
|
||||
while (b != other.end () && b->tag_id () != 0) {
|
||||
auto j = rev_tag_map.find (b->tag_id ());
|
||||
if (j != rev_tag_map.end ()) {
|
||||
t2 = j->first;
|
||||
break;
|
||||
}
|
||||
++b;
|
||||
}
|
||||
|
||||
if (a == end () || b == other.end ()) {
|
||||
return b != other.end ();
|
||||
}
|
||||
|
||||
if (t12 != t2) {
|
||||
return t12 < t2;
|
||||
}
|
||||
|
||||
if (a->get () && b->get ()) {
|
||||
if (rdb::ValueBase::compare (a->get (), b->get ())) {
|
||||
return true;
|
||||
} else if (rdb::ValueBase::compare (b->get (), a->get ())) {
|
||||
return false;
|
||||
}
|
||||
} else if ((a->get () != 0) != (b->get () != 0)) {
|
||||
return (a->get () != 0) < (b->get () != 0);
|
||||
}
|
||||
|
||||
++a;
|
||||
++b;
|
||||
|
||||
}
|
||||
|
||||
return b != other.end ();
|
||||
}
|
||||
|
||||
std::string
|
||||
Values::to_string (const Database *rdb) const
|
||||
{
|
||||
|
|
@ -447,7 +572,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);
|
||||
|
|
@ -479,8 +604,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 ..
|
||||
}
|
||||
|
|
@ -812,14 +937,14 @@ Tags::tag (const std::string &name, bool user_tag)
|
|||
const Tag &
|
||||
Tags::tag (id_type id) const
|
||||
{
|
||||
tl_assert (id - 1 < m_tags.size () && id > 0);
|
||||
tl_assert (id < m_tags.size () + 1 && id > 0);
|
||||
return m_tags [id - 1];
|
||||
}
|
||||
|
||||
Tag &
|
||||
Tags::tag (id_type id)
|
||||
{
|
||||
tl_assert (id - 1 < m_tags.size () && id > 0);
|
||||
tl_assert (id < m_tags.size () + 1 && id > 0);
|
||||
return m_tags [id - 1];
|
||||
}
|
||||
|
||||
|
|
@ -870,6 +995,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;
|
||||
}
|
||||
|
|
@ -1205,6 +1331,10 @@ Database::import_cells (const Cells &cells)
|
|||
Category *
|
||||
Database::create_category (Category *parent, const std::string &name)
|
||||
{
|
||||
if (! parent) {
|
||||
return create_category (name);
|
||||
}
|
||||
|
||||
set_modified ();
|
||||
|
||||
Category *cat = create_category (&parent->sub_categories (), name);
|
||||
|
|
@ -1252,7 +1382,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 ();
|
||||
|
||||
|
|
@ -1289,13 +1419,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);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1305,7 +1435,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));
|
||||
|
|
@ -1399,6 +1529,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)
|
||||
|
|
@ -1625,7 +1762,7 @@ read_db_from_layout (rdb::Database *db, tl::InputStream &is)
|
|||
}
|
||||
|
||||
void
|
||||
Database::load (const std::string &fn)
|
||||
Database::load (std::string fn)
|
||||
{
|
||||
tl::log << "Loading RDB from " << fn;
|
||||
|
||||
|
|
@ -1659,6 +1796,161 @@ Database::load (const std::string &fn)
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class ValueMapEntryCompare
|
||||
{
|
||||
public:
|
||||
ValueMapEntryCompare (const std::map<id_type, id_type> &tag2tag, const std::map<id_type, id_type> &rev_tag2tag)
|
||||
{
|
||||
mp_tag2tag = &tag2tag;
|
||||
mp_rev_tag2tag = &rev_tag2tag;
|
||||
}
|
||||
|
||||
bool operator() (const Item *a, const Item *b) const
|
||||
{
|
||||
return a->values ().compare (b->values (), *mp_tag2tag, *mp_rev_tag2tag);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::map<id_type, id_type> *mp_tag2tag;
|
||||
const std::map<id_type, id_type> *mp_rev_tag2tag;
|
||||
};
|
||||
|
||||
class ValueMapEntry
|
||||
{
|
||||
public:
|
||||
ValueMapEntry ()
|
||||
: mp_tag2tag (0), mp_rev_tag2tag (0)
|
||||
{ }
|
||||
|
||||
void build (const rdb::Database &rdb, id_type cell_id, id_type cat_id, const std::map<id_type, id_type> &tag2tag, const std::map<id_type, id_type> &rev_tag2tag)
|
||||
{
|
||||
mp_tag2tag = &tag2tag;
|
||||
mp_rev_tag2tag = &rev_tag2tag;
|
||||
|
||||
auto i2i = rdb.items_by_cell_and_category (cell_id, cat_id);
|
||||
|
||||
size_t n = 0;
|
||||
for (auto i = i2i.first; i != i2i.second; ++i) {
|
||||
++n;
|
||||
}
|
||||
m_items.reserve (n);
|
||||
|
||||
for (auto i = i2i.first; i != i2i.second; ++i) {
|
||||
m_items.push_back ((*i).operator-> ());
|
||||
}
|
||||
|
||||
ValueMapEntryCompare cmp (*mp_tag2tag, *mp_rev_tag2tag);
|
||||
std::sort (m_items.begin (), m_items.end (), cmp);
|
||||
}
|
||||
|
||||
const Item *find (const rdb::Item &item) const
|
||||
{
|
||||
ValueMapEntryCompare cmp (*mp_tag2tag, *mp_rev_tag2tag);
|
||||
|
||||
auto i = std::lower_bound (m_items.begin (), m_items.end (), &item, cmp);
|
||||
if (i == m_items.end ()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmp (&item, *i) || cmp (*i, &item)) {
|
||||
return 0;
|
||||
} else {
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::vector<const Item *> m_items;
|
||||
const std::map<id_type, id_type> *mp_tag2tag;
|
||||
const std::map<id_type, id_type> *mp_rev_tag2tag;
|
||||
};
|
||||
}
|
||||
|
||||
static void map_category (const rdb::Category &cat, const rdb::Database &db, std::map<id_type, id_type> &cat2cat)
|
||||
{
|
||||
const rdb::Category *this_cat = db.category_by_name (cat.path ());
|
||||
if (this_cat) {
|
||||
cat2cat.insert (std::make_pair (this_cat->id (), cat.id ()));
|
||||
}
|
||||
|
||||
for (auto c = cat.sub_categories ().begin (); c != cat.sub_categories ().end (); ++c) {
|
||||
map_category (*c, db, cat2cat);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Database::apply (const rdb::Database &other)
|
||||
{
|
||||
std::map<id_type, id_type> cell2cell;
|
||||
std::map<id_type, id_type> cat2cat;
|
||||
std::map<id_type, id_type> tag2tag;
|
||||
std::map<id_type, id_type> rev_tag2tag;
|
||||
|
||||
for (auto c = other.cells ().begin (); c != other.cells ().end (); ++c) {
|
||||
// TODO: do we have a consistent scheme of naming variants? What requirements
|
||||
// exist towards detecting variant specific waivers
|
||||
const rdb::Cell *this_cell = cell_by_qname (c->qname ());
|
||||
if (this_cell) {
|
||||
cell2cell.insert (std::make_pair (this_cell->id (), c->id ()));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto c = other.categories ().begin (); c != other.categories ().end (); ++c) {
|
||||
map_category (*c, *this, cat2cat);
|
||||
}
|
||||
|
||||
std::map<std::string, id_type> tags_by_name;
|
||||
for (auto c = tags ().begin_tags (); c != tags ().end_tags (); ++c) {
|
||||
tags_by_name.insert (std::make_pair (c->name (), c->id ()));
|
||||
}
|
||||
|
||||
for (auto c = other.tags ().begin_tags (); c != other.tags ().end_tags (); ++c) {
|
||||
auto t = tags_by_name.find (c->name ());
|
||||
if (t != tags_by_name.end ()) {
|
||||
tag2tag.insert (std::make_pair (t->second, c->id ()));
|
||||
rev_tag2tag.insert (std::make_pair (c->id (), t->second));
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::pair<id_type, id_type>, ValueMapEntry> value_map;
|
||||
|
||||
for (Items::iterator i = items_non_const ().begin (); i != items_non_const ().end (); ++i) {
|
||||
|
||||
auto icell = cell2cell.find (i->cell_id ());
|
||||
if (icell == cell2cell.end ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto icat = cat2cat.find (i->category_id ());
|
||||
if (icat == cat2cat.end ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// build a cache of value vs. value
|
||||
auto vmap = value_map.find (std::make_pair (icell->second, icat->second));
|
||||
if (vmap == value_map.end ()) {
|
||||
vmap = value_map.insert (std::make_pair (std::make_pair (icell->second, icat->second), ValueMapEntry ())).first;
|
||||
vmap->second.build (other, icell->second, icat->second, tag2tag, rev_tag2tag);
|
||||
}
|
||||
|
||||
// find a value in the reference DB
|
||||
const rdb::Item *other = vmap->second.find (*i);
|
||||
if (other) {
|
||||
|
||||
// actually transfer the attributes here
|
||||
|
||||
i->set_comment (other->comment ());
|
||||
// TODO: this has some optimization potential in terms of performance ...
|
||||
i->set_image_str (other->image_str ());
|
||||
i->set_tag_str (other->tag_str ());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Database::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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -506,10 +506,7 @@ public:
|
|||
return type_index_of<C> ();
|
||||
}
|
||||
|
||||
bool compare (const ValueBase *other) const
|
||||
{
|
||||
return m_value < static_cast<const Value<C> *> (other)->m_value;
|
||||
}
|
||||
bool compare (const ValueBase *other) const;
|
||||
|
||||
bool is_shape () const;
|
||||
|
||||
|
|
@ -679,6 +676,19 @@ public:
|
|||
*/
|
||||
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::map<id_type, id_type> &tag_map, const std::map<id_type, id_type> &rev_tag_map) const;
|
||||
|
||||
/**
|
||||
* @brief The const iterator (begin)
|
||||
*/
|
||||
|
|
@ -739,6 +749,14 @@ public:
|
|||
m_values.swap (other.m_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the values
|
||||
*/
|
||||
void clear ()
|
||||
{
|
||||
m_values.clear ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert the values collection to a string
|
||||
*/
|
||||
|
|
@ -993,6 +1011,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
|
||||
*/
|
||||
|
|
@ -1017,6 +1055,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;
|
||||
|
|
@ -1441,7 +1480,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
|
||||
|
|
@ -1467,7 +1506,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Get the cell name
|
||||
* @brief Gets the cell name
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
|
|
@ -1475,7 +1514,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.
|
||||
*/
|
||||
|
|
@ -1485,7 +1524,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Get the variant id
|
||||
* @brief Gets the variant id
|
||||
*/
|
||||
const std::string &variant () const
|
||||
{
|
||||
|
|
@ -1493,7 +1532,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.
|
||||
*/
|
||||
|
|
@ -1502,6 +1541,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)
|
||||
*/
|
||||
|
|
@ -1579,6 +1636,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;
|
||||
|
|
@ -2182,7 +2240,7 @@ public:
|
|||
*/
|
||||
Cell *create_cell (const std::string &name)
|
||||
{
|
||||
return create_cell (name, std::string ());
|
||||
return create_cell (name, std::string (), std::string ());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2191,8 +2249,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!)
|
||||
|
|
@ -2286,6 +2347,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
|
||||
|
|
@ -2378,12 +2444,29 @@ public:
|
|||
*/
|
||||
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
|
||||
*
|
||||
* @brief This clears the existing database.
|
||||
* Note: This clears the existing database.
|
||||
* The argument intentionally is a copy, so we can call
|
||||
* "load (this->filename ())" for reloading.
|
||||
*/
|
||||
void load (const std::string &filename);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ 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_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") +
|
||||
|
|
@ -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))
|
||||
|
|
@ -116,17 +118,25 @@ make_rdb_structure (rdb::Database *rdb)
|
|||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Implementation of rdb::Database::save
|
||||
// Implementation of rdb::Database::save and write
|
||||
// TODO: move this somewhere else - with generalized functionality
|
||||
|
||||
void
|
||||
rdb::Database::save (const std::string &fn)
|
||||
{
|
||||
write (fn);
|
||||
set_filename (fn);
|
||||
}
|
||||
|
||||
void
|
||||
rdb::Database::write (const std::string &fn)
|
||||
{
|
||||
tl::OutputStream os (fn, tl::OutputStream::OM_Auto);
|
||||
make_rdb_structure (this).write (os, *this);
|
||||
set_filename (fn);
|
||||
|
||||
if (tl::verbosity () >= 10) {
|
||||
tl::log << "Saved RDB to " << fn;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -174,10 +174,28 @@ public:
|
|||
const rdb::Cell *cell_for_id (const db::Layout *layout, db::cell_index_type ci)
|
||||
{
|
||||
tl_assert (layout != 0);
|
||||
|
||||
std::string cn = layout->cell_name (ci);
|
||||
const rdb::Cell *rdb_cell = mp_rdb->cell_by_qname (cn);
|
||||
std::string layout_cn = cn;
|
||||
std::string qname = cn;
|
||||
std::string var;
|
||||
|
||||
// resolve references to original cells in deep mode and determine variant
|
||||
if (layout->builder ()) {
|
||||
const db::Layout *source = layout->builder ()->source ().layout ();
|
||||
if (source) {
|
||||
const std::pair<db::cell_index_type, std::string> &vs = layout->builder ()->variant_of_source (ci);
|
||||
if (! vs.second.empty () && source->is_valid_cell_index (vs.first)) {
|
||||
var = vs.second;
|
||||
cn = source->cell_name (vs.first);
|
||||
qname = cn + ":" + var;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rdb::Cell *rdb_cell = mp_rdb->cell_by_qname (qname);
|
||||
if (! rdb_cell) {
|
||||
return mp_rdb->create_cell (cn);
|
||||
return mp_rdb->create_cell (cn, var, layout_cn);
|
||||
} else {
|
||||
return rdb_cell;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,15 +69,15 @@ void run_rve_test (tl::TestBase *_this, const std::string &fn_rve, const std::st
|
|||
|
||||
TEST(1)
|
||||
{
|
||||
run_rve_test (_this, "rve1.db", "rve1_au.txt");
|
||||
run_rve_test (_this, "rve1.db", "rve1_au_2.txt");
|
||||
}
|
||||
|
||||
TEST(2)
|
||||
{
|
||||
run_rve_test (_this, "rve2.db", "rve2_au.txt");
|
||||
run_rve_test (_this, "rve2.db", "rve2_au_2.txt");
|
||||
}
|
||||
|
||||
TEST(3)
|
||||
{
|
||||
run_rve_test (_this, "rve3.db", "rve3_au.txt");
|
||||
run_rve_test (_this, "rve3.db", "rve3_au_2.txt");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
@ -598,3 +599,226 @@ TEST(7)
|
|||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST(8_ApplyBasicEmptyValue)
|
||||
{
|
||||
rdb::Database db1;
|
||||
rdb::Category *cat1 = db1.create_category ("cat_name");
|
||||
rdb::Cell *c1 = db1.create_cell ("cell");
|
||||
rdb::Item *i1 = db1.create_item (c1->id (), cat1->id ());
|
||||
|
||||
rdb::Database db2;
|
||||
db2.create_category ("dummy_cat");
|
||||
rdb::Category *cat2 = db2.create_category ("cat_name");
|
||||
db2.create_cell ("dummy_cell");
|
||||
rdb::Cell *c2 = db2.create_cell ("cell");
|
||||
rdb::Item *i2 = db2.create_item (c2->id (), cat2->id ());
|
||||
|
||||
rdb::id_type tag2 = db2.tags ().tag ("tag2").id ();
|
||||
i2->add_tag (tag2);
|
||||
|
||||
EXPECT_EQ (i2->tag_str (), "tag2");
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// empty value apply
|
||||
db1.apply (db2);
|
||||
|
||||
EXPECT_EQ (i1->tag_str (), "tag2");
|
||||
}
|
||||
|
||||
TEST(9_ApplyBasicSomeValue)
|
||||
{
|
||||
rdb::Database db1;
|
||||
rdb::Category *cat1 = db1.create_category ("cat_name");
|
||||
rdb::Cell *c1 = db1.create_cell ("cell");
|
||||
rdb::Item *i1 = db1.create_item (c1->id (), cat1->id ());
|
||||
i1->add_value (std::string ("abc"));
|
||||
|
||||
rdb::Database db2;
|
||||
db2.create_category ("dummy_cat");
|
||||
rdb::Category *cat2 = db2.create_category ("cat_name");
|
||||
db2.create_cell ("dummy_cell");
|
||||
rdb::Cell *c2 = db2.create_cell ("cell");
|
||||
rdb::Item *i2 = db2.create_item (c2->id (), cat2->id ());
|
||||
|
||||
db2.tags ().tag ("dummy_tag");
|
||||
rdb::id_type tag2 = db2.tags ().tag ("tag2").id ();
|
||||
i2->add_tag (tag2);
|
||||
|
||||
EXPECT_EQ (i2->tag_str (), "tag2");
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// empty value apply
|
||||
db1.apply (db2);
|
||||
|
||||
// not applied (different value)
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// incorrect value
|
||||
i2->add_value (17);
|
||||
|
||||
db1.apply (db2);
|
||||
|
||||
// still not applied
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// correct value
|
||||
i2->values ().clear ();
|
||||
i2->add_value (std::string ("abc"));
|
||||
|
||||
db1.apply (db2);
|
||||
|
||||
// now, the tag is applied
|
||||
EXPECT_EQ (i1->tag_str (), "tag2");
|
||||
|
||||
// too many values
|
||||
i1->remove_tags ();
|
||||
i2->add_value (17);
|
||||
|
||||
db1.apply (db2);
|
||||
|
||||
// not applied
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
}
|
||||
|
||||
TEST(10_ApplyTaggedValue)
|
||||
{
|
||||
rdb::Database db1;
|
||||
rdb::Category *cat1 = db1.create_category ("cat_name");
|
||||
rdb::Cell *c1 = db1.create_cell ("cell");
|
||||
rdb::Item *i1 = db1.create_item (c1->id (), cat1->id ());
|
||||
rdb::id_type vtag11 = db1.tags ().tag ("vtag1").id ();
|
||||
rdb::id_type vtag12 = db1.tags ().tag ("vtag2").id ();
|
||||
i1->add_value (std::string ("abc"));
|
||||
|
||||
rdb::Database db2;
|
||||
db2.create_category ("dummy_cat");
|
||||
rdb::Category *cat2 = db2.create_category ("cat_name");
|
||||
db2.create_cell ("dummy_cell");
|
||||
rdb::Cell *c2 = db2.create_cell ("cell");
|
||||
rdb::Item *i2 = db2.create_item (c2->id (), cat2->id ());
|
||||
db2.tags ().tag ("dummy_tag");
|
||||
|
||||
rdb::id_type tag2 = db2.tags ().tag ("tag2").id ();
|
||||
rdb::id_type vtag21 = db2.tags ().tag ("vtag1").id ();
|
||||
i2->add_tag (tag2);
|
||||
i2->add_value (std::string ("abc"), vtag21);
|
||||
|
||||
// empty tag vs. vtag1
|
||||
db1.apply (db2);
|
||||
|
||||
// not applied (empty tag vs. tagged)
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// vtag2 vs. vtag1
|
||||
i1->values ().clear ();
|
||||
i1->add_value (std::string ("abc"), vtag12);
|
||||
|
||||
db1.apply (db2);
|
||||
|
||||
// not applied (different tags)
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// vtag1 vs. vtag1
|
||||
i1->values ().clear ();
|
||||
i1->add_value (std::string ("abc"), vtag11);
|
||||
|
||||
db1.apply (db2);
|
||||
|
||||
// this time it is applied (same tag)
|
||||
EXPECT_EQ (i1->tag_str (), "tag2");
|
||||
}
|
||||
|
||||
TEST(11_ApplyWrongCat)
|
||||
{
|
||||
rdb::Database db1;
|
||||
rdb::Category *cat1 = db1.create_category ("cat_name");
|
||||
rdb::Cell *c1 = db1.create_cell ("cell");
|
||||
rdb::Item *i1 = db1.create_item (c1->id (), cat1->id ());
|
||||
|
||||
rdb::Database db2;
|
||||
db2.create_category ("dummy_cat");
|
||||
rdb::Category *cat2 = db2.create_category ("xcat_name");
|
||||
db2.create_cell ("dummy_cell");
|
||||
rdb::Cell *c2 = db2.create_cell ("cell");
|
||||
rdb::Item *i2 = db2.create_item (c2->id (), cat2->id ());
|
||||
|
||||
rdb::id_type tag2 = db2.tags ().tag ("tag2").id ();
|
||||
i2->add_tag (tag2);
|
||||
|
||||
EXPECT_EQ (i2->tag_str (), "tag2");
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// empty value apply
|
||||
db1.apply (db2);
|
||||
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
}
|
||||
|
||||
TEST(12_ApplyWrongCell)
|
||||
{
|
||||
rdb::Database db1;
|
||||
rdb::Category *cat1 = db1.create_category ("cat_name");
|
||||
rdb::Cell *c1 = db1.create_cell ("cell");
|
||||
rdb::Item *i1 = db1.create_item (c1->id (), cat1->id ());
|
||||
|
||||
rdb::Database db2;
|
||||
db2.create_category ("dummy_cat");
|
||||
rdb::Category *cat2 = db2.create_category ("cat_name");
|
||||
db2.create_cell ("dummy_cell");
|
||||
rdb::Cell *c2 = db2.create_cell ("xcell");
|
||||
rdb::Item *i2 = db2.create_item (c2->id (), cat2->id ());
|
||||
|
||||
rdb::id_type tag2 = db2.tags ().tag ("tag2").id ();
|
||||
i2->add_tag (tag2);
|
||||
|
||||
EXPECT_EQ (i2->tag_str (), "tag2");
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// empty value apply
|
||||
db1.apply (db2);
|
||||
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
}
|
||||
|
||||
TEST(13_ApplyIgnoreUnknownTag)
|
||||
{
|
||||
rdb::Database db1;
|
||||
rdb::Category *cat1 = db1.create_category ("cat_name");
|
||||
rdb::Cell *c1 = db1.create_cell ("cell");
|
||||
rdb::Item *i1 = db1.create_item (c1->id (), cat1->id ());
|
||||
rdb::id_type vtag11 = db1.tags ().tag ("vtag1").id ();
|
||||
i1->add_value (std::string ("abc"), vtag11);
|
||||
|
||||
rdb::Database db2;
|
||||
db2.create_category ("dummy_cat");
|
||||
rdb::Category *cat2 = db2.create_category ("cat_name");
|
||||
db2.create_cell ("dummy_cell");
|
||||
rdb::Cell *c2 = db2.create_cell ("cell");
|
||||
rdb::Item *i2 = db2.create_item (c2->id (), cat2->id ());
|
||||
db2.tags ().tag ("dummy_tag");
|
||||
|
||||
rdb::id_type tag2 = db2.tags ().tag ("tag2").id ();
|
||||
rdb::id_type vtag21 = db2.tags ().tag ("vtag1").id ();
|
||||
rdb::id_type vtag22 = db2.tags ().tag ("vtag2").id ();
|
||||
i2->add_tag (tag2);
|
||||
|
||||
// same tags, different values
|
||||
i2->add_value (std::string ("xyz"), vtag21);
|
||||
|
||||
db1.apply (db2);
|
||||
|
||||
// not applied
|
||||
EXPECT_EQ (i1->tag_str (), "");
|
||||
|
||||
// different tags without mapping
|
||||
i2->values ().clear ();
|
||||
i2->add_value (std::string ("xyz"), vtag22);
|
||||
|
||||
// values with incompatible tags are ignored -> tag2 is applied
|
||||
db1.apply (db2);
|
||||
|
||||
EXPECT_EQ (i1->tag_str (), "tag2");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
source($drc_test_source)
|
||||
report("Report comment with\nanother line", $drc_test_report)
|
||||
|
||||
deep
|
||||
|
||||
l1 = input(1, 0)
|
||||
l1 = l1.sized(0.1, 0.0)
|
||||
|
||||
l1.output("l1", "L1 (1/0 sized by x=100nm,y=0)")
|
||||
l1.width(1.0.um).output("w1um", "w < 1µm\nFrom sized input")
|
||||
|
||||
l1s = l1.snapped(200.nm)
|
||||
l1s.output("l1_snapped", "L1 snapped to 200nm")
|
||||
l1s.width(1.0.um).output("w1um_snapped", "w < 1µm\nFrom snapped input")
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
source($drc_test_source)
|
||||
report("Report comment with\nanother line", $drc_test_report)
|
||||
|
||||
deep
|
||||
|
||||
l1 = input(1, 0)
|
||||
l1s = l1.sized(0.1, 0.0)
|
||||
|
||||
l1.output([ "input", "L1" ], "Original layer")
|
||||
l1s.output([ "input", "L1S" ], "Sized original layer")
|
||||
|
||||
l1s.width(1.0.um).output("w1um", "w < 1µm\nFrom sized input")
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
source($drc_test_source)
|
||||
report("Report comment with\nanother line", $drc_test_report)
|
||||
|
||||
deep
|
||||
|
||||
l1 = input(1, 0)
|
||||
l1 = l1.sized(0.1, 0.0)
|
||||
|
||||
l1.output(["inputs", "l1"], "L1 (1/0 sized by x=100nm,y=0)")
|
||||
l1.width(1.0.um).output("w1um", "w < 1µm\nAnother line")
|
||||
|
||||
l1s = l1.snapped(200.nm)
|
||||
l1s.output([ "inputs", "l1_snapped" ], "L1 snapped to 200nm")
|
||||
l1s.width(1.0.um).output("w1um_snapped", "w < 1µm\nFrom snapped input")
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,585 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<report-database>
|
||||
<description>Report comment with
|
||||
another line</description>
|
||||
<original-file/>
|
||||
<generator>drc: script='.drc'</generator>
|
||||
<top-cell>TOP</top-cell>
|
||||
<tags>
|
||||
</tags>
|
||||
<categories>
|
||||
<category>
|
||||
<name>l1</name>
|
||||
<description>L1 (1/0 sized by x=100nm,y=0)</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>w1um</name>
|
||||
<description>w < 1µm
|
||||
From sized input</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>l1_snapped</name>
|
||||
<description>L1 snapped to 200nm</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>w1um_snapped</name>
|
||||
<description>w < 1µm
|
||||
From snapped input</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
</categories>
|
||||
<cells>
|
||||
<cell>
|
||||
<name>TOP</name>
|
||||
<variant/>
|
||||
<layout-name/>
|
||||
<references>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0</variant>
|
||||
<layout-name>A</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 0.5,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r90</variant>
|
||||
<layout-name>A$VAR1</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r270 *1 2,2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0;r0(-0.1,0)</variant>
|
||||
<layout-name>A</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 0.5,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0;r0</variant>
|
||||
<layout-name>A$VAR1$1</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 1.2,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
</cells>
|
||||
<items>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.7,3.9;3.3,4;3.6,4.6;5.1,4.9;5.3,4.9;5.2,4.2;5,4.2;3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.1,3;2.1,3.6;2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (-0.1,0;-0.1,1.6;0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,-0.1;0,1.7;0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.6,4.6;4.256,4.731)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.53,4.233;3.804,4.285)|(3.455,4.31;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.3,4;3.6,4.6)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.266,4.733;5.1,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(4.138,4.708;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;3.804,4.285)|(3.6,4.6;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.6,4.6;4.408,4.762)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.1,4.9;5.3,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;4.343,4.247)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.1,3;2.1,3.6)|(2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.9,3;2.1,3)|(2.1,3.6;2.9,3.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.1,0;-0.1,1.6)|(0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,-0.1;0,1.7)|(0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.4,4;3.6,4.6;5.2,5;5.4,5;5.2,4.2;3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.2,3;2.2,3.6;3,3.6;3,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1_snapped</category>
|
||||
<cell>A:r0;r0(-0.1,0)</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (-0.1,0;-0.1,1.6;0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1_snapped</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.8;0.2,1.8;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>l1_snapped</category>
|
||||
<cell>A:r0;r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.6;0.4,1.6;0.4,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.467,4.2;3.6,4.6)|(4.521,4.2;3.8,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.4,4;3.55,4.45)|(3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.4,4;3.6,4.6)|(4,4;3.4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.314,4.778;5.2,5)|(5.4,5;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;3.8,4.2)|(3.6,4.6;5.2,5)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4,4;3.4,4)|(3.6,4.6;4.547,4.837)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,5;5.4,5)|(5.4,5;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;4.6,4.2)|(5.2,5;5.4,5)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4,4;3.4,4)|(3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.2,3;2.2,3.6)|(3,3.6;3,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3,3;2.2,3)|(2.2,3.6;3,3.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r0;r0(-0.1,0)</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.1,0;-0.1,1.6)|(0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0;0,1.8)|(0.2,1.8;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r0;r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0;0,1.6)|(0.4,1.6;0.4,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
</items>
|
||||
</report-database>
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<report-database>
|
||||
<description>Report comment with
|
||||
another line</description>
|
||||
<original-file/>
|
||||
<generator>drc: script='.drc'</generator>
|
||||
<top-cell>TOP</top-cell>
|
||||
<tags>
|
||||
</tags>
|
||||
<categories>
|
||||
<category>
|
||||
<name>input</name>
|
||||
<description/>
|
||||
<categories>
|
||||
<category>
|
||||
<name>L1</name>
|
||||
<description>Original layer</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>L1S</name>
|
||||
<description>Sized original layer</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>w1um</name>
|
||||
<description>w < 1µm
|
||||
From sized input</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
</categories>
|
||||
<cells>
|
||||
<cell>
|
||||
<name>TOP</name>
|
||||
<variant/>
|
||||
<layout-name/>
|
||||
<references>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0</variant>
|
||||
<layout-name>A</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 0.5,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r90</variant>
|
||||
<layout-name>A$VAR1</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r270 *1 2,2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
</cells>
|
||||
<items>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.8,3.9;3.4,4;3.7,4.6;5.2,4.9;5.1,4.2;3.7,4.3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.2,3;2.2,3.6;2.8,3.6;2.8,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.6;0.2,1.6;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.6;0.2,1.6;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1S</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.7,3.9;3.3,4;3.6,4.6;5.1,4.9;5.3,4.9;5.2,4.2;5,4.2;3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1S</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.1,3;2.1,3.6;2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1S</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (-0.1,0;-0.1,1.6;0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>input.L1S</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,-0.1;0,1.7;0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.6,4.6;4.256,4.731)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.53,4.233;3.804,4.285)|(3.455,4.31;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.3,4;3.6,4.6)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.266,4.733;5.1,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(4.138,4.708;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;3.804,4.285)|(3.6,4.6;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.6,4.6;4.408,4.762)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.1,4.9;5.3,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;4.343,4.247)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.1,3;2.1,3.6)|(2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.9,3;2.1,3)|(2.1,3.6;2.9,3.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.1,0;-0.1,1.6)|(0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,-0.1;0,1.7)|(0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
</items>
|
||||
</report-database>
|
||||
|
|
@ -0,0 +1,596 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<report-database>
|
||||
<description>Report comment with
|
||||
another line</description>
|
||||
<original-file/>
|
||||
<generator>drc: script='.drc'</generator>
|
||||
<top-cell>TOP</top-cell>
|
||||
<tags>
|
||||
<tag>
|
||||
<name>waived</name>
|
||||
<description/>
|
||||
</tag>
|
||||
</tags>
|
||||
<categories>
|
||||
<category>
|
||||
<name>inputs</name>
|
||||
<description/>
|
||||
<categories>
|
||||
<category>
|
||||
<name>l1</name>
|
||||
<description>L1 (1/0 sized by x=100nm,y=0)</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>l1_snapped</name>
|
||||
<description>L1 snapped to 200nm</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>w1um</name>
|
||||
<description>w < 1µm
|
||||
Another line</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>w1um_snapped</name>
|
||||
<description>w < 1µm
|
||||
From snapped input</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
</categories>
|
||||
<cells>
|
||||
<cell>
|
||||
<name>TOP</name>
|
||||
<variant/>
|
||||
<layout-name/>
|
||||
<references>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0</variant>
|
||||
<layout-name>A</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 0.5,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r90</variant>
|
||||
<layout-name>A$VAR1</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r270 *1 2,2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0;r0(-0.1,0)</variant>
|
||||
<layout-name>A</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 0.5,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0;r0</variant>
|
||||
<layout-name>A$VAR1$1</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 1.2,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
</cells>
|
||||
<items>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.7,3.9;3.3,4;3.6,4.6;5.1,4.9;5.3,4.9;5.2,4.2;5,4.2;3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.1,3;2.1,3.6;2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (-0.1,0;-0.1,1.6;0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,-0.1;0,1.7;0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.6,4.6;4.256,4.731)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.53,4.233;3.804,4.285)|(3.455,4.31;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.3,4;3.6,4.6)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.266,4.733;5.1,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(4.138,4.708;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;3.804,4.285)|(3.6,4.6;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.6,4.6;4.408,4.762)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment>First item von w1um</comment>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.1,4.9;5.3,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;4.343,4.247)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.1,3;2.1,3.6)|(2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.9,3;2.1,3)|(2.1,3.6;2.9,3.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.1,0;-0.1,1.6)|(0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,-0.1;0,1.7)|(0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.4,4;3.6,4.6;5.2,5;5.4,5;5.2,4.2;3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.2,3;2.2,3.6;3,3.6;3,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>A:r0;r0(-0.1,0)</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment>A comment on the only waived input shape</comment>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (-0.1,0;-0.1,1.6;0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.8;0.2,1.8;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>A:r0;r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.6;0.4,1.6;0.4,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.467,4.2;3.6,4.6)|(4.521,4.2;3.8,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.4,4;3.55,4.45)|(3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.4,4;3.6,4.6)|(4,4;3.4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.314,4.778;5.2,5)|(5.4,5;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;3.8,4.2)|(3.6,4.6;5.2,5)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4,4;3.4,4)|(3.6,4.6;4.547,4.837)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,5;5.4,5)|(5.4,5;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;4.6,4.2)|(5.2,5;5.4,5)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4,4;3.4,4)|(3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.2,3;2.2,3.6)|(3,3.6;3,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3,3;2.2,3)|(2.2,3.6;3,3.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r0;r0(-0.1,0)</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.1,0;-0.1,1.6)|(0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0;0,1.8)|(0.2,1.8;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r0;r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment>A comment
|
||||
With two lines</comment>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0;0,1.6)|(0.4,1.6;0.4,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
</items>
|
||||
</report-database>
|
||||
|
|
@ -0,0 +1,616 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<report-database>
|
||||
<description>waiving
|
||||
another line</description>
|
||||
<original-file>/home/matthias/klayout/testdata/waiving.gds</original-file>
|
||||
<generator>drc: script='/home/matthias/.klayout/drc/waiving.lydrc'</generator>
|
||||
<top-cell>TOP</top-cell>
|
||||
<tags>
|
||||
<tag>
|
||||
<name>waived</name>
|
||||
<description/>
|
||||
</tag>
|
||||
<tag>
|
||||
<name>red</name>
|
||||
<description/>
|
||||
</tag>
|
||||
<tag>
|
||||
<name>green</name>
|
||||
<description/>
|
||||
</tag>
|
||||
<tag>
|
||||
<name>blue</name>
|
||||
<description/>
|
||||
</tag>
|
||||
<tag>
|
||||
<name>yellow</name>
|
||||
<description/>
|
||||
</tag>
|
||||
<tag>
|
||||
<name>important</name>
|
||||
<description/>
|
||||
</tag>
|
||||
</tags>
|
||||
<categories>
|
||||
<category>
|
||||
<name>inputs</name>
|
||||
<description/>
|
||||
<categories>
|
||||
<category>
|
||||
<name>l1</name>
|
||||
<description>L1 (1/0 sized by x=100nm,y=0)</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>l1_snapped</name>
|
||||
<description>L1 snapped to 200nm</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>w1um</name>
|
||||
<description>w < 1µm
|
||||
Another line</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
<category>
|
||||
<name>w1um_snapped</name>
|
||||
<description>w < 1µm
|
||||
From snapped input</description>
|
||||
<categories>
|
||||
</categories>
|
||||
</category>
|
||||
</categories>
|
||||
<cells>
|
||||
<cell>
|
||||
<name>TOP</name>
|
||||
<variant/>
|
||||
<layout-name/>
|
||||
<references>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0</variant>
|
||||
<layout-name>A</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 0.5,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r90</variant>
|
||||
<layout-name>A$VAR1</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r270 *1 2,2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0;r0(-0.1,0)</variant>
|
||||
<layout-name>A</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 0.5,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
<cell>
|
||||
<name>A</name>
|
||||
<variant>r0;r0</variant>
|
||||
<layout-name>A$VAR1$1</layout-name>
|
||||
<references>
|
||||
<ref>
|
||||
<parent>TOP</parent>
|
||||
<trans>r0 *1 1.2,1.2</trans>
|
||||
</ref>
|
||||
</references>
|
||||
</cell>
|
||||
</cells>
|
||||
<items>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.7,3.9;3.3,4;3.6,4.6;5.1,4.9;5.3,4.9;5.2,4.2;5,4.2;3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.1,3;2.1,3.6;2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (-0.1,0;-0.1,1.6;0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,-0.1;0,1.7;0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment>First item von w1um</comment>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.1,4.9;5.3,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.6,4.6;4.408,4.762)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(4.138,4.708;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.9,3;2.1,3)|(2.1,3.6;2.9,3.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.9,3.9;3.7,3.9)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.3,4;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.3,4;3.6,4.6)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.6,4.6;4.256,4.731)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.53,4.233;3.804,4.285)|(3.455,4.31;3.6,4.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.1,3;2.1,3.6)|(2.9,3.6;2.9,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;5,4.2)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.7,3.9;3.3,4)|(3.804,4.285;3.9,3.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;4.343,4.247)|(5.1,4.9;5.3,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.266,4.733;5.1,4.9)|(5.3,4.9;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5,4.2;3.804,4.285)|(3.6,4.6;5.1,4.9)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>A:r0</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.1,0;-0.1,1.6)|(0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,-0.1;0,1.7)|(0.2,1.7;0.2,-0.1)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (3.4,4;3.6,4.6;5.2,5;5.4,5;5.2,4.2;3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (2.2,3;2.2,3.6;3,3.6;3,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>A:r0;r0(-0.1,0)</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment>A comment on the only waived input shape</comment>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (-0.1,0;-0.1,1.6;0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.8;0.2,1.8;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>inputs.l1_snapped</category>
|
||||
<cell>A:r0;r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>polygon: (0,0;0,1.6;0.4,1.6;0.4,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;4.6,4.2)|(5.2,5;5.4,5)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4,4;3.4,4)|(3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,5;5.4,5)|(5.4,5;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4,4;3.4,4)|(3.6,4.6;4.547,4.837)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (5.2,4.2;3.8,4.2)|(3.6,4.6;5.2,5)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (4.314,4.778;5.2,5)|(5.4,5;5.2,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.4,4;3.6,4.6)|(4,4;3.4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.4,4;3.55,4.45)|(3.8,4.2;4,4)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3.467,4.2;3.6,4.6)|(4.521,4.2;3.8,4.2)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (3,3;2.2,3)|(2.2,3.6;3,3.6)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (2.2,3;2.2,3.6)|(3,3.6;3,3)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r0;r0(-0.1,0)</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.1,0;-0.1,1.6)|(0.3,1.6;0.3,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags>waived</tags>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r90</cell>
|
||||
<visited>true</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0;0,1.8)|(0.2,1.8;0.2,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
<item>
|
||||
<tags/>
|
||||
<category>w1um_snapped</category>
|
||||
<cell>A:r0;r0</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment>A comment
|
||||
With two lines</comment>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0;0,1.6)|(0.4,1.6;0.4,0)</value>
|
||||
</values>
|
||||
</item>
|
||||
</items>
|
||||
</report-database>
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
<cell>
|
||||
<name>TOP</name>
|
||||
<variant/>
|
||||
<layout-name/>
|
||||
<references>
|
||||
</references>
|
||||
</cell>
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (-0.2,0.7;1,0.7)|(1,1.1;-0.2,1.1)</value>
|
||||
|
|
@ -46,6 +48,7 @@
|
|||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0;0,0.9)|(0.3,0.9;0.3,0)</value>
|
||||
|
|
@ -57,6 +60,7 @@
|
|||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0.3,0;0,0)|(0,0.9;0.3,0.9)</value>
|
||||
|
|
@ -68,6 +72,7 @@
|
|||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0.5,0;0.5,0.9)|(0.8,0.9;0.8,0)</value>
|
||||
|
|
@ -79,6 +84,7 @@
|
|||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0.8,0;0.5,0)|(0.5,0.9;0.8,0.9)</value>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
<cell>
|
||||
<name>TOP</name>
|
||||
<variant/>
|
||||
<layout-name/>
|
||||
<references>
|
||||
</references>
|
||||
</cell>
|
||||
|
|
@ -29,6 +30,7 @@
|
|||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0,0.9;0.3,0.9)/(1,1.1;-0.2,1.1)</value>
|
||||
|
|
@ -40,6 +42,7 @@
|
|||
<cell>TOP</cell>
|
||||
<visited>false</visited>
|
||||
<multiplicity>1</multiplicity>
|
||||
<comment/>
|
||||
<image/>
|
||||
<values>
|
||||
<value>edge-pair: (0.5,0.9;0.8,0.9)/(1,1.1;-0.2,1.1)</value>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue