mirror of https://github.com/KLayout/klayout.git
WIP: first steps for making technology a db component.
This commit is contained in:
parent
6bc1537bea
commit
c360f6d4a7
|
|
@ -11,7 +11,6 @@ SOURCES = \
|
|||
dbBox.cc \
|
||||
dbBoxConvert.cc \
|
||||
dbBoxScanner.cc \
|
||||
dbCommonReader.cc \
|
||||
dbCell.cc \
|
||||
dbCellGraphUtils.cc \
|
||||
dbCellHullGenerator.cc \
|
||||
|
|
@ -20,6 +19,7 @@ SOURCES = \
|
|||
dbClipboard.cc \
|
||||
dbClipboardData.cc \
|
||||
dbClip.cc \
|
||||
dbCommonReader.cc \
|
||||
dbEdge.cc \
|
||||
dbEdgePair.cc \
|
||||
dbEdgePairRelations.cc \
|
||||
|
|
@ -70,6 +70,7 @@ SOURCES = \
|
|||
dbStatic.cc \
|
||||
dbStream.cc \
|
||||
dbStreamLayers.cc \
|
||||
dbTechnology.cc \
|
||||
dbTestSupport.cc \
|
||||
dbText.cc \
|
||||
dbTextWriter.cc \
|
||||
|
|
@ -79,9 +80,16 @@ SOURCES = \
|
|||
dbVector.cc \
|
||||
dbWriter.cc \
|
||||
dbWriterTools.cc \
|
||||
dbVariableWidthPath.cc \
|
||||
dbNamedLayerReader.cc \
|
||||
dbEdgesToContours.cc \
|
||||
dbForceLink.cc \
|
||||
dbPlugin.cc \
|
||||
dbInit.cc \
|
||||
gsiDeclDbBox.cc \
|
||||
gsiDeclDbCell.cc \
|
||||
gsiDeclDbCellMapping.cc \
|
||||
gsiDeclDbCommonStreamOptions.cc \
|
||||
gsiDeclDbEdge.cc \
|
||||
gsiDeclDbEdgePair.cc \
|
||||
gsiDeclDbEdgePairs.cc \
|
||||
|
|
@ -104,18 +112,13 @@ SOURCES = \
|
|||
gsiDeclDbShape.cc \
|
||||
gsiDeclDbShapeProcessor.cc \
|
||||
gsiDeclDbShapes.cc \
|
||||
gsiDeclDbTechnologies.cc \
|
||||
gsiDeclDbText.cc \
|
||||
gsiDeclDbTilingProcessor.cc \
|
||||
gsiDeclDbTrans.cc \
|
||||
gsiDeclDbVector.cc \
|
||||
gsiDeclDbLayoutDiff.cc \
|
||||
gsiDeclDbGlyphs.cc \
|
||||
dbVariableWidthPath.cc \
|
||||
dbNamedLayerReader.cc \
|
||||
dbEdgesToContours.cc \
|
||||
dbForceLink.cc \
|
||||
dbPlugin.cc \
|
||||
dbInit.cc
|
||||
|
||||
HEADERS = \
|
||||
dbArray.h \
|
||||
|
|
@ -131,6 +134,7 @@ HEADERS = \
|
|||
dbClipboardData.h \
|
||||
dbClipboard.h \
|
||||
dbClip.h \
|
||||
dbCommonReader.h \
|
||||
dbEdge.h \
|
||||
dbEdgePair.h \
|
||||
dbEdgePairRelations.h \
|
||||
|
|
@ -186,6 +190,7 @@ HEADERS = \
|
|||
dbStream.h \
|
||||
dbStreamLayers.h \
|
||||
dbTestSupport.h \
|
||||
dbTechnology.h \
|
||||
dbText.h \
|
||||
dbTextWriter.h \
|
||||
dbTilingProcessor.h \
|
||||
|
|
@ -195,14 +200,13 @@ HEADERS = \
|
|||
dbVector.h \
|
||||
dbWriter.h \
|
||||
dbWriterTools.h \
|
||||
dbCommonReader.h \
|
||||
dbGlyphs.h \
|
||||
dbCommon.h \
|
||||
dbVariableWidthPath.h \
|
||||
dbNamedLayerReader.h \
|
||||
dbForceLink.h \
|
||||
dbPlugin.h \
|
||||
dbInit.h
|
||||
dbGlyphs.h \
|
||||
dbCommon.h \
|
||||
dbVariableWidthPath.h \
|
||||
dbNamedLayerReader.h \
|
||||
dbForceLink.h \
|
||||
dbPlugin.h \
|
||||
dbInit.h
|
||||
|
||||
RESOURCES = \
|
||||
dbResources.qrc
|
||||
|
|
|
|||
|
|
@ -73,6 +73,16 @@ public:
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_reader_options_element () const
|
||||
{
|
||||
return new db::ReaderOptionsXMLElement<db::CommonReaderOptions> ("common",
|
||||
tl::make_member (&db::CommonReaderOptions::create_other_layers, "create-other-layers") +
|
||||
tl::make_member (&db::CommonReaderOptions::layer_map, "layer-map") +
|
||||
tl::make_member (&db::CommonReaderOptions::enable_properties, "enable-properties") +
|
||||
tl::make_member (&db::CommonReaderOptions::enable_text_objects, "enable-text-objects")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::StreamFormatDeclaration> reader_decl (new CommonFormatDeclaration (), 20, "Common");
|
||||
|
|
|
|||
|
|
@ -34,7 +34,44 @@ namespace tl
|
|||
|
||||
namespace db
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Implementation of load_options_xml_element_list
|
||||
|
||||
tl::XMLElementList load_options_xml_element_list ()
|
||||
{
|
||||
tl::XMLElementList elements;
|
||||
|
||||
for (tl::Registrar<db::StreamFormatDeclaration>::iterator cls = tl::Registrar<db::StreamFormatDeclaration>::begin (); cls != tl::Registrar<db::StreamFormatDeclaration>::end (); ++cls) {
|
||||
const db::StreamFormatDeclaration *decl = dynamic_cast <const db::StreamFormatDeclaration *> (&*cls);
|
||||
if (decl) {
|
||||
elements.append (decl->xml_reader_options_element ());
|
||||
}
|
||||
}
|
||||
|
||||
// ignore all unknown elements
|
||||
elements.append (tl::make_member<db::LoadLayoutOptions> ("*"));
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
tl::XMLElementList save_options_xml_element_list ()
|
||||
{
|
||||
tl::XMLElementList elements;
|
||||
|
||||
for (tl::Registrar<db::StreamFormatDeclaration>::iterator cls = tl::Registrar<db::StreamFormatDeclaration>::begin (); cls != tl::Registrar<db::StreamFormatDeclaration>::end (); ++cls) {
|
||||
const StreamFormatDeclaration *decl = dynamic_cast <const StreamFormatDeclaration *> (&*cls);
|
||||
if (decl) {
|
||||
elements.append (decl->xml_writer_options_element ());
|
||||
}
|
||||
}
|
||||
|
||||
// ignore all unknown elements
|
||||
elements.append (tl::make_member<db::FormatSpecificWriterOptions> ("*"));
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,12 @@
|
|||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbSaveLayoutOptions.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
|
||||
#include "tlClassRegistry.h"
|
||||
#include "tlXMLParser.h"
|
||||
#include "tlXMLWriter.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
@ -103,8 +108,197 @@ public:
|
|||
* @brief Returns true, when the format supports export (has a writer)
|
||||
*/
|
||||
virtual bool can_write () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElement object that represents the reader options within a technology XML tree
|
||||
*
|
||||
* This method is supposed to return an instance ReaderOptionsXMLElement<RO> where RO is the
|
||||
* specific reader options type. The return value can be 0 to indicate there is no specific reader
|
||||
* option.
|
||||
*
|
||||
* The returned XMLElement is destroyed by the caller and needs to be a new object.
|
||||
*/
|
||||
virtual tl::XMLElementBase *xml_reader_options_element () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElement object that represents this writer options within a technology XML tree
|
||||
*
|
||||
* This method is supposed to return an instance WriterOptionsXMLElement<WO> where WO is the
|
||||
* specific writer options type. The return value can be 0 to indicate there is no specific writer
|
||||
* option.
|
||||
*
|
||||
* The returned XMLElement is destroyed by the caller and needs to be a new object.
|
||||
*/
|
||||
virtual tl::XMLElementBase *xml_writer_options_element () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the stream options (custom read adaptor)
|
||||
*
|
||||
* OPT is a reader or writer options class and HOST is the host class. For example, OPT
|
||||
* can be db::GDS2ReaderOptions and HOST then is db::LoadLayoutOptions.
|
||||
*/
|
||||
template <class OPT, class HOST>
|
||||
class StreamOptionsReadAdaptor
|
||||
{
|
||||
public:
|
||||
typedef tl::pass_by_ref_tag tag;
|
||||
|
||||
StreamOptionsReadAdaptor ()
|
||||
: mp_options (0), m_done (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
const OPT &operator () () const
|
||||
{
|
||||
return mp_options->template get_options<OPT> ();
|
||||
}
|
||||
|
||||
bool at_end () const
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
void start (const HOST &options)
|
||||
{
|
||||
mp_options = &options;
|
||||
m_done = false;
|
||||
}
|
||||
|
||||
void next ()
|
||||
{
|
||||
mp_options = 0;
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
private:
|
||||
const HOST *mp_options;
|
||||
bool m_done;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the stream option (custom write adaptor)
|
||||
*
|
||||
* See StreamOptionsReadAdaptor for details.
|
||||
*/
|
||||
template <class OPT, class HOST>
|
||||
class StreamOptionsWriteAdaptor
|
||||
{
|
||||
public:
|
||||
StreamOptionsWriteAdaptor ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void operator () (HOST &options, tl::XMLReaderState &reader) const
|
||||
{
|
||||
std::auto_ptr<OPT> opt (new OPT ());
|
||||
|
||||
tl::XMLObjTag<OPT> tag;
|
||||
*opt = *reader.back (tag);
|
||||
|
||||
options.set_options (opt.release ());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A XMLElement specialization for stream options
|
||||
*/
|
||||
template <class OPT, class HOST>
|
||||
class StreamOptionsXMLElement
|
||||
: public tl::XMLElement<OPT, HOST, StreamOptionsReadAdaptor<OPT, HOST>, StreamOptionsWriteAdaptor<OPT, HOST> >
|
||||
{
|
||||
public:
|
||||
StreamOptionsXMLElement (const std::string &element_name, const tl::XMLElementList &children)
|
||||
: tl::XMLElement<OPT, HOST, StreamOptionsReadAdaptor<OPT, HOST>, StreamOptionsWriteAdaptor<OPT, HOST> > (StreamOptionsReadAdaptor<OPT, HOST> (), StreamOptionsWriteAdaptor<OPT, HOST> (), element_name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
StreamOptionsXMLElement (const StreamOptionsXMLElement &d)
|
||||
: tl::XMLElement<OPT, HOST, StreamOptionsReadAdaptor<OPT, HOST>, StreamOptionsWriteAdaptor<OPT, HOST> > (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A custom XMLElement for the serialization of reader options
|
||||
*
|
||||
* StreamReaderPluginDeclaration::xml_element can return such an element to
|
||||
* insert a custom XML element into the XML tree which represents the
|
||||
* reader options.
|
||||
*/
|
||||
template <class OPT>
|
||||
class ReaderOptionsXMLElement
|
||||
: public StreamOptionsXMLElement<OPT, db::LoadLayoutOptions>
|
||||
{
|
||||
public:
|
||||
ReaderOptionsXMLElement (const std::string &element_name, const tl::XMLElementList &children)
|
||||
: StreamOptionsXMLElement<OPT, db::LoadLayoutOptions> (element_name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ReaderOptionsXMLElement (const ReaderOptionsXMLElement &d)
|
||||
: StreamOptionsXMLElement<OPT, db::LoadLayoutOptions> (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *clone () const
|
||||
{
|
||||
return new ReaderOptionsXMLElement (*this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A custom XMLElement for the serialization of writer options
|
||||
*
|
||||
* StreamWriterPluginDeclaration::xml_element can return such an element to
|
||||
* insert a custom XML element into the XML tree which represents the
|
||||
* writer options.
|
||||
*/
|
||||
template <class OPT>
|
||||
class WriterOptionsXMLElement
|
||||
: public StreamOptionsXMLElement<OPT, db::SaveLayoutOptions>
|
||||
{
|
||||
public:
|
||||
WriterOptionsXMLElement (const std::string &element_name, const tl::XMLElementList &children)
|
||||
: StreamOptionsXMLElement<OPT, db::SaveLayoutOptions> (element_name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
WriterOptionsXMLElement (const WriterOptionsXMLElement &d)
|
||||
: StreamOptionsXMLElement<OPT, db::SaveLayoutOptions> (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *clone () const
|
||||
{
|
||||
return new WriterOptionsXMLElement (*this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns the XMLElement list that can represent a db::LoadLayoutOptions object
|
||||
*/
|
||||
DB_PUBLIC tl::XMLElementList load_options_xml_element_list ();
|
||||
|
||||
/**
|
||||
* @brief Returns the XMLElement list that can represent a db::SaveLayoutOptions object
|
||||
*/
|
||||
DB_PUBLIC tl::XMLElementList save_options_xml_element_list ();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,472 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbTechnology.h"
|
||||
#include "dbStream.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace tl
|
||||
{
|
||||
template <> tl::Registrar<db::TechnologyComponentProvider> *Registrar<db::TechnologyComponentProvider>::instance = 0;
|
||||
}
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Technologies::Technologies ()
|
||||
{
|
||||
m_technologies.push_back (new Technology (std::string (""), "(Default)"));
|
||||
m_changed = false;
|
||||
m_in_update = false;
|
||||
}
|
||||
|
||||
Technologies::Technologies (const Technologies &other)
|
||||
: tl::Object ()
|
||||
{
|
||||
m_changed = false;
|
||||
m_in_update = false;
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
Technologies::~Technologies ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Technologies &
|
||||
Technologies::operator= (const Technologies &other)
|
||||
{
|
||||
if (&other != this) {
|
||||
m_technologies = other.m_technologies;
|
||||
for (iterator i = begin (); i != end (); ++i) {
|
||||
i->technology_changed_with_sender_event.add (this, &Technologies::technology_changed);
|
||||
}
|
||||
technologies_changed ();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
static std::auto_ptr<db::Technologies> sp_technologies;
|
||||
|
||||
db::Technologies *
|
||||
Technologies::instance ()
|
||||
{
|
||||
if (! sp_technologies.get ()) {
|
||||
sp_technologies.reset (new db::Technologies ());
|
||||
}
|
||||
return sp_technologies.get ();
|
||||
}
|
||||
|
||||
static tl::XMLElementList xml_elements ()
|
||||
{
|
||||
return make_element ((Technologies::const_iterator (Technologies::*) () const) &Technologies::begin, (Technologies::const_iterator (Technologies::*) () const) &Technologies::end, &Technologies::add, "technology",
|
||||
Technology::xml_elements ()
|
||||
);
|
||||
}
|
||||
|
||||
std::string
|
||||
Technologies::to_xml () const
|
||||
{
|
||||
// create a copy to filter out the ones which are not persisted
|
||||
db::Technologies copy;
|
||||
for (const_iterator t = begin (); t != end (); ++t) {
|
||||
if (t->is_persisted ()) {
|
||||
copy.add (new Technology (*t));
|
||||
}
|
||||
}
|
||||
|
||||
tl::OutputStringStream os;
|
||||
tl::XMLStruct<db::Technologies> xml_struct ("technologies", xml_elements ());
|
||||
tl::OutputStream oss (os);
|
||||
xml_struct.write (oss, copy);
|
||||
return os.string ();
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::load_from_xml (const std::string &s)
|
||||
{
|
||||
// create a copy to filter out the ones which are not persisted and remain
|
||||
db::Technologies copy;
|
||||
for (const_iterator t = begin (); t != end (); ++t) {
|
||||
if (! t->is_persisted ()) {
|
||||
copy.add (new Technology (*t));
|
||||
}
|
||||
}
|
||||
|
||||
tl::XMLStringSource source (s);
|
||||
tl::XMLStruct<db::Technologies> xml_struct ("technologies", xml_elements ());
|
||||
xml_struct.parse (source, copy);
|
||||
|
||||
*this = copy;
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::add_tech (Technology *tech, bool replace_same)
|
||||
{
|
||||
if (! tech) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::auto_ptr<Technology> tech_ptr (tech);
|
||||
|
||||
Technology *t = 0;
|
||||
for (tl::stable_vector<Technology>::iterator i = m_technologies.begin (); !t && i != m_technologies.end (); ++i) {
|
||||
if (i->name () == tech->name ()) {
|
||||
t = i.operator-> ();
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
if (replace_same) {
|
||||
*t = *tech;
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("A technology with this name already exists: %1").arg (tl::to_qstring (tech->name ()))));
|
||||
}
|
||||
} else {
|
||||
m_technologies.push_back (tech_ptr.release ());
|
||||
tech->technology_changed_with_sender_event.add (this, &Technologies::technology_changed);
|
||||
}
|
||||
|
||||
technologies_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::remove (const std::string &name)
|
||||
{
|
||||
for (tl::stable_vector<Technology>::iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
if (t->name () == name) {
|
||||
m_technologies.erase (t);
|
||||
technologies_changed ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::clear ()
|
||||
{
|
||||
if (! m_technologies.empty ()) {
|
||||
m_technologies.clear ();
|
||||
technologies_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::technology_changed (Technology *t)
|
||||
{
|
||||
if (m_in_update) {
|
||||
m_changed = true;
|
||||
} else {
|
||||
technology_changed_event (t);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::technologies_changed ()
|
||||
{
|
||||
if (m_in_update) {
|
||||
m_changed = true;
|
||||
} else {
|
||||
technologies_changed_event ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::begin_updates ()
|
||||
{
|
||||
tl_assert (! m_in_update);
|
||||
m_in_update = true;
|
||||
m_changed = false;
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::end_updates ()
|
||||
{
|
||||
if (m_in_update) {
|
||||
m_in_update = false;
|
||||
if (m_changed) {
|
||||
m_changed = false;
|
||||
technologies_changed ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::notify_technologies_changed ()
|
||||
{
|
||||
technologies_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::end_updates_no_event ()
|
||||
{
|
||||
m_in_update = false;
|
||||
m_changed = false;
|
||||
}
|
||||
|
||||
bool
|
||||
Technologies::has_technology (const std::string &name) const
|
||||
{
|
||||
for (tl::stable_vector<Technology>::const_iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
if (t->name () == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Technology *
|
||||
Technologies::technology_by_name (const std::string &name)
|
||||
{
|
||||
for (tl::stable_vector<Technology>::iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
if (t->name () == name) {
|
||||
return &*t;
|
||||
}
|
||||
}
|
||||
|
||||
tl_assert (! m_technologies.empty ());
|
||||
return &*m_technologies.begin ();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Technology implementation
|
||||
|
||||
Technology::Technology ()
|
||||
: m_name (), m_description (), m_dbu (0.001), m_persisted (true), m_readonly (false)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
Technology::Technology (const std::string &name, const std::string &description)
|
||||
: m_name (name), m_description (description), m_dbu (0.001), m_persisted (true), m_readonly (false)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
void
|
||||
Technology::init ()
|
||||
{
|
||||
m_add_other_layers = true;
|
||||
|
||||
for (tl::Registrar<db::TechnologyComponentProvider>::iterator cls = tl::Registrar<db::TechnologyComponentProvider>::begin (); cls != tl::Registrar<db::TechnologyComponentProvider>::end (); ++cls) {
|
||||
m_components.push_back (cls->create_component ());
|
||||
}
|
||||
}
|
||||
|
||||
Technology::~Technology ()
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
delete *c;
|
||||
}
|
||||
m_components.clear ();
|
||||
}
|
||||
|
||||
Technology::Technology (const Technology &d)
|
||||
: tl::Object (),
|
||||
m_name (d.m_name), m_description (d.m_description), m_grain_name (d.m_grain_name), m_dbu (d.m_dbu),
|
||||
m_explicit_base_path (d.m_explicit_base_path), m_default_base_path (d.m_default_base_path),
|
||||
m_load_layout_options (d.m_load_layout_options),
|
||||
m_save_layout_options (d.m_save_layout_options),
|
||||
m_lyp_path (d.m_lyp_path), m_add_other_layers (d.m_add_other_layers), m_persisted (d.m_persisted),
|
||||
m_readonly (d.m_readonly), m_lyt_file (d.m_lyt_file)
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = d.m_components.begin (); c != d.m_components.end (); ++c) {
|
||||
m_components.push_back ((*c)->clone ());
|
||||
}
|
||||
}
|
||||
|
||||
Technology &Technology::operator= (const Technology &d)
|
||||
{
|
||||
if (this != &d) {
|
||||
|
||||
m_name = d.m_name;
|
||||
m_description = d.m_description;
|
||||
m_grain_name = d.m_grain_name;
|
||||
m_dbu = d.m_dbu;
|
||||
m_default_base_path = d.m_default_base_path;
|
||||
m_explicit_base_path = d.m_explicit_base_path;
|
||||
m_load_layout_options = d.m_load_layout_options;
|
||||
m_save_layout_options = d.m_save_layout_options;
|
||||
m_lyp_path = d.m_lyp_path;
|
||||
m_add_other_layers = d.m_add_other_layers;
|
||||
m_persisted = d.m_persisted;
|
||||
m_readonly = d.m_readonly;
|
||||
m_lyt_file = d.m_lyt_file;
|
||||
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
delete *c;
|
||||
}
|
||||
m_components.clear ();
|
||||
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = d.m_components.begin (); c != d.m_components.end (); ++c) {
|
||||
m_components.push_back ((*c)->clone ());
|
||||
}
|
||||
|
||||
technology_changed ();
|
||||
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tl::XMLElementList
|
||||
Technology::xml_elements ()
|
||||
{
|
||||
tl::XMLElementList elements =
|
||||
tl::make_member (&Technology::name, &Technology::set_name, "name") +
|
||||
tl::make_member (&Technology::description, &Technology::set_description, "description") +
|
||||
tl::make_member (&Technology::dbu, &Technology::set_dbu, "dbu") +
|
||||
tl::make_member (&Technology::explicit_base_path, &Technology::set_explicit_base_path, "base-path") +
|
||||
tl::make_member (&Technology::default_base_path, &Technology::set_default_base_path, "original-base-path") +
|
||||
tl::make_member (&Technology::layer_properties_file, &Technology::set_layer_properties_file, "layer-properties_file") +
|
||||
tl::make_member (&Technology::add_other_layers, &Technology::set_add_other_layers, "add-other-layers") +
|
||||
tl::make_element (&Technology::load_layout_options, &Technology::set_load_layout_options, "reader-options",
|
||||
db::load_options_xml_element_list ()
|
||||
) +
|
||||
tl::make_element (&Technology::save_layout_options, &Technology::set_save_layout_options, "writer-options",
|
||||
db::save_options_xml_element_list ()
|
||||
);
|
||||
|
||||
for (tl::Registrar<db::TechnologyComponentProvider>::iterator cls = tl::Registrar<db::TechnologyComponentProvider>::begin (); cls != tl::Registrar<db::TechnologyComponentProvider>::end (); ++cls) {
|
||||
elements.append (cls->xml_element ());
|
||||
}
|
||||
|
||||
// ignore all unknown elements
|
||||
elements.append (tl::make_member<Technology> ("*"));
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
const TechnologyComponent *
|
||||
Technology::component_by_name (const std::string &component_name) const
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
if ((*c)->name () == component_name) {
|
||||
return *c;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TechnologyComponent *
|
||||
Technology::component_by_name (const std::string &component_name)
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
if ((*c)->name () == component_name) {
|
||||
return *c;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector <std::string>
|
||||
Technology::component_names () const
|
||||
{
|
||||
std::vector <std::string> names;
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
names.push_back ((*c)->name ());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
void
|
||||
Technology::set_component (TechnologyComponent *component)
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
if ((*c)->name () == component->name ()) {
|
||||
if (*c != component) {
|
||||
delete *c;
|
||||
*c = component;
|
||||
technology_changed_event ();
|
||||
technology_changed_with_sender_event (this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Technology::correct_path (const std::string &fp) const
|
||||
{
|
||||
if (base_path ().empty ()) {
|
||||
return fp;
|
||||
}
|
||||
|
||||
QString rfp = QDir (tl::to_qstring (base_path ())).relativeFilePath (tl::to_qstring (fp));
|
||||
if (rfp.startsWith (QString::fromUtf8 (".."))) {
|
||||
// upwards or beside - don't correct:
|
||||
return fp;
|
||||
} else {
|
||||
return tl::to_string (rfp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technology::load (const std::string &fn)
|
||||
{
|
||||
tl::XMLFileSource source (fn);
|
||||
tl::XMLStruct<db::Technology> xml_struct ("technology", xml_elements ());
|
||||
xml_struct.parse (source, *this);
|
||||
|
||||
// use the tech file's path as the default base path
|
||||
std::string lyt_file = tl::to_string (QFileInfo (tl::to_qstring (fn)).absoluteDir ().path ());
|
||||
set_default_base_path (lyt_file);
|
||||
|
||||
set_tech_file_path (fn);
|
||||
}
|
||||
|
||||
void
|
||||
Technology::save (const std::string &fn) const
|
||||
{
|
||||
tl::XMLStruct<db::Technology> xml_struct ("technology", xml_elements ());
|
||||
tl::OutputStream os (fn, tl::OutputStream::OM_Plain);
|
||||
xml_struct.write (os, *this);
|
||||
}
|
||||
|
||||
std::string
|
||||
Technology::build_effective_path (const std::string &p) const
|
||||
{
|
||||
if (p.empty () || base_path ().empty ()) {
|
||||
return p;
|
||||
}
|
||||
|
||||
QFileInfo f (tl::to_qstring (p));
|
||||
if (f.isAbsolute ()) {
|
||||
return p;
|
||||
} else {
|
||||
return tl::to_string (QDir (tl::to_qstring (base_path ())).filePath (tl::to_qstring (p)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,867 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbTechnology
|
||||
#define HDR_dbTechnology
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "tlStableVector.h"
|
||||
#include "tlString.h"
|
||||
#include "tlEvents.h"
|
||||
#include "tlXMLParser.h"
|
||||
#include "tlTypeTraits.h"
|
||||
#include "tlClassRegistry.h"
|
||||
#include "dbStreamLayers.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
#include "dbSaveLayoutOptions.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
class Technology;
|
||||
class TechnologyComponent;
|
||||
|
||||
/**
|
||||
* @brief A container for the technology settings
|
||||
*
|
||||
* The container associates a technology with a name and provides an
|
||||
* iterator for the technologies.
|
||||
* The container features at least one technology (the default) which is
|
||||
* present in any case. If a technology with an unknown name is requested,
|
||||
* this default technology is returned.
|
||||
*/
|
||||
class DB_PUBLIC Technologies
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
typedef tl::stable_vector<Technology>::const_iterator const_iterator;
|
||||
typedef tl::stable_vector<Technology>::iterator iterator;
|
||||
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
Technologies ();
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
~Technologies ();
|
||||
|
||||
/**
|
||||
* @brief Copy ctor
|
||||
*/
|
||||
Technologies (const Technologies &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment operator
|
||||
*/
|
||||
Technologies &operator= (const Technologies &other);
|
||||
|
||||
/**
|
||||
* @brief Const iterator - begin
|
||||
*/
|
||||
const_iterator begin () const
|
||||
{
|
||||
return m_technologies.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Const iterator - end
|
||||
*/
|
||||
const_iterator end () const
|
||||
{
|
||||
return m_technologies.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief iterator - begin
|
||||
*/
|
||||
iterator begin ()
|
||||
{
|
||||
return m_technologies.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Const iterator - end
|
||||
*/
|
||||
iterator end ()
|
||||
{
|
||||
return m_technologies.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The number of technologies
|
||||
*/
|
||||
size_t technologies () const
|
||||
{
|
||||
return m_technologies.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a technology to the setup
|
||||
*
|
||||
* The container becomes owner of the technology object.
|
||||
* Replaces a technology with the name of the given technology.
|
||||
*/
|
||||
void add (Technology *technology)
|
||||
{
|
||||
add_tech (technology, true /*replace*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a technology with a new name
|
||||
*
|
||||
* Like \add, but throws an exception if a technology with this name
|
||||
* already exists. Takes over ownership over the technology object.
|
||||
* The technology object is discarded if an exception is thrown.
|
||||
*/
|
||||
void add_new (Technology *technology)
|
||||
{
|
||||
add_tech (technology, false /*throws exception on same name*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a technology with the given name from the setup
|
||||
*/
|
||||
void remove (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Clears the list of technologies
|
||||
*/
|
||||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Begins a bulk operation
|
||||
* This method will disable "technologies_changed" events until (later) end_updates () is called.
|
||||
*/
|
||||
void begin_updates ();
|
||||
|
||||
/**
|
||||
* @brief Ends a bulk operation
|
||||
*/
|
||||
void end_updates ();
|
||||
|
||||
/**
|
||||
* @brief Ends a bulk operation
|
||||
* This version does not send an technologies_changed event but just cancels the bulk
|
||||
* operation. begin_updates/end_updates_no_event is essentially equivalent to blocking
|
||||
* signals.
|
||||
*/
|
||||
void end_updates_no_event ();
|
||||
|
||||
/**
|
||||
* @brief Notifies the system of changes in technologies
|
||||
* For performance reasons, changes inside a technology are not propagated to
|
||||
* the system directly. Only bulk changes (such as adding or removing technologies
|
||||
* are). To inform the system of individual technology updates, call this method
|
||||
* after a technology or multiple technologies have been changed.
|
||||
*/
|
||||
void notify_technologies_changed ();
|
||||
|
||||
/**
|
||||
* @brief Checks, if a technology with the given name exists
|
||||
*/
|
||||
bool has_technology (const std::string &name) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the technology with the given name
|
||||
*
|
||||
* If no technology with that name exists, the default technology is returned.
|
||||
*/
|
||||
Technology *technology_by_name (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Returns the technology with the given name (const version)
|
||||
*
|
||||
* If no technology with that name exists, the default technology is returned.
|
||||
*/
|
||||
const Technology *technology_by_name (const std::string &name) const
|
||||
{
|
||||
return const_cast<Technologies *> (this)->technology_by_name (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts the list into an XML string
|
||||
*/
|
||||
std::string to_xml () const;
|
||||
|
||||
/**
|
||||
* @brief Reads the list from an XML string
|
||||
*/
|
||||
void load_from_xml (const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Returns the singleton instance
|
||||
*/
|
||||
static db::Technologies *instance ();
|
||||
|
||||
/**
|
||||
* @brief An event indicating that the list of technologies has changed
|
||||
* If a technology is added or removed, this event is triggered.
|
||||
*/
|
||||
tl::Event technologies_changed_event;
|
||||
|
||||
/**
|
||||
* @brief An event indicating that one technology in the list has changed
|
||||
* If a technology is modified, this event is triggered with that technology as argument of the event.
|
||||
*/
|
||||
tl::event<Technology *> technology_changed_event;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Forward the event from the individual technologies
|
||||
*/
|
||||
void technology_changed (Technology *t);
|
||||
|
||||
/**
|
||||
* @brief Sends the technologies_changed event
|
||||
*/
|
||||
void technologies_changed ();
|
||||
|
||||
private:
|
||||
tl::stable_vector<Technology> m_technologies;
|
||||
bool m_changed;
|
||||
bool m_in_update;
|
||||
|
||||
void add_tech (Technology *technology, bool replace_same);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A technology
|
||||
*
|
||||
* This class represents one technology.
|
||||
* A technology has a name and a description.
|
||||
*/
|
||||
class DB_PUBLIC Technology
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The default constructor
|
||||
*/
|
||||
Technology ();
|
||||
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
Technology (const std::string &name, const std::string &description);
|
||||
|
||||
/**
|
||||
* @brief The copy constructor
|
||||
*/
|
||||
Technology (const Technology &tech);
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
~Technology ();
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
Technology &operator= (const Technology &tech);
|
||||
|
||||
/**
|
||||
* @brief Gets the name
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the name
|
||||
*/
|
||||
void set_name (const std::string &n)
|
||||
{
|
||||
if (n != m_name) {
|
||||
m_name = n;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the package source
|
||||
*
|
||||
* This attribute indicates that this technology was contributed by a package
|
||||
*/
|
||||
void set_grain_name (const std::string &g)
|
||||
{
|
||||
m_grain_name = g;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the package source
|
||||
*/
|
||||
const std::string &grain_name () const
|
||||
{
|
||||
return m_grain_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the base path
|
||||
*
|
||||
* The base path is an effective path - if the explicit path is set, it is
|
||||
* used. If not, the default path is used. The default path is the one from which
|
||||
* a technology file was imported. The explicit one is the one that is specified
|
||||
* explicitly.
|
||||
*/
|
||||
const std::string &base_path () const
|
||||
{
|
||||
return m_explicit_base_path.empty () ? m_default_base_path : m_explicit_base_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Makes a file path relative to the base path if one is specified.
|
||||
*
|
||||
* Only files below the base path will be made relative. Files above or beside
|
||||
* won't be made relative.
|
||||
*/
|
||||
std::string correct_path (const std::string &fp) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the default base path
|
||||
*/
|
||||
const std::string &default_base_path () const
|
||||
{
|
||||
return m_default_base_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the default base path
|
||||
*/
|
||||
void set_default_base_path (const std::string &p)
|
||||
{
|
||||
if (m_default_base_path != p) {
|
||||
m_default_base_path = p;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the explicit base path
|
||||
*/
|
||||
const std::string &explicit_base_path () const
|
||||
{
|
||||
return m_explicit_base_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the explicit base path
|
||||
*/
|
||||
void set_explicit_base_path (const std::string &p)
|
||||
{
|
||||
if (m_explicit_base_path != p) {
|
||||
m_explicit_base_path = p;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the path of the tech file if the technology was loaded from a tech file
|
||||
*/
|
||||
const std::string &tech_file_path () const
|
||||
{
|
||||
return m_lyt_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the path of the tech file
|
||||
* This method is intended for internal use only.
|
||||
*/
|
||||
void set_tech_file_path (const std::string &lyt_file)
|
||||
{
|
||||
m_lyt_file = lyt_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the description
|
||||
*/
|
||||
const std::string &description () const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the description
|
||||
*/
|
||||
void set_description (const std::string &d)
|
||||
{
|
||||
if (m_description != d) {
|
||||
m_description = d;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the default database unit
|
||||
*/
|
||||
double dbu () const
|
||||
{
|
||||
return m_dbu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the default database unit
|
||||
*/
|
||||
void set_dbu (double d)
|
||||
{
|
||||
if (fabs (m_dbu - d) > 1e-10) {
|
||||
m_dbu = d;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the layer properties file path (empty if none is specified)
|
||||
*/
|
||||
const std::string &layer_properties_file () const
|
||||
{
|
||||
return m_lyp_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the effective layer properties file path (empty if none is specified)
|
||||
*
|
||||
* The effective path is the one extended by the base path if relative.
|
||||
*/
|
||||
std::string eff_layer_properties_file () const
|
||||
{
|
||||
return build_effective_path (m_lyp_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the layer properties file path (set to empty string to remove layer properties file)
|
||||
*/
|
||||
void set_layer_properties_file (const std::string &lyp)
|
||||
{
|
||||
if (m_lyp_path != lyp) {
|
||||
m_lyp_path = lyp;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the flag indicating whether to add other layers to the layer properties
|
||||
*/
|
||||
bool add_other_layers () const
|
||||
{
|
||||
return m_add_other_layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the flag indicating whether to add other layers to the layer properties
|
||||
*
|
||||
* If "add_other_layers" is true, the layers in the layout but not specified in the
|
||||
* layer properties file will be added automatically.
|
||||
*/
|
||||
void set_add_other_layers (bool add_other_layers)
|
||||
{
|
||||
if (m_add_other_layers != add_other_layers) {
|
||||
m_add_other_layers = add_other_layers;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gets the layout reader options
|
||||
*/
|
||||
const db::LoadLayoutOptions &load_layout_options () const
|
||||
{
|
||||
return m_load_layout_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the layout reader options
|
||||
*/
|
||||
void set_load_layout_options (const db::LoadLayoutOptions &options)
|
||||
{
|
||||
m_load_layout_options = options;
|
||||
technology_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gets the layout writer options
|
||||
*/
|
||||
const db::SaveLayoutOptions &save_layout_options () const
|
||||
{
|
||||
return m_save_layout_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the layout writer options
|
||||
*/
|
||||
void set_save_layout_options (const db::SaveLayoutOptions &options)
|
||||
{
|
||||
m_save_layout_options = options;
|
||||
technology_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load from file (import)
|
||||
*/
|
||||
void load (const std::string &fn);
|
||||
|
||||
/**
|
||||
* @brief Save to file (export)
|
||||
*/
|
||||
void save (const std::string &fn) const;
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElementList that specifies the technology's XML representation
|
||||
*/
|
||||
static tl::XMLElementList xml_elements ();
|
||||
|
||||
/**
|
||||
* @brief Sets the technology component by the component name
|
||||
*
|
||||
* This replaces the technology component with the given name.
|
||||
* The Technology object will become owner of the component.
|
||||
*/
|
||||
void set_component (TechnologyComponent *component);
|
||||
|
||||
/**
|
||||
* @brief Gets the technology component by the component name
|
||||
*
|
||||
* If no component with that name exists, 0 is returned.
|
||||
*/
|
||||
const TechnologyComponent *component_by_name (const std::string &component_name) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the technology component by the component name (non-const version)
|
||||
*
|
||||
* If no component with that name exists, 0 is returned.
|
||||
*/
|
||||
TechnologyComponent *component_by_name (const std::string &component_name);
|
||||
|
||||
/**
|
||||
* @brief Gets the component names
|
||||
*/
|
||||
std::vector <std::string> component_names () const;
|
||||
|
||||
/**
|
||||
* @brief Builds the effective path from a relative or absolute one using the base path if necessary
|
||||
*/
|
||||
std::string build_effective_path (const std::string &p) const;
|
||||
|
||||
/**
|
||||
* @brief Returns a flag indicating whether the technology is persisted or not
|
||||
*
|
||||
* If the flag is false, this technology is not included into the XML string
|
||||
* of the technologies.
|
||||
*/
|
||||
bool is_persisted () const
|
||||
{
|
||||
return m_persisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a flag indicating whether the technology is persisted
|
||||
*/
|
||||
void set_persisted (bool f)
|
||||
{
|
||||
m_persisted = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a flag indicating whether the technology is readonly
|
||||
*
|
||||
* If the flag is false, the technology can be edited. Otherwise it's locked for editing.
|
||||
*/
|
||||
bool is_readonly () const
|
||||
{
|
||||
return m_readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a flag indicating whether the technology is readonly
|
||||
*/
|
||||
void set_readonly (bool f)
|
||||
{
|
||||
m_readonly = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief An event indicating that the technology has changed
|
||||
*/
|
||||
tl::Event technology_changed_event;
|
||||
|
||||
/**
|
||||
* @brief An event indicating that the technology has changed (with a sender argument)
|
||||
*/
|
||||
tl::event<Technology *> technology_changed_with_sender_event;
|
||||
|
||||
private:
|
||||
std::string m_name, m_description;
|
||||
std::string m_grain_name;
|
||||
double m_dbu;
|
||||
std::string m_explicit_base_path, m_default_base_path;
|
||||
db::LoadLayoutOptions m_load_layout_options;
|
||||
db::SaveLayoutOptions m_save_layout_options;
|
||||
std::string m_lyp_path;
|
||||
std::string m_lyt_path;
|
||||
bool m_add_other_layers;
|
||||
std::vector <TechnologyComponent *> m_components;
|
||||
bool m_persisted;
|
||||
bool m_readonly;
|
||||
std::string m_lyt_file;
|
||||
|
||||
void init ();
|
||||
|
||||
void technology_changed ()
|
||||
{
|
||||
technology_changed_with_sender_event (this);
|
||||
technology_changed_event ();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A technology component
|
||||
*
|
||||
* A technology component is a part of the data for one technology.
|
||||
* Plugins may register technology components in every technology and
|
||||
* use those components to store their specific data.
|
||||
* A technology component has a name and a description. The name is used
|
||||
* to identify a component within a technology. The description is shown
|
||||
* in the setup dialogs.
|
||||
* This class is the base class for all technology components.
|
||||
*/
|
||||
class DB_PUBLIC TechnologyComponent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
*
|
||||
* @param name The name of the technology component
|
||||
* @param descriptor The description of the technology component
|
||||
*/
|
||||
TechnologyComponent (const std::string &name, const std::string &description)
|
||||
: m_name (name), m_description (description)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
virtual ~TechnologyComponent ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the name
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the description
|
||||
*/
|
||||
const std::string &description () const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clone this instance
|
||||
*/
|
||||
virtual TechnologyComponent *clone () const = 0;
|
||||
|
||||
private:
|
||||
std::string m_name, m_description;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A base class for a technology component provider
|
||||
*/
|
||||
class DB_PUBLIC TechnologyComponentProvider
|
||||
: public tl::RegisteredClass<TechnologyComponentProvider>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
TechnologyComponentProvider ()
|
||||
: tl::RegisteredClass<TechnologyComponentProvider> (this)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
virtual ~TechnologyComponentProvider ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates the technology component
|
||||
*/
|
||||
virtual TechnologyComponent *create_component () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElement object that represents this component within a technology XML tree
|
||||
*
|
||||
* The object returned is destroyed by the caller.
|
||||
*/
|
||||
virtual tl::XMLElementBase *xml_element () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the technology component (custom read adaptor)
|
||||
*/
|
||||
|
||||
template <class TC>
|
||||
class TechnologyComponentReadAdaptor
|
||||
{
|
||||
public:
|
||||
typedef tl::pass_by_ref_tag tag;
|
||||
|
||||
TechnologyComponentReadAdaptor (const std::string &name)
|
||||
: m_name (name), mp_t (0), m_done (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
const TC &operator () () const
|
||||
{
|
||||
const TC *tc = dynamic_cast<const TC *> ((const_cast <db::Technology *> (mp_t))->component_by_name (m_name));
|
||||
if (! tc) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Unknown technology component: ")) + m_name);
|
||||
}
|
||||
|
||||
return *tc;
|
||||
}
|
||||
|
||||
bool at_end () const
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
void start (const db::Technology &t)
|
||||
{
|
||||
mp_t = &t;
|
||||
m_done = false;
|
||||
}
|
||||
|
||||
void next ()
|
||||
{
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
const db::Technology *mp_t;
|
||||
bool m_done;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the technology component (custom write adaptor)
|
||||
*/
|
||||
|
||||
template <class TC>
|
||||
class TechnologyComponentWriteAdaptor
|
||||
{
|
||||
public:
|
||||
TechnologyComponentWriteAdaptor (const std::string &name)
|
||||
: m_name (name)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void operator () (db::Technology &t, tl::XMLReaderState &reader) const
|
||||
{
|
||||
const TechnologyComponent *tc_basic = t.component_by_name (m_name);
|
||||
TC *tc = 0;
|
||||
if (! tc_basic) {
|
||||
tc = new TC ();
|
||||
} else {
|
||||
tc = dynamic_cast<TC *> (tc_basic->clone ());
|
||||
if (! tc) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Invalid technology component: ")) + m_name);
|
||||
}
|
||||
}
|
||||
|
||||
tl::XMLObjTag<TC> tag;
|
||||
*tc = *reader.back (tag);
|
||||
|
||||
t.set_component (tc);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A custom XMLElement for the serialization of technology components
|
||||
*
|
||||
* TechnologyComponentProvider::xml_element can return such an element to
|
||||
* insert a custom XML element into the XML tree which represents the
|
||||
* technology component.
|
||||
*
|
||||
* The name of the element will be the name of the technology component.
|
||||
*/
|
||||
|
||||
template <class TC>
|
||||
class TechnologyComponentXMLElement
|
||||
: public tl::XMLElement<TC, db::Technology, TechnologyComponentReadAdaptor<TC>, TechnologyComponentWriteAdaptor<TC> >
|
||||
{
|
||||
public:
|
||||
TechnologyComponentXMLElement (const std::string &name, const tl::XMLElementList &children)
|
||||
: tl::XMLElement<TC, db::Technology, TechnologyComponentReadAdaptor<TC>, TechnologyComponentWriteAdaptor<TC> > (TechnologyComponentReadAdaptor<TC> (name), TechnologyComponentWriteAdaptor<TC> (name), name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
TechnologyComponentXMLElement (const TechnologyComponentXMLElement &d)
|
||||
: tl::XMLElement<TC, db::Technology, TechnologyComponentReadAdaptor<TC>, TechnologyComponentWriteAdaptor<TC> > (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *clone () const
|
||||
{
|
||||
return new TechnologyComponentXMLElement (*this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
/**
|
||||
* @brief Type traits
|
||||
*/
|
||||
template <> struct type_traits <db::TechnologyComponent> : public type_traits<void> {
|
||||
typedef tl::false_tag has_default_constructor;
|
||||
typedef tl::false_tag has_copy_constructor;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -21,10 +21,10 @@
|
|||
*/
|
||||
|
||||
#include "dbTestSupport.h"
|
||||
#include "dbCommonReader.h"
|
||||
#include "dbStreamLayers.h"
|
||||
#include "dbReader.h"
|
||||
#include "dbWriter.h"
|
||||
#include "dbCommonReader.h"
|
||||
#include "dbCell.h"
|
||||
#include "dbCellInst.h"
|
||||
#include "dbLayoutDiff.h"
|
||||
|
|
|
|||
|
|
@ -24,96 +24,13 @@
|
|||
|
||||
#include "dbCommonReader.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
#include "layCommonReaderPlugin.h"
|
||||
#include "ui_CommonReaderOptionsPage.h"
|
||||
#include "gsiDecl.h"
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
namespace lay
|
||||
namespace dn
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// CommonReaderOptionPage definition and implementation
|
||||
|
||||
CommonReaderOptionPage::CommonReaderOptionPage (QWidget *parent)
|
||||
: StreamReaderOptionsPage (parent)
|
||||
{
|
||||
mp_ui = new Ui::CommonReaderOptionPage ();
|
||||
mp_ui->setupUi (this);
|
||||
}
|
||||
|
||||
CommonReaderOptionPage::~CommonReaderOptionPage ()
|
||||
{
|
||||
delete mp_ui;
|
||||
mp_ui = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CommonReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
{
|
||||
static const db::CommonReaderOptions default_options;
|
||||
const db::CommonReaderOptions *options = dynamic_cast<const db::CommonReaderOptions *> (o);
|
||||
if (!options) {
|
||||
options = &default_options;
|
||||
}
|
||||
|
||||
mp_ui->enable_text_cbx->setChecked (options->enable_text_objects);
|
||||
mp_ui->enable_properties_cbx->setChecked (options->enable_properties);
|
||||
mp_ui->layer_map->set_layer_map (options->layer_map);
|
||||
mp_ui->read_all_cbx->setChecked (options->create_other_layers);
|
||||
}
|
||||
|
||||
void
|
||||
CommonReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
{
|
||||
db::CommonReaderOptions *options = dynamic_cast<db::CommonReaderOptions *> (o);
|
||||
if (options) {
|
||||
|
||||
options->enable_text_objects = mp_ui->enable_text_cbx->isChecked ();
|
||||
options->enable_properties = mp_ui->enable_properties_cbx->isChecked ();
|
||||
options->layer_map = mp_ui->layer_map->get_layer_map ();
|
||||
options->create_other_layers = mp_ui->read_all_cbx->isChecked ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// CommonReaderPluginDeclaration definition and implementation
|
||||
|
||||
class CommonReaderPluginDeclaration
|
||||
: public StreamReaderPluginDeclaration
|
||||
{
|
||||
public:
|
||||
CommonReaderPluginDeclaration ()
|
||||
: StreamReaderPluginDeclaration (db::CommonReaderOptions ().format_name ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
StreamReaderOptionsPage *format_specific_options_page (QWidget *parent) const
|
||||
{
|
||||
return new CommonReaderOptionPage (parent);
|
||||
}
|
||||
|
||||
db::FormatSpecificReaderOptions *create_specific_options () const
|
||||
{
|
||||
return new db::CommonReaderOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::ReaderOptionsXMLElement<db::CommonReaderOptions> ("common",
|
||||
tl::make_member (&db::CommonReaderOptions::create_other_layers, "create-other-layers") +
|
||||
tl::make_member (&db::CommonReaderOptions::layer_map, "layer-map") +
|
||||
tl::make_member (&db::CommonReaderOptions::enable_properties, "enable-properties") +
|
||||
tl::make_member (&db::CommonReaderOptions::enable_text_objects, "enable-text-objects")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::CommonReaderPluginDeclaration (), 10000, "CommonReader");
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// gsi Implementation of specific methods
|
||||
|
||||
|
|
@ -164,7 +81,7 @@ static void set_properties_enabled (db::LoadLayoutOptions *options, bool l)
|
|||
options->get_options<db::CommonReaderOptions> ().enable_properties = l;
|
||||
}
|
||||
|
||||
// extend lay::LoadLayoutOptions with the Common options
|
||||
// extend lay::LoadLayoutOptions with the Common options
|
||||
static
|
||||
gsi::ClassExt<db::LoadLayoutOptions> common_reader_options (
|
||||
gsi::method_ext ("set_layer_map", &set_layer_map, gsi::arg ("map"), gsi::arg ("create_other_layers"),
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "gsiDecl.h"
|
||||
#include "layTechnology.h"
|
||||
#include "dbTechnology.h"
|
||||
#include "tlXMLWriter.h"
|
||||
#include "tlXMLParser.h"
|
||||
|
||||
|
|
@ -30,84 +30,84 @@ namespace gsi
|
|||
static std::vector<std::string> technology_names ()
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
names.push_back (t->name ());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
static lay::Technology *technology_by_name (const std::string &name)
|
||||
static db::Technology *technology_by_name (const std::string &name)
|
||||
{
|
||||
return lay::Technologies::instance ()->technology_by_name (name);
|
||||
return db::Technologies::instance ()->technology_by_name (name);
|
||||
}
|
||||
|
||||
static lay::Technology *create_technology (const std::string &name)
|
||||
static db::Technology *create_technology (const std::string &name)
|
||||
{
|
||||
lay::Technology *tech = new lay::Technology ();
|
||||
db::Technology *tech = new db::Technology ();
|
||||
tech->set_name (name);
|
||||
lay::Technologies::instance ()->add_new (tech);
|
||||
db::Technologies::instance ()->add_new (tech);
|
||||
return tech;
|
||||
}
|
||||
|
||||
static void remove_technology (const std::string &name)
|
||||
{
|
||||
lay::Technologies::instance ()->remove (name);
|
||||
db::Technologies::instance ()->remove (name);
|
||||
}
|
||||
|
||||
static bool has_technology (const std::string &name)
|
||||
{
|
||||
return lay::Technologies::instance ()->has_technology (name);
|
||||
return db::Technologies::instance ()->has_technology (name);
|
||||
}
|
||||
|
||||
static std::string technologies_to_xml ()
|
||||
{
|
||||
return lay::Technologies::instance ()->to_xml ();
|
||||
return db::Technologies::instance ()->to_xml ();
|
||||
}
|
||||
|
||||
static void technologies_from_xml (const std::string &s)
|
||||
{
|
||||
lay::Technologies::instance ()->load_from_xml (s);
|
||||
db::Technologies::instance ()->load_from_xml (s);
|
||||
}
|
||||
|
||||
static lay::Technology technology_from_xml (const std::string &s)
|
||||
static db::Technology technology_from_xml (const std::string &s)
|
||||
{
|
||||
lay::Technology tech;
|
||||
db::Technology tech;
|
||||
tl::XMLStringSource source (s);
|
||||
tl::XMLStruct<lay::Technology> xml_struct ("technology", lay::Technology::xml_elements ());
|
||||
tl::XMLStruct<db::Technology> xml_struct ("technology", db::Technology::xml_elements ());
|
||||
xml_struct.parse (source, tech);
|
||||
return tech;
|
||||
}
|
||||
|
||||
static std::string technology_to_xml (const lay::Technology *tech)
|
||||
static std::string technology_to_xml (const db::Technology *tech)
|
||||
{
|
||||
if (! tech) {
|
||||
return std::string ();
|
||||
} else {
|
||||
tl::OutputStringStream os;
|
||||
tl::XMLStruct<lay::Technology> xml_struct ("technology", lay::Technology::xml_elements ());
|
||||
tl::XMLStruct<db::Technology> xml_struct ("technology", db::Technology::xml_elements ());
|
||||
tl::OutputStream oss (os);
|
||||
xml_struct.write (oss, *tech);
|
||||
return os.string ();
|
||||
}
|
||||
}
|
||||
|
||||
static lay::TechnologyComponent *get_component (lay::Technology *tech, const std::string &name)
|
||||
static db::TechnologyComponent *get_component (db::Technology *tech, const std::string &name)
|
||||
{
|
||||
return tech->component_by_name (name);
|
||||
}
|
||||
|
||||
static std::vector<std::string> get_component_names (const lay::Technology *tech)
|
||||
static std::vector<std::string> get_component_names (const db::Technology *tech)
|
||||
{
|
||||
return tech->component_names ();
|
||||
}
|
||||
|
||||
gsi::Class<lay::TechnologyComponent> technology_component_decl ("lay", "TechnologyComponent",
|
||||
gsi::method ("name", &lay::TechnologyComponent::name,
|
||||
gsi::Class<db::TechnologyComponent> technology_component_decl ("lay", "TechnologyComponent",
|
||||
gsi::method ("name", &db::TechnologyComponent::name,
|
||||
"@brief Gets the formal name of the technology component\n"
|
||||
"This is the name by which the component can be obtained from a technology using "
|
||||
"\\Technology#component."
|
||||
) +
|
||||
gsi::method ("description", &lay::TechnologyComponent::description,
|
||||
gsi::method ("description", &db::TechnologyComponent::description,
|
||||
"@brief Gets the human-readable description string of the technology component\n"
|
||||
),
|
||||
"@brief A part of a technology definition\n"
|
||||
|
|
@ -122,16 +122,16 @@ gsi::Class<lay::TechnologyComponent> technology_component_decl ("lay", "Technolo
|
|||
"This class has been introduced in version 0.25."
|
||||
);
|
||||
|
||||
LAYBASIC_PUBLIC gsi::Class<lay::TechnologyComponent> &decl_layTechnologyComponent () { return technology_component_decl; }
|
||||
DB_PUBLIC gsi::Class<db::TechnologyComponent> &decl_layTechnologyComponent () { return technology_component_decl; }
|
||||
|
||||
gsi::Class<lay::Technology> technology_decl ("lay", "Technology",
|
||||
gsi::method ("name", &lay::Technology::name,
|
||||
gsi::Class<db::Technology> technology_decl ("lay", "Technology",
|
||||
gsi::method ("name", &db::Technology::name,
|
||||
"@brief Gets the name of the technology"
|
||||
) +
|
||||
gsi::method ("name=", &lay::Technology::set_name, gsi::arg ("name"),
|
||||
gsi::method ("name=", &db::Technology::set_name, gsi::arg ("name"),
|
||||
"@brief Sets the name of the technology"
|
||||
) +
|
||||
gsi::method ("base_path", &lay::Technology::base_path,
|
||||
gsi::method ("base_path", &db::Technology::base_path,
|
||||
"@brief Gets the base path of the technology\n"
|
||||
"\n"
|
||||
"The base path is the effective path where files are read from if their "
|
||||
|
|
@ -140,15 +140,15 @@ gsi::Class<lay::Technology> technology_decl ("lay", "Technology",
|
|||
"a technology file was imported. The explicit one is the one that is specified\n"
|
||||
"explicitly with \\explicit_base_path=.\n"
|
||||
) +
|
||||
gsi::method ("default_base_path", &lay::Technology::default_base_path,
|
||||
gsi::method ("default_base_path", &db::Technology::default_base_path,
|
||||
"@brief Gets the default base path\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the default base path.\n"
|
||||
) +
|
||||
gsi::method ("default_base_path=", &lay::Technology::set_default_base_path, gsi::arg ("path"),
|
||||
gsi::method ("default_base_path=", &db::Technology::set_default_base_path, gsi::arg ("path"),
|
||||
"@hide\n" // only for testing
|
||||
) +
|
||||
gsi::method ("correct_path", &lay::Technology::correct_path, gsi::arg ("path"),
|
||||
gsi::method ("correct_path", &db::Technology::correct_path, gsi::arg ("path"),
|
||||
"@brief Makes a file path relative to the base path if one is specified\n"
|
||||
"\n"
|
||||
"This method turns an absolute path into one relative to the base path. "
|
||||
|
|
@ -157,7 +157,7 @@ gsi::Class<lay::Technology> technology_decl ("lay", "Technology",
|
|||
"\n"
|
||||
"See \\base_path for details about the default base path.\n"
|
||||
) +
|
||||
gsi::method ("eff_path", &lay::Technology::build_effective_path, gsi::arg ("path"),
|
||||
gsi::method ("eff_path", &db::Technology::build_effective_path, gsi::arg ("path"),
|
||||
"@brief Makes a file path relative to the base path if one is specified\n"
|
||||
"\n"
|
||||
"This method will return the actual path for a file from the file's path. "
|
||||
|
|
@ -166,55 +166,55 @@ gsi::Class<lay::Technology> technology_decl ("lay", "Technology",
|
|||
"\n"
|
||||
"See \\base_path for details about the default base path.\n"
|
||||
) +
|
||||
gsi::method ("explicit_base_path", &lay::Technology::explicit_base_path,
|
||||
gsi::method ("explicit_base_path", &db::Technology::explicit_base_path,
|
||||
"@brief Gets the explicit base path\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the explicit base path.\n"
|
||||
) +
|
||||
gsi::method ("explicit_base_path=", &lay::Technology::set_explicit_base_path, gsi::arg ("path"),
|
||||
gsi::method ("explicit_base_path=", &db::Technology::set_explicit_base_path, gsi::arg ("path"),
|
||||
"@brief Sets the explicit base path\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the explicit base path.\n"
|
||||
) +
|
||||
gsi::method ("description", &lay::Technology::description,
|
||||
gsi::method ("description", &db::Technology::description,
|
||||
"@brief Gets the description\n"
|
||||
"\n"
|
||||
"The technology description is shown to the user in technology selection dialogs and for "
|
||||
"display purposes."
|
||||
) +
|
||||
gsi::method ("description=", &lay::Technology::set_description, gsi::arg ("description"),
|
||||
gsi::method ("description=", &db::Technology::set_description, gsi::arg ("description"),
|
||||
"@brief Sets the description\n"
|
||||
) +
|
||||
gsi::method ("dbu", &lay::Technology::dbu,
|
||||
gsi::method ("dbu", &db::Technology::dbu,
|
||||
"@brief Gets the default database unit\n"
|
||||
"\n"
|
||||
"The default database unit is the one used when creating a layout for example."
|
||||
) +
|
||||
gsi::method ("dbu=", &lay::Technology::set_dbu, gsi::arg ("dbu"),
|
||||
gsi::method ("dbu=", &db::Technology::set_dbu, gsi::arg ("dbu"),
|
||||
"@brief Sets the default database unit\n"
|
||||
) +
|
||||
gsi::method ("layer_properties_file", &lay::Technology::layer_properties_file,
|
||||
gsi::method ("layer_properties_file", &db::Technology::layer_properties_file,
|
||||
"@brief Gets the path of the layer properties file\n"
|
||||
"\n"
|
||||
"If empty, no layer properties file is associated with the technology. "
|
||||
"If non-empty, this path will be corrected by the base path (see \\correct_path) and "
|
||||
"this layer properties file will be loaded for layouts with this technology."
|
||||
) +
|
||||
gsi::method ("layer_properties_file=", &lay::Technology::set_layer_properties_file, gsi::arg ("file"),
|
||||
gsi::method ("layer_properties_file=", &db::Technology::set_layer_properties_file, gsi::arg ("file"),
|
||||
"@brief Sets the path of the layer properties file\n"
|
||||
"\n"
|
||||
"See \\layer_properties_file for details about this property."
|
||||
) +
|
||||
gsi::method ("eff_layer_properties_file", &lay::Technology::eff_layer_properties_file,
|
||||
gsi::method ("eff_layer_properties_file", &db::Technology::eff_layer_properties_file,
|
||||
"@brief Gets the effective path of the layer properties file\n"
|
||||
) +
|
||||
gsi::method ("add_other_layers?", &lay::Technology::add_other_layers,
|
||||
gsi::method ("add_other_layers?", &db::Technology::add_other_layers,
|
||||
"@brief Gets the flag indicating whether to add other layers to the layer properties\n"
|
||||
) +
|
||||
gsi::method ("add_other_layers=", &lay::Technology::set_add_other_layers, gsi::arg ("add"),
|
||||
gsi::method ("add_other_layers=", &db::Technology::set_add_other_layers, gsi::arg ("add"),
|
||||
"@brief Sets the flag indicating whether to add other layers to the layer properties\n"
|
||||
) +
|
||||
gsi::method ("load_layout_options", &lay::Technology::load_layout_options,
|
||||
gsi::method ("load_layout_options", &db::Technology::load_layout_options,
|
||||
"@brief Gets the layout reader options\n"
|
||||
"\n"
|
||||
"This method returns the layout reader options that are used when reading layouts "
|
||||
|
|
@ -228,12 +228,12 @@ gsi::Class<lay::Technology> technology_decl ("lay", "Technology",
|
|||
"tech.load_layout_options = opt\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
gsi::method ("load_layout_options=", &lay::Technology::set_load_layout_options, gsi::arg ("options"),
|
||||
gsi::method ("load_layout_options=", &db::Technology::set_load_layout_options, gsi::arg ("options"),
|
||||
"@brief Sets the layout reader options\n"
|
||||
"\n"
|
||||
"See \\load_layout_options for a description of this property.\n"
|
||||
) +
|
||||
gsi::method ("save_layout_options", &lay::Technology::save_layout_options,
|
||||
gsi::method ("save_layout_options", &db::Technology::save_layout_options,
|
||||
"@brief Gets the layout writer options\n"
|
||||
"\n"
|
||||
"This method returns the layout writer options that are used when writing layouts "
|
||||
|
|
@ -247,15 +247,15 @@ gsi::Class<lay::Technology> technology_decl ("lay", "Technology",
|
|||
"tech.save_layout_options = opt\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
gsi::method ("save_layout_options=", &lay::Technology::set_save_layout_options, gsi::arg ("options"),
|
||||
gsi::method ("save_layout_options=", &db::Technology::set_save_layout_options, gsi::arg ("options"),
|
||||
"@brief Sets the layout writer options\n"
|
||||
"\n"
|
||||
"See \\save_layout_options for a description of this property.\n"
|
||||
) +
|
||||
gsi::method ("load", &lay::Technology::load, gsi::arg ("file"),
|
||||
gsi::method ("load", &db::Technology::load, gsi::arg ("file"),
|
||||
"@brief Loads the technology definition from a file\n"
|
||||
) +
|
||||
gsi::method ("load", &lay::Technology::save, gsi::arg ("file"),
|
||||
gsi::method ("load", &db::Technology::save, gsi::arg ("file"),
|
||||
"@brief Saves the technology definition to a file\n"
|
||||
) +
|
||||
gsi::method ("technology_names", &technology_names,
|
||||
|
|
@ -334,7 +334,7 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
|||
}
|
||||
|
||||
// fetch the net tracer data from the technology and apply to the current layout
|
||||
const lay::Technology *tech = cv->technology ();
|
||||
const db::Technology *tech = cv->technology ();
|
||||
if (! tech) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1192,17 +1192,17 @@ BEGIN_PROTECTED
|
|||
tech_name = cv->tech_name ();
|
||||
}
|
||||
|
||||
if (! lay::Technologies::instance ()->has_technology (tech_name)) {
|
||||
if (! db::Technologies::instance ()->has_technology (tech_name)) {
|
||||
throw std::runtime_error (tl::to_string (QObject::tr ("Invalid technology attached to layout: ")) + tech_name);
|
||||
}
|
||||
|
||||
// create a temporary copy
|
||||
lay::Technology tech = *lay::Technologies::instance ()->technology_by_name (tech_name);
|
||||
db::Technology tech = *db::Technologies::instance ()->technology_by_name (tech_name);
|
||||
|
||||
// call the dialog and if successful, install the new technology
|
||||
lay::TechComponentSetupDialog dialog (this, &tech, net_tracer_component_name);
|
||||
if (dialog.exec ()) {
|
||||
*lay::Technologies::instance ()->technology_by_name (tech.name ()) = tech;
|
||||
*db::Technologies::instance ()->technology_by_name (tech.name ()) = tech;
|
||||
}
|
||||
|
||||
END_PROTECTED
|
||||
|
|
|
|||
|
|
@ -358,13 +358,13 @@ NetTracerLayerExpressionInfo::get (const db::Layout &layout, const NetTracerTech
|
|||
// NetTracerTechnologyComponent implementation
|
||||
|
||||
NetTracerTechnologyComponent::NetTracerTechnologyComponent ()
|
||||
: lay::TechnologyComponent (net_tracer_component_name, tl::to_string (QObject::tr ("Connectivity")))
|
||||
: db::TechnologyComponent (net_tracer_component_name, tl::to_string (QObject::tr ("Connectivity")))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetTracerTechnologyComponent::NetTracerTechnologyComponent (const NetTracerTechnologyComponent &d)
|
||||
: lay::TechnologyComponent (net_tracer_component_name, tl::to_string (QObject::tr ("Connectivity")))
|
||||
: db::TechnologyComponent (net_tracer_component_name, tl::to_string (QObject::tr ("Connectivity")))
|
||||
{
|
||||
m_connections = d.m_connections;
|
||||
m_symbols = d.m_symbols;
|
||||
|
|
@ -414,12 +414,6 @@ NetTracerTechnologyComponent::get_tracer_data (const db::Layout &layout) const
|
|||
return data;
|
||||
}
|
||||
|
||||
lay::TechnologyComponentEditor *
|
||||
NetTracerTechnologyComponent::create_editor (QWidget *parent)
|
||||
{
|
||||
return new NetTracerTechComponentEditor (parent);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// NetTracerConnectivityColumnDelegate definition and implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ private:
|
|||
};
|
||||
|
||||
class EXT_PUBLIC NetTracerTechnologyComponent
|
||||
: public lay::TechnologyComponent
|
||||
: public db::TechnologyComponent
|
||||
{
|
||||
public:
|
||||
typedef std::vector<NetTracerConnectionInfo>::const_iterator const_iterator;
|
||||
|
|
@ -469,9 +469,7 @@ public:
|
|||
|
||||
NetTracerData get_tracer_data (const db::Layout &layout) const;
|
||||
|
||||
virtual lay::TechnologyComponentEditor *create_editor (QWidget *parent);
|
||||
|
||||
lay::TechnologyComponent *clone () const
|
||||
db::TechnologyComponent *clone () const
|
||||
{
|
||||
return new NetTracerTechnologyComponent (*this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,12 +79,23 @@ extern std::string net_tracer_component_name;
|
|||
// -----------------------------------------------------------------------------------
|
||||
// NetTracerPlugin definition and implementation
|
||||
|
||||
class NetTracerPluginDeclaration
|
||||
: public lay::PluginDeclaration,
|
||||
public lay::TechnologyComponentProvider
|
||||
class NetTracerTechnologyEditorProvider
|
||||
: public lay::TechnologyEditorProvider
|
||||
{
|
||||
public:
|
||||
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const
|
||||
virtual lay::TechnologyComponentEditor *create_editor (QWidget *parent) const
|
||||
{
|
||||
return new NetTracerTechComponentEditor (parent);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::TechnologyEditorProvider> editor_decl (new NetTracerTechnologyEditorProvider (), 13000, "NetTracerPlugin");
|
||||
|
||||
class NetTracerPluginDeclaration
|
||||
: public lay::PluginDeclaration
|
||||
{
|
||||
public:
|
||||
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const
|
||||
{
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_nt_window_mode, "fit-net"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_nt_window_dim, "1.0"));
|
||||
|
|
@ -99,7 +110,7 @@ public:
|
|||
options.push_back (std::pair<std::string, std::string> (cfg_nt_marker_intensity, "50"));
|
||||
}
|
||||
|
||||
virtual std::vector<std::pair <std::string, lay::ConfigPage *> > config_pages (QWidget *parent) const
|
||||
virtual std::vector<std::pair <std::string, lay::ConfigPage *> > config_pages (QWidget *parent) const
|
||||
{
|
||||
std::vector<std::pair <std::string, lay::ConfigPage *> > pages;
|
||||
pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Other Tools|Net Tracer")), new NetTracerConfigPage (parent)));
|
||||
|
|
@ -113,32 +124,40 @@ public:
|
|||
menu_entries.push_back (lay::MenuEntry ("net_trace_group", "tools_menu.end"));
|
||||
menu_entries.push_back (lay::MenuEntry ("ext::net_trace", "net_trace", "tools_menu.end", tl::to_string (QObject::tr ("Trace Net"))));
|
||||
}
|
||||
|
||||
|
||||
virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::PluginRoot *root, lay::LayoutView *view) const
|
||||
{
|
||||
return new NetTracerDialog (root, view);
|
||||
}
|
||||
};
|
||||
|
||||
virtual const lay::TechnologyComponentProvider *technology_component_provider () const
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new NetTracerPluginDeclaration (), 13000, "NetTracerPlugin");
|
||||
|
||||
class NetTracerTechnologyComponentProvider
|
||||
: public db::TechnologyComponentProvider
|
||||
{
|
||||
public:
|
||||
NetTracerTechnologyComponentProvider ()
|
||||
: db::TechnologyComponentProvider ()
|
||||
{
|
||||
return this;
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual lay::TechnologyComponent *create_component () const
|
||||
virtual db::TechnologyComponent *create_component () const
|
||||
{
|
||||
return new NetTracerTechnologyComponent ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::TechnologyComponentXMLElement<NetTracerTechnologyComponent> (net_tracer_component_name,
|
||||
return new db::TechnologyComponentXMLElement<NetTracerTechnologyComponent> (net_tracer_component_name,
|
||||
tl::make_member ((NetTracerTechnologyComponent::const_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::begin, (NetTracerTechnologyComponent::const_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::end, &NetTracerTechnologyComponent::add, "connection") +
|
||||
tl::make_member ((NetTracerTechnologyComponent::const_symbol_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::begin_symbols, (NetTracerTechnologyComponent::const_symbol_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::end_symbols, &NetTracerTechnologyComponent::add_symbol, "symbols")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new NetTracerPluginDeclaration (), 13000, "NetTracerPlugin");
|
||||
static tl::RegisteredClass<db::TechnologyComponentProvider> tc_decl (new NetTracerTechnologyComponentProvider (), 13000, "NetTracerPlugin");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +187,7 @@ static void def_symbol (ext::NetTracerTechnologyComponent *tech, const std::stri
|
|||
tech->add_symbol (ext::NetTracerSymbolInfo (db::LayerProperties (name), expr));
|
||||
}
|
||||
|
||||
gsi::Class<lay::TechnologyComponent> &decl_layTechnologyComponent ();
|
||||
gsi::Class<db::TechnologyComponent> &decl_layTechnologyComponent ();
|
||||
|
||||
gsi::Class<ext::NetTracerTechnologyComponent> decl_NetTracerTechnology (decl_layTechnologyComponent (), "lay", "NetTracerTechnology",
|
||||
gsi::method_ext ("connection", &def_connection2, gsi::arg("a"), gsi::arg("b"),
|
||||
|
|
@ -216,7 +235,7 @@ static void trace2 (ext::NetTracer *net_tracer, const ext::NetTracerTechnologyCo
|
|||
|
||||
static ext::NetTracerData get_tracer_data_from_cv (const lay::CellViewRef &cv)
|
||||
{
|
||||
const lay::Technology *tech = cv->technology ();
|
||||
const db::Technology *tech = cv->technology ();
|
||||
tl_assert (tech != 0);
|
||||
|
||||
const ext::NetTracerTechnologyComponent *tech_component = dynamic_cast <const ext::NetTracerTechnologyComponent *> (tech->component_by_name (ext::net_tracer_component_name));
|
||||
|
|
@ -239,7 +258,7 @@ static void trace2_cv (ext::NetTracer *net_tracer, const lay::CellViewRef &cv, c
|
|||
|
||||
static ext::NetTracerData get_tracer_data_from_tech (const std::string &tech_name, const db::Layout &layout)
|
||||
{
|
||||
const lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (tech_name);
|
||||
const db::Technology *tech = db::Technologies::instance ()->technology_by_name (tech_name);
|
||||
tl_assert (tech != 0);
|
||||
|
||||
const ext::NetTracerTechnologyComponent *tech_component = dynamic_cast <const ext::NetTracerTechnologyComponent *> (tech->component_by_name (ext::net_tracer_component_name));
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ static tl::XMLElementList xml_elements ()
|
|||
) +
|
||||
tl::make_member (&StreamImportData::explicit_trans, "explicit-trans") +
|
||||
tl::make_element (&StreamImportData::options, "options",
|
||||
lay::load_options_xml_element_list ()
|
||||
db::load_options_xml_element_list ()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -670,7 +670,7 @@ ApplicationBase::init_app ()
|
|||
tl::info << "Importing technology from " << f->second.second;
|
||||
}
|
||||
|
||||
lay::Technology t;
|
||||
db::Technology t;
|
||||
t.load (f->second.second);
|
||||
|
||||
tc->add_temp_tech (t);
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ LibraryController::sync_files ()
|
|||
|
||||
// add the technologies as potential sources for library definitions
|
||||
|
||||
for (lay::Technologies::iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
for (db::Technologies::iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
if (! t->base_path ().empty ()) {
|
||||
paths.push_back (std::make_pair (t->base_path (), t->name ()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ MacroController::sync_macro_sources ()
|
|||
std::map<std::string, std::vector<std::string> > grain_names_by_path;
|
||||
std::set<std::string> readonly_paths;
|
||||
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
if (! t->base_path ().empty ()) {
|
||||
QDir base_dir (tl::to_qstring (t->base_path ()));
|
||||
if (base_dir.exists ()) {
|
||||
|
|
@ -652,7 +652,7 @@ static std::string menu_name (std::set<std::string> &used_names, const std::stri
|
|||
}
|
||||
|
||||
void
|
||||
MacroController::add_macro_items_to_menu (lym::MacroCollection &collection, std::set<std::string> &used_names, std::set<std::string> &groups, const lay::Technology *tech)
|
||||
MacroController::add_macro_items_to_menu (lym::MacroCollection &collection, std::set<std::string> &used_names, std::set<std::string> &groups, const db::Technology *tech)
|
||||
{
|
||||
for (lym::MacroCollection::child_iterator c = collection.begin_children (); c != collection.end_children (); ++c) {
|
||||
|
||||
|
|
@ -775,7 +775,7 @@ MacroController::do_update_menu_with_macros ()
|
|||
return;
|
||||
}
|
||||
|
||||
const lay::Technology *tech = 0;
|
||||
const db::Technology *tech = 0;
|
||||
if (lay::TechnologyController::instance ()) {
|
||||
tech = lay::TechnologyController::instance ()->active_technology ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,16 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
namespace db
|
||||
{
|
||||
class Technology;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class MacroEditorDialog;
|
||||
class MainWindow;
|
||||
class Technology;
|
||||
class Action;
|
||||
|
||||
/**
|
||||
|
|
@ -248,7 +252,7 @@ private:
|
|||
std::vector<std::pair<std::string, bool> > m_menu_items_hidden;
|
||||
|
||||
void sync_implicit_macros (bool ask_before_autorun);
|
||||
void add_macro_items_to_menu (lym::MacroCollection &collection, std::set<std::string> &used_names, std::set<std::string> &groups, const lay::Technology *tech);
|
||||
void add_macro_items_to_menu (lym::MacroCollection &collection, std::set<std::string> &used_names, std::set<std::string> &groups, const db::Technology *tech);
|
||||
void do_update_menu_with_macros ();
|
||||
void do_sync_with_external_sources ();
|
||||
void sync_file_watcher ();
|
||||
|
|
|
|||
|
|
@ -3390,13 +3390,13 @@ MainWindow::cm_pull_in ()
|
|||
void
|
||||
MainWindow::cm_reader_options ()
|
||||
{
|
||||
mp_layout_load_options->edit_global_options (this, lay::Technologies::instance ());
|
||||
mp_layout_load_options->edit_global_options (this, db::Technologies::instance ());
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::cm_writer_options ()
|
||||
{
|
||||
mp_layout_save_options->edit_global_options (this, lay::Technologies::instance ());
|
||||
mp_layout_save_options->edit_global_options (this, db::Technologies::instance ());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4154,7 +4154,7 @@ MainWindow::open_recent ()
|
|||
return;
|
||||
}
|
||||
|
||||
if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, lay::Technologies::instance ())) {
|
||||
if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, db::Technologies::instance ())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4203,7 +4203,7 @@ MainWindow::open (int mode)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, lay::Technologies::instance ())) {
|
||||
if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, db::Technologies::instance ())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ public:
|
|||
*/
|
||||
lay::CellViewRef load_layout (const std::string &filename, const std::string &technology, int mode = 0)
|
||||
{
|
||||
return load_layout (filename, lay::Technologies::instance ()->technology_by_name (technology)->load_layout_options (), technology, mode);
|
||||
return load_layout (filename, db::Technologies::instance ()->technology_by_name (technology)->load_layout_options (), technology, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "layStream.h"
|
||||
#include "tlXMLParser.h"
|
||||
#include "tlStream.h"
|
||||
#include "dbStream.h"
|
||||
#include "rdb.h"
|
||||
|
||||
#include <fstream>
|
||||
|
|
@ -261,10 +262,10 @@ session_structure ("session",
|
|||
tl::make_member<std::string, SessionLayoutDescriptor> (&SessionLayoutDescriptor::file_path, "file-path") +
|
||||
tl::make_member<bool, SessionLayoutDescriptor> (&SessionLayoutDescriptor::save_options_valid, "save-options-valid") +
|
||||
tl::make_element<db::SaveLayoutOptions, SessionLayoutDescriptor> (&SessionLayoutDescriptor::save_options, "save-options",
|
||||
lay::save_options_xml_element_list ()
|
||||
db::save_options_xml_element_list ()
|
||||
) +
|
||||
tl::make_element<db::LoadLayoutOptions, SessionLayoutDescriptor> (&SessionLayoutDescriptor::load_options, "load-options",
|
||||
lay::load_options_xml_element_list ()
|
||||
db::load_options_xml_element_list ()
|
||||
)
|
||||
) +
|
||||
tl::make_element<SessionViewDescriptor, std::vector<SessionViewDescriptor>::const_iterator, Session> (&Session::begin_views, &Session::end_views, &Session::add_view, "view",
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "lymMacro.h"
|
||||
#include "tlAssert.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlClassRegistry.h"
|
||||
#include "dbStream.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
|
|
@ -52,7 +53,7 @@ namespace lay
|
|||
// ----------------------------------------------------------------
|
||||
|
||||
static std::string
|
||||
title_for_technology (const lay::Technology *t)
|
||||
title_for_technology (const db::Technology *t)
|
||||
{
|
||||
std::string d;
|
||||
if (t->name ().empty ()) {
|
||||
|
|
@ -544,7 +545,7 @@ TechSetupDialog::~TechSetupDialog ()
|
|||
void
|
||||
TechSetupDialog::clear_components ()
|
||||
{
|
||||
for (std::map <std::string, lay::TechnologyComponent *>::iterator tc = m_technology_components.begin (); tc != m_technology_components.end (); ++tc) {
|
||||
for (std::map <std::string, db::TechnologyComponent *>::iterator tc = m_technology_components.begin (); tc != m_technology_components.end (); ++tc) {
|
||||
delete tc->second;
|
||||
}
|
||||
m_technology_components.clear ();
|
||||
|
|
@ -627,7 +628,7 @@ TechSetupDialog::update ()
|
|||
}
|
||||
|
||||
int
|
||||
TechSetupDialog::exec (lay::Technologies &technologies)
|
||||
TechSetupDialog::exec (db::Technologies &technologies)
|
||||
{
|
||||
if (s_first_show) {
|
||||
TipDialog td (this,
|
||||
|
|
@ -649,7 +650,7 @@ TechSetupDialog::exec (lay::Technologies &technologies)
|
|||
|
||||
// clean up
|
||||
update_tech (0);
|
||||
m_technologies = lay::Technologies ();
|
||||
m_technologies = db::Technologies ();
|
||||
update_tech_tree ();
|
||||
|
||||
return ret;
|
||||
|
|
@ -662,7 +663,7 @@ BEGIN_PROTECTED
|
|||
|
||||
commit_tech_component ();
|
||||
|
||||
lay::Technology *t = selected_tech ();
|
||||
db::Technology *t = selected_tech ();
|
||||
if (! t) {
|
||||
t = m_technologies.technology_by_name (std::string ());
|
||||
tl_assert (t != 0);
|
||||
|
|
@ -698,7 +699,7 @@ BEGIN_PROTECTED
|
|||
}
|
||||
}
|
||||
|
||||
lay::Technology *nt = new lay::Technology (*t);
|
||||
db::Technology *nt = new db::Technology (*t);
|
||||
|
||||
nt->set_tech_file_path (tl::to_string (tech_dir.absoluteFilePath (tn + QString::fromUtf8 (".lyt"))));
|
||||
nt->set_default_base_path (tl::to_string (tech_dir.absolutePath ()));
|
||||
|
|
@ -720,7 +721,7 @@ TechSetupDialog::delete_clicked ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
lay::Technology *t = selected_tech ();
|
||||
db::Technology *t = selected_tech ();
|
||||
if (! t) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("No technology selected")));
|
||||
}
|
||||
|
|
@ -737,7 +738,7 @@ BEGIN_PROTECTED
|
|||
QObject::tr ("Are you sure to delete this technology?\nThis operation cannot be undone, except by cancelling the technology manager."),
|
||||
QMessageBox::No | QMessageBox::Yes) == QMessageBox::Yes) {
|
||||
|
||||
for (lay::Technologies::const_iterator i = m_technologies.begin (); i != m_technologies.end (); ++i) {
|
||||
for (db::Technologies::const_iterator i = m_technologies.begin (); i != m_technologies.end (); ++i) {
|
||||
|
||||
if (i->name () == t->name ()) {
|
||||
|
||||
|
|
@ -763,7 +764,7 @@ BEGIN_PROTECTED
|
|||
|
||||
commit_tech_component ();
|
||||
|
||||
lay::Technology *t = selected_tech ();
|
||||
db::Technology *t = selected_tech ();
|
||||
if (! t) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("No technology selected")));
|
||||
}
|
||||
|
|
@ -821,13 +822,13 @@ BEGIN_PROTECTED
|
|||
std::string fn;
|
||||
if (open_dialog.get_open (fn)) {
|
||||
|
||||
lay::Technology t;
|
||||
db::Technology t;
|
||||
t.load (fn);
|
||||
|
||||
if (m_technologies.has_technology (t.name ())) {
|
||||
*m_technologies.technology_by_name (t.name ()) = t;
|
||||
} else {
|
||||
m_technologies.add (new lay::Technology (t));
|
||||
m_technologies.add (new db::Technology (t));
|
||||
}
|
||||
|
||||
update_tech_tree ();
|
||||
|
|
@ -843,7 +844,7 @@ TechSetupDialog::export_clicked ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
lay::Technology *t = selected_tech ();
|
||||
db::Technology *t = selected_tech ();
|
||||
if (! t) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("No technology selected")));
|
||||
}
|
||||
|
|
@ -863,12 +864,12 @@ TechSetupDialog::update_tech_tree ()
|
|||
{
|
||||
tech_tree->clear ();
|
||||
|
||||
std::map <std::string, const lay::Technology *> tech_by_name;
|
||||
for (lay::Technologies::const_iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
std::map <std::string, const db::Technology *> tech_by_name;
|
||||
for (db::Technologies::const_iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
tech_by_name.insert (std::make_pair (t->name (), &*t));
|
||||
}
|
||||
|
||||
for (std::map <std::string, const lay::Technology *>::const_iterator t = tech_by_name.begin (); t != tech_by_name.end (); ++t) {
|
||||
for (std::map <std::string, const db::Technology *>::const_iterator t = tech_by_name.begin (); t != tech_by_name.end (); ++t) {
|
||||
|
||||
QFont f (tech_tree->font ());
|
||||
f.setItalic (t->second->is_readonly ());
|
||||
|
|
@ -882,7 +883,7 @@ TechSetupDialog::update_tech_tree ()
|
|||
}
|
||||
|
||||
std::vector <std::string> tc_names = t->second->component_names ();
|
||||
std::map <std::string, const lay::TechnologyComponent *> tc_by_name;
|
||||
std::map <std::string, const db::TechnologyComponent *> tc_by_name;
|
||||
for (std::vector <std::string>::const_iterator n = tc_names.begin (); n != tc_names.end (); ++n) {
|
||||
tc_by_name.insert (std::make_pair (*n, t->second->component_by_name (*n)));
|
||||
}
|
||||
|
|
@ -912,7 +913,7 @@ TechSetupDialog::update_tech_tree ()
|
|||
}
|
||||
}
|
||||
|
||||
for (std::map <std::string, const lay::TechnologyComponent *>::const_iterator c = tc_by_name.begin (); c != tc_by_name.end (); ++c) {
|
||||
for (std::map <std::string, const db::TechnologyComponent *>::const_iterator c = tc_by_name.begin (); c != tc_by_name.end (); ++c) {
|
||||
tci = new QTreeWidgetItem (ti);
|
||||
tci->setData (0, Qt::DisplayRole, QVariant (tl::to_qstring (c->second->description ())));
|
||||
tci->setData (0, Qt::UserRole + 1, QVariant (tl::to_qstring (c->first)));
|
||||
|
|
@ -923,7 +924,7 @@ TechSetupDialog::update_tech_tree ()
|
|||
}
|
||||
|
||||
void
|
||||
TechSetupDialog::update_tech (lay::Technology *t)
|
||||
TechSetupDialog::update_tech (db::Technology *t)
|
||||
{
|
||||
if (t == mp_current_tech) {
|
||||
return;
|
||||
|
|
@ -967,10 +968,16 @@ TechSetupDialog::update_tech (lay::Technology *t)
|
|||
std::vector <std::string> tc_names = t->component_names ();
|
||||
for (std::vector <std::string>::const_iterator n = tc_names.begin (); n != tc_names.end (); ++n) {
|
||||
|
||||
TechnologyComponent *tc = t->component_by_name (*n)->clone ();
|
||||
db::TechnologyComponent *tc = t->component_by_name (*n)->clone ();
|
||||
m_technology_components.insert (std::make_pair (*n, tc));
|
||||
|
||||
tce_widget = tc->create_editor (this);
|
||||
tce_widget = 0;
|
||||
for (tl::Registrar<lay::TechnologyEditorProvider>::iterator cls = tl::Registrar<lay::TechnologyEditorProvider>::begin (); cls != tl::Registrar<lay::TechnologyEditorProvider>::begin () && ! tce_widget; ++cls) {
|
||||
if (cls.current_name () == tc->name ()) {
|
||||
tce_widget = cls->create_editor (this);
|
||||
}
|
||||
}
|
||||
|
||||
if (tce_widget) {
|
||||
tce_widget->setEnabled (!t->is_readonly ());
|
||||
tce_widget->set_technology (t, tc);
|
||||
|
|
@ -990,7 +997,7 @@ TechSetupDialog::update_tech_component ()
|
|||
std::map <std::string, lay::TechnologyComponentEditor *>::const_iterator tce = m_component_editors.find (tc_name);
|
||||
if (tce != m_component_editors.end ()) {
|
||||
|
||||
std::map <std::string, lay::TechnologyComponent *>::const_iterator tc = m_technology_components.find (tc_name);
|
||||
std::map <std::string, db::TechnologyComponent *>::const_iterator tc = m_technology_components.find (tc_name);
|
||||
if (tc != m_technology_components.end ()) {
|
||||
mp_current_tech_component = tc->second;
|
||||
} else {
|
||||
|
|
@ -1010,7 +1017,7 @@ TechSetupDialog::update_tech_component ()
|
|||
}
|
||||
|
||||
void
|
||||
TechSetupDialog::select_tech (const lay::Technology &tech)
|
||||
TechSetupDialog::select_tech (const db::Technology &tech)
|
||||
{
|
||||
// unselect the previous technology
|
||||
update_tech (0);
|
||||
|
|
@ -1081,7 +1088,7 @@ TechSetupDialog::commit_tech_component ()
|
|||
|
||||
QTreeWidgetItem *item = tech_tree->topLevelItem (i - 1);
|
||||
|
||||
lay::Technology *t = m_technologies.technology_by_name (tl::to_string (item->data (0, Qt::UserRole).toString ()));
|
||||
db::Technology *t = m_technologies.technology_by_name (tl::to_string (item->data (0, Qt::UserRole).toString ()));
|
||||
item->setData (0, Qt::DisplayRole, QVariant (tl::to_qstring (title_for_technology (t))));
|
||||
|
||||
}
|
||||
|
|
@ -1103,7 +1110,7 @@ TechSetupDialog::selected_tech_component_name ()
|
|||
return std::string ();
|
||||
}
|
||||
|
||||
lay::Technology *
|
||||
db::Technology *
|
||||
TechSetupDialog::selected_tech ()
|
||||
{
|
||||
QTreeWidgetItem *item = tech_tree->currentItem ();
|
||||
|
|
@ -1128,7 +1135,7 @@ TechSetupDialog::selected_tech ()
|
|||
// ----------------------------------------------------------------
|
||||
// TechComponentSetupDialog implementation
|
||||
|
||||
TechComponentSetupDialog::TechComponentSetupDialog (QWidget *parent, Technology *tech, const std::string &component_name)
|
||||
TechComponentSetupDialog::TechComponentSetupDialog (QWidget *parent, db::Technology *tech, const std::string &component_name)
|
||||
: QDialog (parent),
|
||||
mp_tech (tech), mp_component (0), mp_editor (0)
|
||||
{
|
||||
|
|
@ -1142,12 +1149,18 @@ TechComponentSetupDialog::TechComponentSetupDialog (QWidget *parent, Technology
|
|||
setWindowTitle (tl::to_qstring (tl::to_string (QObject::tr ("Edit Technology")) + " - " + tech->name ()));
|
||||
}
|
||||
|
||||
const TechnologyComponent *component = tech->component_by_name (component_name);
|
||||
const db::TechnologyComponent *component = tech->component_by_name (component_name);
|
||||
if (component) {
|
||||
|
||||
mp_component = component->clone ();
|
||||
|
||||
mp_editor = mp_component->create_editor (content_frame);
|
||||
mp_editor = 0;
|
||||
for (tl::Registrar<lay::TechnologyEditorProvider>::iterator cls = tl::Registrar<lay::TechnologyEditorProvider>::begin (); cls != tl::Registrar<lay::TechnologyEditorProvider>::begin () && ! mp_editor; ++cls) {
|
||||
if (cls.current_name () == mp_component->name ()) {
|
||||
mp_editor = cls->create_editor (content_frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (mp_editor) {
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout (content_frame);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
namespace db
|
||||
{
|
||||
class Technology;
|
||||
}
|
||||
|
||||
namespace lym
|
||||
{
|
||||
class Macro;
|
||||
|
|
@ -48,7 +53,6 @@ namespace lay
|
|||
{
|
||||
|
||||
class TechnologyComponentEditor;
|
||||
class Technology;
|
||||
|
||||
class TechBaseEditorPage
|
||||
: public TechnologyComponentEditor,
|
||||
|
|
@ -133,7 +137,7 @@ public:
|
|||
TechSetupDialog (QWidget *parent);
|
||||
~TechSetupDialog ();
|
||||
|
||||
int exec (lay::Technologies &technologies);
|
||||
int exec (db::Technologies &technologies);
|
||||
|
||||
protected slots:
|
||||
void current_tech_changed (QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
||||
|
|
@ -146,22 +150,22 @@ protected slots:
|
|||
|
||||
private:
|
||||
void update_tech_tree ();
|
||||
void update_tech (lay::Technology *tech);
|
||||
void update_tech (db::Technology *tech);
|
||||
void update_tech_component ();
|
||||
void accept ();
|
||||
lay::Technology *selected_tech ();
|
||||
void select_tech (const lay::Technology &tech);
|
||||
db::Technology *selected_tech ();
|
||||
void select_tech (const db::Technology &tech);
|
||||
std::string selected_tech_component_name ();
|
||||
void commit_tech_component ();
|
||||
void clear_components ();
|
||||
void update ();
|
||||
|
||||
lay::Technologies m_technologies;
|
||||
lay::Technology *mp_current_tech;
|
||||
db::Technologies m_technologies;
|
||||
db::Technology *mp_current_tech;
|
||||
std::map <std::string, lay::TechnologyComponentEditor *> m_component_editors;
|
||||
std::map <std::string, lay::TechnologyComponent *> m_technology_components;
|
||||
std::map <std::string, db::TechnologyComponent *> m_technology_components;
|
||||
lay::TechnologyComponentEditor *mp_current_editor;
|
||||
lay::TechnologyComponent *mp_current_tech_component;
|
||||
db::TechnologyComponent *mp_current_tech_component;
|
||||
bool m_current_tech_changed_enabled;
|
||||
};
|
||||
|
||||
|
|
@ -170,16 +174,16 @@ class LAY_PUBLIC TechComponentSetupDialog
|
|||
public Ui::TechComponentSetupDialog
|
||||
{
|
||||
public:
|
||||
TechComponentSetupDialog (QWidget *parent, Technology *tech, const std::string &component_name);
|
||||
TechComponentSetupDialog (QWidget *parent, db::Technology *tech, const std::string &component_name);
|
||||
~TechComponentSetupDialog ();
|
||||
|
||||
protected:
|
||||
void accept ();
|
||||
|
||||
private:
|
||||
Technology *mp_tech;
|
||||
TechnologyComponent *mp_component;
|
||||
TechnologyComponentEditor *mp_editor;
|
||||
db::Technology *mp_tech;
|
||||
db::TechnologyComponent *mp_component;
|
||||
lay::TechnologyComponentEditor *mp_editor;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,8 +128,8 @@ TechnologyController::connect_events ()
|
|||
|
||||
tl::Object::detach_from_all_events ();
|
||||
|
||||
lay::Technologies::instance ()->technology_changed_event.add (this, &TechnologyController::technology_changed);
|
||||
lay::Technologies::instance ()->technologies_changed_event.add (this, &TechnologyController::technologies_changed);
|
||||
db::Technologies::instance ()->technology_changed_event.add (this, &TechnologyController::technology_changed);
|
||||
db::Technologies::instance ()->technologies_changed_event.add (this, &TechnologyController::technologies_changed);
|
||||
|
||||
if (mp_mw) {
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ TechnologyController::connect_events ()
|
|||
}
|
||||
}
|
||||
|
||||
lay::Technology *
|
||||
db::Technology *
|
||||
TechnologyController::active_technology () const
|
||||
{
|
||||
return mp_active_technology;
|
||||
|
|
@ -163,12 +163,12 @@ TechnologyController::active_technology () const
|
|||
void
|
||||
TechnologyController::update_active_technology ()
|
||||
{
|
||||
lay::Technology *active_tech = 0;
|
||||
db::Technology *active_tech = 0;
|
||||
if (mp_mw && mp_mw->current_view () && mp_mw->current_view ()->active_cellview_index () >= 0 && mp_mw->current_view ()->active_cellview_index () <= int (mp_mw->current_view ()->cellviews ())) {
|
||||
|
||||
std::string tn = mp_mw->current_view ()->active_cellview ()->tech_name ();
|
||||
if (lay::Technologies::instance ()->has_technology (tn)) {
|
||||
active_tech = lay::Technologies::instance ()->technology_by_name (tn);
|
||||
if (db::Technologies::instance ()->has_technology (tn)) {
|
||||
active_tech = db::Technologies::instance ()->technology_by_name (tn);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -207,7 +207,7 @@ TechnologyController::technologies_changed ()
|
|||
if (pr) {
|
||||
m_configure_enabled = false;
|
||||
try {
|
||||
pr->config_set (cfg_technologies, lay::Technologies::instance ()->to_xml ());
|
||||
pr->config_set (cfg_technologies, db::Technologies::instance ()->to_xml ());
|
||||
m_configure_enabled = true;
|
||||
} catch (...) {
|
||||
m_configure_enabled = true;
|
||||
|
|
@ -220,7 +220,7 @@ TechnologyController::technologies_changed ()
|
|||
}
|
||||
|
||||
void
|
||||
TechnologyController::technology_changed (lay::Technology *)
|
||||
TechnologyController::technology_changed (db::Technology *)
|
||||
{
|
||||
technologies_changed ();
|
||||
}
|
||||
|
|
@ -248,7 +248,7 @@ TechnologyController::configure (const std::string &name, const std::string &val
|
|||
if (! value.empty ()) {
|
||||
|
||||
try {
|
||||
lay::Technologies new_tech = *lay::Technologies::instance ();
|
||||
db::Technologies new_tech = *db::Technologies::instance ();
|
||||
new_tech.load_from_xml (value);
|
||||
replace_technologies (new_tech);
|
||||
m_technologies_configured = true;
|
||||
|
|
@ -310,13 +310,13 @@ TechnologyController::update_current_technology ()
|
|||
action.set_title (title);
|
||||
}
|
||||
|
||||
std::map<std::string, const lay::Technology *> tech_by_name;
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
std::map<std::string, const db::Technology *> tech_by_name;
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
tech_by_name.insert (std::make_pair (t->name (), t.operator-> ()));
|
||||
}
|
||||
|
||||
int it = 0;
|
||||
for (std::map<std::string, const lay::Technology *>::const_iterator t = tech_by_name.begin (); t != tech_by_name.end (); ++t, ++it) {
|
||||
for (std::map<std::string, const db::Technology *>::const_iterator t = tech_by_name.begin (); t != tech_by_name.end (); ++t, ++it) {
|
||||
m_tech_actions[it].set_checked (t->second->name () == m_current_technology);
|
||||
}
|
||||
}
|
||||
|
|
@ -333,14 +333,14 @@ TechnologyController::update_menu ()
|
|||
m_current_technology = lay::LayoutView::current ()->active_cellview ()->tech_name ();
|
||||
}
|
||||
|
||||
if (! lay::Technologies::instance()->has_technology (m_current_technology)) {
|
||||
if (! db::Technologies::instance()->has_technology (m_current_technology)) {
|
||||
m_current_technology = std::string ();
|
||||
}
|
||||
|
||||
std::string title = tech_string_from_name (m_current_technology);
|
||||
|
||||
size_t ntech = 0;
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
++ntech;
|
||||
}
|
||||
|
||||
|
|
@ -358,13 +358,13 @@ TechnologyController::update_menu ()
|
|||
|
||||
m_tech_actions.clear ();
|
||||
|
||||
std::map<std::string, const lay::Technology *> tech_by_name;
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
std::map<std::string, const db::Technology *> tech_by_name;
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
tech_by_name.insert (std::make_pair (t->name (), t.operator-> ()));
|
||||
}
|
||||
|
||||
int it = 0;
|
||||
for (std::map<std::string, const lay::Technology *>::const_iterator t = tech_by_name.begin (); t != tech_by_name.end (); ++t, ++it) {
|
||||
for (std::map<std::string, const db::Technology *>::const_iterator t = tech_by_name.begin (); t != tech_by_name.end (); ++t, ++it) {
|
||||
|
||||
std::string title = tech_string_from_name (t->first);
|
||||
|
||||
|
|
@ -382,7 +382,7 @@ TechnologyController::update_menu ()
|
|||
}
|
||||
|
||||
void
|
||||
TechnologyController::replace_technologies (const lay::Technologies &technologies)
|
||||
TechnologyController::replace_technologies (const db::Technologies &technologies)
|
||||
{
|
||||
bool has_active_tech = (mp_active_technology != 0);
|
||||
std::string active_tech_name;
|
||||
|
|
@ -390,19 +390,19 @@ TechnologyController::replace_technologies (const lay::Technologies &technologie
|
|||
active_tech_name = mp_active_technology->name ();
|
||||
}
|
||||
|
||||
lay::Technologies ().instance ()->begin_updates ();
|
||||
*lay::Technologies ().instance () = technologies;
|
||||
lay::Technologies ().instance ()->end_updates_no_event ();
|
||||
db::Technologies ().instance ()->begin_updates ();
|
||||
*db::Technologies ().instance () = technologies;
|
||||
db::Technologies ().instance ()->end_updates_no_event ();
|
||||
|
||||
if (has_active_tech) {
|
||||
mp_active_technology = lay::Technologies::instance ()->technology_by_name (active_tech_name);
|
||||
mp_active_technology = db::Technologies::instance ()->technology_by_name (active_tech_name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TechnologyController::show_editor ()
|
||||
{
|
||||
lay::Technologies new_tech = *lay::Technologies ().instance ();
|
||||
db::Technologies new_tech = *db::Technologies ().instance ();
|
||||
|
||||
if (mp_editor && mp_editor->exec (new_tech)) {
|
||||
|
||||
|
|
@ -410,12 +410,12 @@ TechnologyController::show_editor ()
|
|||
|
||||
// determine the technology files that need to be deleted and delete them
|
||||
std::set<std::string> files_before;
|
||||
for (lay::Technologies::const_iterator t = new_tech.begin (); t != new_tech.end (); ++t) {
|
||||
for (db::Technologies::const_iterator t = new_tech.begin (); t != new_tech.end (); ++t) {
|
||||
if (! t->tech_file_path ().empty () && ! t->is_persisted ()) {
|
||||
files_before.insert (t->tech_file_path ());
|
||||
}
|
||||
}
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
if (! t->tech_file_path ().empty () && ! t->is_persisted () && files_before.find (t->tech_file_path ()) == files_before.end ()) {
|
||||
// TODO: issue an error if files could not be removed
|
||||
QFile (tl::to_qstring (t->tech_file_path ())).remove ();
|
||||
|
|
@ -426,7 +426,7 @@ TechnologyController::show_editor ()
|
|||
|
||||
// save the technologies that need to be saved
|
||||
// TODO: save only the ones that really need saving
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t) {
|
||||
|
||||
if (! t->tech_file_path ().empty () && ! t->is_persisted ()) {
|
||||
|
||||
|
|
@ -489,25 +489,25 @@ TechnologyController::default_root ()
|
|||
void
|
||||
TechnologyController::load ()
|
||||
{
|
||||
rescan (*lay::Technologies::instance ());
|
||||
rescan (*db::Technologies::instance ());
|
||||
}
|
||||
|
||||
void
|
||||
TechnologyController::sync_with_external_sources ()
|
||||
{
|
||||
rescan (*lay::Technologies::instance ());
|
||||
rescan (*db::Technologies::instance ());
|
||||
}
|
||||
|
||||
void
|
||||
TechnologyController::rescan (lay::Technologies &technologies)
|
||||
TechnologyController::rescan (db::Technologies &technologies)
|
||||
{
|
||||
lay::Technologies current = technologies;
|
||||
db::Technologies current = technologies;
|
||||
|
||||
// start with all persisted technologies (at least "default")
|
||||
technologies.clear ();
|
||||
for (lay::Technologies::const_iterator t = current.begin (); t != current.end (); ++t) {
|
||||
for (db::Technologies::const_iterator t = current.begin (); t != current.end (); ++t) {
|
||||
if (t->is_persisted ()) {
|
||||
technologies.add (new lay::Technology (*t));
|
||||
technologies.add (new db::Technology (*t));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -562,12 +562,12 @@ TechnologyController::rescan (lay::Technologies &technologies)
|
|||
tl::info << "Auto-importing technology from " << tl::to_string (*lf);
|
||||
}
|
||||
|
||||
lay::Technology t;
|
||||
db::Technology t;
|
||||
t.load (tl::to_string (*lf));
|
||||
t.set_persisted (false); // don't save that one in the configuration
|
||||
t.set_readonly (readonly || ! QFileInfo (dir.filePath (*lf)).isWritable ());
|
||||
t.set_grain_name (grain_name);
|
||||
technologies.add (new lay::Technology (t));
|
||||
technologies.add (new db::Technology (t));
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::warn << tl::to_string (QObject::tr ("Unable to auto-import technology file ")) << tl::to_string (*lf) << ": " << ex.msg ();
|
||||
|
|
@ -577,9 +577,9 @@ TechnologyController::rescan (lay::Technologies &technologies)
|
|||
|
||||
}
|
||||
|
||||
for (std::vector<lay::Technology>::const_iterator t = m_temp_tech.begin (); t != m_temp_tech.end (); ++t) {
|
||||
for (std::vector<db::Technology>::const_iterator t = m_temp_tech.begin (); t != m_temp_tech.end (); ++t) {
|
||||
|
||||
lay::Technology *tech = new lay::Technology (*t);
|
||||
db::Technology *tech = new db::Technology (*t);
|
||||
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
|
||||
|
|
@ -589,7 +589,7 @@ TechnologyController::rescan (lay::Technologies &technologies)
|
|||
}
|
||||
|
||||
void
|
||||
TechnologyController::add_temp_tech (const lay::Technology &t)
|
||||
TechnologyController::add_temp_tech (const db::Technology &t)
|
||||
{
|
||||
m_temp_tech.push_back (t);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public:
|
|||
* @brief Gets the active technology object or 0 if none is active
|
||||
* The active technology is the one the current cellview uses
|
||||
*/
|
||||
lay::Technology *active_technology () const;
|
||||
db::Technology *active_technology () const;
|
||||
|
||||
/**
|
||||
* @brief Adds a path as a search path for technologies
|
||||
|
|
@ -81,12 +81,12 @@ public:
|
|||
* but are not persisted or editable.
|
||||
* "load" needs to be called after temp technologies have been added.
|
||||
*/
|
||||
void add_temp_tech (const lay::Technology &t);
|
||||
void add_temp_tech (const db::Technology &t);
|
||||
|
||||
/**
|
||||
* @brief Updates the given technology collection with the technologies from the search path and the temp technologies
|
||||
*/
|
||||
void rescan (lay::Technologies &technologies);
|
||||
void rescan (db::Technologies &technologies);
|
||||
|
||||
/**
|
||||
* @brief Loads the global list of technologies
|
||||
|
|
@ -133,19 +133,19 @@ private:
|
|||
lay::TechSetupDialog *mp_editor;
|
||||
lay::MainWindow *mp_mw;
|
||||
std::vector<std::string> m_paths;
|
||||
std::vector<lay::Technology> m_temp_tech;
|
||||
lay::Technology *mp_active_technology;
|
||||
std::vector<db::Technology> m_temp_tech;
|
||||
db::Technology *mp_active_technology;
|
||||
|
||||
void update_active_technology ();
|
||||
void connect_events ();
|
||||
void technologies_changed ();
|
||||
void technology_changed (lay::Technology *);
|
||||
void technology_changed (db::Technology *);
|
||||
bool configure (const std::string &name, const std::string &value);
|
||||
void config_finalize ();
|
||||
bool menu_activated (const std::string &symbol) const;
|
||||
void update_current_technology ();
|
||||
void update_menu ();
|
||||
void replace_technologies (const lay::Technologies &technologies);
|
||||
void replace_technologies (const db::Technologies &technologies);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace gsi
|
|||
|
||||
static db::LoadLayoutOptions get_options_from_technology (const std::string &technology)
|
||||
{
|
||||
return lay::Technologies::instance ()->technology_by_name (technology)->load_layout_options ();
|
||||
return db::Technologies::instance ()->technology_by_name (technology)->load_layout_options ();
|
||||
}
|
||||
|
||||
// Extend "LoadLayoutOptions" by contributions from lay
|
||||
|
|
|
|||
|
|
@ -203,10 +203,10 @@ LayoutHandle::remove_ref ()
|
|||
}
|
||||
}
|
||||
|
||||
const lay::Technology *
|
||||
const db::Technology *
|
||||
LayoutHandle::technology () const
|
||||
{
|
||||
return lay::Technologies::instance ()->technology_by_name (m_tech_name);
|
||||
return db::Technologies::instance ()->technology_by_name (m_tech_name);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -221,7 +221,7 @@ void
|
|||
LayoutHandle::set_tech_name (const std::string &tn)
|
||||
{
|
||||
if (tn != m_tech_name) {
|
||||
if (lay::Technologies::instance ()->has_technology (tn)) {
|
||||
if (db::Technologies::instance ()->has_technology (tn)) {
|
||||
m_tech_name = tn;
|
||||
} else {
|
||||
m_tech_name = std::string ();
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the technology attached to this layout
|
||||
*/
|
||||
const lay::Technology *technology () const;
|
||||
const db::Technology *technology () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the technology name for this layout
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public:
|
|||
CommonReaderOptionPage (QWidget *parent);
|
||||
~CommonReaderOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
|
||||
private:
|
||||
Ui::CommonReaderOptionPage *mp_ui;
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@ NewLayoutPropertiesDialog::tech_changed ()
|
|||
{
|
||||
double dbu = 0.001;
|
||||
int technology_index = mp_ui->tech_cbx->currentIndex ();
|
||||
if (technology_index >= 0 && technology_index < (int) lay::Technologies::instance ()->technologies ()) {
|
||||
dbu = lay::Technologies::instance ()->begin () [technology_index].dbu ();
|
||||
if (technology_index >= 0 && technology_index < (int) db::Technologies::instance ()->technologies ()) {
|
||||
dbu = db::Technologies::instance ()->begin () [technology_index].dbu ();
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x40700
|
||||
|
|
@ -129,7 +129,7 @@ NewLayoutPropertiesDialog::exec_dialog (std::string &technology, std::string &ce
|
|||
{
|
||||
mp_ui->tech_cbx->clear ();
|
||||
unsigned int technology_index = 0;
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t, ++technology_index) {
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t, ++technology_index) {
|
||||
|
||||
std::string d = t->name ();
|
||||
if (! d.empty () && ! t->description ().empty ()) {
|
||||
|
|
@ -157,8 +157,8 @@ NewLayoutPropertiesDialog::exec_dialog (std::string &technology, std::string &ce
|
|||
|
||||
// get the selected technology name
|
||||
int technology_index = mp_ui->tech_cbx->currentIndex ();
|
||||
if (technology_index >= 0 && technology_index < (int) lay::Technologies::instance ()->technologies ()) {
|
||||
technology = lay::Technologies::instance ()->begin () [technology_index].name ();
|
||||
if (technology_index >= 0 && technology_index < (int) db::Technologies::instance ()->technologies ()) {
|
||||
technology = db::Technologies::instance ()->begin () [technology_index].name ();
|
||||
} else {
|
||||
technology = std::string ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,9 +110,9 @@ LayoutPropertiesForm::commit ()
|
|||
// get the selected technology name
|
||||
std::string technology;
|
||||
int technology_index = tech_cbx->currentIndex ();
|
||||
const lay::Technology *tech = 0;
|
||||
if (technology_index >= 0 && technology_index < (int) lay::Technologies::instance ()->technologies ()) {
|
||||
tech = &(lay::Technologies::instance ()->begin () [technology_index]);
|
||||
const db::Technology *tech = 0;
|
||||
if (technology_index >= 0 && technology_index < (int) db::Technologies::instance ()->technologies ()) {
|
||||
tech = &(db::Technologies::instance ()->begin () [technology_index]);
|
||||
technology = tech->name ();
|
||||
}
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ BEGIN_PROTECTED
|
|||
|
||||
tech_cbx->clear ();
|
||||
unsigned int technology_index = 0;
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t, ++technology_index) {
|
||||
for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t, ++technology_index) {
|
||||
|
||||
std::string d = t->name ();
|
||||
if (! d.empty () && ! t->description ().empty ()) {
|
||||
|
|
|
|||
|
|
@ -2442,7 +2442,7 @@ LayoutView::signal_apply_technology (lay::LayoutHandle *layout_handle)
|
|||
if (cellview (i).handle () == layout_handle) {
|
||||
|
||||
std::string lyp_file;
|
||||
const lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (cellview (i)->tech_name ());
|
||||
const db::Technology *tech = db::Technologies::instance ()->technology_by_name (cellview (i)->tech_name ());
|
||||
if (tech && ! tech->eff_layer_properties_file ().empty ()) {
|
||||
lyp_file = tech->eff_layer_properties_file ();
|
||||
}
|
||||
|
|
@ -3005,7 +3005,7 @@ LayoutView::add_layout (lay::LayoutHandle *layout_handle, bool add_cellview, boo
|
|||
// Use the "layer-properties-file" meta info from the handle to get the layer properties file.
|
||||
// If no such file is present, use the default file or the technology specific file.
|
||||
std::string lyp_file = m_def_lyp_file;
|
||||
const lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (layout_handle->tech_name ());
|
||||
const db::Technology *tech = db::Technologies::instance ()->technology_by_name (layout_handle->tech_name ());
|
||||
if (tech && ! tech->eff_layer_properties_file ().empty ()) {
|
||||
lyp_file = tech->eff_layer_properties_file ();
|
||||
add_other_layers = tech->add_other_layers ();
|
||||
|
|
@ -3072,7 +3072,7 @@ LayoutView::add_layout (lay::LayoutHandle *layout_handle, bool add_cellview, boo
|
|||
unsigned int
|
||||
LayoutView::create_layout (const std::string &technology, bool add_cellview, bool initialize_layers)
|
||||
{
|
||||
const lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (technology);
|
||||
const db::Technology *tech = db::Technologies::instance ()->technology_by_name (technology);
|
||||
|
||||
db::Layout *layout = new db::Layout (manager ());
|
||||
if (tech) {
|
||||
|
|
@ -3097,7 +3097,7 @@ LayoutView::load_layout (const std::string &filename, const db::LoadLayoutOption
|
|||
|
||||
bool set_max_hier = (m_full_hier_new_cell || has_max_hier ());
|
||||
|
||||
const lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (technology);
|
||||
const db::Technology *tech = db::Technologies::instance ()->technology_by_name (technology);
|
||||
|
||||
// create a new layout handle
|
||||
lay::CellView cv;
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ LoadLayoutOptionsDialog::update ()
|
|||
return;
|
||||
}
|
||||
|
||||
const lay::Technology *tech = m_tech_array [m_technology_index];
|
||||
const db::Technology *tech = m_tech_array [m_technology_index];
|
||||
mp_ui->options_tab->setEnabled (tech && tech->is_persisted ());
|
||||
|
||||
for (std::vector< std::pair<StreamReaderOptionsPage *, std::string> >::iterator page = m_pages.begin (); page != m_pages.end (); ++page) {
|
||||
|
|
@ -197,7 +197,7 @@ LoadLayoutOptionsDialog::update ()
|
|||
}
|
||||
|
||||
bool
|
||||
LoadLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, lay::Technologies *technologies)
|
||||
LoadLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies)
|
||||
{
|
||||
m_opt_array.clear ();
|
||||
m_tech_array.clear ();
|
||||
|
|
@ -219,7 +219,7 @@ LoadLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, lay:
|
|||
unsigned int i = 0;
|
||||
m_technology_index = -1;
|
||||
|
||||
for (lay::Technologies::const_iterator t = technologies->begin (); t != technologies->end (); ++t, ++i) {
|
||||
for (db::Technologies::const_iterator t = technologies->begin (); t != technologies->end (); ++t, ++i) {
|
||||
|
||||
std::string d = t->name ();
|
||||
if (! d.empty () && ! t->description ().empty ()) {
|
||||
|
|
@ -256,7 +256,7 @@ LoadLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, lay:
|
|||
|
||||
i = 0;
|
||||
technologies->begin_updates ();
|
||||
for (lay::Technologies::iterator t = technologies->begin (); t != technologies->end () && i < m_opt_array.size (); ++t, ++i) {
|
||||
for (db::Technologies::iterator t = technologies->begin (); t != technologies->end () && i < m_opt_array.size (); ++t, ++i) {
|
||||
technologies->begin ()[i].set_load_layout_options (m_opt_array [i]);
|
||||
}
|
||||
technologies->end_updates ();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class QAbstractButton;
|
|||
namespace db
|
||||
{
|
||||
class LoadLayoutOptions;
|
||||
class Technologies;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
|
|
@ -53,7 +54,6 @@ namespace lay
|
|||
class LayoutView;
|
||||
class PluginRoot;
|
||||
class FileDialog;
|
||||
class Technologies;
|
||||
|
||||
class LAYBASIC_PUBLIC LoadLayoutOptionsDialog
|
||||
: public QDialog
|
||||
|
|
@ -64,7 +64,7 @@ public:
|
|||
LoadLayoutOptionsDialog (QWidget *parent, const std::string &title);
|
||||
~LoadLayoutOptionsDialog ();
|
||||
|
||||
bool edit_global_options (lay::PluginRoot *config_root, lay::Technologies *technologies);
|
||||
bool edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies);
|
||||
bool get_options (db::LoadLayoutOptions &options);
|
||||
|
||||
void show_always (bool sa)
|
||||
|
|
@ -89,7 +89,7 @@ private:
|
|||
bool m_show_always;
|
||||
int m_technology_index;
|
||||
std::vector<db::LoadLayoutOptions> m_opt_array;
|
||||
std::vector<const lay::Technology *> m_tech_array;
|
||||
std::vector<const db::Technology *> m_tech_array;
|
||||
|
||||
void commit ();
|
||||
void update ();
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ SaveLayoutOptionsDialog::update ()
|
|||
}
|
||||
|
||||
bool
|
||||
SaveLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, lay::Technologies *technologies)
|
||||
SaveLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies)
|
||||
{
|
||||
m_opt_array.clear ();
|
||||
m_tech_array.clear ();
|
||||
|
|
@ -244,7 +244,7 @@ SaveLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, lay:
|
|||
unsigned int i = 0;
|
||||
m_technology_index = -1;
|
||||
|
||||
for (lay::Technologies::const_iterator t = technologies->begin (); t != technologies->end (); ++t, ++i) {
|
||||
for (db::Technologies::const_iterator t = technologies->begin (); t != technologies->end (); ++t, ++i) {
|
||||
|
||||
std::string d = t->name ();
|
||||
if (! d.empty () && ! t->description ().empty ()) {
|
||||
|
|
@ -270,7 +270,7 @@ SaveLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, lay:
|
|||
|
||||
// get the selected technology name and store in the config
|
||||
unsigned int i = 0;
|
||||
for (lay::Technologies::iterator t = technologies->begin (); t != technologies->end () && i < m_opt_array.size (); ++t, ++i) {
|
||||
for (db::Technologies::iterator t = technologies->begin (); t != technologies->end () && i < m_opt_array.size (); ++t, ++i) {
|
||||
technologies->begin ()[i].set_save_layout_options (m_opt_array [i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class QWidget;
|
|||
namespace db
|
||||
{
|
||||
class SaveLayoutOptions;
|
||||
class Technologies;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
|
|
@ -46,7 +47,6 @@ namespace lay
|
|||
|
||||
class LayoutView;
|
||||
class PluginRoot;
|
||||
class Technologies;
|
||||
|
||||
class LAYBASIC_PUBLIC SaveLayoutAsOptionsDialog
|
||||
: public QDialog, private Ui::SaveLayoutAsOptionsDialog
|
||||
|
|
@ -68,7 +68,7 @@ private:
|
|||
std::vector<int> m_tab_positions;
|
||||
std::string m_filename;
|
||||
db::SaveLayoutOptions m_options;
|
||||
const lay::Technology *mp_tech;
|
||||
const db::Technology *mp_tech;
|
||||
};
|
||||
|
||||
class LAYBASIC_PUBLIC SaveLayoutOptionsDialog
|
||||
|
|
@ -80,7 +80,7 @@ public:
|
|||
SaveLayoutOptionsDialog (QWidget *parent, const std::string &title);
|
||||
~SaveLayoutOptionsDialog ();
|
||||
|
||||
bool edit_global_options (lay::PluginRoot *config_root, lay::Technologies *technologies);
|
||||
bool edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies);
|
||||
bool get_options (db::SaveLayoutOptions &options);
|
||||
|
||||
public slots:
|
||||
|
|
@ -93,7 +93,7 @@ private:
|
|||
std::vector< std::pair<StreamWriterOptionsPage *, std::string> > m_pages;
|
||||
int m_technology_index;
|
||||
std::vector<db::SaveLayoutOptions> m_opt_array;
|
||||
std::vector<const lay::Technology *> m_tech_array;
|
||||
std::vector<const db::Technology *> m_tech_array;
|
||||
|
||||
void commit ();
|
||||
void update ();
|
||||
|
|
|
|||
|
|
@ -82,42 +82,5 @@ const StreamWriterPluginDeclaration *StreamWriterPluginDeclaration::plugin_for_f
|
|||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Implementation of load_options_xml_element_list
|
||||
|
||||
tl::XMLElementList load_options_xml_element_list ()
|
||||
{
|
||||
tl::XMLElementList elements;
|
||||
|
||||
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||
const StreamReaderPluginDeclaration *decl = dynamic_cast <const StreamReaderPluginDeclaration *> (&*cls);
|
||||
if (decl) {
|
||||
elements.append (decl->xml_element ());
|
||||
}
|
||||
}
|
||||
|
||||
// ignore all unknown elements
|
||||
elements.append (tl::make_member<db::LoadLayoutOptions> ("*"));
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
tl::XMLElementList save_options_xml_element_list ()
|
||||
{
|
||||
tl::XMLElementList elements;
|
||||
|
||||
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||
const StreamWriterPluginDeclaration *decl = dynamic_cast <const StreamWriterPluginDeclaration *> (&*cls);
|
||||
if (decl) {
|
||||
elements.append (decl->xml_element ());
|
||||
}
|
||||
}
|
||||
|
||||
// ignore all unknown elements
|
||||
elements.append (tl::make_member<db::FormatSpecificWriterOptions> ("*"));
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ namespace db
|
|||
class FormatSpecificReaderOptions;
|
||||
class LoadLayoutOptions;
|
||||
class SaveLayoutOptions;
|
||||
class Technology;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
|
|
@ -45,7 +46,6 @@ namespace lay
|
|||
|
||||
class PluginRoot;
|
||||
class LayoutHandle;
|
||||
class Technology;
|
||||
|
||||
/**
|
||||
* @brief The base class for writer configuration pages
|
||||
|
|
@ -70,7 +70,7 @@ public:
|
|||
* Plugin object provided and load the widgets accordingly.
|
||||
* The options object can be cast to the specific format object.
|
||||
*/
|
||||
virtual void setup (const db::FormatSpecificWriterOptions * /*options*/, const lay::Technology * /*tech*/)
|
||||
virtual void setup (const db::FormatSpecificWriterOptions * /*options*/, const db::Technology * /*tech*/)
|
||||
{
|
||||
// the default implementation does nothing.
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ public:
|
|||
* and commit the changes through
|
||||
* The options object can be cast to the specific format object.
|
||||
*/
|
||||
virtual void commit (db::FormatSpecificWriterOptions * /*options*/, const lay::Technology * /*tech*/, bool /*gzip*/)
|
||||
virtual void commit (db::FormatSpecificWriterOptions * /*options*/, const db::Technology * /*tech*/, bool /*gzip*/)
|
||||
{
|
||||
// the default implementation does nothing.
|
||||
}
|
||||
|
|
@ -112,7 +112,7 @@ public:
|
|||
* Plugin object provided and load the widgets accordingly.
|
||||
* The options object can be cast to the specific format object.
|
||||
*/
|
||||
virtual void setup (const db::FormatSpecificReaderOptions * /*options*/, const lay::Technology * /*tech*/)
|
||||
virtual void setup (const db::FormatSpecificReaderOptions * /*options*/, const db::Technology * /*tech*/)
|
||||
{
|
||||
// the default implementation does nothing.
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ public:
|
|||
* and commit the changes through
|
||||
* The options object can be cast to the specific format object.
|
||||
*/
|
||||
virtual void commit (db::FormatSpecificReaderOptions * /*options*/, const lay::Technology * /*tech*/)
|
||||
virtual void commit (db::FormatSpecificReaderOptions * /*options*/, const db::Technology * /*tech*/)
|
||||
{
|
||||
// the default implementation does nothing.
|
||||
}
|
||||
|
|
@ -209,32 +209,8 @@ public:
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElement object that represents this component within a technology XML tree
|
||||
*
|
||||
* This method is supposed to return an instance ReaderOptionsXMLElement<RO> where RO is the
|
||||
* specific reader options type. The return value can be 0 to indicate there is no specific reader
|
||||
* option.
|
||||
*
|
||||
* The returned XMLElement is destroyed by the caller and needs to be a new object.
|
||||
*/
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns the XMLElement list that can represent a db::LoadLayoutOptions object
|
||||
*/
|
||||
LAYBASIC_PUBLIC tl::XMLElementList load_options_xml_element_list ();
|
||||
|
||||
/**
|
||||
* @brief Returns the XMLElement list that can represent a db::SaveLayoutOptions object
|
||||
*/
|
||||
LAYBASIC_PUBLIC tl::XMLElementList save_options_xml_element_list ();
|
||||
|
||||
/**
|
||||
* @brief A specialisation of Plugin declaration for stream reader plugins
|
||||
*/
|
||||
|
|
@ -283,171 +259,6 @@ public:
|
|||
{
|
||||
// the default implementation does nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElement object that represents this component within a technology XML tree
|
||||
*
|
||||
* This method is supposed to return an instance WriterOptionsXMLElement<WO> where WO is the
|
||||
* specific writer options type. The return value can be 0 to indicate there is no specific writer
|
||||
* option.
|
||||
*
|
||||
* The returned XMLElement is destroyed by the caller and needs to be a new object.
|
||||
*/
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the stream options (custom read adaptor)
|
||||
*
|
||||
* OPT is a reader or writer options class and HOST is the host class. For example, OPT
|
||||
* can be db::GDS2ReaderOptions and HOST then is db::LoadLayoutOptions.
|
||||
*/
|
||||
template <class OPT, class HOST>
|
||||
class StreamOptionsReadAdaptor
|
||||
{
|
||||
public:
|
||||
typedef tl::pass_by_ref_tag tag;
|
||||
|
||||
StreamOptionsReadAdaptor ()
|
||||
: mp_options (0), m_done (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
const OPT &operator () () const
|
||||
{
|
||||
return mp_options->template get_options<OPT> ();
|
||||
}
|
||||
|
||||
bool at_end () const
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
void start (const HOST &options)
|
||||
{
|
||||
mp_options = &options;
|
||||
m_done = false;
|
||||
}
|
||||
|
||||
void next ()
|
||||
{
|
||||
mp_options = 0;
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
private:
|
||||
const HOST *mp_options;
|
||||
bool m_done;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the stream option (custom write adaptor)
|
||||
*
|
||||
* See StreamOptionsReadAdaptor for details.
|
||||
*/
|
||||
template <class OPT, class HOST>
|
||||
class StreamOptionsWriteAdaptor
|
||||
{
|
||||
public:
|
||||
StreamOptionsWriteAdaptor ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void operator () (HOST &options, tl::XMLReaderState &reader) const
|
||||
{
|
||||
std::auto_ptr<OPT> opt (new OPT ());
|
||||
|
||||
tl::XMLObjTag<OPT> tag;
|
||||
*opt = *reader.back (tag);
|
||||
|
||||
options.set_options (opt.release ());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A XMLElement specialization for stream options
|
||||
*/
|
||||
template <class OPT, class HOST>
|
||||
class StreamOptionsXMLElement
|
||||
: public tl::XMLElement<OPT, HOST, StreamOptionsReadAdaptor<OPT, HOST>, StreamOptionsWriteAdaptor<OPT, HOST> >
|
||||
{
|
||||
public:
|
||||
StreamOptionsXMLElement (const std::string &element_name, const tl::XMLElementList &children)
|
||||
: tl::XMLElement<OPT, HOST, StreamOptionsReadAdaptor<OPT, HOST>, StreamOptionsWriteAdaptor<OPT, HOST> > (StreamOptionsReadAdaptor<OPT, HOST> (), StreamOptionsWriteAdaptor<OPT, HOST> (), element_name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
StreamOptionsXMLElement (const StreamOptionsXMLElement &d)
|
||||
: tl::XMLElement<OPT, HOST, StreamOptionsReadAdaptor<OPT, HOST>, StreamOptionsWriteAdaptor<OPT, HOST> > (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A custom XMLElement for the serialization of reader options
|
||||
*
|
||||
* StreamReaderPluginDeclaration::xml_element can return such an element to
|
||||
* insert a custom XML element into the XML tree which represents the
|
||||
* reader options.
|
||||
*/
|
||||
template <class OPT>
|
||||
class ReaderOptionsXMLElement
|
||||
: public StreamOptionsXMLElement<OPT, db::LoadLayoutOptions>
|
||||
{
|
||||
public:
|
||||
ReaderOptionsXMLElement (const std::string &element_name, const tl::XMLElementList &children)
|
||||
: StreamOptionsXMLElement<OPT, db::LoadLayoutOptions> (element_name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ReaderOptionsXMLElement (const ReaderOptionsXMLElement &d)
|
||||
: StreamOptionsXMLElement<OPT, db::LoadLayoutOptions> (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *clone () const
|
||||
{
|
||||
return new ReaderOptionsXMLElement (*this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A custom XMLElement for the serialization of writer options
|
||||
*
|
||||
* StreamWriterPluginDeclaration::xml_element can return such an element to
|
||||
* insert a custom XML element into the XML tree which represents the
|
||||
* writer options.
|
||||
*/
|
||||
template <class OPT>
|
||||
class WriterOptionsXMLElement
|
||||
: public StreamOptionsXMLElement<OPT, db::SaveLayoutOptions>
|
||||
{
|
||||
public:
|
||||
WriterOptionsXMLElement (const std::string &element_name, const tl::XMLElementList &children)
|
||||
: StreamOptionsXMLElement<OPT, db::SaveLayoutOptions> (element_name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
WriterOptionsXMLElement (const WriterOptionsXMLElement &d)
|
||||
: StreamOptionsXMLElement<OPT, db::SaveLayoutOptions> (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *clone () const
|
||||
{
|
||||
return new WriterOptionsXMLElement (*this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,440 +33,7 @@
|
|||
namespace lay
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Technologies::Technologies ()
|
||||
{
|
||||
m_technologies.push_back (new Technology (std::string (""), "(Default)"));
|
||||
m_changed = false;
|
||||
m_in_update = false;
|
||||
}
|
||||
|
||||
Technologies::Technologies (const Technologies &other)
|
||||
: tl::Object ()
|
||||
{
|
||||
m_changed = false;
|
||||
m_in_update = false;
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
Technologies::~Technologies ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Technologies &
|
||||
Technologies::operator= (const Technologies &other)
|
||||
{
|
||||
if (&other != this) {
|
||||
m_technologies = other.m_technologies;
|
||||
for (iterator i = begin (); i != end (); ++i) {
|
||||
i->technology_changed_with_sender_event.add (this, &Technologies::technology_changed);
|
||||
}
|
||||
technologies_changed ();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
static std::auto_ptr<lay::Technologies> sp_technologies;
|
||||
|
||||
lay::Technologies *
|
||||
Technologies::instance ()
|
||||
{
|
||||
if (! sp_technologies.get ()) {
|
||||
sp_technologies.reset (new lay::Technologies ());
|
||||
}
|
||||
return sp_technologies.get ();
|
||||
}
|
||||
|
||||
static tl::XMLElementList xml_elements ()
|
||||
{
|
||||
return make_element ((Technologies::const_iterator (Technologies::*) () const) &Technologies::begin, (Technologies::const_iterator (Technologies::*) () const) &Technologies::end, &Technologies::add, "technology",
|
||||
Technology::xml_elements ()
|
||||
);
|
||||
}
|
||||
|
||||
std::string
|
||||
Technologies::to_xml () const
|
||||
{
|
||||
// create a copy to filter out the ones which are not persisted
|
||||
lay::Technologies copy;
|
||||
for (const_iterator t = begin (); t != end (); ++t) {
|
||||
if (t->is_persisted ()) {
|
||||
copy.add (new Technology (*t));
|
||||
}
|
||||
}
|
||||
|
||||
tl::OutputStringStream os;
|
||||
tl::XMLStruct<lay::Technologies> xml_struct ("technologies", xml_elements ());
|
||||
tl::OutputStream oss (os);
|
||||
xml_struct.write (oss, copy);
|
||||
return os.string ();
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::load_from_xml (const std::string &s)
|
||||
{
|
||||
// create a copy to filter out the ones which are not persisted and remain
|
||||
lay::Technologies copy;
|
||||
for (const_iterator t = begin (); t != end (); ++t) {
|
||||
if (! t->is_persisted ()) {
|
||||
copy.add (new Technology (*t));
|
||||
}
|
||||
}
|
||||
|
||||
tl::XMLStringSource source (s);
|
||||
tl::XMLStruct<lay::Technologies> xml_struct ("technologies", xml_elements ());
|
||||
xml_struct.parse (source, copy);
|
||||
|
||||
*this = copy;
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::add_tech (Technology *tech, bool replace_same)
|
||||
{
|
||||
if (! tech) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::auto_ptr<Technology> tech_ptr (tech);
|
||||
|
||||
Technology *t = 0;
|
||||
for (tl::stable_vector<Technology>::iterator i = m_technologies.begin (); !t && i != m_technologies.end (); ++i) {
|
||||
if (i->name () == tech->name ()) {
|
||||
t = i.operator-> ();
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
if (replace_same) {
|
||||
*t = *tech;
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("A technology with this name already exists: %1").arg (tl::to_qstring (tech->name ()))));
|
||||
}
|
||||
} else {
|
||||
m_technologies.push_back (tech_ptr.release ());
|
||||
tech->technology_changed_with_sender_event.add (this, &Technologies::technology_changed);
|
||||
}
|
||||
|
||||
technologies_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::remove (const std::string &name)
|
||||
{
|
||||
for (tl::stable_vector<Technology>::iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
if (t->name () == name) {
|
||||
m_technologies.erase (t);
|
||||
technologies_changed ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::clear ()
|
||||
{
|
||||
if (! m_technologies.empty ()) {
|
||||
m_technologies.clear ();
|
||||
technologies_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::technology_changed (Technology *t)
|
||||
{
|
||||
if (m_in_update) {
|
||||
m_changed = true;
|
||||
} else {
|
||||
technology_changed_event (t);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::technologies_changed ()
|
||||
{
|
||||
if (m_in_update) {
|
||||
m_changed = true;
|
||||
} else {
|
||||
technologies_changed_event ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::begin_updates ()
|
||||
{
|
||||
tl_assert (! m_in_update);
|
||||
m_in_update = true;
|
||||
m_changed = false;
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::end_updates ()
|
||||
{
|
||||
if (m_in_update) {
|
||||
m_in_update = false;
|
||||
if (m_changed) {
|
||||
m_changed = false;
|
||||
technologies_changed ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::notify_technologies_changed ()
|
||||
{
|
||||
technologies_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Technologies::end_updates_no_event ()
|
||||
{
|
||||
m_in_update = false;
|
||||
m_changed = false;
|
||||
}
|
||||
|
||||
bool
|
||||
Technologies::has_technology (const std::string &name) const
|
||||
{
|
||||
for (tl::stable_vector<Technology>::const_iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
if (t->name () == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Technology *
|
||||
Technologies::technology_by_name (const std::string &name)
|
||||
{
|
||||
for (tl::stable_vector<Technology>::iterator t = m_technologies.begin (); t != m_technologies.end (); ++t) {
|
||||
if (t->name () == name) {
|
||||
return &*t;
|
||||
}
|
||||
}
|
||||
|
||||
tl_assert (! m_technologies.empty ());
|
||||
return &*m_technologies.begin ();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Technology implementation
|
||||
|
||||
Technology::Technology ()
|
||||
: m_name (), m_description (), m_dbu (0.001), m_persisted (true), m_readonly (false)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
Technology::Technology (const std::string &name, const std::string &description)
|
||||
: m_name (name), m_description (description), m_dbu (0.001), m_persisted (true), m_readonly (false)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
void
|
||||
Technology::init ()
|
||||
{
|
||||
m_add_other_layers = true;
|
||||
|
||||
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||
if (cls->technology_component_provider () != 0) {
|
||||
m_components.push_back (cls->technology_component_provider ()->create_component ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Technology::~Technology ()
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
delete *c;
|
||||
}
|
||||
m_components.clear ();
|
||||
}
|
||||
|
||||
Technology::Technology (const Technology &d)
|
||||
: tl::Object (),
|
||||
m_name (d.m_name), m_description (d.m_description), m_grain_name (d.m_grain_name), m_dbu (d.m_dbu),
|
||||
m_explicit_base_path (d.m_explicit_base_path), m_default_base_path (d.m_default_base_path),
|
||||
m_load_layout_options (d.m_load_layout_options),
|
||||
m_save_layout_options (d.m_save_layout_options),
|
||||
m_lyp_path (d.m_lyp_path), m_add_other_layers (d.m_add_other_layers), m_persisted (d.m_persisted),
|
||||
m_readonly (d.m_readonly), m_lyt_file (d.m_lyt_file)
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = d.m_components.begin (); c != d.m_components.end (); ++c) {
|
||||
m_components.push_back ((*c)->clone ());
|
||||
}
|
||||
}
|
||||
|
||||
Technology &Technology::operator= (const Technology &d)
|
||||
{
|
||||
if (this != &d) {
|
||||
|
||||
m_name = d.m_name;
|
||||
m_description = d.m_description;
|
||||
m_grain_name = d.m_grain_name;
|
||||
m_dbu = d.m_dbu;
|
||||
m_default_base_path = d.m_default_base_path;
|
||||
m_explicit_base_path = d.m_explicit_base_path;
|
||||
m_load_layout_options = d.m_load_layout_options;
|
||||
m_save_layout_options = d.m_save_layout_options;
|
||||
m_lyp_path = d.m_lyp_path;
|
||||
m_add_other_layers = d.m_add_other_layers;
|
||||
m_persisted = d.m_persisted;
|
||||
m_readonly = d.m_readonly;
|
||||
m_lyt_file = d.m_lyt_file;
|
||||
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
delete *c;
|
||||
}
|
||||
m_components.clear ();
|
||||
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = d.m_components.begin (); c != d.m_components.end (); ++c) {
|
||||
m_components.push_back ((*c)->clone ());
|
||||
}
|
||||
|
||||
technology_changed ();
|
||||
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tl::XMLElementList
|
||||
Technology::xml_elements ()
|
||||
{
|
||||
tl::XMLElementList elements =
|
||||
tl::make_member (&Technology::name, &Technology::set_name, "name") +
|
||||
tl::make_member (&Technology::description, &Technology::set_description, "description") +
|
||||
tl::make_member (&Technology::dbu, &Technology::set_dbu, "dbu") +
|
||||
tl::make_member (&Technology::explicit_base_path, &Technology::set_explicit_base_path, "base-path") +
|
||||
tl::make_member (&Technology::default_base_path, &Technology::set_default_base_path, "original-base-path") +
|
||||
tl::make_member (&Technology::layer_properties_file, &Technology::set_layer_properties_file, "layer-properties_file") +
|
||||
tl::make_member (&Technology::add_other_layers, &Technology::set_add_other_layers, "add-other-layers") +
|
||||
tl::make_element (&Technology::load_layout_options, &Technology::set_load_layout_options, "reader-options",
|
||||
lay::load_options_xml_element_list ()
|
||||
) +
|
||||
tl::make_element (&Technology::save_layout_options, &Technology::set_save_layout_options, "writer-options",
|
||||
lay::save_options_xml_element_list ()
|
||||
);
|
||||
|
||||
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||
if (cls->technology_component_provider () != 0) {
|
||||
elements.append (cls->technology_component_provider ()->xml_element ());
|
||||
}
|
||||
}
|
||||
|
||||
// ignore all unknown elements
|
||||
elements.append (tl::make_member<Technology> ("*"));
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
const TechnologyComponent *
|
||||
Technology::component_by_name (const std::string &component_name) const
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
if ((*c)->name () == component_name) {
|
||||
return *c;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TechnologyComponent *
|
||||
Technology::component_by_name (const std::string &component_name)
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
if ((*c)->name () == component_name) {
|
||||
return *c;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector <std::string>
|
||||
Technology::component_names () const
|
||||
{
|
||||
std::vector <std::string> names;
|
||||
for (std::vector <TechnologyComponent *>::const_iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
names.push_back ((*c)->name ());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
void
|
||||
Technology::set_component (TechnologyComponent *component)
|
||||
{
|
||||
for (std::vector <TechnologyComponent *>::iterator c = m_components.begin (); c != m_components.end (); ++c) {
|
||||
if ((*c)->name () == component->name ()) {
|
||||
if (*c != component) {
|
||||
delete *c;
|
||||
*c = component;
|
||||
technology_changed_event ();
|
||||
technology_changed_with_sender_event (this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Technology::correct_path (const std::string &fp) const
|
||||
{
|
||||
if (base_path ().empty ()) {
|
||||
return fp;
|
||||
}
|
||||
|
||||
QString rfp = QDir (tl::to_qstring (base_path ())).relativeFilePath (tl::to_qstring (fp));
|
||||
if (rfp.startsWith (QString::fromUtf8 (".."))) {
|
||||
// upwards or beside - don't correct:
|
||||
return fp;
|
||||
} else {
|
||||
return tl::to_string (rfp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Technology::load (const std::string &fn)
|
||||
{
|
||||
tl::XMLFileSource source (fn);
|
||||
tl::XMLStruct<lay::Technology> xml_struct ("technology", xml_elements ());
|
||||
xml_struct.parse (source, *this);
|
||||
|
||||
// use the tech file's path as the default base path
|
||||
std::string lyt_file = tl::to_string (QFileInfo (tl::to_qstring (fn)).absoluteDir ().path ());
|
||||
set_default_base_path (lyt_file);
|
||||
|
||||
set_tech_file_path (fn);
|
||||
}
|
||||
|
||||
void
|
||||
Technology::save (const std::string &fn) const
|
||||
{
|
||||
tl::XMLStruct<lay::Technology> xml_struct ("technology", xml_elements ());
|
||||
tl::OutputStream os (fn, tl::OutputStream::OM_Plain);
|
||||
xml_struct.write (os, *this);
|
||||
}
|
||||
|
||||
std::string
|
||||
Technology::build_effective_path (const std::string &p) const
|
||||
{
|
||||
if (p.empty () || base_path ().empty ()) {
|
||||
return p;
|
||||
}
|
||||
|
||||
QFileInfo f (tl::to_qstring (p));
|
||||
if (f.isAbsolute ()) {
|
||||
return p;
|
||||
} else {
|
||||
return tl::to_string (QDir (tl::to_qstring (base_path ())).filePath (tl::to_qstring (p)));
|
||||
}
|
||||
}
|
||||
// .. nothing yet ..
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,689 +26,13 @@
|
|||
|
||||
#include "laybasicCommon.h"
|
||||
|
||||
#include "tlStableVector.h"
|
||||
#include "tlString.h"
|
||||
#include "tlEvents.h"
|
||||
#include "tlXMLParser.h"
|
||||
#include "tlTypeTraits.h"
|
||||
#include "dbStreamLayers.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
#include "dbSaveLayoutOptions.h"
|
||||
#include "dbTechnology.h"
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class Technology;
|
||||
class TechnologyComponent;
|
||||
class TechnologyComponentEditor;
|
||||
|
||||
/**
|
||||
* @brief A container for the technology settings
|
||||
*
|
||||
* The container associates a technology with a name and provides an
|
||||
* iterator for the technologies.
|
||||
* The container features at least one technology (the default) which is
|
||||
* present in any case. If a technology with an unknown name is requested,
|
||||
* this default technology is returned.
|
||||
*/
|
||||
class LAYBASIC_PUBLIC Technologies
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
typedef tl::stable_vector<Technology>::const_iterator const_iterator;
|
||||
typedef tl::stable_vector<Technology>::iterator iterator;
|
||||
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
Technologies ();
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
~Technologies ();
|
||||
|
||||
/**
|
||||
* @brief Copy ctor
|
||||
*/
|
||||
Technologies (const Technologies &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment operator
|
||||
*/
|
||||
Technologies &operator= (const Technologies &other);
|
||||
|
||||
/**
|
||||
* @brief Const iterator - begin
|
||||
*/
|
||||
const_iterator begin () const
|
||||
{
|
||||
return m_technologies.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Const iterator - end
|
||||
*/
|
||||
const_iterator end () const
|
||||
{
|
||||
return m_technologies.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief iterator - begin
|
||||
*/
|
||||
iterator begin ()
|
||||
{
|
||||
return m_technologies.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Const iterator - end
|
||||
*/
|
||||
iterator end ()
|
||||
{
|
||||
return m_technologies.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The number of technologies
|
||||
*/
|
||||
size_t technologies () const
|
||||
{
|
||||
return m_technologies.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a technology to the setup
|
||||
*
|
||||
* The container becomes owner of the technology object.
|
||||
* Replaces a technology with the name of the given technology.
|
||||
*/
|
||||
void add (Technology *technology)
|
||||
{
|
||||
add_tech (technology, true /*replace*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a technology with a new name
|
||||
*
|
||||
* Like \add, but throws an exception if a technology with this name
|
||||
* already exists. Takes over ownership over the technology object.
|
||||
* The technology object is discarded if an exception is thrown.
|
||||
*/
|
||||
void add_new (Technology *technology)
|
||||
{
|
||||
add_tech (technology, false /*throws exception on same name*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a technology with the given name from the setup
|
||||
*/
|
||||
void remove (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Clears the list of technologies
|
||||
*/
|
||||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Begins a bulk operation
|
||||
* This method will disable "technologies_changed" events until (later) end_updates () is called.
|
||||
*/
|
||||
void begin_updates ();
|
||||
|
||||
/**
|
||||
* @brief Ends a bulk operation
|
||||
*/
|
||||
void end_updates ();
|
||||
|
||||
/**
|
||||
* @brief Ends a bulk operation
|
||||
* This version does not send an technologies_changed event but just cancels the bulk
|
||||
* operation. begin_updates/end_updates_no_event is essentially equivalent to blocking
|
||||
* signals.
|
||||
*/
|
||||
void end_updates_no_event ();
|
||||
|
||||
/**
|
||||
* @brief Notifies the system of changes in technologies
|
||||
* For performance reasons, changes inside a technology are not propagated to
|
||||
* the system directly. Only bulk changes (such as adding or removing technologies
|
||||
* are). To inform the system of individual technology updates, call this method
|
||||
* after a technology or multiple technologies have been changed.
|
||||
*/
|
||||
void notify_technologies_changed ();
|
||||
|
||||
/**
|
||||
* @brief Checks, if a technology with the given name exists
|
||||
*/
|
||||
bool has_technology (const std::string &name) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the technology with the given name
|
||||
*
|
||||
* If no technology with that name exists, the default technology is returned.
|
||||
*/
|
||||
Technology *technology_by_name (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Returns the technology with the given name (const version)
|
||||
*
|
||||
* If no technology with that name exists, the default technology is returned.
|
||||
*/
|
||||
const Technology *technology_by_name (const std::string &name) const
|
||||
{
|
||||
return const_cast<Technologies *> (this)->technology_by_name (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts the list into an XML string
|
||||
*/
|
||||
std::string to_xml () const;
|
||||
|
||||
/**
|
||||
* @brief Reads the list from an XML string
|
||||
*/
|
||||
void load_from_xml (const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Returns the singleton instance
|
||||
*/
|
||||
static lay::Technologies *instance ();
|
||||
|
||||
/**
|
||||
* @brief An event indicating that the list of technologies has changed
|
||||
* If a technology is added or removed, this event is triggered.
|
||||
*/
|
||||
tl::Event technologies_changed_event;
|
||||
|
||||
/**
|
||||
* @brief An event indicating that one technology in the list has changed
|
||||
* If a technology is modified, this event is triggered with that technology as argument of the event.
|
||||
*/
|
||||
tl::event<Technology *> technology_changed_event;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Forward the event from the individual technologies
|
||||
*/
|
||||
void technology_changed (Technology *t);
|
||||
|
||||
/**
|
||||
* @brief Sends the technologies_changed event
|
||||
*/
|
||||
void technologies_changed ();
|
||||
|
||||
private:
|
||||
tl::stable_vector<Technology> m_technologies;
|
||||
bool m_changed;
|
||||
bool m_in_update;
|
||||
|
||||
void add_tech (Technology *technology, bool replace_same);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A technology
|
||||
*
|
||||
* This class represents one technology.
|
||||
* A technology has a name and a description.
|
||||
*/
|
||||
class LAYBASIC_PUBLIC Technology
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The default constructor
|
||||
*/
|
||||
Technology ();
|
||||
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
Technology (const std::string &name, const std::string &description);
|
||||
|
||||
/**
|
||||
* @brief The copy constructor
|
||||
*/
|
||||
Technology (const Technology &tech);
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
~Technology ();
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
Technology &operator= (const Technology &tech);
|
||||
|
||||
/**
|
||||
* @brief Gets the name
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the name
|
||||
*/
|
||||
void set_name (const std::string &n)
|
||||
{
|
||||
if (n != m_name) {
|
||||
m_name = n;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the package source
|
||||
*
|
||||
* This attribute indicates that this technology was contributed by a package
|
||||
*/
|
||||
void set_grain_name (const std::string &g)
|
||||
{
|
||||
m_grain_name = g;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the package source
|
||||
*/
|
||||
const std::string &grain_name () const
|
||||
{
|
||||
return m_grain_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the base path
|
||||
*
|
||||
* The base path is an effective path - if the explicit path is set, it is
|
||||
* used. If not, the default path is used. The default path is the one from which
|
||||
* a technology file was imported. The explicit one is the one that is specified
|
||||
* explicitly.
|
||||
*/
|
||||
const std::string &base_path () const
|
||||
{
|
||||
return m_explicit_base_path.empty () ? m_default_base_path : m_explicit_base_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Makes a file path relative to the base path if one is specified.
|
||||
*
|
||||
* Only files below the base path will be made relative. Files above or beside
|
||||
* won't be made relative.
|
||||
*/
|
||||
std::string correct_path (const std::string &fp) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the default base path
|
||||
*/
|
||||
const std::string &default_base_path () const
|
||||
{
|
||||
return m_default_base_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the default base path
|
||||
*/
|
||||
void set_default_base_path (const std::string &p)
|
||||
{
|
||||
if (m_default_base_path != p) {
|
||||
m_default_base_path = p;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the explicit base path
|
||||
*/
|
||||
const std::string &explicit_base_path () const
|
||||
{
|
||||
return m_explicit_base_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the explicit base path
|
||||
*/
|
||||
void set_explicit_base_path (const std::string &p)
|
||||
{
|
||||
if (m_explicit_base_path != p) {
|
||||
m_explicit_base_path = p;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the path of the tech file if the technology was loaded from a tech file
|
||||
*/
|
||||
const std::string &tech_file_path () const
|
||||
{
|
||||
return m_lyt_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the path of the tech file
|
||||
* This method is intended for internal use only.
|
||||
*/
|
||||
void set_tech_file_path (const std::string &lyt_file)
|
||||
{
|
||||
m_lyt_file = lyt_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the description
|
||||
*/
|
||||
const std::string &description () const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the description
|
||||
*/
|
||||
void set_description (const std::string &d)
|
||||
{
|
||||
if (m_description != d) {
|
||||
m_description = d;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the default database unit
|
||||
*/
|
||||
double dbu () const
|
||||
{
|
||||
return m_dbu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the default database unit
|
||||
*/
|
||||
void set_dbu (double d)
|
||||
{
|
||||
if (fabs (m_dbu - d) > 1e-10) {
|
||||
m_dbu = d;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the layer properties file path (empty if none is specified)
|
||||
*/
|
||||
const std::string &layer_properties_file () const
|
||||
{
|
||||
return m_lyp_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the effective layer properties file path (empty if none is specified)
|
||||
*
|
||||
* The effective path is the one extended by the base path if relative.
|
||||
*/
|
||||
std::string eff_layer_properties_file () const
|
||||
{
|
||||
return build_effective_path (m_lyp_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the layer properties file path (set to empty string to remove layer properties file)
|
||||
*/
|
||||
void set_layer_properties_file (const std::string &lyp)
|
||||
{
|
||||
if (m_lyp_path != lyp) {
|
||||
m_lyp_path = lyp;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the flag indicating whether to add other layers to the layer properties
|
||||
*/
|
||||
bool add_other_layers () const
|
||||
{
|
||||
return m_add_other_layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the flag indicating whether to add other layers to the layer properties
|
||||
*
|
||||
* If "add_other_layers" is true, the layers in the layout but not specified in the
|
||||
* layer properties file will be added automatically.
|
||||
*/
|
||||
void set_add_other_layers (bool add_other_layers)
|
||||
{
|
||||
if (m_add_other_layers != add_other_layers) {
|
||||
m_add_other_layers = add_other_layers;
|
||||
technology_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gets the layout reader options
|
||||
*/
|
||||
const db::LoadLayoutOptions &load_layout_options () const
|
||||
{
|
||||
return m_load_layout_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the layout reader options
|
||||
*/
|
||||
void set_load_layout_options (const db::LoadLayoutOptions &options)
|
||||
{
|
||||
m_load_layout_options = options;
|
||||
technology_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gets the layout writer options
|
||||
*/
|
||||
const db::SaveLayoutOptions &save_layout_options () const
|
||||
{
|
||||
return m_save_layout_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the layout writer options
|
||||
*/
|
||||
void set_save_layout_options (const db::SaveLayoutOptions &options)
|
||||
{
|
||||
m_save_layout_options = options;
|
||||
technology_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load from file (import)
|
||||
*/
|
||||
void load (const std::string &fn);
|
||||
|
||||
/**
|
||||
* @brief Save to file (export)
|
||||
*/
|
||||
void save (const std::string &fn) const;
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElementList that specifies the technology's XML representation
|
||||
*/
|
||||
static tl::XMLElementList xml_elements ();
|
||||
|
||||
/**
|
||||
* @brief Sets the technology component by the component name
|
||||
*
|
||||
* This replaces the technology component with the given name.
|
||||
* The Technology object will become owner of the component.
|
||||
*/
|
||||
void set_component (TechnologyComponent *component);
|
||||
|
||||
/**
|
||||
* @brief Gets the technology component by the component name
|
||||
*
|
||||
* If no component with that name exists, 0 is returned.
|
||||
*/
|
||||
const TechnologyComponent *component_by_name (const std::string &component_name) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the technology component by the component name (non-const version)
|
||||
*
|
||||
* If no component with that name exists, 0 is returned.
|
||||
*/
|
||||
TechnologyComponent *component_by_name (const std::string &component_name);
|
||||
|
||||
/**
|
||||
* @brief Gets the component names
|
||||
*/
|
||||
std::vector <std::string> component_names () const;
|
||||
|
||||
/**
|
||||
* @brief Builds the effective path from a relative or absolute one using the base path if necessary
|
||||
*/
|
||||
std::string build_effective_path (const std::string &p) const;
|
||||
|
||||
/**
|
||||
* @brief Returns a flag indicating whether the technology is persisted or not
|
||||
*
|
||||
* If the flag is false, this technology is not included into the XML string
|
||||
* of the technologies.
|
||||
*/
|
||||
bool is_persisted () const
|
||||
{
|
||||
return m_persisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a flag indicating whether the technology is persisted
|
||||
*/
|
||||
void set_persisted (bool f)
|
||||
{
|
||||
m_persisted = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a flag indicating whether the technology is readonly
|
||||
*
|
||||
* If the flag is false, the technology can be edited. Otherwise it's locked for editing.
|
||||
*/
|
||||
bool is_readonly () const
|
||||
{
|
||||
return m_readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a flag indicating whether the technology is readonly
|
||||
*/
|
||||
void set_readonly (bool f)
|
||||
{
|
||||
m_readonly = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief An event indicating that the technology has changed
|
||||
*/
|
||||
tl::Event technology_changed_event;
|
||||
|
||||
/**
|
||||
* @brief An event indicating that the technology has changed (with a sender argument)
|
||||
*/
|
||||
tl::event<Technology *> technology_changed_with_sender_event;
|
||||
|
||||
private:
|
||||
std::string m_name, m_description;
|
||||
std::string m_grain_name;
|
||||
double m_dbu;
|
||||
std::string m_explicit_base_path, m_default_base_path;
|
||||
db::LoadLayoutOptions m_load_layout_options;
|
||||
db::SaveLayoutOptions m_save_layout_options;
|
||||
std::string m_lyp_path;
|
||||
std::string m_lyt_path;
|
||||
bool m_add_other_layers;
|
||||
std::vector <TechnologyComponent *> m_components;
|
||||
bool m_persisted;
|
||||
bool m_readonly;
|
||||
std::string m_lyt_file;
|
||||
|
||||
void init ();
|
||||
|
||||
void technology_changed ()
|
||||
{
|
||||
technology_changed_with_sender_event (this);
|
||||
technology_changed_event ();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A technology component
|
||||
*
|
||||
* A technology component is a part of the data for one technology.
|
||||
* Plugins may register technology components in every technology and
|
||||
* use those components to store their specific data.
|
||||
* A technology component has a name and a description. The name is used
|
||||
* to identify a component within a technology. The description is shown
|
||||
* in the setup dialogs.
|
||||
* This class is the base class for all technology components.
|
||||
*/
|
||||
class LAYBASIC_PUBLIC TechnologyComponent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
*
|
||||
* @param name The name of the technology component
|
||||
* @param descriptor The description of the technology component
|
||||
*/
|
||||
TechnologyComponent (const std::string &name, const std::string &description)
|
||||
: m_name (name), m_description (description)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
virtual ~TechnologyComponent ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the name
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the description
|
||||
*/
|
||||
const std::string &description () const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates the editor
|
||||
*
|
||||
* The implementation of this method is supposed to create an editor for
|
||||
* the given component. It is guaranteed that the component that is given
|
||||
* to the editor is one that has been delivered by create_component ().
|
||||
*/
|
||||
virtual TechnologyComponentEditor *create_editor (QWidget * /*parent*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clone this instance
|
||||
*/
|
||||
virtual TechnologyComponent *clone () const = 0;
|
||||
|
||||
private:
|
||||
std::string m_name, m_description;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A base class for an editor for a technology component
|
||||
*
|
||||
|
|
@ -740,7 +64,7 @@ public:
|
|||
/**
|
||||
* @brief Set the technology and component for the editor
|
||||
*/
|
||||
void set_technology (Technology *tech, TechnologyComponent *tech_component)
|
||||
void set_technology (db::Technology *tech, db::TechnologyComponent *tech_component)
|
||||
{
|
||||
mp_tech = tech;
|
||||
mp_tech_component = tech_component;
|
||||
|
|
@ -763,31 +87,31 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
Technology *tech ()
|
||||
db::Technology *tech ()
|
||||
{
|
||||
return mp_tech;
|
||||
}
|
||||
|
||||
TechnologyComponent *tech_component ()
|
||||
db::TechnologyComponent *tech_component ()
|
||||
{
|
||||
return mp_tech_component;
|
||||
}
|
||||
|
||||
private:
|
||||
Technology *mp_tech;
|
||||
TechnologyComponent *mp_tech_component;
|
||||
db::Technology *mp_tech;
|
||||
db::TechnologyComponent *mp_tech_component;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A base class for a technology component provider
|
||||
*/
|
||||
class LAYBASIC_PUBLIC TechnologyComponentProvider
|
||||
class LAYBASIC_PUBLIC TechnologyEditorProvider
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
TechnologyComponentProvider ()
|
||||
TechnologyEditorProvider ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -795,7 +119,7 @@ public:
|
|||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
virtual ~TechnologyComponentProvider ()
|
||||
virtual ~TechnologyEditorProvider ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -803,146 +127,13 @@ public:
|
|||
/**
|
||||
* @brief Creates the technology component
|
||||
*/
|
||||
virtual TechnologyComponent *create_component () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Delivers the XMLElement object that represents this component within a technology XML tree
|
||||
*
|
||||
* The object returned is destroyed by the caller.
|
||||
*/
|
||||
virtual tl::XMLElementBase *xml_element () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the technology component (custom read adaptor)
|
||||
*/
|
||||
|
||||
template <class TC>
|
||||
class TechnologyComponentReadAdaptor
|
||||
{
|
||||
public:
|
||||
typedef tl::pass_by_ref_tag tag;
|
||||
|
||||
TechnologyComponentReadAdaptor (const std::string &name)
|
||||
: m_name (name), mp_t (0), m_done (false)
|
||||
virtual TechnologyComponentEditor *create_editor (QWidget * /*parent*/) const
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
const TC &operator () () const
|
||||
{
|
||||
const TC *tc = dynamic_cast<const TC *> ((const_cast <lay::Technology *> (mp_t))->component_by_name (m_name));
|
||||
if (! tc) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Unknown technology component: ")) + m_name);
|
||||
}
|
||||
|
||||
return *tc;
|
||||
}
|
||||
|
||||
bool at_end () const
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
void start (const lay::Technology &t)
|
||||
{
|
||||
mp_t = &t;
|
||||
m_done = false;
|
||||
}
|
||||
|
||||
void next ()
|
||||
{
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
const lay::Technology *mp_t;
|
||||
bool m_done;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the XML serialization of the technology component (custom write adaptor)
|
||||
*/
|
||||
|
||||
template <class TC>
|
||||
class TechnologyComponentWriteAdaptor
|
||||
{
|
||||
public:
|
||||
TechnologyComponentWriteAdaptor (const std::string &name)
|
||||
: m_name (name)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void operator () (lay::Technology &t, tl::XMLReaderState &reader) const
|
||||
{
|
||||
const TechnologyComponent *tc_basic = t.component_by_name (m_name);
|
||||
TC *tc = 0;
|
||||
if (! tc_basic) {
|
||||
tc = new TC ();
|
||||
} else {
|
||||
tc = dynamic_cast<TC *> (tc_basic->clone ());
|
||||
if (! tc) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Invalid technology component: ")) + m_name);
|
||||
}
|
||||
}
|
||||
|
||||
tl::XMLObjTag<TC> tag;
|
||||
*tc = *reader.back (tag);
|
||||
|
||||
t.set_component (tc);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A custom XMLElement for the serialization of technology components
|
||||
*
|
||||
* TechnologyComponentProvider::xml_element can return such an element to
|
||||
* insert a custom XML element into the XML tree which represents the
|
||||
* technology component.
|
||||
*
|
||||
* The name of the element will be the name of the technology component.
|
||||
*/
|
||||
|
||||
template <class TC>
|
||||
class TechnologyComponentXMLElement
|
||||
: public tl::XMLElement<TC, lay::Technology, TechnologyComponentReadAdaptor<TC>, TechnologyComponentWriteAdaptor<TC> >
|
||||
{
|
||||
public:
|
||||
TechnologyComponentXMLElement (const std::string &name, const tl::XMLElementList &children)
|
||||
: tl::XMLElement<TC, lay::Technology, TechnologyComponentReadAdaptor<TC>, TechnologyComponentWriteAdaptor<TC> > (TechnologyComponentReadAdaptor<TC> (name), TechnologyComponentWriteAdaptor<TC> (name), name, children)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
TechnologyComponentXMLElement (const TechnologyComponentXMLElement &d)
|
||||
: tl::XMLElement<TC, lay::Technology, TechnologyComponentReadAdaptor<TC>, TechnologyComponentWriteAdaptor<TC> > (d)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *clone () const
|
||||
{
|
||||
return new TechnologyComponentXMLElement (*this);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
/**
|
||||
* @brief Type traits
|
||||
*/
|
||||
template <> struct type_traits <lay::TechnologyComponent> : public type_traits<void> {
|
||||
typedef tl::false_tag has_default_constructor;
|
||||
typedef tl::false_tag has_copy_constructor;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ FORMS = \
|
|||
UserPropertiesForm.ui \
|
||||
UserPropertiesEditForm.ui \
|
||||
SpecificLoadLayoutOptionsDialog.ui \
|
||||
CommonReaderOptionsPage.ui \
|
||||
SelectLineStyleForm.ui \
|
||||
LayoutViewConfigPage6a.ui \
|
||||
EditLineStylesForm.ui
|
||||
|
|
@ -154,14 +153,12 @@ SOURCES = \
|
|||
rdbMarkerBrowser.cc \
|
||||
rdbMarkerBrowserDialog.cc \
|
||||
rdbMarkerBrowserPage.cc \
|
||||
layCommonReaderPlugin.cc \
|
||||
layLineStyles.cc \
|
||||
laySelectLineStyleForm.cc \
|
||||
layLineStylePalette.cc \
|
||||
layEditLineStylesForm.cc \
|
||||
layEditLineStyleWidget.cc \
|
||||
layBackgroundAwareTreeStyle.cc \
|
||||
gsiDeclLayTechnologies.cc
|
||||
|
||||
HEADERS = \
|
||||
gtf.h \
|
||||
|
|
|
|||
|
|
@ -164,6 +164,25 @@ public:
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_reader_options_element () const
|
||||
{
|
||||
return new db::ReaderOptionsXMLElement<db::CIFReaderOptions> ("cif",
|
||||
tl::make_member (&db::CIFReaderOptions::wire_mode, "wire-mode") +
|
||||
tl::make_member (&db::CIFReaderOptions::dbu, "dbu") +
|
||||
tl::make_member (&db::CIFReaderOptions::layer_map, "layer-map") +
|
||||
tl::make_member (&db::CIFReaderOptions::create_other_layers, "create-other-layers") +
|
||||
tl::make_member (&db::CIFReaderOptions::keep_layer_names, "keep-layer-names")
|
||||
);
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_writer_options_element () const
|
||||
{
|
||||
return new db::WriterOptionsXMLElement<db::CIFWriterOptions> ("cif",
|
||||
tl::make_member (&db::CIFWriterOptions::dummy_calls, "dummy-calls") +
|
||||
tl::make_member (&db::CIFWriterOptions::blank_separator, "blank-separator")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::StreamFormatDeclaration> reader_decl (new CIFFormatDeclaration (), 100, "CIF");
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ CIFReaderOptionPage::~CIFReaderOptionPage ()
|
|||
}
|
||||
|
||||
void
|
||||
CIFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
CIFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
static const db::CIFReaderOptions default_options;
|
||||
const db::CIFReaderOptions *options = dynamic_cast<const db::CIFReaderOptions *> (o);
|
||||
|
|
@ -65,7 +65,7 @@ CIFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay:
|
|||
}
|
||||
|
||||
void
|
||||
CIFReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
CIFReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
db::CIFReaderOptions *options = dynamic_cast<db::CIFReaderOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -102,17 +102,6 @@ public:
|
|||
{
|
||||
return new db::CIFReaderOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::ReaderOptionsXMLElement<db::CIFReaderOptions> ("cif",
|
||||
tl::make_member (&db::CIFReaderOptions::wire_mode, "wire-mode") +
|
||||
tl::make_member (&db::CIFReaderOptions::dbu, "dbu") +
|
||||
tl::make_member (&db::CIFReaderOptions::layer_map, "layer-map") +
|
||||
tl::make_member (&db::CIFReaderOptions::create_other_layers, "create-other-layers") +
|
||||
tl::make_member (&db::CIFReaderOptions::keep_layer_names, "keep-layer-names")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::CIFReaderPluginDeclaration (), 10000, "CIFReader");
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public:
|
|||
CIFReaderOptionPage (QWidget *parent);
|
||||
~CIFReaderOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
|
||||
private:
|
||||
Ui::CIFReaderOptionPage *mp_ui;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ CIFWriterOptionPage::~CIFWriterOptionPage ()
|
|||
}
|
||||
|
||||
void
|
||||
CIFWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/)
|
||||
CIFWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
const db::CIFWriterOptions *options = dynamic_cast<const db::CIFWriterOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -61,7 +61,7 @@ CIFWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const lay:
|
|||
}
|
||||
|
||||
void
|
||||
CIFWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/, bool /*gzip*/)
|
||||
CIFWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/, bool /*gzip*/)
|
||||
{
|
||||
db::CIFWriterOptions *options = dynamic_cast<db::CIFWriterOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -92,14 +92,6 @@ public:
|
|||
{
|
||||
return new db::CIFWriterOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::WriterOptionsXMLElement<db::CIFWriterOptions> ("cif",
|
||||
tl::make_member (&db::CIFWriterOptions::dummy_calls, "dummy-calls") +
|
||||
tl::make_member (&db::CIFWriterOptions::blank_separator, "blank-separator")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::CIFWriterPluginDeclaration (), 10000, "CIFWriter");
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ public:
|
|||
CIFWriterOptionPage (QWidget *parent);
|
||||
~CIFWriterOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const lay::Technology *tech, bool gzip);
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip);
|
||||
|
||||
private:
|
||||
Ui::CIFWriterOptionPage *mp_ui;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = lay_plugin
|
||||
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "dbCommonReader.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
#include "layCommonReaderPlugin.h"
|
||||
#include "ui_CommonReaderOptionsPage.h"
|
||||
#include "gsiDecl.h"
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// CommonReaderOptionPage definition and implementation
|
||||
|
||||
CommonReaderOptionPage::CommonReaderOptionPage (QWidget *parent)
|
||||
: StreamReaderOptionsPage (parent)
|
||||
{
|
||||
mp_ui = new Ui::CommonReaderOptionPage ();
|
||||
mp_ui->setupUi (this);
|
||||
}
|
||||
|
||||
CommonReaderOptionPage::~CommonReaderOptionPage ()
|
||||
{
|
||||
delete mp_ui;
|
||||
mp_ui = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CommonReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
static const db::CommonReaderOptions default_options;
|
||||
const db::CommonReaderOptions *options = dynamic_cast<const db::CommonReaderOptions *> (o);
|
||||
if (!options) {
|
||||
options = &default_options;
|
||||
}
|
||||
|
||||
mp_ui->enable_text_cbx->setChecked (options->enable_text_objects);
|
||||
mp_ui->enable_properties_cbx->setChecked (options->enable_properties);
|
||||
mp_ui->layer_map->set_layer_map (options->layer_map);
|
||||
mp_ui->read_all_cbx->setChecked (options->create_other_layers);
|
||||
}
|
||||
|
||||
void
|
||||
CommonReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
db::CommonReaderOptions *options = dynamic_cast<db::CommonReaderOptions *> (o);
|
||||
if (options) {
|
||||
|
||||
options->enable_text_objects = mp_ui->enable_text_cbx->isChecked ();
|
||||
options->enable_properties = mp_ui->enable_properties_cbx->isChecked ();
|
||||
options->layer_map = mp_ui->layer_map->get_layer_map ();
|
||||
options->create_other_layers = mp_ui->read_all_cbx->isChecked ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// CommonReaderPluginDeclaration definition and implementation
|
||||
|
||||
class CommonReaderPluginDeclaration
|
||||
: public StreamReaderPluginDeclaration
|
||||
{
|
||||
public:
|
||||
CommonReaderPluginDeclaration ()
|
||||
: StreamReaderPluginDeclaration (db::CommonReaderOptions ().format_name ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
StreamReaderOptionsPage *format_specific_options_page (QWidget *parent) const
|
||||
{
|
||||
return new CommonReaderOptionPage (parent);
|
||||
}
|
||||
|
||||
db::FormatSpecificReaderOptions *create_specific_options () const
|
||||
{
|
||||
return new db::CommonReaderOptions ();
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::CommonReaderPluginDeclaration (), 10000, "CommonReader");
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
TARGET = cif
|
||||
DESTDIR = $$OUT_PWD/../../../../lay_plugins
|
||||
|
||||
include($$PWD/../../../lay_plugin.pri)
|
||||
|
||||
INCLUDEPATH += $$PWD/../db_plugin
|
||||
DEPENDPATH += $$PWD/../db_plugin
|
||||
LIBS += -L$$DESTDIR/../db_plugins -lcif
|
||||
|
||||
!isEmpty(RPATH) {
|
||||
QMAKE_RPATHDIR += $$RPATH/db_plugins
|
||||
}
|
||||
|
||||
HEADERS = \
|
||||
|
||||
SOURCES = \
|
||||
layCommonStreamOptions.cc \
|
||||
|
||||
FORMS = \
|
||||
CommonReaderOptionsPage.ui \
|
||||
|
|
@ -139,6 +139,31 @@ public:
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_reader_options_element () const
|
||||
{
|
||||
return new db::ReaderOptionsXMLElement<db::DXFReaderOptions> ("dxf",
|
||||
tl::make_member (&db::DXFReaderOptions::dbu, "dbu") +
|
||||
tl::make_member (&db::DXFReaderOptions::unit, "unit") +
|
||||
tl::make_member (&db::DXFReaderOptions::text_scaling, "text-scaling") +
|
||||
tl::make_member (&db::DXFReaderOptions::circle_points, "circle-points") +
|
||||
tl::make_member (&db::DXFReaderOptions::circle_accuracy, "circle-accuracy") +
|
||||
tl::make_member (&db::DXFReaderOptions::contour_accuracy, "contour-accuracy") +
|
||||
tl::make_member (&db::DXFReaderOptions::polyline_mode, "polyline-mode") +
|
||||
tl::make_member (&db::DXFReaderOptions::render_texts_as_polygons, "render-texts-as-polygons") +
|
||||
tl::make_member (&db::DXFReaderOptions::keep_other_cells, "keep-other-cells") +
|
||||
tl::make_member (&db::DXFReaderOptions::keep_layer_names, "keep-layer-names") +
|
||||
tl::make_member (&db::DXFReaderOptions::create_other_layers, "create-other-layers") +
|
||||
tl::make_member (&db::DXFReaderOptions::layer_map, "layer-map")
|
||||
);
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_writer_options_element () const
|
||||
{
|
||||
return new db::WriterOptionsXMLElement<db::DXFWriterOptions> ("cif",
|
||||
tl::make_member (&db::DXFWriterOptions::polygon_mode, "polygon-mode")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::StreamFormatDeclaration> reader_decl (new DXFFormatDeclaration (), 100, "DXF");
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ DXFReaderOptionPage::~DXFReaderOptionPage ()
|
|||
}
|
||||
|
||||
void
|
||||
DXFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
DXFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
static const db::DXFReaderOptions default_options;
|
||||
const db::DXFReaderOptions *options = dynamic_cast<const db::DXFReaderOptions *> (o);
|
||||
|
|
@ -71,7 +71,7 @@ DXFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay:
|
|||
}
|
||||
|
||||
void
|
||||
DXFReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
DXFReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
db::DXFReaderOptions *options = dynamic_cast<db::DXFReaderOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -124,24 +124,6 @@ public:
|
|||
{
|
||||
return new db::DXFReaderOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::ReaderOptionsXMLElement<db::DXFReaderOptions> ("dxf",
|
||||
tl::make_member (&db::DXFReaderOptions::dbu, "dbu") +
|
||||
tl::make_member (&db::DXFReaderOptions::unit, "unit") +
|
||||
tl::make_member (&db::DXFReaderOptions::text_scaling, "text-scaling") +
|
||||
tl::make_member (&db::DXFReaderOptions::circle_points, "circle-points") +
|
||||
tl::make_member (&db::DXFReaderOptions::circle_accuracy, "circle-accuracy") +
|
||||
tl::make_member (&db::DXFReaderOptions::contour_accuracy, "contour-accuracy") +
|
||||
tl::make_member (&db::DXFReaderOptions::polyline_mode, "polyline-mode") +
|
||||
tl::make_member (&db::DXFReaderOptions::render_texts_as_polygons, "render-texts-as-polygons") +
|
||||
tl::make_member (&db::DXFReaderOptions::keep_other_cells, "keep-other-cells") +
|
||||
tl::make_member (&db::DXFReaderOptions::keep_layer_names, "keep-layer-names") +
|
||||
tl::make_member (&db::DXFReaderOptions::create_other_layers, "create-other-layers") +
|
||||
tl::make_member (&db::DXFReaderOptions::layer_map, "layer-map")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::DXFReaderPluginDeclaration (), 10000, "DXFReader");
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public:
|
|||
DXFReaderOptionPage (QWidget *parent);
|
||||
~DXFReaderOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
|
||||
private:
|
||||
Ui::DXFReaderOptionPage *mp_ui;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ DXFWriterOptionPage::~DXFWriterOptionPage ()
|
|||
}
|
||||
|
||||
void
|
||||
DXFWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/)
|
||||
DXFWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
const db::DXFWriterOptions *options = dynamic_cast<const db::DXFWriterOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -57,7 +57,7 @@ DXFWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const lay:
|
|||
}
|
||||
|
||||
void
|
||||
DXFWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/, bool /*gzip*/)
|
||||
DXFWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/, bool /*gzip*/)
|
||||
{
|
||||
db::DXFWriterOptions *options = dynamic_cast<db::DXFWriterOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -87,13 +87,6 @@ public:
|
|||
{
|
||||
return new db::DXFWriterOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::WriterOptionsXMLElement<db::DXFWriterOptions> ("cif",
|
||||
tl::make_member (&db::DXFWriterOptions::polygon_mode, "polygon-mode")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::DXFWriterPluginDeclaration (), 10000, "DXFWriter");
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public:
|
|||
DXFWriterOptionPage (QWidget *parent);
|
||||
~DXFWriterOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const lay::Technology *tech, bool gzip);
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip);
|
||||
|
||||
private:
|
||||
Ui::DXFWriterOptionPage *mp_ui;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,29 @@ class GDS2FormatDeclaration
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_writer_options_element () const
|
||||
{
|
||||
return new db::WriterOptionsXMLElement<db::GDS2WriterOptions> ("gds2",
|
||||
tl::make_member (&db::GDS2WriterOptions::write_timestamps, "write-timestamps") +
|
||||
tl::make_member (&db::GDS2WriterOptions::write_cell_properties, "write-cell-properties") +
|
||||
tl::make_member (&db::GDS2WriterOptions::write_file_properties, "write-file-properties") +
|
||||
tl::make_member (&db::GDS2WriterOptions::no_zero_length_paths, "no-zero-length-paths") +
|
||||
tl::make_member (&db::GDS2WriterOptions::multi_xy_records, "multi-xy-records") +
|
||||
tl::make_member (&db::GDS2WriterOptions::max_vertex_count, "max-vertex-count") +
|
||||
tl::make_member (&db::GDS2WriterOptions::max_cellname_length, "max-cellname-length") +
|
||||
tl::make_member (&db::GDS2WriterOptions::libname, "libname")
|
||||
);
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_reader_options_element () const
|
||||
{
|
||||
return new db::ReaderOptionsXMLElement<db::GDS2ReaderOptions> ("gds2",
|
||||
tl::make_member (&db::GDS2ReaderOptions::box_mode, "box-mode") +
|
||||
tl::make_member (&db::GDS2ReaderOptions::allow_big_records, "allow-big-records") +
|
||||
tl::make_member (&db::GDS2ReaderOptions::allow_multi_xy_records, "allow-multi-xy-records")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::StreamFormatDeclaration> format_decl (new GDS2FormatDeclaration (), 0, "GDS2");
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ GDS2ReaderOptionPage::~GDS2ReaderOptionPage ()
|
|||
}
|
||||
|
||||
void
|
||||
GDS2ReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
GDS2ReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
static const db::GDS2ReaderOptions default_options;
|
||||
const db::GDS2ReaderOptions *options = dynamic_cast<const db::GDS2ReaderOptions *> (o);
|
||||
|
|
@ -64,7 +64,7 @@ GDS2ReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay
|
|||
}
|
||||
|
||||
void
|
||||
GDS2ReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const lay::Technology * /*tech*/)
|
||||
GDS2ReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
db::GDS2ReaderOptions *options = dynamic_cast<db::GDS2ReaderOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -98,15 +98,6 @@ public:
|
|||
{
|
||||
return new db::GDS2ReaderOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::ReaderOptionsXMLElement<db::GDS2ReaderOptions> ("gds2",
|
||||
tl::make_member (&db::GDS2ReaderOptions::box_mode, "box-mode") +
|
||||
tl::make_member (&db::GDS2ReaderOptions::allow_big_records, "allow-big-records") +
|
||||
tl::make_member (&db::GDS2ReaderOptions::allow_multi_xy_records, "allow-multi-xy-records")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::GDS2ReaderPluginDeclaration (), 10000, "GDS2Reader");
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public:
|
|||
GDS2ReaderOptionPage (QWidget *parent);
|
||||
~GDS2ReaderOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
|
||||
private:
|
||||
Ui::GDS2ReaderOptionPage *mp_ui;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ GDS2WriterOptionPage::~GDS2WriterOptionPage ()
|
|||
}
|
||||
|
||||
void
|
||||
GDS2WriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/)
|
||||
GDS2WriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
const db::GDS2WriterOptions *options = dynamic_cast<const db::GDS2WriterOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -68,7 +68,7 @@ GDS2WriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const lay
|
|||
}
|
||||
|
||||
void
|
||||
GDS2WriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/, bool /*gzip*/)
|
||||
GDS2WriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/, bool /*gzip*/)
|
||||
{
|
||||
db::GDS2WriterOptions *options = dynamic_cast<db::GDS2WriterOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -135,20 +135,6 @@ public:
|
|||
return new db::GDS2WriterOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::WriterOptionsXMLElement<db::GDS2WriterOptions> ("gds2",
|
||||
tl::make_member (&db::GDS2WriterOptions::write_timestamps, "write-timestamps") +
|
||||
tl::make_member (&db::GDS2WriterOptions::write_cell_properties, "write-cell-properties") +
|
||||
tl::make_member (&db::GDS2WriterOptions::write_file_properties, "write-file-properties") +
|
||||
tl::make_member (&db::GDS2WriterOptions::no_zero_length_paths, "no-zero-length-paths") +
|
||||
tl::make_member (&db::GDS2WriterOptions::multi_xy_records, "multi-xy-records") +
|
||||
tl::make_member (&db::GDS2WriterOptions::max_vertex_count, "max-vertex-count") +
|
||||
tl::make_member (&db::GDS2WriterOptions::max_cellname_length, "max-cellname-length") +
|
||||
tl::make_member (&db::GDS2WriterOptions::libname, "libname")
|
||||
);
|
||||
}
|
||||
|
||||
void initialize_options_from_layout_handle (db::FormatSpecificWriterOptions *o, const lay::LayoutHandle &lh) const
|
||||
{
|
||||
// Initialize the libname property from meta data with key "libname".
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ public:
|
|||
GDS2WriterOptionPage (QWidget *parent);
|
||||
~GDS2WriterOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const lay::Technology *tech, bool gzip);
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip);
|
||||
|
||||
public slots:
|
||||
void multi_xy_clicked ();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,278 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "tlTimer.h"
|
||||
#include "tlStream.h"
|
||||
|
||||
#include "dbReader.h"
|
||||
#include "dbStream.h"
|
||||
#include "dbLEFImporter.h"
|
||||
#include "dbDEFImporter.h"
|
||||
#include "dbLEFDEFImporter.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Plugin for the stream reader
|
||||
|
||||
/**
|
||||
* @brief Determines the format of the given stream
|
||||
* Returns true, if the stream has LEF format
|
||||
*/
|
||||
static bool is_lef_format (const std::string &fn)
|
||||
{
|
||||
static const char *suffixes[] = { ".lef", ".LEF", ".lef.gz", ".LEF.gz" };
|
||||
|
||||
// NOTE: there is no reliable way of (easily) detecting the format. Hence we use the file
|
||||
// name's suffix for the format hint.
|
||||
for (size_t i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); ++i) {
|
||||
std::string suffix = suffixes [i];
|
||||
if (fn.size () > suffix.size () && fn.find (suffix) == fn.size () - suffix.size ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines the format of the given stream
|
||||
* Returns true, if the stream has DEF format
|
||||
*/
|
||||
static bool is_def_format (const std::string &fn)
|
||||
{
|
||||
static const char *suffixes[] = { ".def", ".DEF", ".def.gz", ".DEF.gz" };
|
||||
|
||||
// NOTE: there is no reliable way of (easily) detecting the format. Hence we use the file
|
||||
// name's suffix for the format hint.
|
||||
for (size_t i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); ++i) {
|
||||
std::string suffix = suffixes [i];
|
||||
if (fn.size () > suffix.size () && fn.find (suffix) == fn.size () - suffix.size ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class LEFDEFReader
|
||||
: public db::ReaderBase
|
||||
{
|
||||
public:
|
||||
|
||||
LEFDEFReader (tl::InputStream &s)
|
||||
: m_stream (s)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual const db::LayerMap &read (db::Layout &layout, const db::LoadLayoutOptions &options) throw (tl::Exception)
|
||||
{
|
||||
return read_lefdef (layout, options, is_lef_format (m_stream.filename ()));
|
||||
}
|
||||
|
||||
virtual const db::LayerMap &read (db::Layout &layout) throw (tl::Exception)
|
||||
{
|
||||
return read_lefdef (layout, db::LoadLayoutOptions (), is_lef_format (m_stream.filename ()));
|
||||
}
|
||||
|
||||
virtual const char *format () const
|
||||
{
|
||||
return "LEFDEF";
|
||||
}
|
||||
private:
|
||||
tl::InputStream &m_stream;
|
||||
db::LayerMap m_layer_map;
|
||||
|
||||
std::string correct_path (const std::string &fn)
|
||||
{
|
||||
QFileInfo fi (tl::to_qstring (fn));
|
||||
if (! fi.isAbsolute ()) {
|
||||
QDir input_dir (QFileInfo (tl::to_qstring (m_stream.absolute_path ())).dir ());
|
||||
return tl::to_string (input_dir.filePath (fi.filePath ()));
|
||||
} else {
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
|
||||
const db::LayerMap &read_lefdef (db::Layout &layout, const db::LoadLayoutOptions &options, bool import_lef) throw (tl::Exception)
|
||||
{
|
||||
const db::LEFDEFReaderOptions *lefdef_options = dynamic_cast<const db::LEFDEFReaderOptions *> (options.get_options (format ()));
|
||||
static db::LEFDEFReaderOptions default_options;
|
||||
if (! lefdef_options) {
|
||||
lefdef_options = &default_options;
|
||||
}
|
||||
|
||||
// Take the layer map and the "read all layers" flag from the reader options - hence we override the
|
||||
db::LEFDEFLayerDelegate layers (lefdef_options);
|
||||
layers.prepare (layout);
|
||||
layout.dbu (lefdef_options->dbu ());
|
||||
|
||||
if (import_lef) {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Reading LEF file")));
|
||||
|
||||
db::LEFImporter importer;
|
||||
|
||||
for (std::vector<std::string>::const_iterator l = lefdef_options->begin_lef_files (); l != lefdef_options->end_lef_files (); ++l) {
|
||||
|
||||
std::string lp = correct_path (*l);
|
||||
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << lp;
|
||||
importer.read (lef_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << m_stream.source ();
|
||||
importer.read (m_stream, layout, layers);
|
||||
|
||||
} else {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Reading DEF file")));
|
||||
|
||||
DEFImporter importer;
|
||||
|
||||
for (std::vector<std::string>::const_iterator l = lefdef_options->begin_lef_files (); l != lefdef_options->end_lef_files (); ++l) {
|
||||
|
||||
std::string lp = correct_path (*l);
|
||||
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << lp;
|
||||
importer.read_lef (lef_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
// Additionally read all LEF files next to the DEF file
|
||||
|
||||
QDir input_dir (QFileInfo (tl::to_qstring (m_stream.absolute_path ())).dir ());
|
||||
if (input_dir.exists () && input_dir.isReadable ()) {
|
||||
|
||||
QStringList entries = input_dir.entryList ();
|
||||
for (QStringList::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
||||
|
||||
if (is_lef_format (tl::to_string (*e))) {
|
||||
|
||||
std::string lp = tl::to_string (input_dir.filePath (*e));
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << lp;
|
||||
importer.read_lef (lef_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << m_stream.source ();
|
||||
importer.read (m_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
layers.finish (layout);
|
||||
|
||||
m_layer_map = layers.layer_map ();
|
||||
return m_layer_map;
|
||||
}
|
||||
};
|
||||
|
||||
class LEFDEFFormatDeclaration
|
||||
: public db::StreamFormatDeclaration
|
||||
{
|
||||
virtual std::string format_name () const { return "LEFDEF"; }
|
||||
virtual std::string format_desc () const { return "LEF/DEF"; }
|
||||
virtual std::string format_title () const { return "LEF/DEF (unified reader)"; }
|
||||
virtual std::string file_format () const { return "LEF/DEF files (*.lef *.LEF *.lef.gz *.LEF.gz *.def *.DEF *.def.gz *.DEF.gz)"; }
|
||||
|
||||
virtual bool detect (tl::InputStream &stream) const
|
||||
{
|
||||
return is_lef_format (stream.filename ()) || is_def_format (stream.filename ());
|
||||
}
|
||||
|
||||
virtual db::ReaderBase *create_reader (tl::InputStream &s) const
|
||||
{
|
||||
return new db::LEFDEFReader (s);
|
||||
}
|
||||
|
||||
virtual db::WriterBase *create_writer () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool can_read () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool can_write () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_reader_options_element () const
|
||||
{
|
||||
return new db::ReaderOptionsXMLElement<LEFDEFReaderOptions> ("lefdef",
|
||||
tl::make_member (&LEFDEFReaderOptions::read_all_layers, &LEFDEFReaderOptions::set_read_all_layers, "read-all-layers") +
|
||||
tl::make_member (&LEFDEFReaderOptions::layer_map, &LEFDEFReaderOptions::set_layer_map, "layer-map") +
|
||||
tl::make_member (&LEFDEFReaderOptions::dbu, &LEFDEFReaderOptions::set_dbu, "dbu") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_net_names, &LEFDEFReaderOptions::set_produce_net_names, "produce-net-names") +
|
||||
tl::make_member (&LEFDEFReaderOptions::net_property_name, &LEFDEFReaderOptions::set_net_property_name, "net-property-name") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_inst_names, &LEFDEFReaderOptions::set_produce_inst_names, "produce-inst-names") +
|
||||
tl::make_member (&LEFDEFReaderOptions::inst_property_name, &LEFDEFReaderOptions::set_inst_property_name, "inst-property-name") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_cell_outlines, &LEFDEFReaderOptions::set_produce_cell_outlines, "produce-cell-outlines") +
|
||||
tl::make_member (&LEFDEFReaderOptions::cell_outline_layer, &LEFDEFReaderOptions::set_cell_outline_layer, "cell-outline-layer") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_placement_blockages, &LEFDEFReaderOptions::set_produce_placement_blockages, "produce-placement-blockages") +
|
||||
tl::make_member (&LEFDEFReaderOptions::placement_blockage_layer, &LEFDEFReaderOptions::set_placement_blockage_layer, "placement-blockage-layer") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_regions, &LEFDEFReaderOptions::set_produce_regions, "produce-regions") +
|
||||
tl::make_member (&LEFDEFReaderOptions::region_layer, &LEFDEFReaderOptions::set_region_layer, "region-layer") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_via_geometry, &LEFDEFReaderOptions::set_produce_via_geometry, "produce-via-geometry") +
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_suffix, &LEFDEFReaderOptions::set_via_geometry_suffix, "via-geometry-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_datatype, &LEFDEFReaderOptions::set_via_geometry_datatype, "via-geometry-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_pins, &LEFDEFReaderOptions::set_produce_pins, "produce-pins") +
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_suffix, &LEFDEFReaderOptions::set_pins_suffix, "pins-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_datatype, &LEFDEFReaderOptions::set_pins_datatype, "pins-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_obstructions, &LEFDEFReaderOptions::set_produce_obstructions, "produce-obstructions") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_suffix, &LEFDEFReaderOptions::set_obstructions_suffix, "obstructions-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_datatype, &LEFDEFReaderOptions::set_obstructions_datatype, "obstructions-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_blockages, &LEFDEFReaderOptions::set_produce_blockages, "produce-blockages") +
|
||||
tl::make_member (&LEFDEFReaderOptions::blockages_suffix, &LEFDEFReaderOptions::set_blockages_suffix, "blockages-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::blockages_datatype, &LEFDEFReaderOptions::set_blockages_datatype, "blockages-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_labels, &LEFDEFReaderOptions::set_produce_labels, "produce-labels") +
|
||||
tl::make_member (&LEFDEFReaderOptions::labels_suffix, &LEFDEFReaderOptions::set_labels_suffix, "labels-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::labels_datatype, &LEFDEFReaderOptions::set_labels_datatype, "labels-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_routing, &LEFDEFReaderOptions::set_produce_routing, "produce-routing") +
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_suffix, &LEFDEFReaderOptions::set_routing_suffix, "routing-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_datatype, &LEFDEFReaderOptions::set_routing_datatype, "routing-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::begin_lef_files, &LEFDEFReaderOptions::end_lef_files, &LEFDEFReaderOptions::push_lef_file, "lef-files")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::StreamFormatDeclaration> format_decl (new LEFDEFFormatDeclaration (), 500, "LEFDEF");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -5,12 +5,13 @@ DESTDIR = $$OUT_PWD/../../../../db_plugins
|
|||
include($$PWD/../../../db_plugin.pri)
|
||||
|
||||
HEADERS = \
|
||||
dbDEFImporter.h \
|
||||
dbLEFDEFImporter.h \
|
||||
dbLEFImporter.h
|
||||
dbDEFImporter.h \
|
||||
dbLEFDEFImporter.h \
|
||||
dbLEFImporter.h
|
||||
|
||||
SOURCES = \
|
||||
gsiDeclDbLEFDEF.cc \
|
||||
dbDEFImporter.cc \
|
||||
dbLEFDEFImporter.cc \
|
||||
dbLEFImporter.cc
|
||||
dbLEFDEFPlugin.cc \
|
||||
dbDEFImporter.cc \
|
||||
dbLEFDEFImporter.cc \
|
||||
dbLEFImporter.cc
|
||||
|
|
|
|||
|
|
@ -128,10 +128,10 @@ public:
|
|||
tl::InputStream stream (data.file);
|
||||
|
||||
std::string tech_name = lay::MainWindow::instance ()->initial_technology ();
|
||||
if (! lay::Technologies::instance ()->has_technology (tech_name)) {
|
||||
if (! db::Technologies::instance ()->has_technology (tech_name)) {
|
||||
tech_name.clear (); // use default technology
|
||||
}
|
||||
const lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (tech_name);
|
||||
const db::Technology *tech = db::Technologies::instance ()->technology_by_name (tech_name);
|
||||
db::LEFDEFReaderOptions options;
|
||||
if (tech) {
|
||||
const db::LEFDEFReaderOptions *tech_options = dynamic_cast<const db::LEFDEFReaderOptions *>(tech->load_layout_options ().get_options ("LEFDEF"));
|
||||
|
|
|
|||
|
|
@ -317,11 +317,11 @@ BEGIN_PROTECTED
|
|||
|
||||
std::string tech_name;
|
||||
tech_name = lay::MainWindow::instance ()->initial_technology ();
|
||||
if (! lay::Technologies::instance ()->has_technology (tech_name)) {
|
||||
if (! db::Technologies::instance ()->has_technology (tech_name)) {
|
||||
tech_name.clear (); // use default technology
|
||||
}
|
||||
|
||||
lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (tech_name);
|
||||
db::Technology *tech = db::Technologies::instance ()->technology_by_name (tech_name);
|
||||
if (!tech) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -365,7 +365,7 @@ LEFDEFReaderOptionsEditor::LEFDEFReaderOptionsEditor (QWidget *parent)
|
|||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, const lay::Technology * /*tech*/)
|
||||
LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, const db::Technology * /*tech*/)
|
||||
{
|
||||
db::LEFDEFReaderOptions *data = dynamic_cast<db::LEFDEFReaderOptions *> (options);
|
||||
if (! data) {
|
||||
|
|
@ -436,7 +436,7 @@ LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, con
|
|||
}
|
||||
|
||||
void
|
||||
LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options, const lay::Technology *tech)
|
||||
LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech)
|
||||
{
|
||||
static db::LEFDEFReaderOptions empty;
|
||||
const db::LEFDEFReaderOptions *data = dynamic_cast<const db::LEFDEFReaderOptions *> (options);
|
||||
|
|
@ -445,7 +445,7 @@ LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options
|
|||
}
|
||||
|
||||
// TODO: there should be a const weak ptr ...
|
||||
mp_tech.reset (const_cast<lay::Technology *> (tech));
|
||||
mp_tech.reset (const_cast<db::Technology *> (tech));
|
||||
|
||||
dbu->setText (tl::to_qstring (tl::to_string (data->dbu ())));
|
||||
read_all_cbx->setChecked (data->read_all_layers ());
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ Q_OBJECT
|
|||
public:
|
||||
LEFDEFReaderOptionsEditor (QWidget *parent);
|
||||
|
||||
void commit (db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
void setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech);
|
||||
|
||||
private slots:
|
||||
void checkbox_changed ();
|
||||
|
|
@ -100,7 +100,7 @@ private slots:
|
|||
void move_lef_files_down_clicked ();
|
||||
|
||||
private:
|
||||
tl::weak_ptr<lay::Technology> mp_tech;
|
||||
tl::weak_ptr<db::Technology> mp_tech;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,214 +34,9 @@
|
|||
#include "layStream.h"
|
||||
#include "layLEFDEFImportDialogs.h"
|
||||
|
||||
#include "gsiDecl.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Plugin for the stream reader
|
||||
|
||||
/**
|
||||
* @brief Determines the format of the given stream
|
||||
* Returns true, if the stream has LEF format
|
||||
*/
|
||||
static bool is_lef_format (const std::string &fn)
|
||||
{
|
||||
static const char *suffixes[] = { ".lef", ".LEF", ".lef.gz", ".LEF.gz" };
|
||||
|
||||
// NOTE: there is no reliable way of (easily) detecting the format. Hence we use the file
|
||||
// name's suffix for the format hint.
|
||||
for (size_t i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); ++i) {
|
||||
std::string suffix = suffixes [i];
|
||||
if (fn.size () > suffix.size () && fn.find (suffix) == fn.size () - suffix.size ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines the format of the given stream
|
||||
* Returns true, if the stream has DEF format
|
||||
*/
|
||||
static bool is_def_format (const std::string &fn)
|
||||
{
|
||||
static const char *suffixes[] = { ".def", ".DEF", ".def.gz", ".DEF.gz" };
|
||||
|
||||
// NOTE: there is no reliable way of (easily) detecting the format. Hence we use the file
|
||||
// name's suffix for the format hint.
|
||||
for (size_t i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); ++i) {
|
||||
std::string suffix = suffixes [i];
|
||||
if (fn.size () > suffix.size () && fn.find (suffix) == fn.size () - suffix.size ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class LEFDEFReader
|
||||
: public db::ReaderBase
|
||||
{
|
||||
public:
|
||||
|
||||
LEFDEFReader (tl::InputStream &s)
|
||||
: m_stream (s)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual const db::LayerMap &read (db::Layout &layout, const db::LoadLayoutOptions &options) throw (tl::Exception)
|
||||
{
|
||||
return read_lefdef (layout, options, is_lef_format (m_stream.filename ()));
|
||||
}
|
||||
|
||||
virtual const db::LayerMap &read (db::Layout &layout) throw (tl::Exception)
|
||||
{
|
||||
return read_lefdef (layout, db::LoadLayoutOptions (), is_lef_format (m_stream.filename ()));
|
||||
}
|
||||
|
||||
virtual const char *format () const
|
||||
{
|
||||
return "LEFDEF";
|
||||
}
|
||||
private:
|
||||
tl::InputStream &m_stream;
|
||||
db::LayerMap m_layer_map;
|
||||
|
||||
std::string correct_path (const std::string &fn)
|
||||
{
|
||||
QFileInfo fi (tl::to_qstring (fn));
|
||||
if (! fi.isAbsolute ()) {
|
||||
QDir input_dir (QFileInfo (tl::to_qstring (m_stream.absolute_path ())).dir ());
|
||||
return tl::to_string (input_dir.filePath (fi.filePath ()));
|
||||
} else {
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
|
||||
const db::LayerMap &read_lefdef (db::Layout &layout, const db::LoadLayoutOptions &options, bool import_lef) throw (tl::Exception)
|
||||
{
|
||||
const db::LEFDEFReaderOptions *lefdef_options = dynamic_cast<const db::LEFDEFReaderOptions *> (options.get_options (format ()));
|
||||
static db::LEFDEFReaderOptions default_options;
|
||||
if (! lefdef_options) {
|
||||
lefdef_options = &default_options;
|
||||
}
|
||||
|
||||
// Take the layer map and the "read all layers" flag from the reader options - hence we override the
|
||||
db::LEFDEFLayerDelegate layers (lefdef_options);
|
||||
layers.prepare (layout);
|
||||
layout.dbu (lefdef_options->dbu ());
|
||||
|
||||
if (import_lef) {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Reading LEF file")));
|
||||
|
||||
db::LEFImporter importer;
|
||||
|
||||
for (std::vector<std::string>::const_iterator l = lefdef_options->begin_lef_files (); l != lefdef_options->end_lef_files (); ++l) {
|
||||
|
||||
std::string lp = correct_path (*l);
|
||||
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << lp;
|
||||
importer.read (lef_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << m_stream.source ();
|
||||
importer.read (m_stream, layout, layers);
|
||||
|
||||
} else {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Reading DEF file")));
|
||||
|
||||
DEFImporter importer;
|
||||
|
||||
for (std::vector<std::string>::const_iterator l = lefdef_options->begin_lef_files (); l != lefdef_options->end_lef_files (); ++l) {
|
||||
|
||||
std::string lp = correct_path (*l);
|
||||
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << lp;
|
||||
importer.read_lef (lef_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
// Additionally read all LEF files next to the DEF file
|
||||
|
||||
QDir input_dir (QFileInfo (tl::to_qstring (m_stream.absolute_path ())).dir ());
|
||||
if (input_dir.exists () && input_dir.isReadable ()) {
|
||||
|
||||
QStringList entries = input_dir.entryList ();
|
||||
for (QStringList::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
||||
|
||||
if (is_lef_format (tl::to_string (*e))) {
|
||||
|
||||
std::string lp = tl::to_string (input_dir.filePath (*e));
|
||||
tl::InputStream lef_stream (lp);
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << lp;
|
||||
importer.read_lef (lef_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tl::log << tl::to_string (QObject::tr ("Reading")) << " " << m_stream.source ();
|
||||
importer.read (m_stream, layout, layers);
|
||||
|
||||
}
|
||||
|
||||
layers.finish (layout);
|
||||
|
||||
m_layer_map = layers.layer_map ();
|
||||
return m_layer_map;
|
||||
}
|
||||
};
|
||||
|
||||
class LEFDEFFormatDeclaration
|
||||
: public db::StreamFormatDeclaration
|
||||
{
|
||||
virtual std::string format_name () const { return "LEFDEF"; }
|
||||
virtual std::string format_desc () const { return "LEF/DEF"; }
|
||||
virtual std::string format_title () const { return "LEF/DEF (unified reader)"; }
|
||||
virtual std::string file_format () const { return "LEF/DEF files (*.lef *.LEF *.lef.gz *.LEF.gz *.def *.DEF *.def.gz *.DEF.gz)"; }
|
||||
|
||||
virtual bool detect (tl::InputStream &stream) const
|
||||
{
|
||||
return is_lef_format (stream.filename ()) || is_def_format (stream.filename ());
|
||||
}
|
||||
|
||||
virtual db::ReaderBase *create_reader (tl::InputStream &s) const
|
||||
{
|
||||
return new LEFDEFReader (s);
|
||||
}
|
||||
|
||||
virtual db::WriterBase *create_writer () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool can_read () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool can_write () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::StreamFormatDeclaration> format_decl (new LEFDEFFormatDeclaration (), 500, "LEFDEF");
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// LEFDEFPluginDeclaration definition and implementation
|
||||
|
||||
|
|
@ -264,44 +59,6 @@ public:
|
|||
{
|
||||
return new LEFDEFReaderOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::ReaderOptionsXMLElement<LEFDEFReaderOptions> ("lefdef",
|
||||
tl::make_member (&LEFDEFReaderOptions::read_all_layers, &LEFDEFReaderOptions::set_read_all_layers, "read-all-layers") +
|
||||
tl::make_member (&LEFDEFReaderOptions::layer_map, &LEFDEFReaderOptions::set_layer_map, "layer-map") +
|
||||
tl::make_member (&LEFDEFReaderOptions::dbu, &LEFDEFReaderOptions::set_dbu, "dbu") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_net_names, &LEFDEFReaderOptions::set_produce_net_names, "produce-net-names") +
|
||||
tl::make_member (&LEFDEFReaderOptions::net_property_name, &LEFDEFReaderOptions::set_net_property_name, "net-property-name") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_inst_names, &LEFDEFReaderOptions::set_produce_inst_names, "produce-inst-names") +
|
||||
tl::make_member (&LEFDEFReaderOptions::inst_property_name, &LEFDEFReaderOptions::set_inst_property_name, "inst-property-name") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_cell_outlines, &LEFDEFReaderOptions::set_produce_cell_outlines, "produce-cell-outlines") +
|
||||
tl::make_member (&LEFDEFReaderOptions::cell_outline_layer, &LEFDEFReaderOptions::set_cell_outline_layer, "cell-outline-layer") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_placement_blockages, &LEFDEFReaderOptions::set_produce_placement_blockages, "produce-placement-blockages") +
|
||||
tl::make_member (&LEFDEFReaderOptions::placement_blockage_layer, &LEFDEFReaderOptions::set_placement_blockage_layer, "placement-blockage-layer") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_regions, &LEFDEFReaderOptions::set_produce_regions, "produce-regions") +
|
||||
tl::make_member (&LEFDEFReaderOptions::region_layer, &LEFDEFReaderOptions::set_region_layer, "region-layer") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_via_geometry, &LEFDEFReaderOptions::set_produce_via_geometry, "produce-via-geometry") +
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_suffix, &LEFDEFReaderOptions::set_via_geometry_suffix, "via-geometry-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::via_geometry_datatype, &LEFDEFReaderOptions::set_via_geometry_datatype, "via-geometry-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_pins, &LEFDEFReaderOptions::set_produce_pins, "produce-pins") +
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_suffix, &LEFDEFReaderOptions::set_pins_suffix, "pins-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::pins_datatype, &LEFDEFReaderOptions::set_pins_datatype, "pins-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_obstructions, &LEFDEFReaderOptions::set_produce_obstructions, "produce-obstructions") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_suffix, &LEFDEFReaderOptions::set_obstructions_suffix, "obstructions-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::obstructions_datatype, &LEFDEFReaderOptions::set_obstructions_datatype, "obstructions-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_blockages, &LEFDEFReaderOptions::set_produce_blockages, "produce-blockages") +
|
||||
tl::make_member (&LEFDEFReaderOptions::blockages_suffix, &LEFDEFReaderOptions::set_blockages_suffix, "blockages-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::blockages_datatype, &LEFDEFReaderOptions::set_blockages_datatype, "blockages-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_labels, &LEFDEFReaderOptions::set_produce_labels, "produce-labels") +
|
||||
tl::make_member (&LEFDEFReaderOptions::labels_suffix, &LEFDEFReaderOptions::set_labels_suffix, "labels-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::labels_datatype, &LEFDEFReaderOptions::set_labels_datatype, "labels-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::produce_routing, &LEFDEFReaderOptions::set_produce_routing, "produce-routing") +
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_suffix, &LEFDEFReaderOptions::set_routing_suffix, "routing-suffix") +
|
||||
tl::make_member (&LEFDEFReaderOptions::routing_datatype, &LEFDEFReaderOptions::set_routing_datatype, "routing-datatype") +
|
||||
tl::make_member (&LEFDEFReaderOptions::begin_lef_files, &LEFDEFReaderOptions::end_lef_files, &LEFDEFReaderOptions::push_lef_file, "lef-files")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new LEFDEFPluginDeclaration (), 10001, "LEFDEFReader");
|
||||
|
|
|
|||
|
|
@ -463,6 +463,18 @@ public:
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_writer_options_element () const
|
||||
{
|
||||
return new db::WriterOptionsXMLElement<db::OASISWriterOptions> ("oasis",
|
||||
tl::make_member (&db::OASISWriterOptions::compression_level, "compression-level") +
|
||||
tl::make_member (&db::OASISWriterOptions::write_cblocks, "write-cblocks") +
|
||||
tl::make_member (&db::OASISWriterOptions::strict_mode, "strict-mode") +
|
||||
tl::make_member (&db::OASISWriterOptions::write_std_properties, "write-std-properties") +
|
||||
tl::make_member (&db::OASISWriterOptions::subst_char, "subst-char") +
|
||||
tl::make_member (&db::OASISWriterOptions::permissive, "permissive")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::StreamFormatDeclaration> reader_decl (new OASISFormatDeclaration (), 10, "OASIS");
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ public:
|
|||
OASISWriterOptionPage (QWidget *parent);
|
||||
~OASISWriterOptionPage ();
|
||||
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const lay::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const lay::Technology *tech, bool gzip);
|
||||
void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech);
|
||||
void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip);
|
||||
|
||||
private:
|
||||
Ui::OASISWriterOptionPage *mp_ui;
|
||||
|
|
@ -63,7 +63,7 @@ OASISWriterOptionPage::~OASISWriterOptionPage ()
|
|||
}
|
||||
|
||||
void
|
||||
OASISWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/)
|
||||
OASISWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/)
|
||||
{
|
||||
const db::OASISWriterOptions *options = dynamic_cast<const db::OASISWriterOptions *> (o);
|
||||
if (options) {
|
||||
|
|
@ -77,7 +77,7 @@ OASISWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const la
|
|||
}
|
||||
|
||||
void
|
||||
OASISWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const lay::Technology * /*tech*/, bool gzip)
|
||||
OASISWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/, bool gzip)
|
||||
{
|
||||
if (gzip && mp_ui->write_cblocks->isChecked ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("gzip compression cannot be used with CBLOCK compression")));
|
||||
|
|
@ -120,18 +120,6 @@ public:
|
|||
{
|
||||
return new db::OASISWriterOptions ();
|
||||
}
|
||||
|
||||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new lay::WriterOptionsXMLElement<db::OASISWriterOptions> ("oasis",
|
||||
tl::make_member (&db::OASISWriterOptions::compression_level, "compression-level") +
|
||||
tl::make_member (&db::OASISWriterOptions::write_cblocks, "write-cblocks") +
|
||||
tl::make_member (&db::OASISWriterOptions::strict_mode, "strict-mode") +
|
||||
tl::make_member (&db::OASISWriterOptions::write_std_properties, "write-std-properties") +
|
||||
tl::make_member (&db::OASISWriterOptions::subst_char, "subst-char") +
|
||||
tl::make_member (&db::OASISWriterOptions::permissive, "permissive")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::OASISWriterPluginDeclaration (), 10000, "OASISWriter");
|
||||
|
|
|
|||
Loading…
Reference in New Issue