mirror of https://github.com/KLayout/klayout.git
commit
ebfc506bd9
|
|
@ -105,7 +105,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
|
|||
if (format.empty () || format == gds2_format_name || format == gds2text_format_name) {
|
||||
cmd << tl::arg (group +
|
||||
"#--keep-instances", &m_keep_instances, "Keeps instances of dropped cells",
|
||||
"If given, instances of dropped cell's won't be removed. Hence, ghost cells are "
|
||||
"If given, instances of dropped cells won't be removed. Hence, ghost cells are "
|
||||
"produced. The resulting layout may not be readable by consumers that require "
|
||||
"all instantiated cells to be present as actual cells.\n"
|
||||
"Dropped cells are those which are removed by a negative cell selection (see "
|
||||
|
|
@ -136,11 +136,11 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
|
|||
"\n"
|
||||
"Multiple operations can be specified by combining them with a comma. "
|
||||
"Positive and negative selection happens in the order given. Hence it's possible "
|
||||
"to select a cell with it's children and then unselect some children of this cell.\n"
|
||||
"to select a cell with its children and then unselect some children of this cell.\n"
|
||||
"\n"
|
||||
"Examples:\n\n"
|
||||
"* \"TOP1,TOP2\" - Select cells TOP1 and TOP2 with all of their children\n"
|
||||
"* \"(TOP)\" - Select only cell TOP, but none of it's child cells\n"
|
||||
"* \"(TOP)\" - Select only cell TOP, but none of its child cells\n"
|
||||
"* \"TOP,-A\" - Select cell TOP (plus children), then remove A (with children)"
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ module RBA
|
|||
|
||||
# get the layer definitions
|
||||
def get_layers(parameters)
|
||||
@layer_param_index.collect { |i| parameters[i] }
|
||||
@layer_param_index.collect { |i| parameters[i] || RBA::LayerInfo::new }
|
||||
end
|
||||
|
||||
# coerce parameters (make consistent)
|
||||
|
|
|
|||
|
|
@ -358,10 +358,10 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
|
|||
pdecl.unit = unit
|
||||
if not (choices is None):
|
||||
if not isinstance(choices, list) and not isinstance(choices, tuple):
|
||||
raise "choices value must be an list/tuple of two-element arrays (description, value)"
|
||||
raise TypeError("choices value must be an list/tuple of two-element arrays (description, value)")
|
||||
for c in choices:
|
||||
if (not isinstance(choices, list) and not isinstance(choices, tuple)) or len(c) != 2:
|
||||
raise "choices value must be an list/tuple of two-element arrays (description, value)"
|
||||
raise TypeError("choices value must be an list/tuple of two-element arrays (description, value)")
|
||||
pdecl.add_choice(c[0],c[1])
|
||||
|
||||
# return the declaration object for further operations
|
||||
|
|
@ -430,7 +430,10 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
|
|||
"""
|
||||
layers = []
|
||||
for i in self._layer_param_index:
|
||||
layers.append(parameters[i])
|
||||
if parameters[i] is not None:
|
||||
layers.append(parameters[i])
|
||||
else:
|
||||
layers.append(pya.LayerInfo())
|
||||
return layers
|
||||
|
||||
def callback(self, layout, name, states):
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ HierarchyBuilder::reset ()
|
|||
void
|
||||
HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_type var)
|
||||
{
|
||||
// non_var (despite it's name) may be a variant created previously.
|
||||
// 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);
|
||||
if (v != m_variants_to_original_target_map.end ()) {
|
||||
non_var = v->second;
|
||||
|
|
|
|||
|
|
@ -1358,7 +1358,7 @@ Layout::add_cell (const char *name)
|
|||
m_cells.push_back_ptr (new_cell);
|
||||
m_cell_ptrs [new_index] = new_cell;
|
||||
|
||||
// enter it's index and cell_name
|
||||
// enter its index and cell_name
|
||||
register_cell_name (name, new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
|
|
@ -1380,7 +1380,7 @@ Layout::add_anonymous_cell ()
|
|||
m_cells.push_back_ptr (new_cell);
|
||||
m_cell_ptrs [new_index] = new_cell;
|
||||
|
||||
// enter it's index and cell_name
|
||||
// enter its index and cell_name
|
||||
register_cell_name (0, new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
|
|
@ -1393,7 +1393,7 @@ Layout::add_anonymous_cell ()
|
|||
void
|
||||
Layout::register_cell_name (const char *name, cell_index_type ci)
|
||||
{
|
||||
// enter it's index and cell_name
|
||||
// enter its index and cell_name
|
||||
char *cp;
|
||||
|
||||
if (name == 0) {
|
||||
|
|
@ -2254,7 +2254,7 @@ Layout::get_pcell_variant_dict (pcell_id_type pcell_id, const std::map<std::stri
|
|||
m_cells.push_back_ptr (variant);
|
||||
m_cell_ptrs [new_index] = variant;
|
||||
|
||||
// enter it's index and cell_name
|
||||
// enter its index and cell_name
|
||||
register_cell_name (b.c_str (), new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
|
|
@ -2293,7 +2293,7 @@ Layout::get_pcell_variant (pcell_id_type pcell_id, const std::vector<tl::Variant
|
|||
m_cells.push_back_ptr (variant);
|
||||
m_cell_ptrs [new_index] = variant;
|
||||
|
||||
// enter it's index and cell_name
|
||||
// enter its index and cell_name
|
||||
register_cell_name (b.c_str (), new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
|
|
@ -2932,7 +2932,7 @@ Layout::get_lib_proxy (Library *lib, cell_index_type cell_index)
|
|||
m_cells.push_back_ptr (proxy);
|
||||
m_cell_ptrs [new_index] = proxy;
|
||||
|
||||
// enter it's index and cell_name
|
||||
// enter its index and cell_name
|
||||
register_cell_name (b.c_str (), new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
|
|
@ -2968,7 +2968,7 @@ Layout::create_cold_proxy (const db::LayoutOrCellContextInfo &info)
|
|||
m_cells.push_back_ptr (proxy);
|
||||
m_cell_ptrs [new_index] = proxy;
|
||||
|
||||
// enter it's index and cell_name
|
||||
// enter its index and cell_name
|
||||
register_cell_name (b.c_str (), new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
|
|
|
|||
|
|
@ -199,51 +199,51 @@ PCellVariant::update (ImportLayerMapping *layer_mapping)
|
|||
|
||||
if (m_parameters[i].is_user<db::DBox> ()) {
|
||||
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (m_parameters[i].to_user<db::DBox> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties (db::Box (m_parameters[i].to_user<db::DBox> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::Box> ()) {
|
||||
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(m_parameters[i].to_user<db::Box> (), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties (m_parameters[i].to_user<db::Box> (), layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::DEdge> ()) {
|
||||
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties(db::Edge (m_parameters[i].to_user<db::DEdge> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties (db::Edge (m_parameters[i].to_user<db::DEdge> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::Edge> ()) {
|
||||
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties(m_parameters[i].to_user<db::Edge> (), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties (m_parameters[i].to_user<db::Edge> (), layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::DPoint> ()) {
|
||||
|
||||
db::DPoint p = m_parameters[i].to_user<db::DPoint> ();
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (db::DBox (p, p) * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PointWithProperties (db::Point (p * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::Point> ()) {
|
||||
|
||||
db::Point p = m_parameters[i].to_user<db::Point> ();
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (p, p), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PointWithProperties (p, layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::DPolygon> ()) {
|
||||
|
||||
db::complex_trans<db::DCoord, db::Coord> dbu_trans (1.0 / layout ()->dbu ());
|
||||
db::Polygon poly = m_parameters[i].to_user<db::DPolygon> ().transformed (dbu_trans, false);
|
||||
// Hint: we don't compress the polygon since we don't want to loose information
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties(poly, layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties (poly, layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::Polygon> ()) {
|
||||
|
||||
db::Polygon poly = m_parameters[i].to_user<db::Polygon> ();
|
||||
// Hint: we don't compress the polygon since we don't want to loose information
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties(poly, layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties (poly, layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::DPath> ()) {
|
||||
|
||||
db::complex_trans<db::DCoord, db::Coord> dbu_trans (1.0 / layout ()->dbu ());
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties(dbu_trans * m_parameters[i].to_user<db::DPath> (), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties (dbu_trans * m_parameters[i].to_user<db::DPath> (), layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (m_parameters[i].is_user<db::Path> ()) {
|
||||
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties(m_parameters[i].to_user<db::Path> (), layout ()->properties_repository ().properties_id (props)));
|
||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties (m_parameters[i].to_user<db::Path> (), layout ()->properties_repository ().properties_id (props)));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ void path<C>::create_shifted_points (C start, C end, C width, bool forward, Iter
|
|||
Iter ppp = pp;
|
||||
++ppp;
|
||||
|
||||
// Compute the unit vector of the line and it's normal (times width)
|
||||
// Compute the unit vector of the line and its normal (times width)
|
||||
|
||||
db::DVector ed (*pp - *p);
|
||||
ed *= 1.0 / ed.double_length ();
|
||||
|
|
@ -383,7 +383,7 @@ void path<C>::create_shifted_points (C start, C end, C width, bool forward, Iter
|
|||
|
||||
// Segments are too short - the won't intersect: In this case we create a loop of three
|
||||
// points which define the area in self-overlapping way but confined to the path within
|
||||
// the limits of it's width.
|
||||
// the limits of its width.
|
||||
// HINT: the execution of this code is a pretty strong evidence for the existence to loops
|
||||
// in the contour delivered. A proof however is missing ..
|
||||
*pts++ = *pp + vector<C> (nd);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ db::DEdge compute_shifted (const db::edge<C> &e, C dx, C dy, double ext, int nsi
|
|||
{
|
||||
tl_assert (! e.is_degenerate ()); // no coincident points allowed
|
||||
|
||||
// Compute the unit vector of the line and it's normal (times width)
|
||||
// Compute the unit vector of the line and its normal (times width)
|
||||
db::DVector ec (e.d ());
|
||||
ec *= 1.0 / ec.double_length ();
|
||||
db::DVector nc (-ec.y (), ec.x ());
|
||||
|
|
@ -47,7 +47,7 @@ db::DEdge compute_shifted (const db::edge<C> &e, C dx, C dy, double ext, int nsi
|
|||
|
||||
/**
|
||||
* @brief Smart multiplication of a vector with a distance
|
||||
* This function tries to keep the length of the vector on grid if it's
|
||||
* This function tries to keep the length of the vector on grid if its
|
||||
* a 45 degree or horizontal/vertical one.
|
||||
*/
|
||||
template <class C>
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ void create_shifted_points (C /*c*/, bool forward, Iter from, Iter to, WIter wfr
|
|||
WIter www = ww;
|
||||
++www;
|
||||
|
||||
// Compute the unit vector of the line and it's normal (times width)
|
||||
// Compute the unit vector of the line and its normal (times width)
|
||||
|
||||
db::DVector ed (*pp - *p);
|
||||
ed *= 1.0 / ed.double_length ();
|
||||
|
|
@ -258,7 +258,7 @@ void create_shifted_points (C /*c*/, bool forward, Iter from, Iter to, WIter wfr
|
|||
|
||||
// Segments are too short - the won't intersect: In this case we create a loop of three
|
||||
// points which define the area in self-overlapping way but confined to the path within
|
||||
// the limits of it's width.
|
||||
// the limits of its width.
|
||||
// HINT: the execution of this code is a pretty strong evidence for the existence to loops
|
||||
// in the contour delivered. A proof however is missing ..
|
||||
*pts++ = *pp + vector<C> (nd2);
|
||||
|
|
|
|||
|
|
@ -1875,14 +1875,14 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
gsi::method_ext ("write", &write_simple, gsi::arg ("file_name"),
|
||||
"@brief Writes the cell to a layout file\n"
|
||||
"The format of the file will be determined from the file name. Only the cell and "
|
||||
"it's subtree below will be saved.\n"
|
||||
"its subtree below will be saved.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("write", &write_options, gsi::arg ("file_name"), gsi::arg ("options"),
|
||||
"@brief Writes the cell to a layout file\n"
|
||||
"The format of the file will be determined from the file name. Only the cell and "
|
||||
"it's subtree below will be saved.\n"
|
||||
"its subtree below will be saved.\n"
|
||||
"In contrast to the other 'write' method, this version allows one to specify save options, i.e. "
|
||||
"scaling etc.\n"
|
||||
"\n"
|
||||
|
|
@ -2576,7 +2576,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"In contrast to the \\transform method, this method allows propagation of the transformation into child cells. "
|
||||
"More precisely: it applies just a part of the given transformation to the instance, such that when transforming "
|
||||
"the cell instantiated and it's shapes with the same transformation, the result will reflect the desired transformation. Mathematically spoken, the "
|
||||
"the cell instantiated and its shapes with the same transformation, the result will reflect the desired transformation. Mathematically spoken, the "
|
||||
"transformation of the instance (A) is transformed with the given transformation T using \"A' = T * A * Tinv\" where "
|
||||
"Tinv is the inverse of T. In effect, the transformation T commutes with the new instance transformation A' and can be "
|
||||
"applied to child cells as well. This method is therefore useful to transform a hierarchy of cells.\n"
|
||||
|
|
@ -3221,7 +3221,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"The parameters are given in the order the parameters are declared. Use \\pcell_declaration "
|
||||
"on the instance to get the PCell declaration object of the cell. That PCellDeclaration object "
|
||||
"delivers the parameter declaration with it's 'get_parameters' method.\n"
|
||||
"delivers the parameter declaration with its 'get_parameters' method.\n"
|
||||
"Each parameter in the variant list passed to the second list of values corresponds to "
|
||||
"one parameter declaration.\n"
|
||||
"\n"
|
||||
|
|
@ -4013,7 +4013,7 @@ Class<db::Instance> decl_Instance ("db", "Instance",
|
|||
"@param layer_index The index of the layer the bounding box will be computed for.\n"
|
||||
"The bounding box incorporates all instances that the array represents. "
|
||||
"It gives the overall extension of the child cell as seen in the calling cell (or all array members if the instance forms an array) "
|
||||
"for the given layer. If the layer is empty in this cell and all it's children', an empty bounding box will be returned. "
|
||||
"for the given layer. If the layer is empty in this cell and all its children', an empty bounding box will be returned. "
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25. 'bbox' is the preferred synonym for it since version 0.28."
|
||||
) +
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
|
|||
"If used as a pseudo-target for the cell mapping, this index indicates "
|
||||
"that the cell shall be dropped rather than created on the target side "
|
||||
"or skipped by flattening. Instead, all shapes of this cell are discarded "
|
||||
"and it's children are not translated unless explicitly requested or "
|
||||
"and its children are not translated unless explicitly requested or "
|
||||
"if required are children for other cells.\n"
|
||||
"\n"
|
||||
"This constant has been introduced in version 0.25."
|
||||
|
|
|
|||
|
|
@ -727,7 +727,7 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
|
|||
"If 'is_square' is true, only squares will be selected. If 'inverse' is true, the non-rectangle/non-square shapes are returned.\n"
|
||||
) +
|
||||
gsi::constructor ("new_edges", &new_edges, gsi::arg ("input"),
|
||||
"@brief Creates a node converting polygons into it's edges.\n"
|
||||
"@brief Creates a node converting polygons into its edges.\n"
|
||||
) +
|
||||
gsi::constructor ("new_edge_length_filter", &new_edge_length_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("lmin", 0), gsi::arg ("lmax", std::numeric_limits<db::Edge::distance_type>::max (), "max"),
|
||||
"@brief Creates a node filtering edges by their length.\n"
|
||||
|
|
|
|||
|
|
@ -1410,7 +1410,7 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"If the region is (conceptionally) a flat region, it will be inserted into the cell's shapes "
|
||||
"list as a flat sequence of polygons.\n"
|
||||
"If the region is a deep (hierarchical) region, it will create a subhierarchy below the given "
|
||||
"cell and it's shapes will be put into the respective cells. Suitable subcells will be picked "
|
||||
"cell and its shapes will be put into the respective cells. Suitable subcells will be picked "
|
||||
"for inserting the shapes. If a hierarchy already exists below the given cell, the algorithm will "
|
||||
"try to reuse this hierarchy.\n"
|
||||
"\n"
|
||||
|
|
@ -1422,7 +1422,7 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"If the edge collection is (conceptionally) flat, it will be inserted into the cell's shapes "
|
||||
"list as a flat sequence of edges.\n"
|
||||
"If the edge collection is deep (hierarchical), it will create a subhierarchy below the given "
|
||||
"cell and it's edges will be put into the respective cells. Suitable subcells will be picked "
|
||||
"cell and its edges will be put into the respective cells. Suitable subcells will be picked "
|
||||
"for inserting the edges. If a hierarchy already exists below the given cell, the algorithm will "
|
||||
"try to reuse this hierarchy.\n"
|
||||
"\n"
|
||||
|
|
@ -1434,7 +1434,7 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"If the edge pair collection is (conceptionally) flat, it will be inserted into the cell's shapes "
|
||||
"list as a flat sequence of edge pairs.\n"
|
||||
"If the edge pair collection is deep (hierarchical), it will create a subhierarchy below the given "
|
||||
"cell and it's edge pairs will be put into the respective cells. Suitable subcells will be picked "
|
||||
"cell and its edge pairs will be put into the respective cells. Suitable subcells will be picked "
|
||||
"for inserting the edge pairs. If a hierarchy already exists below the given cell, the algorithm will "
|
||||
"try to reuse this hierarchy.\n"
|
||||
"\n"
|
||||
|
|
@ -1446,7 +1446,7 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"If the text collection is (conceptionally) flat, it will be inserted into the cell's shapes "
|
||||
"list as a flat sequence of texts.\n"
|
||||
"If the text collection is deep (hierarchical), it will create a subhierarchy below the given "
|
||||
"cell and it's texts will be put into the respective cells. Suitable subcells will be picked "
|
||||
"cell and its texts will be put into the respective cells. Suitable subcells will be picked "
|
||||
"for inserting the texts. If a hierarchy already exists below the given cell, the algorithm will "
|
||||
"try to reuse this hierarchy.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
"@brief Extracts devices\n"
|
||||
"See the class description for more details.\n"
|
||||
"This method will run device extraction for the given extractor. The layer map is specific\n"
|
||||
"for the extractor and uses the region objects derived with \\make_layer and it's variants.\n"
|
||||
"for the extractor and uses the region objects derived with \\make_layer and its variants.\n"
|
||||
"\n"
|
||||
"In addition, derived regions can be passed too. Certain limitations apply. It's safe to use\n"
|
||||
"boolean operations for deriving layers. Other operations are applicable as long as they are\n"
|
||||
|
|
@ -410,7 +410,7 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
) +
|
||||
gsi::method ("connect", (void (db::LayoutToNetlist::*) (const db::Region &)) &db::LayoutToNetlist::connect, gsi::arg ("l"),
|
||||
"@brief Defines an intra-layer connection for the given layer.\n"
|
||||
"The layer is either an original layer created with \\make_includelayer and it's variants or\n"
|
||||
"The layer is either an original layer created with \\make_includelayer and its variants or\n"
|
||||
"a derived layer. Certain limitations apply. It's safe to use\n"
|
||||
"boolean operations for deriving layers. Other operations are applicable as long as they are\n"
|
||||
"capable of delivering hierarchical layers.\n"
|
||||
|
|
@ -810,7 +810,7 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
"@li Preparation\n"
|
||||
" In this step, the device recognition and extraction layers are drawn from\n"
|
||||
" the framework. Derived can now be computed using boolean operations.\n"
|
||||
" Methods to use in this step are \\make_layer and it's variants.\n"
|
||||
" Methods to use in this step are \\make_layer and its variants.\n"
|
||||
" Layer preparation is not necessarily required to happen before all\n"
|
||||
" other steps. Layers can be computed shortly before they are required.\n"
|
||||
"@/li\n"
|
||||
|
|
@ -821,7 +821,7 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
" may be specified here. Layer preparation may happen between calls to \\extract_devices.\n"
|
||||
"@/li\n"
|
||||
"@li Once the devices are derived, the netlist connectivity can be defined and the\n"
|
||||
" netlist extracted. The connectivity is defined with \\connect and it's\n"
|
||||
" netlist extracted. The connectivity is defined with \\connect and its\n"
|
||||
" flavours. The actual netlist extraction happens with \\extract_netlist.\n"
|
||||
"@/li\n"
|
||||
"@li After netlist extraction, the information is ready to be retrieved.\n"
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ static std::vector<db::LayerProperties> get_layer_declarations_native (const db:
|
|||
std::vector<db::PCellLayerDeclaration> lp = pd->db::PCellDeclaration::get_layer_declarations (parameters);
|
||||
std::vector<db::LayerProperties> ret;
|
||||
for (std::vector<db::PCellLayerDeclaration>::const_iterator l = lp.begin (); l != lp.end (); ++l) {
|
||||
ret.push_back (db::LayerProperties(*l));
|
||||
ret.push_back (db::LayerProperties (*l));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1701,7 +1701,7 @@ Class<db::Circuit> decl_dbCircuit (decl_dbNetlistObject, "db", "Circuit",
|
|||
) +
|
||||
gsi::method ("flatten_subcircuit", &db::Circuit::flatten_subcircuit, gsi::arg ("subcircuit"),
|
||||
"@brief Flattens a subcircuit\n"
|
||||
"This method will substitute the given subcircuit by it's contents. The subcircuit is removed "
|
||||
"This method will substitute the given subcircuit by its contents. The subcircuit is removed "
|
||||
"after this."
|
||||
) +
|
||||
gsi::iterator ("each_subcircuit", (db::Circuit::subcircuit_iterator (db::Circuit::*) ()) &db::Circuit::begin_subcircuits, (db::Circuit::subcircuit_iterator (db::Circuit::*) ()) &db::Circuit::end_subcircuits,
|
||||
|
|
@ -1986,7 +1986,7 @@ Class<db::Netlist> decl_dbNetlist ("db", "Netlist",
|
|||
) +
|
||||
gsi::method ("flatten_circuit", &db::Netlist::flatten_circuit, gsi::arg ("circuit"),
|
||||
"@brief Flattens a subcircuit\n"
|
||||
"This method will substitute all instances (subcircuits) of the given circuit by it's "
|
||||
"This method will substitute all instances (subcircuits) of the given circuit by its "
|
||||
"contents. After this, the circuit is removed."
|
||||
) +
|
||||
gsi::method_ext ("flatten_circuit", &flatten_circuit_by_name, gsi::arg ("pattern"),
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ Class<GenericNetlistCompareLogger> decl_GenericNetlistCompareLogger (decl_dbNetl
|
|||
),
|
||||
"@brief An event receiver for the netlist compare feature.\n"
|
||||
"The \\NetlistComparer class will send compare events to a logger derived from this class. "
|
||||
"Use this class to implement your own logger class. You can override on of it's methods to receive certain "
|
||||
"Use this class to implement your own logger class. You can override on of its methods to receive certain "
|
||||
"kind of events."
|
||||
"\n"
|
||||
"This class has been introduced in version 0.26.\n"
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceE
|
|||
"This method is supposed to set up the device extractor. This involves three basic steps:\n"
|
||||
"defining the name, the device class and setting up the device layers.\n"
|
||||
"\n"
|
||||
"Use \\name= to give the extractor and it's device class a name.\n"
|
||||
"Use \\name= to give the extractor and its device class a name.\n"
|
||||
"Use \\register_device_class to register the device class you need.\n"
|
||||
"Defined the layers by calling \\define_layer once or several times.\n"
|
||||
) +
|
||||
|
|
@ -377,7 +377,7 @@ Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceE
|
|||
"@return The layer descriptor object created for this layer (use 'index' to get the layer's index)\n"
|
||||
"As \\define_layer, this method allows specification of device extraction layer. In addition to \\define_layout, it features "
|
||||
"a fallback layer. If in the device extraction statement, the primary layer is not given, "
|
||||
"the fallback layer will be used. Hence, this layer is optional. The fallback layer is given by it's "
|
||||
"the fallback layer will be used. Hence, this layer is optional. The fallback layer is given by its "
|
||||
"index and must be defined before the layer using the fallback layer is defined. "
|
||||
"For the index, 0 is the first layer defined, 1 the second and so forth."
|
||||
) +
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ struct simple_polygon_defs
|
|||
method ("is_box?", &C::is_box,
|
||||
"@brief Returns a value indicating whether the polygon is a simple box.\n"
|
||||
"\n"
|
||||
"A polygon is a box if it is identical to it's bounding box.\n"
|
||||
"A polygon is a box if it is identical to its bounding box.\n"
|
||||
"\n"
|
||||
"@return True if the polygon is a box.\n"
|
||||
"\n"
|
||||
|
|
@ -1380,7 +1380,7 @@ struct polygon_defs
|
|||
method ("is_box?", &C::is_box,
|
||||
"@brief Returns true, if the polygon is a simple box.\n"
|
||||
"\n"
|
||||
"A polygon is a box if it is identical to it's bounding box.\n"
|
||||
"A polygon is a box if it is identical to its bounding box.\n"
|
||||
"\n"
|
||||
"@return True if the polygon is a box.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ gsi::Class<db::TechnologyComponent> technology_component_decl ("db", "Technology
|
|||
"@brief A part of a technology definition\n"
|
||||
"Technology components extend technology definitions (class \\Technology) by "
|
||||
"specialized subfeature definitions. For example, the net tracer supplies "
|
||||
"it's technology-dependent specification through a technology component called "
|
||||
"its technology-dependent specification through a technology component called "
|
||||
"\\NetTracerTechnology.\n"
|
||||
"\n"
|
||||
"Components are managed within technologies and can be accessed from a technology "
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ gsi::Class<db::TileOutputReceiver> &dbdecl_TileOutputReceiverBase ()
|
|||
gsi::Class<TileOutputReceiver_Impl> decl_TileOutputReceiver (decl_TileOutputReceiverBase, "db", "TileOutputReceiver",
|
||||
gsi::callback ("begin", &TileOutputReceiver_Impl::begin, &TileOutputReceiver_Impl::begin_cb, gsi::arg ("nx"), gsi::arg ("ny"), gsi::arg ("p0"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("frame"),
|
||||
"@brief Initiates the delivery\n"
|
||||
"This method is called before the first tile delivers it's data.\n"
|
||||
"This method is called before the first tile delivers its data.\n"
|
||||
"\n"
|
||||
"@param nx The number of tiles in x direction\n"
|
||||
"@param ny The number of tiles in y direction\n"
|
||||
|
|
|
|||
|
|
@ -739,7 +739,7 @@ struct cplx_trans_defs
|
|||
method ("invert", &C::invert,
|
||||
"@brief Inverts the transformation (in place)\n"
|
||||
"\n"
|
||||
"Inverts the transformation and replaces this transformation by it's\n"
|
||||
"Inverts the transformation and replaces this transformation by its\n"
|
||||
"inverted one.\n"
|
||||
"\n"
|
||||
"@return The inverted transformation\n"
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace gsi
|
|||
gsi::method ("spline_interpolation", &db::UtilsDummy::spi1, gsi::arg ("control_points"), gsi::arg ("weights"), gsi::arg ("degree"), gsi::arg ("knots"), gsi::arg ("relative_accuracy"), gsi::arg ("absolute_accuracy"),
|
||||
"@brief This function computes the Spline curve for a given set of control points (point, weight), degree and knots.\n"
|
||||
"\n"
|
||||
"The knot vector needs to be padded and it's size must fulfill the condition:\n"
|
||||
"The knot vector needs to be padded and its size must fulfill the condition:\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
" knots.size == control_points.size + degree + 1\n"
|
||||
|
|
|
|||
|
|
@ -2409,7 +2409,7 @@ TEST(15_EmptySubCircuitWithoutPinNames)
|
|||
" subcircuit TRANS $3 ($1=OUT,$2=$5,$3=$2);\n"
|
||||
" subcircuit TRANS $4 ($1=OUT,$2=$4,$3=$2);\n"
|
||||
"end;\n"
|
||||
// This circuit is an abstract and it's pins are not defined by the pin names ->
|
||||
// This circuit is an abstract and its pins are not defined by the pin names ->
|
||||
// they are internally marked as swappable
|
||||
"circuit TRANS ($1=$1,$2=$2,$3=$3);\n"
|
||||
"end;\n";
|
||||
|
|
@ -4152,7 +4152,7 @@ TEST(23_NodesRemovedWithError)
|
|||
" subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n"
|
||||
// NOTE: $1 pin should not be connected to different nets, although it's not functional
|
||||
// NOTE: $1 pin should not be connected to different nets, although its not functional
|
||||
" subcircuit INV2 $1 ($1=$3,IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n"
|
||||
" subcircuit INV2 $2 ($1=$6,IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n"
|
||||
"end;\n"
|
||||
|
|
|
|||
|
|
@ -768,7 +768,7 @@ is called on. This operation represents all "other" primary polygons while
|
|||
</p><p>
|
||||
This feature opens new options for processing layouts beyond the
|
||||
abilities of the classical DRC concept. For classic DRC, intra-layer interactions
|
||||
are always symmetric: a polygon cannot be considered separated from it's neighbors
|
||||
are always symmetric: a polygon cannot be considered separated from its neighbors
|
||||
on the same layer.
|
||||
</p><p>
|
||||
The following example computes every part of the input which is closer than
|
||||
|
|
|
|||
|
|
@ -676,7 +676,7 @@ out = l1.drc((secondary(l2) & primary).area > 1.0)
|
|||
</p><p>
|
||||
Some filters operate on properties of the full, local, per-primary shape set.
|
||||
While the loop is executed, the DRC expressions will collect shapes, either
|
||||
from the primary, it's neighborhood (secondaries) or from deriving shape sets.
|
||||
from the primary, its neighborhood (secondaries) or from deriving shape sets.
|
||||
</p><p>
|
||||
Obviously the primary is a simple one: it consists of a single shape, because
|
||||
this is how the loop operates. Derived shape sets however can be more complex.
|
||||
|
|
@ -1537,7 +1537,7 @@ from the other layer. Two polygons overlapping or touching at two locations are
|
|||
</ul>
|
||||
<p>
|
||||
This operation is similar to the "&" operator, but it does also report intersection points
|
||||
between non-colinear, but intersection edges. Such points are reported as point-like,
|
||||
between non-colinear, but intersecting edges. Such points are reported as point-like,
|
||||
degenerated edge objects.
|
||||
</p><p>
|
||||
This method is available for edge layers. The argument must be an edge layer.
|
||||
|
|
@ -3609,7 +3609,7 @@ This method is available for polygon or edge pair layers.
|
|||
<li><tt>layer.with_area_ratio(min, max)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
The area ratio is a measure how far a polygon is approximated by it's
|
||||
The area ratio is a measure how far a polygon is approximated by its
|
||||
bounding box. The value is always larger or equal to 1. Boxes have a
|
||||
area ratio of 1. Larger values mean more empty area inside the bounding box.
|
||||
</p><p>
|
||||
|
|
@ -3883,7 +3883,7 @@ upper limit.
|
|||
</p><p>
|
||||
This method is available for polygon layers only.
|
||||
</p>
|
||||
<a name="with_relative_height"/><h2>"with_relative_height" - Selects polygons by the ratio of the height vs. width of it's bounding box</h2>
|
||||
<a name="with_relative_height"/><h2>"with_relative_height" - Selects polygons by the ratio of the height vs. width of its bounding box</h2>
|
||||
<keyword name="with_relative_height"/>
|
||||
<p>Usage:</p>
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ module DRC
|
|||
#
|
||||
# Some filters operate on properties of the full, local, per-primary shape set.
|
||||
# While the loop is executed, the DRC expressions will collect shapes, either
|
||||
# from the primary, it's neighborhood (secondaries) or from deriving shape sets.
|
||||
# from the primary, its neighborhood (secondaries) or from deriving shape sets.
|
||||
#
|
||||
# Obviously the primary is a simple one: it consists of a single shape, because
|
||||
# this is how the loop operates. Derived shape sets however can be more complex.
|
||||
|
|
@ -528,7 +528,7 @@ module DRC
|
|||
#
|
||||
# This feature opens new options for processing layouts beyond the
|
||||
# abilities of the classical DRC concept. For classic DRC, intra-layer interactions
|
||||
# are always symmetric: a polygon cannot be considered separated from it's neighbors
|
||||
# are always symmetric: a polygon cannot be considered separated from its neighbors
|
||||
# on the same layer.
|
||||
#
|
||||
# The following example computes every part of the input which is closer than
|
||||
|
|
|
|||
|
|
@ -2317,7 +2317,11 @@ CODE
|
|||
c !~ /drc.lym:/ && c !~ /_drc_\w+\.rb:/ && c !~ /\(eval\)/
|
||||
end
|
||||
if cc =~ /(.*)\s*:\s*(\d+)\s*:\s*in.*$/
|
||||
return File::basename($1) + ":" + $2
|
||||
path = $1
|
||||
line = $2.to_i
|
||||
real_path = RBA::Macro::real_path(path, line)
|
||||
real_line = RBA::Macro::real_line(path, line)
|
||||
return File::basename(real_path) + ":" + real_line.to_s
|
||||
else
|
||||
return cc
|
||||
end
|
||||
|
|
@ -2908,7 +2912,7 @@ CODE
|
|||
|
||||
def _make_path(file)
|
||||
# resolves the file path relative to the source's path
|
||||
sp = self.source.path
|
||||
sp = (@def_source || @def_layout) && self.source.path
|
||||
if sp
|
||||
if File.respond_to?(:absolute_path)
|
||||
return File::absolute_path(file, File::dirname(sp))
|
||||
|
|
@ -3238,7 +3242,7 @@ CODE
|
|||
|
||||
cn = cellname && cellname.to_s
|
||||
cn ||= @def_cell && @def_cell.name
|
||||
cn ||= source && source.cell_name
|
||||
cn ||= @def_source && @def_source.cell_obj && @def_source.cell_obj.name
|
||||
|
||||
cn || raise("No cell name specified - either the source was not specified before 'report' or there is no default source. In the latter case, specify a cell name as the third parameter")
|
||||
|
||||
|
|
@ -3281,7 +3285,7 @@ CODE
|
|||
cn ||= @def_cell && @def_cell.name
|
||||
cn ||= @def_source && @def_source.cell_obj && @def_source.cell_obj.name
|
||||
|
||||
cn || raise("No cell name specified - either the source was not specified before 'report' or there is no default source. In the latter case, specify a cell name as the third parameter")
|
||||
cn || raise("No cell name specified - either the source was not specified before 'report' or there is no default source. In the latter case, specify a cell name as the second parameter")
|
||||
|
||||
output_layout = RBA::Layout::new
|
||||
output_cell = output_layout.create_cell(cn)
|
||||
|
|
|
|||
|
|
@ -630,7 +630,7 @@ CODE
|
|||
# @synopsis layer.with_area_ratio(min .. max)
|
||||
# @synopsis layer.with_area_ratio(value)
|
||||
# @synopsis layer.with_area_ratio(min, max)
|
||||
# The area ratio is a measure how far a polygon is approximated by it's
|
||||
# The area ratio is a measure how far a polygon is approximated by its
|
||||
# bounding box. The value is always larger or equal to 1. Boxes have a
|
||||
# area ratio of 1. Larger values mean more empty area inside the bounding box.
|
||||
#
|
||||
|
|
@ -648,7 +648,7 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name with_relative_height
|
||||
# @brief Selects polygons by the ratio of the height vs. width of it's bounding box
|
||||
# @brief Selects polygons by the ratio of the height vs. width of its bounding box
|
||||
# @synopsis layer.with_relative_height(min .. max)
|
||||
# @synopsis layer.with_relative_height(value)
|
||||
# @synopsis layer.with_relative_height(min, max)
|
||||
|
|
|
|||
|
|
@ -800,6 +800,77 @@ TEST(14b_SideTargetsAndReports)
|
|||
compare_text_files (report2, au_report2);
|
||||
}
|
||||
|
||||
TEST(14c_OnlySpecialInputsAndReports)
|
||||
{
|
||||
std::string rs = tl::testdata ();
|
||||
rs += "/drc/drcSimpleTests_14c.drc";
|
||||
|
||||
// apart from that it's a variant of 14b ...
|
||||
|
||||
std::string input = tl::testdata ();
|
||||
input += "/drc/drcSimpleTests_14b.gds";
|
||||
|
||||
std::string au = tl::testdata ();
|
||||
au += "/drc/drcSimpleTests_au14b.gds";
|
||||
|
||||
std::string au2 = tl::testdata ();
|
||||
au2 += "/drc/drcSimpleTests_au14b_2.gds";
|
||||
|
||||
std::string au_report = tl::testdata ();
|
||||
au_report += "/drc/drcSimpleTests_au14b.lyrdb";
|
||||
|
||||
std::string au_report2 = tl::testdata ();
|
||||
au_report2 += "/drc/drcSimpleTests_au14b_2.lyrdb";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
std::string output2 = this->tmp_file ("tmp2.gds");
|
||||
std::string report = this->tmp_file ("tmp.lydrc");
|
||||
std::string report2 = this->tmp_file ("tmp2.lydrc");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$drc_force_gc = true\n"
|
||||
"$drc_test_source = '%s'\n"
|
||||
"$drc_test_target = '%s'\n"
|
||||
"$drc_test_target2 = '%s'\n"
|
||||
"$drc_test_report = '%s'\n"
|
||||
"$drc_test_report2 = '%s'\n"
|
||||
, input, output, output2, report, report2)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro drc;
|
||||
drc.load_from (rs);
|
||||
EXPECT_EQ (drc.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
|
||||
db::Layout layout2;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output2);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout2);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout2, au2, db::NoNormalization);
|
||||
|
||||
compare_text_files (report, au_report);
|
||||
compare_text_files (report2, au_report2);
|
||||
}
|
||||
|
||||
TEST(15_issue548)
|
||||
{
|
||||
std::string rs = tl::testdata ();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PointPropertiesPage</class>
|
||||
<widget class="QWidget" name="PointPropertiesPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>531</width>
|
||||
<height>370</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" stdset="0">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame1">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Sans Serif</family>
|
||||
<pointsize>12</pointsize>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
<underline>false</underline>
|
||||
<strikeout>false</strikeout>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Point Properties</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="layer_lbl">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Point position</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>6</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>x = </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="x_le">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>y = </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="y_le">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>478</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="dbu_cb">
|
||||
<property name="text">
|
||||
<string>Coordinates in database units</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="abs_cb">
|
||||
<property name="text">
|
||||
<string>Absolute (accumulated) transformations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>478</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>211</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="prop_pb">
|
||||
<property name="text">
|
||||
<string>User Properties</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="inst_pb">
|
||||
<property name="text">
|
||||
<string>Instantiation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>dbu_cb</tabstop>
|
||||
<tabstop>abs_cb</tabstop>
|
||||
<tabstop>prop_pb</tabstop>
|
||||
<tabstop>inst_pb</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -92,3 +92,6 @@ LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_laybasic -lklayout_layv
|
|||
|
||||
}
|
||||
|
||||
FORMS += \
|
||||
PointPropertiesPage.ui
|
||||
|
||||
|
|
|
|||
|
|
@ -2537,6 +2537,7 @@ public:
|
|||
{
|
||||
mp_polygon_service = view->get_plugin <edt::PolygonService> ();
|
||||
mp_box_service = view->get_plugin <edt::BoxService> ();
|
||||
mp_point_service = view->get_plugin <edt::PointService> ();
|
||||
mp_text_service = view->get_plugin <edt::TextService> ();
|
||||
mp_path_service = view->get_plugin <edt::PathService> ();
|
||||
mp_inst_service = view->get_plugin <edt::InstService> ();
|
||||
|
|
@ -2587,6 +2588,7 @@ public:
|
|||
private:
|
||||
edt::PolygonService *mp_polygon_service;
|
||||
edt::BoxService *mp_box_service;
|
||||
edt::PointService *mp_point_service;
|
||||
edt::TextService *mp_text_service;
|
||||
edt::PathService *mp_path_service;
|
||||
edt::InstService *mp_inst_service;
|
||||
|
|
|
|||
|
|
@ -849,6 +849,14 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
|
|||
|
||||
}
|
||||
|
||||
} else if (shape->is_point ()) {
|
||||
|
||||
db::Point tp (shape->point ());
|
||||
|
||||
if (hit_box.contains (tp)) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
}
|
||||
|
||||
} else if (shape->is_text ()) {
|
||||
|
||||
db::Point tp (shape->text_trans () * db::Point ());
|
||||
|
|
@ -1000,6 +1008,17 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
|
|||
|
||||
}
|
||||
|
||||
} else if (shape->is_point ()) {
|
||||
|
||||
db::Point tp (shape->point ());
|
||||
|
||||
if (hit_box.contains (tp)) {
|
||||
d = tp.distance (hit_box.center ());
|
||||
edge_sel.clear ();
|
||||
edge_sel.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
match = true;
|
||||
}
|
||||
|
||||
} else if (shape->is_text ()) {
|
||||
|
||||
db::Point tp (shape->text_trans () * db::Point ());
|
||||
|
|
@ -1258,6 +1277,11 @@ PartialService::timeout ()
|
|||
db::Point tp (r->first.shape ().text_trans () * db::Point ());
|
||||
enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, true);
|
||||
|
||||
} else if (r->first.shape ().is_point ()) {
|
||||
|
||||
db::Point tp (r->first.shape ().point ());
|
||||
enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1479,6 +1503,17 @@ PartialService::transform_selection (const db::DTrans &move_trans)
|
|||
shape = shapes.replace (shape, t);
|
||||
}
|
||||
|
||||
} else if (shape.is_point ()) {
|
||||
|
||||
db::Point p;
|
||||
shape.point (p);
|
||||
|
||||
std::map <PointWithIndex, db::Point>::const_iterator np = new_points.find (PointWithIndex (p, 0, 0));
|
||||
|
||||
if (np != new_points.end ()) {
|
||||
shape = shapes.replace (shape, np->second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// transform the selection
|
||||
|
|
@ -2204,7 +2239,7 @@ PartialService::del ()
|
|||
shapes_to_delete_by_cell.insert (std::make_pair (std::make_pair (r->first.cell_index (), std::make_pair (r->first.cv_index (), r->first.layer ())), std::vector <partial_objects::const_iterator> ())).first->second.push_back (r);
|
||||
}
|
||||
|
||||
} else if (shape.is_text ()) {
|
||||
} else if (shape.is_text () || shape.is_point ()) {
|
||||
|
||||
shapes_to_delete_by_cell.insert (std::make_pair (std::make_pair (r->first.cell_index (), std::make_pair (r->first.cv_index (), r->first.layer ())), std::vector <partial_objects::const_iterator> ())).first->second.push_back (r);
|
||||
|
||||
|
|
@ -2684,6 +2719,11 @@ PartialService::do_selection_to_view ()
|
|||
db::Point tp (r->first.shape ().text_trans () * db::Point ());
|
||||
enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, false);
|
||||
|
||||
} else if (r->first.shape ().is_point ()) {
|
||||
|
||||
db::Point tp (r->first.shape ().point ());
|
||||
enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2795,6 +2835,9 @@ PartialService::partial_select (const db::DBox &box, lay::Editable::SelectionMod
|
|||
if (edt::boxes_enabled ()) {
|
||||
shape_flags |= db::ShapeIterator::Boxes;
|
||||
}
|
||||
if (edt::points_enabled ()) {
|
||||
shape_flags |= db::ShapeIterator::Points;
|
||||
}
|
||||
if (edt::texts_enabled ()) {
|
||||
shape_flags |= db::ShapeIterator::Texts;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,8 +245,12 @@ public:
|
|||
|
||||
virtual bool implements_mouse_mode (std::string &title) const
|
||||
{
|
||||
title = m_mouse_mode;
|
||||
return true;
|
||||
if (! m_mouse_mode.empty ()) {
|
||||
title = m_mouse_mode;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -282,6 +286,11 @@ static tl::RegisteredClass<lay::PluginDeclaration> config_decl4 (
|
|||
"edt::Service(Paths)"
|
||||
);
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl5 (
|
||||
new edt::PluginDeclaration<edt::PointService> (tl::to_string (tr ("Points")), std::string (), 0, &get_shape_editor_options_pages),
|
||||
4014,
|
||||
"edt::Service(Points)"
|
||||
);
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl6 (
|
||||
new edt::PluginDeclaration<edt::InstService> (tl::to_string (tr ("Instances")), "instance:edit_mode\t" + tl::to_string (tr ("Instance")) + "\t<:instance_24px.png>" + tl::to_string (tr ("{Create a cell instance}")), &get_inst_options, &get_inst_editor_options_pages),
|
||||
4020,
|
||||
"edt::Service(CellInstances)"
|
||||
|
|
@ -302,6 +311,7 @@ bool is_enabled ()
|
|||
bool polygons_enabled () { return is_enabled<edt::PolygonService> (); }
|
||||
bool paths_enabled () { return is_enabled<edt::PathService> (); }
|
||||
bool boxes_enabled () { return is_enabled<edt::BoxService> (); }
|
||||
bool points_enabled () { return is_enabled<edt::PointService> (); }
|
||||
bool texts_enabled () { return is_enabled<edt::TextService> (); }
|
||||
bool instances_enabled () { return is_enabled<edt::InstService> (); }
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ namespace edt
|
|||
// other types ...
|
||||
bool paths_enabled ();
|
||||
bool boxes_enabled ();
|
||||
bool points_enabled ();
|
||||
bool texts_enabled ();
|
||||
bool instances_enabled ();
|
||||
|
||||
|
|
|
|||
|
|
@ -197,6 +197,42 @@ db::Shape BoxDimensionsChangeApplicator::do_apply (db::Shapes &shapes, const db:
|
|||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// PointDimensionsChangeApplicator implementation
|
||||
|
||||
PointDimensionsChangeApplicator::PointDimensionsChangeApplicator (const db::Point &point, const db::Point &org_point)
|
||||
: m_point (point), m_org_point (org_point)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
db::Shape PointDimensionsChangeApplicator::do_apply (db::Shapes &shapes, const db::Shape &shape, double /*dbu*/, bool relative) const
|
||||
{
|
||||
db::Point org_point;
|
||||
shape.point (org_point);
|
||||
|
||||
db::Point new_point;
|
||||
if (relative) {
|
||||
new_point = org_point + (m_point - m_org_point);
|
||||
} else if (m_point != m_org_point) {
|
||||
new_point = org_point;
|
||||
if (m_point.x () != m_org_point.x ()) {
|
||||
new_point.set_x (m_point.x ());
|
||||
}
|
||||
if (m_point.y () != m_org_point.y ()) {
|
||||
new_point.set_y (m_point.y ());
|
||||
}
|
||||
}
|
||||
|
||||
if (new_point != org_point) {
|
||||
// shape changed - replace the old by the new one
|
||||
return shapes.replace (shape, new_point);
|
||||
} else {
|
||||
// shape did not change
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// PolygonChangeApplicator implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,22 @@ private:
|
|||
db::Coord m_l, m_b, m_r, m_t;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A point change applicator
|
||||
*/
|
||||
class PointDimensionsChangeApplicator
|
||||
: public ChangeApplicator
|
||||
{
|
||||
public:
|
||||
PointDimensionsChangeApplicator (const db::Point &point, const db::Point &org_point);
|
||||
|
||||
bool supports_relative_mode () const { return true; }
|
||||
db::Shape do_apply (db::Shapes &shapes, const db::Shape &shape, double dbu, bool relative) const;
|
||||
|
||||
private:
|
||||
db::Point m_point, m_org_point;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A polygon change applicator
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -853,6 +853,124 @@ BoxPropertiesPage::changed ()
|
|||
emit edited ();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// PointPropertiesPage implementation
|
||||
|
||||
PointPropertiesPage::PointPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent)
|
||||
: ShapePropertiesPage (tl::to_string (tr ("Points")), service, manager, parent),
|
||||
m_dbu (1.0)
|
||||
{
|
||||
setupUi (this);
|
||||
setup ();
|
||||
|
||||
if (! readonly ()) {
|
||||
|
||||
connect (x_le, SIGNAL (editingFinished ()), this, SLOT (changed ()));
|
||||
connect (y_le, SIGNAL (editingFinished ()), this, SLOT (changed ()));
|
||||
|
||||
} else {
|
||||
|
||||
x_le->setReadOnly (true);
|
||||
y_le->setReadOnly (true);
|
||||
|
||||
}
|
||||
|
||||
connect (inst_pb, SIGNAL (clicked ()), this, SLOT (show_inst ()));
|
||||
connect (prop_pb, SIGNAL (clicked ()), this, SLOT (show_props ()));
|
||||
}
|
||||
|
||||
std::string
|
||||
PointPropertiesPage::description (size_t entry) const
|
||||
{
|
||||
const db::Shape &sh = shape (entry);
|
||||
db::CplxTrans dbu_trans (dbu (entry));
|
||||
return ShapePropertiesPage::description (entry) + " - " + tl::sprintf (tl::to_string (tr ("Point%s")), (dbu_trans * sh.point ()).to_string ());
|
||||
}
|
||||
|
||||
void
|
||||
PointPropertiesPage::do_update (const db::Shape &shape, double dbu, const std::string &lname)
|
||||
{
|
||||
m_dbu = dbu;
|
||||
|
||||
layer_lbl->setText (tl::to_qstring (lname));
|
||||
|
||||
db::Point point;
|
||||
shape.point (point);
|
||||
set_point (point);
|
||||
}
|
||||
|
||||
ChangeApplicator *
|
||||
PointPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape &shape, double dbu)
|
||||
{
|
||||
m_dbu = dbu;
|
||||
|
||||
db::Point point = get_point ();
|
||||
|
||||
db::Point org_point;
|
||||
shape.point (org_point);
|
||||
|
||||
if (point != org_point) {
|
||||
return new PointDimensionsChangeApplicator (point, org_point);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
db::Point
|
||||
PointPropertiesPage::get_point () const
|
||||
{
|
||||
bool has_error = false;
|
||||
double x = 0.0, y = 0.0;
|
||||
|
||||
try {
|
||||
tl::from_string_ext (tl::to_string (x_le->text ()), x);
|
||||
lay::indicate_error (x_le, (tl::Exception *) 0);
|
||||
} catch (tl::Exception &ex) {
|
||||
lay::indicate_error (x_le, &ex);
|
||||
has_error = true;
|
||||
}
|
||||
|
||||
try {
|
||||
tl::from_string_ext (tl::to_string (y_le->text ()), y);
|
||||
lay::indicate_error (y_le, (tl::Exception *) 0);
|
||||
} catch (tl::Exception &ex) {
|
||||
lay::indicate_error (y_le, &ex);
|
||||
has_error = true;
|
||||
}
|
||||
|
||||
if (has_error) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid values - see highlighted entry boxes")));
|
||||
}
|
||||
|
||||
db::VCplxTrans t = db::VCplxTrans (trans ().inverted ());
|
||||
bool du = dbu_units ();
|
||||
|
||||
return point_from_dpoint (db::DPoint (x, y), m_dbu, du, t);
|
||||
}
|
||||
|
||||
void
|
||||
PointPropertiesPage::set_point (const db::Point &point)
|
||||
{
|
||||
db::CplxTrans t = db::CplxTrans (trans ());
|
||||
db::DPoint pt = db::DPoint (t (point));
|
||||
|
||||
bool du = dbu_units ();
|
||||
|
||||
x_le->setText (tl::to_qstring (coord_to_string (pt.x (), m_dbu, du)));
|
||||
y_le->setText (tl::to_qstring (coord_to_string (pt.y (), m_dbu, du)));
|
||||
}
|
||||
|
||||
void
|
||||
PointPropertiesPage::changed ()
|
||||
{
|
||||
try {
|
||||
set_point (get_point ());
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
emit edited ();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// TextPropertiesPage implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "edtService.h"
|
||||
#include "ui_PolygonPropertiesPage.h"
|
||||
#include "ui_BoxPropertiesPage.h"
|
||||
#include "ui_PointPropertiesPage.h"
|
||||
#include "ui_PathPropertiesPage.h"
|
||||
#include "ui_EditablePathPropertiesPage.h"
|
||||
#include "ui_TextPropertiesPage.h"
|
||||
|
|
@ -152,6 +153,34 @@ private:
|
|||
void set_box (const db::Box &box);
|
||||
};
|
||||
|
||||
class PointPropertiesPage
|
||||
: public ShapePropertiesPage,
|
||||
public Ui::PointPropertiesPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PointPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent);
|
||||
|
||||
virtual std::string description (size_t entry) const;
|
||||
virtual std::string description () const { return ShapePropertiesPage::description (); }
|
||||
virtual void do_update (const db::Shape &shape, double dbu, const std::string &lname);
|
||||
virtual ChangeApplicator *create_applicator (db::Shapes &shapes, const db::Shape &shape, double dbu);
|
||||
|
||||
public slots:
|
||||
void changed ();
|
||||
|
||||
protected:
|
||||
virtual QCheckBox *dbu_checkbox () const { return dbu_cb; }
|
||||
virtual QCheckBox *abs_checkbox () const { return abs_cb; }
|
||||
|
||||
private:
|
||||
double m_dbu;
|
||||
|
||||
db::Point get_point () const;
|
||||
void set_point (const db::Point &point);
|
||||
};
|
||||
|
||||
class TextPropertiesPage
|
||||
: public ShapePropertiesPage,
|
||||
public Ui::TextPropertiesPage
|
||||
|
|
|
|||
|
|
@ -1108,7 +1108,20 @@ Service::transient_select (const db::DPoint &pos)
|
|||
|
||||
lay::ShapeMarker *marker = new lay::ShapeMarker (view (), r->cv_index ());
|
||||
marker->set (r->shape (), gt, mp_view->cv_transform_variants (r->cv_index (), r->layer ()));
|
||||
marker->set_vertex_size (0);
|
||||
|
||||
bool is_point = false;
|
||||
if (r->shape ().is_edge () || r->shape ().is_box ()) {
|
||||
is_point = r->shape ().bbox ().is_point ();
|
||||
} else if (r->shape ().is_point ()) {
|
||||
is_point = true;
|
||||
}
|
||||
|
||||
if (is_point) {
|
||||
marker->set_vertex_shape (lay::ViewOp::Cross);
|
||||
marker->set_vertex_size (9 /*cross vertex size*/);
|
||||
} else {
|
||||
marker->set_vertex_size (0);
|
||||
}
|
||||
marker->set_line_width (1);
|
||||
marker->set_halo (0);
|
||||
|
||||
|
|
@ -1602,7 +1615,15 @@ Service::do_selection_to_view ()
|
|||
}
|
||||
|
||||
marker->set (r->shape (), gt, *tv_list);
|
||||
if (r->shape ().is_text ()) {
|
||||
|
||||
bool is_point = false;
|
||||
if (r->shape ().is_text () || r->shape ().is_point ()) {
|
||||
is_point = true;
|
||||
} else if (r->shape ().is_edge () || r->shape ().is_box ()) {
|
||||
is_point = r->shape ().bbox ().is_point ();
|
||||
}
|
||||
|
||||
if (is_point) {
|
||||
// show the origins as crosses for texts
|
||||
marker->set_vertex_shape (lay::ViewOp::Cross);
|
||||
marker->set_vertex_size (9 /*cross vertex size*/);
|
||||
|
|
|
|||
|
|
@ -386,6 +386,20 @@ ShapeEditService::deliver_shape (const db::Box &box)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShapeEditService::deliver_shape (const db::Point &point)
|
||||
{
|
||||
if (m_combine_mode == CM_Add) {
|
||||
if (manager ()) {
|
||||
manager ()->transaction (tl::to_string (tr ("Create point")));
|
||||
}
|
||||
cell ().shapes (layer ()).insert (point);
|
||||
if (manager ()) {
|
||||
manager ()->commit ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// PolygonService implementation
|
||||
|
||||
|
|
@ -816,6 +830,103 @@ BoxService::selection_applies (const lay::ObjectInstPath &sel) const
|
|||
return !sel.is_cell_inst () && sel.shape ().is_box ();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// PointService implementation
|
||||
|
||||
PointService::PointService (db::Manager *manager, lay::LayoutViewBase *view)
|
||||
: ShapeEditService (manager, view, db::ShapeIterator::Points)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
std::vector<lay::PropertiesPage *>
|
||||
PointService::properties_pages (db::Manager *manager, QWidget *parent)
|
||||
{
|
||||
std::vector<lay::PropertiesPage *> pages;
|
||||
pages.push_back (new edt::PointPropertiesPage (this, manager, parent));
|
||||
return pages;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
PointService::do_begin_edit (const db::DPoint &p)
|
||||
{
|
||||
get_edit_layer ();
|
||||
|
||||
db::DPoint pp = snap2 (p);
|
||||
m_p = pp;
|
||||
|
||||
set_edit_marker (new lay::Marker (view (), cv_index ()));
|
||||
update_marker ();
|
||||
}
|
||||
|
||||
db::Point
|
||||
PointService::get_point () const
|
||||
{
|
||||
return db::Point (trans () * m_p);
|
||||
}
|
||||
|
||||
void
|
||||
PointService::update_marker ()
|
||||
{
|
||||
lay::Marker *marker = dynamic_cast<lay::Marker *> (edit_marker ());
|
||||
if (marker) {
|
||||
|
||||
db::Point pt = get_point ();
|
||||
marker->set (db::Box (pt, pt), db::VCplxTrans (1.0 / layout ().dbu ()) * trans ().inverted ());
|
||||
|
||||
view ()->message (std::string ("x: ") +
|
||||
tl::micron_to_string (m_p.x ()) +
|
||||
std::string (" y: ") +
|
||||
tl::micron_to_string (m_p.y ()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PointService::do_mouse_move_inactive (const db::DPoint &p)
|
||||
{
|
||||
lay::PointSnapToObjectResult snap_details = snap2_details (p);
|
||||
mouse_cursor_from_snap_details (snap_details);
|
||||
}
|
||||
|
||||
void
|
||||
PointService::do_mouse_move (const db::DPoint &p)
|
||||
{
|
||||
do_mouse_move_inactive (p);
|
||||
|
||||
set_cursor (lay::Cursor::cross);
|
||||
m_p = snap2 (p);
|
||||
update_marker ();
|
||||
}
|
||||
|
||||
bool
|
||||
PointService::do_mouse_click (const db::DPoint &p)
|
||||
{
|
||||
do_mouse_move (p);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PointService::do_finish_edit ()
|
||||
{
|
||||
deliver_shape (get_point ());
|
||||
commit_recent (view ());
|
||||
}
|
||||
|
||||
void
|
||||
PointService::do_cancel_edit ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool
|
||||
PointService::selection_applies (const lay::ObjectInstPath &sel) const
|
||||
{
|
||||
return !sel.is_cell_inst () && sel.shape ().is_point ();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// TextService implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ protected:
|
|||
void deliver_shape (const db::Polygon &poly);
|
||||
void deliver_shape (const db::Path &path);
|
||||
void deliver_shape (const db::Box &box);
|
||||
void deliver_shape (const db::Point &point);
|
||||
virtual void current_layer_changed () { }
|
||||
|
||||
private:
|
||||
|
|
@ -140,6 +141,33 @@ private:
|
|||
db::Box get_box () const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implementation of edt::Service for point editing
|
||||
*/
|
||||
class PointService
|
||||
: public ShapeEditService
|
||||
{
|
||||
public:
|
||||
PointService (db::Manager *manager, lay::LayoutViewBase *view);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
virtual std::vector<lay::PropertiesPage *> properties_pages (db::Manager *manager, QWidget *parent);
|
||||
#endif
|
||||
virtual void do_begin_edit (const db::DPoint &p);
|
||||
virtual void do_mouse_move (const db::DPoint &p);
|
||||
virtual void do_mouse_move_inactive (const db::DPoint &p);
|
||||
virtual bool do_mouse_click (const db::DPoint &p);
|
||||
virtual void do_finish_edit ();
|
||||
virtual void do_cancel_edit ();
|
||||
virtual bool selection_applies (const lay::ObjectInstPath &sel) const;
|
||||
|
||||
private:
|
||||
db::DPoint m_p;
|
||||
|
||||
void update_marker ();
|
||||
db::Point get_point () const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implementation of edt::Service for text editing
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -260,19 +260,19 @@ get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index
|
|||
std::map <std::string, size_t>::const_iterator pnm = pname_map.find (pv->second.to_string ());
|
||||
if (pnm != pname_map.end ()) {
|
||||
|
||||
db::CplxTrans dbu_trans (layout->dbu ());
|
||||
|
||||
if (sh->is_box ()) {
|
||||
if (sh->box ().width () == 0 && sh->box ().height () == 0) {
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (sh->box ().lower_left () * layout->dbu ());
|
||||
} else {
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (sh->box () * layout->dbu ());
|
||||
}
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (dbu_trans * sh->box ());
|
||||
} else if (sh->is_edge ()) {
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (sh->edge () * layout->dbu ());
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (dbu_trans * sh->edge ());
|
||||
} else if (sh->is_point ()) {
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (dbu_trans * sh->point ());
|
||||
} else if (sh->is_polygon ()) {
|
||||
// Hint: we don't compress since we don't want to loose information
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (sh->polygon ().transformed (db::CplxTrans (layout->dbu ()), false));
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (sh->polygon ().transformed (dbu_trans, false));
|
||||
} else if (sh->is_path ()) {
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (db::CplxTrans (layout->dbu ()) * sh->path ());
|
||||
parameters_for_pcell [pnm->second] = tl::Variant (dbu_trans * sh->path ());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -315,7 +315,7 @@ get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index
|
|||
} else if (org_parameters[i].is_user<db::DPoint> ()) {
|
||||
|
||||
db::DPoint p = org_parameters[i].to_user<db::DPoint> ();
|
||||
guiding_shapes.insert (db::BoxWithProperties(db::Box (db::DBox (p, p) * (1.0 / layout->dbu ())), layout->properties_repository ().properties_id (props)));
|
||||
guiding_shapes.insert (db::PointWithProperties(db::Point (p * (1.0 / layout->dbu ())), layout->properties_repository ().properties_id (props)));
|
||||
|
||||
} else if (org_parameters[i].is_user<db::DPolygon> ()) {
|
||||
|
||||
|
|
|
|||
|
|
@ -496,7 +496,7 @@ struct writer
|
|||
|
||||
if (atype.is_ref () || atype.is_ptr ()) {
|
||||
|
||||
// TODO: morph the variant to the requested type and pass it's pointer (requires a non-const reference for arg)
|
||||
// TODO: morph the variant to the requested type and pass its pointer (requires a non-const reference for arg)
|
||||
// -> we would have a reference that can modify the argument (out parameter).
|
||||
R *v = new R (var2c<R>::get (*arg));
|
||||
heap->push (v);
|
||||
|
|
@ -542,7 +542,7 @@ struct writer<StringType>
|
|||
|
||||
} else {
|
||||
|
||||
// TODO: morph the variant to the requested type and pass it's pointer (requires a non-const reference for arg)
|
||||
// TODO: morph the variant to the requested type and pass its pointer (requires a non-const reference for arg)
|
||||
// -> we would have a reference that can modify the argument (out parameter).
|
||||
// NOTE: by convention we pass the ownership to the receiver for adaptors.
|
||||
aa->write<void *> ((void *)new StringAdaptorImpl<std::string> (arg->to_string ()));
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ private:
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief The template providing a binding of a "free iterator" (one that provides it's own at_end method)
|
||||
* @brief The template providing a binding of a "free iterator" (one that provides its own at_end method)
|
||||
*/
|
||||
template <class I>
|
||||
class FreeIterAdaptor
|
||||
|
|
|
|||
|
|
@ -40,10 +40,10 @@ class QtLifetimeMonitor
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief A helper object that is attached to a QObject to monitor it's lifetime
|
||||
* @brief A helper object that is attached to a QObject to monitor its lifetime
|
||||
*
|
||||
* This object will be put into the properties table of the QObject (more precisely: a copy).
|
||||
* When the QObject is destroyed, it's properties are destroyed too and through reference
|
||||
* When the QObject is destroyed, its properties are destroyed too and through reference
|
||||
* counting the destruction of the QObject is detected. The monitoring itself is implemented
|
||||
* through a gsi::ObjectBase object which plugs seamlessly into the gsi type system:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -284,5 +284,9 @@
|
|||
<file alias="bookmark_16px@2x.png">images/bookmark_16px@2x.png</file>
|
||||
<file alias="bookmark_24px.png">images/bookmark_24px.png</file>
|
||||
<file alias="bookmark_24px@2x.png">images/bookmark_24px@2x.png</file>
|
||||
<file alias="find_next_16px.png">images/find_next_16px.png</file>
|
||||
<file alias="find_next_16px@2x.png">images/find_next_16px@2x.png</file>
|
||||
<file alias="find_prev_16px.png">images/find_prev_16px.png</file>
|
||||
<file alias="find_prev_16px@2x.png">images/find_prev_16px@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 689 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 702 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,231 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 4.2333332 4.2333335"
|
||||
version="1.1"
|
||||
id="svg1011"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
sodipodi:docname="find_next_16px.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1013"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="px"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:zoom="12.224789"
|
||||
inkscape:cx="1.9223236"
|
||||
inkscape:cy="9.7752198"
|
||||
inkscape:window-width="1465"
|
||||
inkscape:window-height="666"
|
||||
inkscape:window-x="1099"
|
||||
inkscape:window-y="250"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="layer1"
|
||||
width="16px"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid1074"
|
||||
spacingx="0.13229167"
|
||||
spacingy="0.13229167"
|
||||
empspacing="2" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs1008">
|
||||
<linearGradient
|
||||
id="linearGradient3600">
|
||||
<stop
|
||||
style="stop-color:#ff9f3f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5268"
|
||||
id="radialGradient5274"
|
||||
cx="1240.1577"
|
||||
cy="1031.1023"
|
||||
fx="1240.1577"
|
||||
fy="1031.1023"
|
||||
r="17.716494"
|
||||
gradientTransform="matrix(0.07467134,-2.1333204e-7,1.7097273e-7,0.05973699,-91.281506,-60.271751)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient5268">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5270" />
|
||||
<stop
|
||||
style="stop-color:#adadad;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5272" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5280"
|
||||
id="radialGradient5286"
|
||||
cx="1240.1576"
|
||||
cy="1031.1023"
|
||||
fx="1240.1576"
|
||||
fy="1031.1023"
|
||||
r="17.716494"
|
||||
gradientTransform="matrix(0.07467134,-5.3367783e-7,4.263589e-7,0.05973696,-91.281753,-60.27133)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient5280">
|
||||
<stop
|
||||
style="stop-color:#ababab;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5282" />
|
||||
<stop
|
||||
style="stop-color:#535353;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5284" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5298"
|
||||
id="linearGradient5304"
|
||||
x1="1257.874"
|
||||
y1="1059.4489"
|
||||
x2="1264.9606"
|
||||
y2="1052.3622"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.07467134,0,0,0.07467124,-91.281317,-75.670759)" />
|
||||
<linearGradient
|
||||
id="linearGradient5298">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5300" />
|
||||
<stop
|
||||
id="stop5306"
|
||||
offset="0.50000167"
|
||||
style="stop-color:#8f8f8f;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#353535;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5302" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4099">
|
||||
<stop
|
||||
id="stop4101"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#ff9e3f;stop-opacity:1;"
|
||||
offset="0.65753424"
|
||||
id="stop4485" />
|
||||
<stop
|
||||
id="stop4103"
|
||||
offset="1"
|
||||
style="stop-color:#808080;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:none;stroke:#865b26;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect3596"
|
||||
width="4.2333326"
|
||||
height="4.2333331"
|
||||
x="3.3333333e-07"
|
||||
y="3.3333333e-07"
|
||||
inkscape:export-filename="/home/matthias/klayout/master/src/lay/lay/images/back.png"
|
||||
inkscape:export-xdpi="27.093315"
|
||||
inkscape:export-ydpi="27.093315" />
|
||||
<rect
|
||||
style="fill:none;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect5220"
|
||||
width="4.2333336"
|
||||
height="4.2333336"
|
||||
x="-8.8817842e-16"
|
||||
y="-7.7715612e-16"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25.399982"
|
||||
inkscape:export-ydpi="25.399982" />
|
||||
<ellipse
|
||||
style="fill:url(#radialGradient5274);fill-opacity:1;stroke:url(#radialGradient5286);stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path5258"
|
||||
cx="1.5874953"
|
||||
cy="1.5875114"
|
||||
rx="1.188506"
|
||||
ry="1.1885061"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
<ellipse
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path5278"
|
||||
cx="0.65258032"
|
||||
cy="2.108269"
|
||||
rx="0.21676302"
|
||||
ry="0.51771969"
|
||||
transform="matrix(0.84080627,-0.54133615,0.68097313,0.7323084,0,0)"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
<ellipse
|
||||
style="fill:none;fill-opacity:1;stroke:#303030;stroke-width:0.0746713;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path5308"
|
||||
cx="1.5874953"
|
||||
cy="1.5875114"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25"
|
||||
rx="1.3229176"
|
||||
ry="1.3229157" />
|
||||
<path
|
||||
style="fill:url(#linearGradient5304);fill-opacity:1;fill-rule:evenodd;stroke:#303030;stroke-width:0.0746713;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.9687491,3.4395946 3.4395757,3.9687602 2.1166608,2.645847 2.6458268,2.1166818 Z"
|
||||
id="path5288"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
<path
|
||||
inkscape:export-ydpi="25"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5342"
|
||||
d="M 3.042749,1.4552217 H 1.9843342 l -7.36e-5,1.0595032 h -0.521379 l 1.05066,1.0761548 1.058786,-1.0722781 -0.529505,-0.00388 z"
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.05833334;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98414469" />
|
||||
<path
|
||||
style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.0427083,1.4552084 H 1.984375 l -7.36e-5,1.0595163 H 1.4629626 l 1.050579,1.076168 1.0587045,-1.0722914 -0.5294642,-0.00389 z"
|
||||
id="path5330"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.4 KiB |
|
|
@ -0,0 +1,231 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 4.2333332 4.2333335"
|
||||
version="1.1"
|
||||
id="svg1011"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
sodipodi:docname="find_prev_16px.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1013"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="px"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:zoom="12.224789"
|
||||
inkscape:cx="6.666782"
|
||||
inkscape:cy="14.192475"
|
||||
inkscape:window-width="1092"
|
||||
inkscape:window-height="666"
|
||||
inkscape:window-x="1083"
|
||||
inkscape:window-y="278"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="layer1"
|
||||
width="16px"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid1074"
|
||||
spacingx="0.13229167"
|
||||
spacingy="0.13229167"
|
||||
empspacing="2" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs1008">
|
||||
<linearGradient
|
||||
id="linearGradient3600">
|
||||
<stop
|
||||
style="stop-color:#ff9f3f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5268"
|
||||
id="radialGradient5274"
|
||||
cx="1240.1577"
|
||||
cy="1031.1023"
|
||||
fx="1240.1577"
|
||||
fy="1031.1023"
|
||||
r="17.716494"
|
||||
gradientTransform="matrix(0.07467134,-2.1333204e-7,1.7097273e-7,0.05973699,-91.281506,-60.271751)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient5268">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5270" />
|
||||
<stop
|
||||
style="stop-color:#adadad;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5272" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5280"
|
||||
id="radialGradient5286"
|
||||
cx="1240.1576"
|
||||
cy="1031.1023"
|
||||
fx="1240.1576"
|
||||
fy="1031.1023"
|
||||
r="17.716494"
|
||||
gradientTransform="matrix(0.07467134,-5.3367783e-7,4.263589e-7,0.05973696,-91.281753,-60.27133)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient5280">
|
||||
<stop
|
||||
style="stop-color:#ababab;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5282" />
|
||||
<stop
|
||||
style="stop-color:#535353;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5284" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5298"
|
||||
id="linearGradient5304"
|
||||
x1="1257.874"
|
||||
y1="1059.4489"
|
||||
x2="1264.9606"
|
||||
y2="1052.3622"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.07467134,0,0,0.07467124,-91.281317,-75.670759)" />
|
||||
<linearGradient
|
||||
id="linearGradient5298">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5300" />
|
||||
<stop
|
||||
id="stop5306"
|
||||
offset="0.50000167"
|
||||
style="stop-color:#8f8f8f;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#353535;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5302" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4099">
|
||||
<stop
|
||||
id="stop4101"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#ff9e3f;stop-opacity:1;"
|
||||
offset="0.65753424"
|
||||
id="stop4485" />
|
||||
<stop
|
||||
id="stop4103"
|
||||
offset="1"
|
||||
style="stop-color:#808080;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:none;stroke:#865b26;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect3596"
|
||||
width="4.2333326"
|
||||
height="4.2333331"
|
||||
x="3.3333333e-07"
|
||||
y="3.3333333e-07"
|
||||
inkscape:export-filename="/home/matthias/klayout/master/src/lay/lay/images/back.png"
|
||||
inkscape:export-xdpi="27.093315"
|
||||
inkscape:export-ydpi="27.093315" />
|
||||
<rect
|
||||
style="fill:none;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect5220"
|
||||
width="4.2333336"
|
||||
height="4.2333336"
|
||||
x="-8.8817842e-16"
|
||||
y="-7.7715612e-16"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25.399982"
|
||||
inkscape:export-ydpi="25.399982" />
|
||||
<ellipse
|
||||
style="fill:url(#radialGradient5274);fill-opacity:1;stroke:url(#radialGradient5286);stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path5258"
|
||||
cx="1.5874953"
|
||||
cy="1.5875114"
|
||||
rx="1.188506"
|
||||
ry="1.1885061"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
<ellipse
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path5278"
|
||||
cx="0.65258032"
|
||||
cy="2.108269"
|
||||
rx="0.21676302"
|
||||
ry="0.51771969"
|
||||
transform="matrix(0.84080627,-0.54133615,0.68097313,0.7323084,0,0)"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
<ellipse
|
||||
style="fill:none;fill-opacity:1;stroke:#303030;stroke-width:0.0746713;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path5308"
|
||||
cx="1.5874953"
|
||||
cy="1.5875114"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25"
|
||||
rx="1.3229176"
|
||||
ry="1.3229157" />
|
||||
<path
|
||||
style="fill:url(#linearGradient5304);fill-opacity:1;fill-rule:evenodd;stroke:#303030;stroke-width:0.0746713;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.9687491,3.4395946 3.4395757,3.9687602 2.1166608,2.645847 2.6458268,2.1166818 Z"
|
||||
id="path5288"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
<path
|
||||
inkscape:export-ydpi="25"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5342"
|
||||
d="M 3.0478337,3.5792109 H 1.9895004 L 1.9839304,2.5174183 H 1.4625915 l 1.0505791,-1.076168 1.0587045,1.0722914 -0.5294642,0.00389 z"
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.05833334;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.0478337,3.5792109 H 1.9895004 L 1.9839304,2.5174183 H 1.4625915 l 1.0505791,-1.076168 1.0587045,1.0722914 -0.5294642,0.00389 z"
|
||||
id="path5330"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
|
||||
inkscape:export-xdpi="25"
|
||||
inkscape:export-ydpi="25" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.4 KiB |
|
|
@ -451,7 +451,7 @@ static ImageRef *new_image_pbt (const tl::PixelBuffer &pixel_buffer, const db::D
|
|||
return new ImageRef (img::Object (pixel_buffer, trans));
|
||||
}
|
||||
|
||||
#if HAVE_QT
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
static ImageRef *new_image_qit (const QImage &image, const db::DCplxTrans &trans)
|
||||
{
|
||||
return new ImageRef (img::Object (image, trans));
|
||||
|
|
@ -597,7 +597,7 @@ gsi::Class<ImageRef> decl_Image (decl_BasicImage, "lay", "Image",
|
|||
"@param filename The path to the image file to load.\n"
|
||||
"@param trans The transformation to apply to the image when displaying it.\n"
|
||||
) +
|
||||
#if defined(HAVE_QT)
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
gsi::constructor ("new", &gsi::new_image_qit, gsi::arg ("image"), gsi::arg ("trans", db::DCplxTrans (), "unity"),
|
||||
"@brief Constructor from a image pixel buffer\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -463,10 +463,6 @@
|
|||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/breakpoint_16px.png</normaloff>:/breakpoint_16px.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>F9</string>
|
||||
</property>
|
||||
|
|
@ -636,7 +632,7 @@
|
|||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/find_16px.png</normaloff>:/find_16px.png</iconset>
|
||||
<normaloff>:/find_next_16px.png</normaloff>:/find_next_16px.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+F</string>
|
||||
|
|
@ -646,6 +642,23 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="findPrevButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/find_prev_16px.png</normaloff>:/find_prev_16px.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+F</string>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="replaceModeButton">
|
||||
<property name="sizePolicy">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
@args id, ...
|
||||
This method implements Ruby's fallback mechanism and adds some convenience to
|
||||
QObject: through that implementation, each child object can be accessed through
|
||||
it's name. That method will deliver a reference to the child object or nil if there
|
||||
its name. That method will deliver a reference to the child object or nil if there
|
||||
is no child element with that name.
|
||||
For example:
|
||||
|
||||
|
|
|
|||
|
|
@ -124,9 +124,9 @@ static void ui_exception_handler_tl (const tl::Exception &ex, QWidget *parent)
|
|||
|
||||
if (gsi_excpt->line () > 0) {
|
||||
tl::error << gsi_excpt->sourcefile () << ":" << gsi_excpt->line () << ": "
|
||||
<< gsi_excpt->msg () << tl::to_string (QObject::tr (" (class ")) << gsi_excpt->cls () << ")";
|
||||
<< gsi_excpt->msg ();
|
||||
} else {
|
||||
tl::error << gsi_excpt->msg () << tl::to_string (QObject::tr (" (class ")) << gsi_excpt->cls () << ")";
|
||||
tl::error << gsi_excpt->msg ();
|
||||
}
|
||||
|
||||
lay::RuntimeErrorForm error_dialog (parent, "ruby_error_form", gsi_excpt);
|
||||
|
|
@ -686,28 +686,59 @@ ApplicationBase::init_app ()
|
|||
tc->add_path (*p);
|
||||
}
|
||||
|
||||
tc->load ();
|
||||
|
||||
bool needs_reload = false;
|
||||
|
||||
// disambiguator for tech name
|
||||
std::map<std::string, int> tech_disambiguator;
|
||||
std::map<std::string, std::string> tech_name_for_file;
|
||||
|
||||
for (auto t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
tech_disambiguator.insert (std::make_pair (t->name (), 0));
|
||||
}
|
||||
|
||||
// import technologies from the command line
|
||||
for (std::vector <std::pair<file_type, std::pair<std::string, std::string> > >::iterator f = m_files.begin (); f != m_files.end (); ++f) {
|
||||
|
||||
if (f->first == layout_file_with_tech_file) {
|
||||
|
||||
const std::string &tech_file = f->second.second;
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::info << "Importing technology from " << f->second.second;
|
||||
}
|
||||
|
||||
db::Technology t;
|
||||
t.load (f->second.second);
|
||||
t.load (tech_file);
|
||||
|
||||
// disambiguate the name, so we do not overwrite technologies with the same name from the config
|
||||
if (tech_name_for_file.find (tech_file) != tech_name_for_file.end ()) {
|
||||
t.set_name (tech_name_for_file [tech_file]);
|
||||
} else if (tech_disambiguator.find (t.name ()) != tech_disambiguator.end ()) {
|
||||
int &index = tech_disambiguator [t.name ()];
|
||||
index += 1;
|
||||
t.set_name (t.name () + tl::sprintf ("[%d]", index));
|
||||
tech_name_for_file.insert (std::make_pair (tech_file, t.name ()));
|
||||
} else {
|
||||
tech_disambiguator.insert (std::make_pair (t.name (), 0));
|
||||
tech_name_for_file.insert (std::make_pair (tech_file, t.name ()));
|
||||
}
|
||||
|
||||
tc->add_temp_tech (t);
|
||||
|
||||
f->first = layout_file_with_tech;
|
||||
f->second.second = t.name ();
|
||||
|
||||
needs_reload = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tc->load ();
|
||||
if (needs_reload) {
|
||||
tc->load ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -493,6 +493,7 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection
|
|||
connect (replaceModeButton, SIGNAL (clicked ()), this, SLOT (replace_mode_button_clicked ()));
|
||||
connect (replaceNextButton, SIGNAL (clicked ()), this, SLOT (replace_next_button_clicked ()));
|
||||
connect (findNextButton, SIGNAL (clicked ()), this, SLOT (find_next_button_clicked ()));
|
||||
connect (findPrevButton, SIGNAL (clicked ()), this, SLOT (find_prev_button_clicked ()));
|
||||
connect (replaceAllButton, SIGNAL (clicked ()), this, SLOT (replace_all_button_clicked ()));
|
||||
connect (allVariables, SIGNAL (clicked (bool)), variableList, SLOT (set_show_all (bool)));
|
||||
|
||||
|
|
@ -2021,7 +2022,7 @@ MacroEditorDialog::replace_all_button_clicked ()
|
|||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::search_requested (const QString &s)
|
||||
MacroEditorDialog::search_requested (const QString &s, bool prev)
|
||||
{
|
||||
if (! s.isNull ()) {
|
||||
searchEditBox->setText (s);
|
||||
|
|
@ -2029,7 +2030,21 @@ MacroEditorDialog::search_requested (const QString &s)
|
|||
searchEditBox->selectAll ();
|
||||
}
|
||||
searchEditBox->setFocus ();
|
||||
search_editing ();
|
||||
|
||||
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
|
||||
if (! page) {
|
||||
return;
|
||||
}
|
||||
|
||||
apply_search ();
|
||||
page->find_reset (); // search from the initial position
|
||||
if (! page->has_multi_block_selection ()) {
|
||||
if (! prev) {
|
||||
page->find_next ();
|
||||
} else {
|
||||
page->find_prev ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3511,7 +3526,7 @@ MacroEditorDialog::create_page (lym::Macro *macro)
|
|||
editor->exec_model ()->set_run_mode (m_in_exec);
|
||||
editor->connect_macro (macro);
|
||||
connect (editor.get (), SIGNAL (help_requested (const QString &)), this, SLOT (help_requested (const QString &)));
|
||||
connect (editor.get (), SIGNAL (search_requested (const QString &)), this, SLOT (search_requested (const QString &)));
|
||||
connect (editor.get (), SIGNAL (search_requested (const QString &, bool)), this, SLOT (search_requested (const QString &, bool)));
|
||||
connect (editor.get (), SIGNAL (edit_trace (bool)), this, SLOT (add_edit_trace (bool)));
|
||||
return editor.release ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ private slots:
|
|||
void find_next_button_clicked ();
|
||||
void find_prev_button_clicked ();
|
||||
void help_requested (const QString &s);
|
||||
void search_requested (const QString &s);
|
||||
void search_requested (const QString &s, bool prev);
|
||||
void macro_changed (lym::Macro *macro);
|
||||
void macro_deleted (lym::Macro *macro);
|
||||
void macro_collection_deleted (lym::MacroCollection *collection);
|
||||
|
|
|
|||
|
|
@ -1077,12 +1077,10 @@ MacroEditorPage::find_prev ()
|
|||
first = false;
|
||||
|
||||
int i = -1;
|
||||
int l = 0;
|
||||
int p = 0;
|
||||
while (true) {
|
||||
int ii = m_current_search.indexIn (b.text (), p);
|
||||
if (ii >= 0 && (o < 0 || ii < o)) {
|
||||
l = m_current_search.matchedLength ();
|
||||
i = ii;
|
||||
p = ii + 1;
|
||||
} else {
|
||||
|
|
@ -1091,8 +1089,7 @@ MacroEditorPage::find_prev ()
|
|||
}
|
||||
if (i >= 0) {
|
||||
QTextCursor newc (b);
|
||||
newc.setPosition (i + b.position () + l);
|
||||
newc.setPosition (i + b.position (), QTextCursor::KeepAnchor);
|
||||
newc.setPosition (i + b.position ());
|
||||
m_ignore_cursor_changed_event = true;
|
||||
mp_text->setTextCursor (newc);
|
||||
m_ignore_cursor_changed_event = false;
|
||||
|
|
@ -1136,8 +1133,7 @@ MacroEditorPage::find_next ()
|
|||
int i = m_current_search.indexIn (b.text (), o);
|
||||
if (i >= 0) {
|
||||
QTextCursor newc (b);
|
||||
newc.setPosition (i + b.position () + m_current_search.matchedLength ());
|
||||
newc.setPosition (i + b.position (), QTextCursor::KeepAnchor);
|
||||
newc.setPosition (i + b.position ());
|
||||
m_ignore_cursor_changed_event = true;
|
||||
mp_text->setTextCursor (newc);
|
||||
m_ignore_cursor_changed_event = false;
|
||||
|
|
@ -1158,6 +1154,39 @@ MacroEditorPage::find_next ()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MacroEditorPage::select_match_here ()
|
||||
{
|
||||
if (m_current_search == QRegExp ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextCursor c = mp_text->textCursor ();
|
||||
if (c.isNull ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c.hasSelection ()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QTextBlock b = c.block ();
|
||||
int pos = c.position () - b.position ();
|
||||
int i = m_current_search.indexIn (b.text (), pos);
|
||||
if (i == pos) {
|
||||
QTextCursor newc (b);
|
||||
newc.setPosition (i + b.position () + m_current_search.matchedLength ());
|
||||
newc.setPosition (i + b.position (), QTextCursor::KeepAnchor);
|
||||
m_ignore_cursor_changed_event = true;
|
||||
mp_text->setTextCursor (newc);
|
||||
m_ignore_cursor_changed_event = false;
|
||||
emit edit_trace (false);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorPage::set_editor_focus ()
|
||||
{
|
||||
|
|
@ -1196,7 +1225,9 @@ MacroEditorPage::replace_and_find_next (const QString &replace)
|
|||
return;
|
||||
}
|
||||
|
||||
replace_in_selection (replace, true);
|
||||
if (select_match_here ()) {
|
||||
replace_in_selection (replace, true);
|
||||
}
|
||||
find_next ();
|
||||
}
|
||||
|
||||
|
|
@ -1280,12 +1311,8 @@ MacroEditorPage::replace_in_selection (const QString &replace, bool first)
|
|||
o = i + r.size ();
|
||||
|
||||
if (first) {
|
||||
|
||||
// in single-selection mode, put cursor past substitution
|
||||
c.setPosition (i + b.position ());
|
||||
has_selection = false;
|
||||
done = true;
|
||||
|
||||
} else if (b == be) {
|
||||
pe += int (r.size ()) - int (m_current_search.matchedLength ());
|
||||
}
|
||||
|
|
@ -1734,6 +1761,11 @@ static bool is_find_key (QKeyEvent *ke)
|
|||
return ke->key () == Qt::Key_F && (ke->modifiers () & Qt::ControlModifier) != 0;
|
||||
}
|
||||
|
||||
static bool is_find_backwards_key (QKeyEvent *ke)
|
||||
{
|
||||
return ke->key () == Qt::Key_F && (ke->modifiers () & Qt::ControlModifier) != 0 && (ke->modifiers () & Qt::ShiftModifier) != 0;
|
||||
}
|
||||
|
||||
static bool is_up_key (QKeyEvent *ke)
|
||||
{
|
||||
return ke->key () == Qt::Key_Up;
|
||||
|
|
@ -1755,6 +1787,7 @@ static bool is_any_known_key (QKeyEvent *ke)
|
|||
is_help_key (ke) ||
|
||||
is_find_next_key (ke) ||
|
||||
is_find_key (ke) ||
|
||||
is_find_backwards_key (ke) ||
|
||||
is_up_key (ke) ||
|
||||
is_down_key (ke);
|
||||
}
|
||||
|
|
@ -1848,19 +1881,21 @@ MacroEditorPage::eventFilter (QObject *watched, QEvent *event)
|
|||
QApplication::sendEvent (mp_completer_list, event);
|
||||
return true;
|
||||
|
||||
} else if (is_find_key (ke)) {
|
||||
} else if (is_find_key (ke) || is_find_backwards_key (ke)) {
|
||||
|
||||
bool prev = is_find_backwards_key (ke);
|
||||
|
||||
QTextCursor c = mp_text->textCursor ();
|
||||
if (c.selectionStart () != c.selectionEnd ()) {
|
||||
QTextBlock s = mp_text->document ()->findBlock (c.selectionStart ());
|
||||
QTextBlock e = mp_text->document ()->findBlock (c.selectionEnd ());
|
||||
if (e == s) {
|
||||
emit search_requested (c.selectedText ());
|
||||
emit search_requested (c.selectedText (), prev);
|
||||
} else {
|
||||
emit search_requested (QString ());
|
||||
emit search_requested (QString (), prev);
|
||||
}
|
||||
} else {
|
||||
emit search_requested (QString ());
|
||||
emit search_requested (QString (), prev);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ public:
|
|||
|
||||
signals:
|
||||
void help_requested (const QString &s);
|
||||
void search_requested (const QString &s);
|
||||
void search_requested (const QString &s, bool backward);
|
||||
void edit_trace (bool);
|
||||
|
||||
public slots:
|
||||
|
|
@ -314,6 +314,7 @@ private:
|
|||
void fill_completer_list ();
|
||||
void complete ();
|
||||
QTextCursor get_completer_cursor (int &pos0, int &pos);
|
||||
bool select_match_here ();
|
||||
void replace_in_selection (const QString &replace, bool first);
|
||||
|
||||
bool eventFilter (QObject *watched, QEvent *event);
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ MainWindow::init_menu ()
|
|||
}
|
||||
|
||||
// if not in editable mode, hide all entries from "edit_mode" group
|
||||
// TODO: later do this on each change of the view - each view might get it's own editable mode
|
||||
// TODO: later do this on each change of the view - each view might get its own editable mode
|
||||
bool view_mode = (lay::ApplicationBase::instance () && !lay::ApplicationBase::instance ()->is_editable ());
|
||||
|
||||
std::vector<std::string> edit_mode_grp = menu ()->group ("edit_mode");
|
||||
|
|
@ -742,7 +742,7 @@ MainWindow::about_to_exec ()
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: later, each view may get it's own editable flag
|
||||
// TODO: later, each view may get its own editable flag
|
||||
if (lay::ApplicationBase::instance () && !lay::ApplicationBase::instance ()->is_editable ()) {
|
||||
TipDialog td (this,
|
||||
tl::to_string (QObject::tr ("KLayout has been started in viewer mode. In this mode, editor functions are not available.\n\nTo enable these functions, start KLayout in editor mode by using the \"-e\" command line switch or select it as the default mode in the setup dialog. Choose \"Setup\" in the \"File\" menu and check \"Use editing mode by default\" on the \"Editing Mode\" page in the \"Application\" section.")),
|
||||
|
|
|
|||
|
|
@ -201,10 +201,10 @@ SaltController::install_packages (const std::vector<std::string> &packages, bool
|
|||
}
|
||||
|
||||
if (n.find ("http:") == 0 || n.find ("https:") == 0 || n.find ("file:") == 0 || n[0] == '/' || n[0] == '\\') {
|
||||
// it's a URL
|
||||
// its a URL
|
||||
manager.register_download (std::string (), std::string (), n, v);
|
||||
} else {
|
||||
// it's a plain name
|
||||
// its a plain name
|
||||
manager.register_download (n, std::string (), std::string (), v);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -580,7 +580,7 @@ SaltGrainPropertiesDialog::accept ()
|
|||
if (d->version.empty ()) {
|
||||
dependencies_alert->warn () << tr ("No version specified for dependency '%1'").arg (tl::to_qstring (d->name)) << tl::endl
|
||||
<< tr ("Please consider giving a version here. Versions help deciding whether a package needs to be updated.") << tl::endl
|
||||
<< tr ("If the dependency package has a version itself, the version is automatically set to it's current version.");
|
||||
<< tr ("If the dependency package has a version itself, the version is automatically set to its current version.");
|
||||
}
|
||||
|
||||
if (!d->url.empty ()) {
|
||||
|
|
|
|||
|
|
@ -609,6 +609,9 @@ TechnologyController::rescan (db::Technologies &technologies)
|
|||
for (std::vector<db::Technology>::const_iterator t = m_temp_tech.begin (); t != m_temp_tech.end (); ++t) {
|
||||
|
||||
db::Technology *tech = new db::Technology (*t);
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::info << "Registering special technology from " << tech->tech_file_path () << " as " << tech->name ();
|
||||
}
|
||||
tech->set_persisted (false); // don't save that one in the configuration
|
||||
tech->set_tech_file_path (std::string ()); // don't save to a file either
|
||||
tech->set_readonly (true); // don't edit
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ module PCellLibModule
|
|||
end
|
||||
|
||||
def coerce_parameters_impl
|
||||
# TODO: use x to access parameter x and set_x to modify it's value
|
||||
# TODO: use x to access parameter x and set_x to modify its value
|
||||
end
|
||||
|
||||
def produce_impl
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ class PCell(pya.PCellDeclarationHelper):
|
|||
return "TODO: create description"
|
||||
|
||||
def coerce_parameters_impl(self):
|
||||
# TODO: use x to access parameter x and set_x to modify it's value
|
||||
# TODO: use x to access parameter x and set_x to modify its value
|
||||
|
||||
def produce_impl(self):
|
||||
# TODO: produce the cell content
|
||||
# i.e. self.cell().shapes(self.l_layer).insert(pya.Polygon(...))
|
||||
# i.e. self.cell.shapes(self.l_layer).insert(pya.Polygon(...))
|
||||
|
||||
# optional:
|
||||
# def can_create_from_shape_impl(self):
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ module PCellPackageModule
|
|||
end
|
||||
|
||||
def coerce_parameters_impl
|
||||
# TODO: use x to access parameter x and set_x to modify it's value
|
||||
# TODO: use x to access parameter x and set_x to modify its value
|
||||
end
|
||||
|
||||
def produce_impl
|
||||
|
|
|
|||
|
|
@ -1241,7 +1241,7 @@ Class<lay::LayerPropertiesNode> decl_LayerPropertiesNode (
|
|||
"Each layer properties node object has a unique ID that is created \n"
|
||||
"when a new LayerPropertiesNode object is instantiated. The ID is\n"
|
||||
"copied when the object is copied. The ID can be used to identify the\n"
|
||||
"object irregardless of it's content.\n"
|
||||
"object irregardless of its content.\n"
|
||||
),
|
||||
"@brief A layer properties node structure\n"
|
||||
"\n"
|
||||
|
|
@ -1441,7 +1441,7 @@ Class<lay::LayerPropertiesConstIterator> decl_LayerPropertiesIterator (
|
|||
"@brief Returns the index of the child within the parent\n"
|
||||
"\n"
|
||||
"This method returns the index of that the properties node the iterator points to in the list\n"
|
||||
"of children of it's parent. If the element does not have a parent, the \n"
|
||||
"of children of its parent. If the element does not have a parent, the \n"
|
||||
"index of the element in the global list is returned.\n"
|
||||
),
|
||||
"@brief Layer properties iterator\n"
|
||||
|
|
|
|||
|
|
@ -1438,7 +1438,7 @@ LAYBASIC_PUBLIC Class<lay::LayoutViewBase> decl_LayoutViewBase ("lay", "LayoutVi
|
|||
"@brief Hierarchically iterates over the layers in the given layer list\n"
|
||||
"\n"
|
||||
"This version of this method allows specification of the layer list to be iterated over. "
|
||||
"The layer list is specified by it's index which is a value between 0 and \\num_layer_lists-1."
|
||||
"The layer list is specified by its index which is a value between 0 and \\num_layer_lists-1."
|
||||
"For details see the parameter-less version of this method.\n"
|
||||
"\n"
|
||||
"This method was introduced in version 0.25."
|
||||
|
|
@ -1666,7 +1666,7 @@ LAYBASIC_PUBLIC Class<lay::LayoutViewBase> decl_LayoutViewBase ("lay", "LayoutVi
|
|||
"\n"
|
||||
"If a file is loaded, this event is triggered.\n"
|
||||
"When this event is triggered, the file was already loaded and the new file is the new active cellview.\n"
|
||||
"Despite it's name, this event is also triggered if a layout object is loaded into the view.\n"
|
||||
"Despite its name, this event is also triggered if a layout object is loaded into the view.\n"
|
||||
"\n"
|
||||
"Before version 0.25 this event was based on the observer pattern obsolete now. The corresponding methods "
|
||||
"(add_file_open_observer/remove_file_open_observer) have been removed in 0.25.\n"
|
||||
|
|
@ -1683,7 +1683,7 @@ LAYBASIC_PUBLIC Class<lay::LayoutViewBase> decl_LayoutViewBase ("lay", "LayoutVi
|
|||
gsi::event ("on_layer_list_changed", static_cast<tl::event<int> (lay::LayoutViewBase::*)> (&lay::LayoutViewBase::layer_list_changed_event), gsi::arg ("flags"),
|
||||
"@brief An event indicating that the layer list has changed\n"
|
||||
"\n"
|
||||
"This event is triggered after the layer list has changed it's configuration.\n"
|
||||
"This event is triggered after the layer list has changed its configuration.\n"
|
||||
"The integer argument gives a hint about the nature of the changed:\n"
|
||||
"Bit 0 is set, if the properties (visibility, color etc.) of one or more layers have changed. Bit 1 is\n"
|
||||
"set if the hierarchy has changed. Bit 2 is set, if layer names have changed."
|
||||
|
|
@ -2239,7 +2239,7 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"\n"
|
||||
"This method will construct any path to this cell, not a \n"
|
||||
"particular one. It will clear the context path\n"
|
||||
"and update the context and target cell. Note that the cell is specified by it's index.\n"
|
||||
"and update the context and target cell. Note that the cell is specified by its index.\n"
|
||||
) +
|
||||
method ("cell_name=|set_cell_name", (void (lay::CellViewRef::*) (const std::string &)) &lay::CellViewRef::set_cell, gsi::arg ("cell_name"),
|
||||
"@brief Sets the cell by name\n"
|
||||
|
|
@ -2394,9 +2394,9 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"is addressed by an cell_index or a cell object reference.\n"
|
||||
"The layout pointer can be nil, indicating that the cell view is invalid.\n"
|
||||
"\n"
|
||||
"The cell is not only identified by it's index or object but also \n"
|
||||
"The cell is not only identified by its index or object but also \n"
|
||||
"by the path leading to that cell. This path indicates how to find the\n"
|
||||
"cell in the hierarchical context of it's parent cells. \n"
|
||||
"cell in the hierarchical context of its parent cells. \n"
|
||||
"\n"
|
||||
"The path is in fact composed of two parts: first in an unspecific fashion,\n"
|
||||
"just describing which parent cells are used. The target of this path\n"
|
||||
|
|
|
|||
|
|
@ -730,7 +730,7 @@ Class<gsi::PluginBase> decl_Plugin ("lay", "Plugin",
|
|||
callback ("config_finalize", &gsi::PluginBase::config_finalize, &gsi::PluginBase::f_config_finalize,
|
||||
"@brief Sends the post-configuration request to the plugin\n"
|
||||
"After all configuration parameters have been sent, 'config_finalize' is called to given the plugin a chance to "
|
||||
"update it's internal state according to the new configuration.\n"
|
||||
"update its internal state according to the new configuration.\n"
|
||||
) +
|
||||
callback ("key_event", &gsi::PluginBase::key_event, &gsi::PluginBase::f_key_event, gsi::arg ("key"), gsi::arg ("buttons"),
|
||||
"@brief Handles the key pressed event\n"
|
||||
|
|
@ -840,7 +840,7 @@ Class<gsi::PluginBase> decl_Plugin ("lay", "Plugin",
|
|||
),
|
||||
"@brief The plugin object\n"
|
||||
"\n"
|
||||
"This class provides the actual plugin implementation. Each view gets it's own instance of the plugin class. The plugin factory \\PluginFactory class "
|
||||
"This class provides the actual plugin implementation. Each view gets its own instance of the plugin class. The plugin factory \\PluginFactory class "
|
||||
"must be specialized to provide a factory for new objects of the Plugin class. See the documentation there for details about the plugin mechanism and "
|
||||
"the basic concepts.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -1532,7 +1532,7 @@ Recorder::eventFilter (QObject *object, QEvent *event)
|
|||
|
||||
if (event->type() == QEvent::MouseButtonPress) {
|
||||
|
||||
// send the test event to make the object print it's content
|
||||
// send the test event to make the object print its content
|
||||
QEvent event (QEvent::MaxUser);
|
||||
event.ignore ();
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace lay
|
|||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
// On MacOS, the main menu bar and it's decendent children
|
||||
// On MacOS, the main menu bar and its decendent children
|
||||
// can't be modified using "removeAction", followed by "addAction"
|
||||
// to achieve a move operation.If we try to do so, segmentation faults happen
|
||||
// in the timer event that presumably tries to merge the menu bar
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ void
|
|||
BitmapRenderer::clear ()
|
||||
{
|
||||
// this implementation is efficient but does not free memory -
|
||||
// the idea is to let the BitmapRenderer object manage it's workspace.
|
||||
// the idea is to let the BitmapRenderer object manage its workspace.
|
||||
m_edges.erase (m_edges.begin (), m_edges.end ());
|
||||
// might be manhattan
|
||||
m_ortho = true;
|
||||
|
|
@ -427,7 +427,7 @@ BitmapRenderer::draw (const db::Shape &shape, const db::CplxTrans &trans,
|
|||
db::Box bbox = shape.bbox ();
|
||||
double threshold = 1.0 / trans.mag ();
|
||||
|
||||
if (bbox.width () <= threshold && bbox.height () <= threshold) {
|
||||
if (bbox.width () <= threshold && bbox.height () <= threshold && !shape.is_point ()) {
|
||||
|
||||
db::DPoint dc = trans * bbox.center ();
|
||||
if (fill && ! shape.is_edge ()) {
|
||||
|
|
@ -440,7 +440,7 @@ BitmapRenderer::draw (const db::Shape &shape, const db::CplxTrans &trans,
|
|||
render_dot (dc.x (), dc.y (), vertices);
|
||||
}
|
||||
|
||||
} else if (shape.is_box ()) {
|
||||
} else if (shape.is_box () || shape.is_point ()) {
|
||||
|
||||
draw (bbox, trans, fill, frame, vertices, text);
|
||||
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
|||
match = true;
|
||||
}
|
||||
|
||||
} else if (shape->is_box () || shape->is_text ()) {
|
||||
} else if (shape->is_box () || shape->is_point () || shape->is_text ()) {
|
||||
|
||||
db::Box box = shape->bbox ();
|
||||
if (text_info () && shape->is_text ()) {
|
||||
|
|
|
|||
|
|
@ -5297,11 +5297,7 @@ LayoutViewBase::paste_interactive ()
|
|||
|
||||
std::unique_ptr<db::Transaction> trans (new db::Transaction (manager (), tl::to_string (tr ("Paste and move"))));
|
||||
|
||||
{
|
||||
// let the receivers sort out who is pasting what ..
|
||||
do_paste ();
|
||||
lay::Editables::paste ();
|
||||
}
|
||||
lay::Editables::paste ();
|
||||
|
||||
// temporarily close the transaction and pass to the move service for appending it's own
|
||||
// operations.
|
||||
|
|
@ -5314,6 +5310,12 @@ LayoutViewBase::paste_interactive ()
|
|||
|
||||
void
|
||||
LayoutViewBase::copy ()
|
||||
{
|
||||
copy_view_objects ();
|
||||
}
|
||||
|
||||
void
|
||||
LayoutViewBase::copy_view_objects ()
|
||||
{
|
||||
cancel_edits ();
|
||||
if (! lay::Editables::has_selection ()) {
|
||||
|
|
|
|||
|
|
@ -264,6 +264,13 @@ public:
|
|||
*/
|
||||
virtual void copy ();
|
||||
|
||||
/**
|
||||
* @brief Copies to clipboard (view objects only)
|
||||
*
|
||||
* This version does not look for copy sources in the tree views.
|
||||
*/
|
||||
void copy_view_objects ();
|
||||
|
||||
/**
|
||||
* @brief Cuts to clipboard
|
||||
*
|
||||
|
|
|
|||
|
|
@ -327,6 +327,10 @@ Plugin::~Plugin ()
|
|||
if (mp_parent) {
|
||||
mp_parent->unregister_plugin (this);
|
||||
}
|
||||
// remove us from the children's parent
|
||||
for (auto c = m_children.begin (); c != m_children.end (); ++c) {
|
||||
c->mp_parent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1059,7 +1059,7 @@ RedrawThreadWorker::any_shapes (db::cell_index_type cell_index, unsigned int lev
|
|||
int ret = false;
|
||||
|
||||
const db::Cell &cell = mp_layout->cell (cell_index);
|
||||
if (! cell.shapes (m_layer).begin (db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::Paths | db::ShapeIterator::Boxes, mp_prop_sel, m_inv_prop_sel).at_end ()) {
|
||||
if (! cell.shapes (m_layer).begin (db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::Paths | db::ShapeIterator::Boxes | db::ShapeIterator::Points, mp_prop_sel, m_inv_prop_sel).at_end ()) {
|
||||
ret = true;
|
||||
} else if (levels > 1) {
|
||||
for (db::Cell::child_cell_iterator cc = cell.begin_child_cells (); !cc.at_end () && !ret; ++cc) {
|
||||
|
|
@ -1624,7 +1624,7 @@ RedrawThreadWorker::draw_layer_wo_cache (int from_level, int to_level, db::cell_
|
|||
size_t current_quad_id = 0;
|
||||
size_t current_array_quad_id = 0;
|
||||
|
||||
db::ShapeIterator shape (shapes.begin_touching (*v, db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::Paths, mp_prop_sel, m_inv_prop_sel));
|
||||
db::ShapeIterator shape (shapes.begin_touching (*v, db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::Paths | db::ShapeIterator::Points, mp_prop_sel, m_inv_prop_sel));
|
||||
while (! shape.at_end ()) {
|
||||
|
||||
test_snapshot (update_snapshot);
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ Renderer::draw_propstring (const db::Shape &shape, const db::PropertiesRepositor
|
|||
dp = trans * (db::Point () + shape.text_trans ().disp ());
|
||||
} else if (shape.is_box ()) {
|
||||
dp = trans (shape.box ().p1 ());
|
||||
} else if (shape.is_point ()) {
|
||||
dp = trans (shape.point ());
|
||||
} else if (shape.is_polygon ()) {
|
||||
db::Shape::polygon_edge_iterator e = shape.begin_edge ();
|
||||
dp = trans ((*e).p1 ());
|
||||
|
|
|
|||
|
|
@ -598,7 +598,7 @@ private:
|
|||
|
||||
const db::Shapes &shapes = cell.shapes (l);
|
||||
|
||||
db::ShapeIterator shape = shapes.begin_touching (touch_box, db::ShapeIterator::Polygons | db::ShapeIterator::Paths | db::ShapeIterator::Boxes, mp_prop_sel, m_inv_prop_sel);
|
||||
db::ShapeIterator shape = shapes.begin_touching (touch_box, db::ShapeIterator::Polygons | db::ShapeIterator::Paths | db::ShapeIterator::Boxes | db::ShapeIterator::Points, mp_prop_sel, m_inv_prop_sel);
|
||||
while (! shape.at_end () && m_tests > 0) {
|
||||
|
||||
--m_tests;
|
||||
|
|
@ -653,6 +653,12 @@ private:
|
|||
test_edge (t * db::Edge (box.p2 (), db::Point (box.right (), box.bottom ())));
|
||||
test_edge (t * db::Edge (db::Point (box.right (), box.bottom ()), box.p1 ()));
|
||||
|
||||
} else if (shape->is_point ()) {
|
||||
|
||||
const db::Point &p = shape->point ();
|
||||
|
||||
test_edge (t * db::Edge (p, p));
|
||||
|
||||
}
|
||||
|
||||
++shape;
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@
|
|||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>If this option is selected, the subcircuits parts of a net are represented by individual cells. Otherwise the net with it's subcircuit parts is exported as a whole (flattened).</string>
|
||||
<string>If this option is selected, the subcircuits parts of a net are represented by individual cells. Otherwise the net with its subcircuit parts is exported as a whole (flattened).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ Class<BrowserDialog_Stub> decl_BrowserDialog (QT_EXTERNAL_BASE (QDialog) "lay",
|
|||
"The browser dialog displays HTML code in a browser panel. The HTML code is delivered through a separate "
|
||||
"object of class \\BrowserSource which acts as a \"server\" for a specific kind of URL scheme. Whenever the "
|
||||
"browser sees a URL starting with \"int:\" it will ask the connected BrowserSource object for the HTML code "
|
||||
"of that page using it's 'get' method. The task of the BrowserSource object is to format the data requested "
|
||||
"of that page using its 'get' method. The task of the BrowserSource object is to format the data requested "
|
||||
"in HTML and deliver it.\n"
|
||||
"\n"
|
||||
"One use case for that class is the implementation of rich data browsers for structured information. In a "
|
||||
|
|
@ -699,7 +699,7 @@ Class<InputDialog> decl_InputDialog ("lay", "InputDialog",
|
|||
"@param title The title to display for the dialog\n"
|
||||
"@param label The label text to display for the dialog\n"
|
||||
"@param value The initial value for the input field\n"
|
||||
"@return A \\StringValue object with has_value? set to true, if \"Ok\" was pressed and the value given in it's value attribute\n"
|
||||
"@return A \\StringValue object with has_value? set to true, if \"Ok\" was pressed and the value given in its value attribute\n"
|
||||
"Starting from 0.22, this method is deprecated and it is recommended to use the ask_... equivalent."
|
||||
) +
|
||||
gsi::method ("#get_item", &get_item, gsi::arg ("title"), gsi::arg ("label"), gsi::arg ("items"), gsi::arg ("value"),
|
||||
|
|
@ -708,7 +708,7 @@ Class<InputDialog> decl_InputDialog ("lay", "InputDialog",
|
|||
"@param label The label text to display for the dialog\n"
|
||||
"@param items The list of items to show in the selection element\n"
|
||||
"@param selection The initial selection (index of the element selected initially)\n"
|
||||
"@return A \\StringValue object with has_value? set to true, if \"Ok\" was pressed and the value given in it's value attribute\n"
|
||||
"@return A \\StringValue object with has_value? set to true, if \"Ok\" was pressed and the value given in its value attribute\n"
|
||||
"Starting from 0.22, this method is deprecated and it is recommended to use the ask_... equivalent."
|
||||
) +
|
||||
gsi::method ("#get_string_password", &get_string_password, gsi::arg ("title"), gsi::arg ("label"), gsi::arg ("value"),
|
||||
|
|
@ -716,7 +716,7 @@ Class<InputDialog> decl_InputDialog ("lay", "InputDialog",
|
|||
"@param title The title to display for the dialog\n"
|
||||
"@param label The label text to display for the dialog\n"
|
||||
"@param value The initial value for the input field\n"
|
||||
"@return A \\StringValue object with has_value? set to true, if \"Ok\" was pressed and the value given in it's value attribute\n"
|
||||
"@return A \\StringValue object with has_value? set to true, if \"Ok\" was pressed and the value given in its value attribute\n"
|
||||
"Starting from 0.22, this method is deprecated and it is recommended to use the ask_... equivalent."
|
||||
) +
|
||||
gsi::method ("#get_double", &get_double, gsi::arg ("title"), gsi::arg ("label"), gsi::arg ("value"), gsi::arg ("digits"),
|
||||
|
|
@ -725,7 +725,7 @@ Class<InputDialog> decl_InputDialog ("lay", "InputDialog",
|
|||
"@param label The label text to display for the dialog\n"
|
||||
"@param value The initial value for the input field\n"
|
||||
"@param digits The number of digits allowed\n"
|
||||
"@return A \\DoubleValue object with has_value? set to true, if \"Ok\" was pressed and the value given in it's value attribute\n"
|
||||
"@return A \\DoubleValue object with has_value? set to true, if \"Ok\" was pressed and the value given in its value attribute\n"
|
||||
"Starting from 0.22, this method is deprecated and it is recommended to use the ask_... equivalent."
|
||||
) +
|
||||
gsi::method ("#get_double_ex", &get_double_ex, gsi::arg ("title"), gsi::arg ("label"), gsi::arg ("value"), gsi::arg ("min"), gsi::arg ("max"), gsi::arg ("digits"),
|
||||
|
|
@ -736,7 +736,7 @@ Class<InputDialog> decl_InputDialog ("lay", "InputDialog",
|
|||
"@param min The minimum value allowed\n"
|
||||
"@param max The maximum value allowed\n"
|
||||
"@param digits The number of digits allowed\n"
|
||||
"@return A \\DoubleValue object with has_value? set to true, if \"Ok\" was pressed and the value given in it's value attribute\n"
|
||||
"@return A \\DoubleValue object with has_value? set to true, if \"Ok\" was pressed and the value given in its value attribute\n"
|
||||
"Starting from 0.22, this method is deprecated and it is recommended to use the ask_... equivalent."
|
||||
) +
|
||||
gsi::method ("#get_int", &get_int, gsi::arg ("title"), gsi::arg ("label"), gsi::arg ("value"),
|
||||
|
|
@ -744,7 +744,7 @@ Class<InputDialog> decl_InputDialog ("lay", "InputDialog",
|
|||
"@param title The title to display for the dialog\n"
|
||||
"@param label The label text to display for the dialog\n"
|
||||
"@param value The initial value for the input field\n"
|
||||
"@return A \\IntValue object with has_value? set to true, if \"Ok\" was pressed and the value given in it's value attribute\n"
|
||||
"@return A \\IntValue object with has_value? set to true, if \"Ok\" was pressed and the value given in its value attribute\n"
|
||||
"Starting from 0.22, this method is deprecated and it is recommended to use the ask_... equivalent."
|
||||
) +
|
||||
gsi::method ("#get_int_ex", &get_int_ex, gsi::arg ("title"), gsi::arg ("label"), gsi::arg ("value"), gsi::arg ("min"), gsi::arg ("max"), gsi::arg ("step"),
|
||||
|
|
@ -755,7 +755,7 @@ Class<InputDialog> decl_InputDialog ("lay", "InputDialog",
|
|||
"@param min The minimum value allowed\n"
|
||||
"@param max The maximum value allowed\n"
|
||||
"@param step The step size for the spin buttons\n"
|
||||
"@return A \\IntValue object with has_value? set to true, if \"Ok\" was pressed and the value given in it's value attribute\n"
|
||||
"@return A \\IntValue object with has_value? set to true, if \"Ok\" was pressed and the value given in its value attribute\n"
|
||||
"Starting from 0.22, this method is deprecated and it is recommended to use the ask_... equivalent."
|
||||
) +
|
||||
gsi::method ("ask_string", &ask_string, gsi::arg ("title"), gsi::arg ("label"), gsi::arg ("value"),
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ HCPCellTreeWidget::HCPCellTreeWidget (QWidget *parent, const char *name, QWidget
|
|||
HCPCellTreeWidget::~HCPCellTreeWidget ()
|
||||
{
|
||||
// NOTE: this should not be required, but I got a strange crash on closing the app with Qt 5.12.8
|
||||
// after using changePersistentIndex inside the model when ~QTreeWidget tried to clean up it's
|
||||
// after using changePersistentIndex inside the model when ~QTreeWidget tried to clean up its
|
||||
// persistent indexes and only found a model which was deleted already.
|
||||
QAbstractItemModel *m = model ();
|
||||
if (m) {
|
||||
|
|
|
|||
|
|
@ -735,7 +735,7 @@ void
|
|||
LayoutViewFunctions::cm_cell_cut ()
|
||||
{
|
||||
if (view ()->hierarchy_panel ()) {
|
||||
// TODO: currently the hierarchy panel's cut function does it's own transaction handling.
|
||||
// TODO: currently the hierarchy panel's cut function does its own transaction handling.
|
||||
// Otherwise the cut function is not working propertly.
|
||||
view ()->hierarchy_panel ()->cut ();
|
||||
}
|
||||
|
|
@ -1177,7 +1177,7 @@ LayoutViewFunctions::do_cm_duplicate (bool interactive)
|
|||
db::Clipboard::instance ().swap (saved_clipboard);
|
||||
|
||||
try {
|
||||
view ()->copy ();
|
||||
view ()->copy_view_objects ();
|
||||
view ()->clear_selection ();
|
||||
view ()->cancel ();
|
||||
if (interactive) {
|
||||
|
|
@ -1873,12 +1873,12 @@ LayoutViewFunctions::cm_edit_layer ()
|
|||
{
|
||||
lay::LayerPropertiesConstIterator sel = view ()->current_layer ();
|
||||
if (sel.is_null ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("No layer selected for editing it's properties")));
|
||||
throw tl::Exception (tl::to_string (tr ("No layer selected for editing its properties")));
|
||||
}
|
||||
|
||||
int index = sel->cellview_index ();
|
||||
if (sel->has_children () || index < 0 || int (view ()->cellviews ()) <= index || sel->layer_index () < 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("No valid layer selected for editing it's properties")));
|
||||
throw tl::Exception (tl::to_string (tr ("No valid layer selected for editing its properties")));
|
||||
}
|
||||
|
||||
const lay::CellView &cv = view ()->cellview (index);
|
||||
|
|
|
|||
|
|
@ -1356,7 +1356,7 @@ void
|
|||
LayoutView::cut ()
|
||||
{
|
||||
if (mp_hierarchy_panel && mp_hierarchy_panel->has_focus ()) {
|
||||
// TODO: currently the hierarchy panel's cut function does it's own transaction handling.
|
||||
// TODO: currently the hierarchy panel's cut function does its own transaction handling.
|
||||
// Otherwise the cut function is not working propertly.
|
||||
mp_hierarchy_panel->cut ();
|
||||
} else if (mp_control_panel && mp_control_panel->has_focus ()) {
|
||||
|
|
|
|||
|
|
@ -328,11 +328,11 @@ gsi::ClassExt<db::LoadLayoutOptions> dxf_reader_options (
|
|||
"This method has been added in version 0.25.3."
|
||||
) +
|
||||
gsi::method_ext ("dxf_keep_other_cells=", &set_dxf_keep_other_cells, gsi::arg ("value"),
|
||||
"@brief If this option is set to true, all cells are kept, not only the top cell and it's children\n"
|
||||
"@brief If this option is set to true, all cells are kept, not only the top cell and its children\n"
|
||||
"\nThis property has been added in version 0.21.15.\n"
|
||||
) +
|
||||
gsi::method_ext ("dxf_keep_other_cells?|#dxf_keep_other_cells", &get_dxf_keep_other_cells,
|
||||
"@brief If this option is true, all cells are kept, not only the top cell and it's children\n"
|
||||
"@brief If this option is true, all cells are kept, not only the top cell and its children\n"
|
||||
"\nThis property has been added in version 0.21.15.\n"
|
||||
) +
|
||||
gsi::method_ext ("dxf_polyline_mode=", &set_dxf_polyline_mode, gsi::arg ("mode"),
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@
|
|||
<item row="6" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="keep_other_cells_cbx">
|
||||
<property name="text">
|
||||
<string>Check this box to keep all cells, not only the top cell and it's children</string>
|
||||
<string>Check this box to keep all cells, not only the top cell and its children</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -37,14 +37,29 @@ namespace db
|
|||
// -----------------------------------------------------------------------------------
|
||||
// Path resolution utility
|
||||
|
||||
std::string correct_path (const std::string &fn, const db::Layout &layout, const std::string &base_path)
|
||||
std::string correct_path (const std::string &fn_in, const db::Layout &layout, const std::string &base_path)
|
||||
{
|
||||
const db::Technology *tech = layout.technology ();
|
||||
|
||||
// Allow LEF reference through expressions, i.e.
|
||||
// $(base_path) - path of the main file
|
||||
// $(tech_dir) - the location of the .lyt file if a technology is specified
|
||||
// $(tech_name) - the name of the technology if one is specified
|
||||
// In addition expressions are interpolated, e.g. "$(env('HOME'))".
|
||||
|
||||
tl::Eval expr;
|
||||
expr.set_var ("base_path", base_path);
|
||||
if (tech) {
|
||||
expr.set_var ("tech_dir", tech->base_path ());
|
||||
expr.set_var ("tech_name", tech->name ());
|
||||
}
|
||||
|
||||
std::string fn = expr.interpolate (fn_in);
|
||||
|
||||
if (! tl::is_absolute (fn)) {
|
||||
|
||||
// if a technology is given and the file can be found in the technology's base path, take it
|
||||
// from there.
|
||||
const db::Technology *tech = layout.technology ();
|
||||
|
||||
if (tech && ! tech->base_path ().empty ()) {
|
||||
std::string new_fn = tl::combine_path (tech->base_path (), fn);
|
||||
if (tl::file_exists (new_fn)) {
|
||||
|
|
@ -878,16 +893,18 @@ LEFDEFReaderOptions::special_routing_datatype_str () const
|
|||
LEFDEFReaderState::LEFDEFReaderState (const LEFDEFReaderOptions *tc, db::Layout &layout, const std::string &base_path)
|
||||
: mp_importer (0), m_create_layers (true), m_has_explicit_layer_mapping (false), m_laynum (1), mp_tech_comp (tc)
|
||||
{
|
||||
if (! tc->map_file ().empty ()) {
|
||||
if (! tc) {
|
||||
|
||||
// use default options
|
||||
|
||||
} else if (! tc->map_file ().empty ()) {
|
||||
|
||||
read_map_file (tc->map_file (), layout, base_path);
|
||||
|
||||
} else {
|
||||
|
||||
if (tc) {
|
||||
m_layer_map = tc->layer_map ();
|
||||
m_create_layers = tc->read_all_layers ();
|
||||
}
|
||||
m_layer_map = tc->layer_map ();
|
||||
m_create_layers = tc->read_all_layers ();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -992,7 +1009,6 @@ LEFDEFReaderState::read_map_file (const std::string &filename, db::Layout &layou
|
|||
|
||||
// build an explicit layer mapping now.
|
||||
|
||||
tl_assert (m_has_explicit_layer_mapping);
|
||||
m_layers.clear ();
|
||||
m_layer_map.clear ();
|
||||
|
||||
|
|
@ -1015,9 +1031,12 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
|
|||
|
||||
tl::log << tl::to_string (tr ("Reading LEF/DEF map file")) << " " << file_stream.absolute_path ();
|
||||
|
||||
// Purpose name to purpose code
|
||||
std::map<std::string, LayerPurpose> purpose_translation;
|
||||
purpose_translation ["LEFPIN"] = LEFPins;
|
||||
purpose_translation ["PIN"] = Pins;
|
||||
purpose_translation ["LEFPINNAME"] = LEFLabel;
|
||||
purpose_translation ["PINNAME"] = Label;
|
||||
purpose_translation ["FILL"] = Fills;
|
||||
purpose_translation ["FILLOPC"] = FillsOPC;
|
||||
purpose_translation ["LEFOBS"] = Obstructions;
|
||||
|
|
@ -1027,6 +1046,11 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
|
|||
purpose_translation ["BLOCKAGE"] = Blockage;
|
||||
purpose_translation ["ALL"] = All;
|
||||
|
||||
// List of purposes corresponding to ALL
|
||||
LayerPurpose all_purposes[] = {
|
||||
LEFPins, Pins, Fills, FillsOPC, Obstructions, SpecialRouting, Routing, ViaGeometry
|
||||
};
|
||||
|
||||
while (! ts.at_end ()) {
|
||||
|
||||
const std::string &l = ts.get_line ();
|
||||
|
|
@ -1214,10 +1238,8 @@ LEFDEFReaderState::read_single_map_file (const std::string &path, std::map<std::
|
|||
|
||||
} else if (i->second == All) {
|
||||
|
||||
for (std::map<std::string, LayerPurpose>::const_iterator p = purpose_translation.begin (); p != purpose_translation.end (); ++p) {
|
||||
if (p->second != All && p->second != Blockage) {
|
||||
translated_purposes.insert (LayerDetailsKey (p->second, mask, via_size));
|
||||
}
|
||||
for (LayerPurpose *p = all_purposes; p != all_purposes + sizeof (all_purposes) / sizeof (all_purposes[0]); ++p) {
|
||||
translated_purposes.insert (LayerDetailsKey (*p, mask, via_size));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -540,6 +540,10 @@ TEST(111_mapfile)
|
|||
options.set_map_file ("test.map");
|
||||
|
||||
run_test (_this, "mapfile", "read:in.def", "au.oas.gz", options, false);
|
||||
|
||||
options.set_map_file ("test-nonames.map");
|
||||
|
||||
run_test (_this, "mapfile", "read:in.def", "au.oas.gz", options, false);
|
||||
}
|
||||
|
||||
TEST(112_via_properties)
|
||||
|
|
|
|||
|
|
@ -456,24 +456,27 @@ public:
|
|||
|
||||
std::string name = mt->name (mid);
|
||||
|
||||
// does this method hide a property? -> append "_" in that case
|
||||
std::pair<bool, size_t> t = mt->find_property (mt->is_static (mid), name);
|
||||
if (t.first) {
|
||||
name += "_";
|
||||
}
|
||||
|
||||
// needs static/non-static disambiguation?
|
||||
t = mt->find_method (! mt->is_static (mid), name);
|
||||
std::pair<bool, size_t> t = mt->find_method (! mt->is_static (mid), name);
|
||||
if (t.first) {
|
||||
|
||||
disambiguated_names.push_back (name);
|
||||
if (mt->is_static (mid)) {
|
||||
name = "_class_" + name;
|
||||
mp_module->add_python_doc (*cls, mt, int (mid), tl::sprintf (tl::to_string (tr ("This class method is available as '%s' in Python")), name));
|
||||
} else {
|
||||
name = "_inst_" + name;
|
||||
mp_module->add_python_doc (*cls, mt, int (mid), tl::sprintf (tl::to_string (tr ("This instance method is available as '%s' in Python")), name));
|
||||
}
|
||||
|
||||
mp_module->add_python_doc (*cls, mt, int (mid), tl::sprintf (tl::to_string (tr ("This attribute is available as '%s' in Python")), name));
|
||||
} else {
|
||||
|
||||
// does this method hide a property? -> append "_" in that case
|
||||
t = mt->find_property (mt->is_static (mid), name);
|
||||
if (t.first) {
|
||||
name += "_";
|
||||
mp_module->add_python_doc (*cls, mt, int (mid), tl::sprintf (tl::to_string (tr ("This method is available as '%s' in Python to distiguish it from the property with the same name")), name));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,17 +44,19 @@ void check_error ()
|
|||
{
|
||||
PyObject *py_exc_type = NULL, *py_exc_value = NULL, *py_exc_traceback = NULL;
|
||||
PyErr_Fetch (&py_exc_type, &py_exc_value, &py_exc_traceback);
|
||||
PythonRef exc_type (py_exc_type);
|
||||
PythonRef exc_value (py_exc_value);
|
||||
PythonRef exc_traceback (py_exc_traceback);
|
||||
if (py_exc_type != NULL) {
|
||||
|
||||
std::string exc_cls ("unknown");
|
||||
const char *c = ((PyTypeObject *) exc_type.get ())->tp_name;
|
||||
if (c) {
|
||||
exc_cls = c;
|
||||
}
|
||||
PyErr_NormalizeException (&py_exc_type, &py_exc_value, &py_exc_traceback);
|
||||
|
||||
if (exc_type) {
|
||||
PythonRef exc_type (py_exc_type);
|
||||
PythonRef exc_value (py_exc_value);
|
||||
PythonRef exc_traceback (py_exc_traceback);
|
||||
|
||||
std::string exc_cls ("unknown");
|
||||
const char *c = ((PyTypeObject *) exc_type.get ())->tp_name;
|
||||
if (c) {
|
||||
exc_cls = c;
|
||||
}
|
||||
|
||||
// fetch traceback
|
||||
// TODO: really decref the stack trace? how about the other objects in the stack trace?
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ TEST (basic)
|
|||
try {
|
||||
pya::PythonInterpreter::instance ()->eval_string ("raise Exception(\"an error\")");
|
||||
} catch (tl::ScriptError &ex) {
|
||||
EXPECT_EQ (ex.basic_msg (), std::string ("an error"));
|
||||
EXPECT_EQ (ex.basic_msg (), std::string ("Exception: an error"));
|
||||
EXPECT_EQ (ex.cls () == std::string ("exceptions.Exception") || ex.cls () == std::string ("Exception"), true);
|
||||
err = true;
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ TEST (basic)
|
|||
try {
|
||||
pya::PythonInterpreter::instance ()->eval_string ("Quatsch");
|
||||
} catch (tl::ScriptError &ex) {
|
||||
EXPECT_EQ (ex.basic_msg (), std::string ("name 'Quatsch' is not defined"));
|
||||
EXPECT_EQ (ex.basic_msg (), std::string ("NameError: name 'Quatsch' is not defined"));
|
||||
EXPECT_EQ (ex.cls () == std::string ("exceptions.NameError") || ex.cls () == std::string ("NameError"), true);
|
||||
err = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ TEST (basic)
|
|||
try {
|
||||
rba::RubyInterpreter::instance ()->eval_string ("raise \"an error\"");
|
||||
} catch (tl::Exception &ex) {
|
||||
EXPECT_EQ (std::string (ex.msg (), 0, 8), std::string ("an error"));
|
||||
EXPECT_EQ (std::string (ex.msg (), 0, 22), std::string ("RuntimeError: an error"));
|
||||
err = true;
|
||||
}
|
||||
|
||||
|
|
@ -56,8 +56,8 @@ TEST (basic)
|
|||
try {
|
||||
rba::RubyInterpreter::instance ()->eval_string ("Quatsch");
|
||||
} catch (tl::Exception &ex) {
|
||||
EXPECT_EQ (std::string (ex.msg (), 0, 30) == std::string ("uninitialized constant Quatsch") ||
|
||||
std::string (ex.msg (), 0, 38) == std::string ("uninitialized constant Object::Quatsch"),
|
||||
EXPECT_EQ (std::string (ex.msg (), 0, 41) == std::string ("NameError: uninitialized constant Quatsch") ||
|
||||
std::string (ex.msg (), 0, 49) == std::string ("NameError: uninitialized constant Object::Quatsch"),
|
||||
true);
|
||||
err = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ Class<rdb::Cell> decl_RdbCell ("rdb", "RdbCell",
|
|||
"@brief Gets the cell name\n"
|
||||
"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 it's variants. The \"qualified name\" contains both the cell name and the variant name. "
|
||||
"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. "
|
||||
"@return The cell name\n"
|
||||
) +
|
||||
|
|
@ -347,7 +347,7 @@ Class<rdb::Category> decl_RdbCategory ("rdb", "RdbCategory",
|
|||
) +
|
||||
gsi::method_ext ("scan_layer", &scan_layer, gsi::arg ("layout"), gsi::arg ("layer"), gsi::arg ("cell", (const db::Cell *) 0, "nil"), gsi::arg ("levels", -1), gsi::arg ("with_properties", true),
|
||||
"@brief Scans a layer from a layout into this category, starting with a given cell and a depth specification\n"
|
||||
"Creates RDB items for each polygon or edge shape read from the cell and it's children in the layout on the given layer and puts them into this category.\n"
|
||||
"Creates RDB items for each polygon or edge shape read from the cell and its children in the layout on the given layer and puts them into this category.\n"
|
||||
"New cells will be generated when required.\n"
|
||||
"\"levels\" is the number of hierarchy levels to take the child cells from. 0 means to use only \"cell\" and don't descend, -1 means \"all levels\".\n"
|
||||
"Other settings like database unit, description, top cell etc. are not made in the RDB.\n"
|
||||
|
|
@ -1031,7 +1031,7 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
|
|||
) +
|
||||
gsi::method ("description", &rdb::Database::description,
|
||||
"@brief Gets the databases description\n"
|
||||
"The description is a general purpose string that is supposed to further describe the database and it's content "
|
||||
"The description is a general purpose string that is supposed to further describe the database and its content "
|
||||
"in a human-readable form.\n"
|
||||
"@return The description string\n"
|
||||
) +
|
||||
|
|
|
|||
|
|
@ -79,14 +79,30 @@ BacktraceElement::to_string() const
|
|||
// -------------------------------------------------------------------
|
||||
// ScriptError implementation
|
||||
|
||||
static std::string make_basic_msg (const char *text, const char *cls)
|
||||
{
|
||||
std::string msg;
|
||||
if (*cls) {
|
||||
msg = cls;
|
||||
}
|
||||
if (*cls && *text) {
|
||||
msg += ": ";
|
||||
}
|
||||
if (*text) {
|
||||
msg += text;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
ScriptError::ScriptError (const char *msg, const char *cls, const std::vector<BacktraceElement> &backtrace)
|
||||
: tl::Exception (msg), m_line (-1), m_cls (cls), m_backtrace (backtrace)
|
||||
: tl::Exception (make_basic_msg (msg, cls)), m_line (-1), m_cls (cls), m_backtrace (backtrace)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ScriptError::ScriptError (const char *msg, const char *sourcefile, int line, const char *cls, const std::vector<BacktraceElement> &backtrace)
|
||||
: tl::Exception (msg), m_sourcefile (sourcefile), m_line (line), m_cls (cls), m_backtrace (backtrace)
|
||||
: tl::Exception (make_basic_msg (msg, cls)), m_sourcefile (sourcefile), m_line (line), m_cls (cls), m_backtrace (backtrace)
|
||||
{
|
||||
translate_includes ();
|
||||
}
|
||||
|
|
@ -103,8 +119,8 @@ ScriptError::msg () const
|
|||
std::string m = basic_msg ();
|
||||
|
||||
if (! m_context.empty ()) {
|
||||
m += tl::to_string (tr (" in ")) + m_context;
|
||||
}
|
||||
m += tl::to_string (tr (" in ")) + m_context;
|
||||
}
|
||||
|
||||
for (std::vector<BacktraceElement>::const_iterator bt = backtrace ().begin (); bt != backtrace ().end (); ++bt) {
|
||||
m += "\n ";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
lyin = layout($drc_test_source)
|
||||
cn = lyin.layout.top_cell.name
|
||||
|
||||
lyin2 = layout($drc_test_source)
|
||||
|
||||
target($drc_test_target, cn)
|
||||
|
||||
l1 = lyin.input(1, 0)
|
||||
l2 = lyin2.input(2, 0)
|
||||
|
||||
tcopy = new_target($drc_test_target2, cn)
|
||||
rcopy = new_report("Report 2", $drc_test_report2, cn)
|
||||
|
||||
l1.output(tcopy, 101, 0)
|
||||
l2.output(tcopy, 102, 0)
|
||||
|
||||
l1.output(1, 0)
|
||||
l1.space(1.0.um).output(100, 0)
|
||||
|
||||
report("Report 1", $drc_test_report, cn)
|
||||
|
||||
l2.space(1.0.um).output("l2 space < 1µm")
|
||||
l1.width(1.0.um).output("l1 width < 1µm")
|
||||
|
||||
l1.sep(l2, 1.0.um).output(rcopy, "l1 sep l2 < 1µm")
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
DIEAREA ALL 100 0
|
||||
M0PO LEFPIN,LEFOBS,PIN,NET,SPNET,VIA 10 0
|
||||
VIA0 LEFPIN,LEFOBS,VIA,PIN,NET,SPNET 11 0
|
||||
M1 LEFPIN 12 0
|
||||
M1 LEFOBS 12 1
|
||||
M1 PIN 12 2
|
||||
M1 NET 12 3
|
||||
M1 SPNET 12 4
|
||||
M1 VIA 12 5
|
||||
M1 FILLOPC 12 100
|
||||
M1 FILLOPC:MASK:1 12 101
|
||||
M1 FILLOPC:MASK:2 12 102
|
||||
M1 BLOCKAGEFILL 12 150
|
||||
M1 BLOCKAGE 12 151
|
||||
M1 FILL 12 152
|
||||
M1 PINNAME 12 10
|
||||
M1 LEFPINNAME 12 10
|
||||
VIA1 LEFPIN,LEFOBS,VIA,PIN,NET,SPNET 13 0
|
||||
M2 LEFPIN,LEFOBS,PIN,NET,SPNET,VIA 14 0
|
||||
Loading…
Reference in New Issue