Merge remote-tracking branch 'remotes/origin/pymod' into net-extract

This commit is contained in:
Matthias Koefferlein 2018-11-25 23:16:56 +01:00
commit 5c7cd02af3
49 changed files with 839 additions and 354 deletions

View File

@ -320,7 +320,7 @@ class Config(object):
""" """
Gets the version string Gets the version string
""" """
return "0.26.0.dev7" return "0.26.0.dev8"
config = Config() config = Config()

View File

@ -169,7 +169,7 @@ PluginDeclaration::config_finalize ()
} }
void void
PluginDeclaration::initialized (lay::PluginRoot *) PluginDeclaration::initialized (lay::PluginRoot *root)
{ {
// Check if we already have templates (initial setup) // Check if we already have templates (initial setup)
bool any_templates = false; bool any_templates = false;
@ -198,8 +198,8 @@ PluginDeclaration::initialized (lay::PluginRoot *)
m_templates.push_back (ant::Template (tl::to_string (QObject::tr ("Box")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_box, true, lay::AC_Global, std::string ())); m_templates.push_back (ant::Template (tl::to_string (QObject::tr ("Box")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_box, true, lay::AC_Global, std::string ()));
lay::PluginRoot::instance ()->config_set (cfg_ruler_templates, ant::TemplatesConverter ().to_string (m_templates)); root->config_set (cfg_ruler_templates, ant::TemplatesConverter ().to_string (m_templates));
lay::PluginRoot::instance ()->config_end (); root->config_end ();
} }
} }

View File

@ -242,7 +242,8 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
"* 0: create POLYLINE (default)\n" "* 0: create POLYLINE (default)\n"
"* 1: create LWPOLYLINE\n" "* 1: create LWPOLYLINE\n"
"* 2: decompose into SOLID\n" "* 2: decompose into SOLID\n"
"* 3: create HATCH" "* 3: create HATCH\n"
"* 4: create LINE"
) )
; ;

View File

@ -110,25 +110,82 @@ EdgesToContours::contour (size_t i) const
} }
} }
namespace {
template <class C>
class point_matcher
{
public:
point_matcher () : m_vp_min (0.0), m_d_min (0.0), m_any (false)
{
// .. nothing yet ..
}
/**
* @brief A search criterion for fitting next edges for a point (with attached edge)
* This search will select the edge whose starting point is closest to the
* end point of the reference edge and - if both points are coincident - forms
* the smallest angle with the reference edge.
*/
bool more (const db::point<C> &p, const db::edge<C> &e, const db::edge<C> &other, bool swapped)
{
typedef db::coord_traits<C> coord_traits;
double d = p.double_distance (swapped ? other.p2 () : other.p1 ());
double vp = db::vprod (other.d (), e.d ()) * (1.0 / other.d ().double_length ());
if (! m_any) {
m_vp_min = vp;
m_d_min = d;
m_any = true;
return true;
} else if (fabs (d - m_d_min) < coord_traits::prec ()) {
double vp = db::vprod (other.d (), e.d ()) * (1.0 / other.d ().double_length ());
if (vp < m_vp_min) {
m_vp_min = vp;
return true;
} else {
return false;
}
} else if (d < m_d_min) {
m_vp_min = vp;
m_d_min = d;
return true;
} else {
return false;
}
}
private:
double m_vp_min;
double m_d_min;
bool m_any;
};
}
template <class Iter, class C> static template <class Iter, class C> static
EdgeRef<Iter> *search_follower (const db::point<C> &p, const EdgeRef<Iter> *e, C distance, const db::box_tree<db::box<C>, EdgeRef<Iter> *, EdgeRefToBox<Iter, false> > &t1, const db::box_tree<db::box<C>, EdgeRef<Iter> *, EdgeRefToBox<Iter, true> > &t2) EdgeRef<Iter> *search_follower (const db::point<C> &p, const EdgeRef<Iter> *e, C distance, const db::box_tree<db::box<C>, EdgeRef<Iter> *, EdgeRefToBox<Iter, false> > &t1, const db::box_tree<db::box<C>, EdgeRef<Iter> *, EdgeRefToBox<Iter, true> > &t2)
{ {
typedef db::box<C> box_type; typedef db::box<C> box_type;
double vp_min = 0.0;
EdgeRef<Iter> *cand = 0; EdgeRef<Iter> *cand = 0;
bool fwd = true; bool fwd = true;
point_matcher<C> pm;
// try in forward tree // try in forward tree
typename db::box_tree<box_type, EdgeRef<Iter> *, EdgeRefToBox<Iter, false> >::touching_iterator f = t1.begin_touching (box_type (p, p), EdgeRefToBox <Iter, false> (distance)); typename db::box_tree<box_type, EdgeRef<Iter> *, EdgeRefToBox<Iter, false> >::touching_iterator f = t1.begin_touching (box_type (p, p), EdgeRefToBox <Iter, false> (distance));
while (! f.at_end ()) { while (! f.at_end ()) {
if (*f != e && ! (*f)->connected && (*f)->swapped != 1) { if (*f != e && ! (*f)->connected && (*f)->swapped != 1 && pm.more (p, *e->iter, *(*f)->iter, false)) {
double vp = db::vprod ((*f)->iter->d (), e->iter->d ()) * (1.0 / (*f)->iter->d ().double_length ()); cand = *f;
if (! cand || vp < vp_min) {
vp_min = vp;
cand = *f;
}
} }
++f; ++f;
} }
@ -136,13 +193,9 @@ EdgeRef<Iter> *search_follower (const db::point<C> &p, const EdgeRef<Iter> *e, C
if (! t2.empty ()) { if (! t2.empty ()) {
typename db::box_tree<box_type, EdgeRef<Iter> *, EdgeRefToBox<Iter, true> >::touching_iterator f = t2.begin_touching (box_type (p, p), EdgeRefToBox <Iter, true> (distance)); typename db::box_tree<box_type, EdgeRef<Iter> *, EdgeRefToBox<Iter, true> >::touching_iterator f = t2.begin_touching (box_type (p, p), EdgeRefToBox <Iter, true> (distance));
while (! f.at_end ()) { while (! f.at_end ()) {
if (*f != e && ! (*f)->connected && (*f)->swapped != -1) { if (*f != e && ! (*f)->connected && (*f)->swapped != -1 && pm.more (p, *e->iter, *(*f)->iter, true)) {
double vp = db::vprod ((*f)->iter->d (), e->iter->d ()) * (1.0 / (*f)->iter->d ().double_length ()); cand = *f;
if (! cand || vp < vp_min) { fwd = false;
vp_min = vp;
cand = *f;
fwd = false;
}
} }
++f; ++f;
} }

View File

@ -1114,7 +1114,7 @@ ApplicationBase::run ()
// Give the plugins a change to do some last-minute initialisation and checks // Give the plugins a change to do some last-minute initialisation and checks
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) { for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls); lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
pd->initialized (mw); pd->initialized (plugin_root ());
} }
if (! m_no_gui && m_gtf_replay.empty () && m_gtf_record.empty ()) { if (! m_no_gui && m_gtf_replay.empty () && m_gtf_record.empty ()) {
@ -1280,6 +1280,7 @@ ApplicationBase::special_app_flag (const std::string &name)
GuiApplication::GuiApplication (int &argc, char **argv) GuiApplication::GuiApplication (int &argc, char **argv)
: QApplication (argc, argv), ApplicationBase (false), : QApplication (argc, argv), ApplicationBase (false),
mp_mw (0), mp_mw (0),
mp_plugin_root (0),
mp_recorder (0) mp_recorder (0)
{ {
// install a special style proxy to overcome the issue of black-on-black tree expanders // install a special style proxy to overcome the issue of black-on-black tree expanders
@ -1300,6 +1301,9 @@ GuiApplication::~GuiApplication ()
} }
shutdown (); shutdown ();
delete mp_plugin_root;
mp_plugin_root = 0;
} }
bool bool
@ -1455,15 +1459,18 @@ GuiApplication::start_recording ()
lay::PluginRoot * lay::PluginRoot *
GuiApplication::plugin_root () const GuiApplication::plugin_root () const
{ {
return mp_mw; return mp_plugin_root;
} }
void void
GuiApplication::setup () GuiApplication::setup ()
{ {
tl_assert (mp_mw == 0); tl_assert (mp_mw == 0 && mp_plugin_root == 0);
mp_plugin_root = new lay::PluginRootToMainWindow ();
mp_mw = new lay::MainWindow (this, mp_plugin_root, "main_window");
mp_plugin_root->attach_to (mp_mw);
mp_mw = new lay::MainWindow (this, "main_window");
QObject::connect (mp_mw, SIGNAL (closed ()), this, SLOT (quit ())); QObject::connect (mp_mw, SIGNAL (closed ()), this, SLOT (quit ()));
// create a password dialog for use with the HTTP streams // create a password dialog for use with the HTTP streams

View File

@ -57,6 +57,7 @@ namespace lay
{ {
class MainWindow; class MainWindow;
class PluginRootToMainWindow;
class PluginRoot; class PluginRoot;
class ProgressReporter; class ProgressReporter;
class ProgressBar; class ProgressBar;
@ -443,6 +444,7 @@ protected:
private: private:
MainWindow *mp_mw; MainWindow *mp_mw;
PluginRootToMainWindow *mp_plugin_root;
gtf::Recorder *mp_recorder; gtf::Recorder *mp_recorder;
}; };

View File

@ -32,7 +32,7 @@
#include <QDomDocument> #include <QDomDocument>
// #define DEBUG_HIGHLIGHTER // #define DEBUG_HIGHLIGHTER
/** /**
* @brief Provide a compare operator for QList<QString> because Qt doesn't * @brief Provide a compare operator for QList<QString> because Qt doesn't
@ -907,20 +907,31 @@ GenericSyntaxHighlighterAttributes::GenericSyntaxHighlighterAttributes (const Ge
: mp_basic_attributes (basic_attributes) : mp_basic_attributes (basic_attributes)
{ {
if (! basic_attributes) { if (! basic_attributes) {
add (QString::fromUtf8 ("Normal"), dsNormal, false, false, false, false, 0, 0, 0, 0); add (QString::fromUtf8 ("Normal"), dsNormal, false, false, false, false, 0, 0, 0, 0);
add (QString::fromUtf8 ("Alert"), dsAlert, true, false, false, false, "#BF0303", "#9C0D0D", "#F7E7E7", 0); add (QString::fromUtf8 ("Alert"), dsAlert, true, false, false, false, "#BF0303", "#9C0D0D", "#F7E7E7", 0);
add (QString::fromUtf8 ("Base-N Integer"), dsBaseN, false, false, false, false, "#B07E00", "#FFDD00", 0, 0); add (QString::fromUtf8 ("Base-N Integer"), dsBaseN, false, false, false, false, "#B07E00", "#FFDD00", 0, 0);
add (QString::fromUtf8 ("Character"), dsChar, false, false, false, false, "#FF80E0", "#FF80E0", 0, 0); add (QString::fromUtf8 ("Character"), dsChar, false, false, false, false, "#FF80E0", "#FF80E0", 0, 0);
add (QString::fromUtf8 ("Comment"), dsComment, false, true, false, false, "#888786", "#A6C2E4", 0, 0); add (QString::fromUtf8 ("Comment"), dsComment, false, true, false, false, "#888786", "#A6C2E4", 0, 0);
add (QString::fromUtf8 ("Data Type"), dsDataType, false, false, false, false, "#0057AE", "#00316E", 0, 0); add (QString::fromUtf8 ("Data Type"), dsDataType, false, false, false, false, "#0057AE", "#00316E", 0, 0);
add (QString::fromUtf8 ("Decimal/Value"), dsDecVal, false, false, false, false, "#B07E00", "#FFDD00", 0, 0); add (QString::fromUtf8 ("Decimal/Value"), dsDecVal, false, false, false, false, "#B07E00", "#FFDD00", 0, 0);
add (QString::fromUtf8 ("Error"), dsError, false, false, true, false, "#BF0303", "#9C0D0D", 0, 0); add (QString::fromUtf8 ("Error"), dsError, false, false, true, false, "#BF0303", "#9C0D0D", 0, 0);
add (QString::fromUtf8 ("Floating Point"), dsFloat, false, false, false, false, "#B07E00", "#FFDD00", 0, 0); add (QString::fromUtf8 ("Floating Point"), dsFloat, false, false, false, false, "#B07E00", "#FFDD00", 0, 0);
add (QString::fromUtf8 ("Function"), dsFunction, false, false, false, false, "#442886", "#442886", 0, 0); add (QString::fromUtf8 ("Function"), dsFunction, false, false, false, false, "#442886", "#442886", 0, 0);
add (QString::fromUtf8 ("Keyword"), dsKeyword, true, false, false, false, 0, 0, 0, 0); add (QString::fromUtf8 ("Keyword"), dsKeyword, true, false, false, false, 0, 0, 0, 0);
add (QString::fromUtf8 ("Others"), dsOthers, false, false, false, false, "#006E26", "#80FF80", 0, 0); add (QString::fromUtf8 ("Others"), dsOthers, false, false, false, false, "#006E26", "#80FF80", 0, 0);
add (QString::fromUtf8 ("Region Marker"), dsRegionMarker, false, false, false, false, "#0057AE", "#00316E", "#E1EAF8", 0); add (QString::fromUtf8 ("Region Marker"), dsRegionMarker, false, false, false, false, "#0057AE", "#00316E", "#E1EAF8", 0);
add (QString::fromUtf8 ("String"), dsString, false, false, false, false, "#BF0303", "#9C0D0D", 0, 0); add (QString::fromUtf8 ("String"), dsString, false, false, false, false, "#BF0303", "#9C0D0D", 0, 0);
add (QString::fromUtf8 ("Operator"), dsOperator, false, false, false, false, "#1F1C1B", 0, 0, 0);
add (QString::fromUtf8 ("Control Flow"), dsControlFlow, true, false, false, false, "#1F1C1B", 0, 0, 0);
add (QString::fromUtf8 ("Built-in"), dsBuiltIn, true, false, false, false, "#644A9B", "#452886", 0, 0);
add (QString::fromUtf8 ("Variable"), dsVariable, false, false, false, false, "#0057AE", "#00316e", 0, 0);
add (QString::fromUtf8 ("Extension"), dsExtension, false, false, false, false, "#0095FF", 0, 0, 0);
add (QString::fromUtf8 ("Preprocessor"), dsPreprocessor, false, false, false, false, "#006E28", "#006e28", 0, 0);
add (QString::fromUtf8 ("Import"), dsImport, false, false, false, false, "#FF5500", "#FF5500", 0, 0);
add (QString::fromUtf8 ("Verbatim String"), dsVerbatimString, false, false, false, false, "#BF0303", "#9C0E0E", 0, 0);
add (QString::fromUtf8 ("Special String"), dsSpecialString, false, false, false, false, "#FF5500", "#FF5500", 0, 0);
add (QString::fromUtf8 ("Special Character"), dsSpecialChar, false, false, false, false, "#3DAEE9", "#FCFCFC", 0, 0);
add (QString::fromUtf8 ("Attribute"), dsAttribute, false, false, false, false, "#0057AE", "#00316E", 0, 0);
} }
} }
@ -1416,7 +1427,7 @@ parse_rule (QDomElement e, GenericSyntaxHighlighterContexts &contexts, std::map<
} }
static GenericSyntaxHighlighterContext static GenericSyntaxHighlighterContext
parse_context (QDomElement e, GenericSyntaxHighlighterContexts &contexts, std::map<QString, GenericSyntaxHighlighterRuleStringList> &lists, GenericSyntaxHighlighterAttributes &attributes) parse_context (QDomElement e, const std::map<QString, QDomElement> &contexts_by_name, GenericSyntaxHighlighterContexts &contexts, std::map<QString, GenericSyntaxHighlighterRuleStringList> &lists, GenericSyntaxHighlighterAttributes &attributes)
{ {
GenericSyntaxHighlighterContext context; GenericSyntaxHighlighterContext context;
@ -1424,7 +1435,11 @@ parse_context (QDomElement e, GenericSyntaxHighlighterContexts &contexts, std::m
if (n.isElement()) { if (n.isElement()) {
QDomElement ee = n.toElement(); QDomElement ee = n.toElement();
if (ee.tagName () == QString::fromUtf8 ("IncludeRules")) { if (ee.tagName () == QString::fromUtf8 ("IncludeRules")) {
context.include (contexts.context (ee.attributeNode (QString::fromUtf8 ("context")).value ())); QString included_name = ee.attributeNode (QString::fromUtf8 ("context")).value ();
std::map<QString, QDomElement>::const_iterator c2n = contexts_by_name.find (included_name);
if (c2n != contexts_by_name.end ()) {
context.include (parse_context (c2n->second, contexts_by_name, contexts, lists, attributes));
}
} else { } else {
context.add_rule (parse_rule (ee, contexts, lists, attributes)); context.add_rule (parse_rule (ee, contexts, lists, attributes));
} }
@ -1498,6 +1513,18 @@ parse_item_data (QDomElement e, GenericSyntaxHighlighterAttributes &attributes)
else if (s == QString::fromUtf8 ("dsOthers")) { ds = dsOthers; } else if (s == QString::fromUtf8 ("dsOthers")) { ds = dsOthers; }
else if (s == QString::fromUtf8 ("dsRegionMarker")) { ds = dsRegionMarker; } else if (s == QString::fromUtf8 ("dsRegionMarker")) { ds = dsRegionMarker; }
else if (s == QString::fromUtf8 ("dsString")) { ds = dsString; } else if (s == QString::fromUtf8 ("dsString")) { ds = dsString; }
else if (s == QString::fromUtf8 ("dsOperator")) { ds = dsOperator; }
else if (s == QString::fromUtf8 ("dsControlFlow")) { ds = dsControlFlow; }
else if (s == QString::fromUtf8 ("dsBuiltIn")) { ds = dsBuiltIn; }
else if (s == QString::fromUtf8 ("dsVariable")) { ds = dsVariable; }
else if (s == QString::fromUtf8 ("dsExtension")) { ds = dsExtension; }
else if (s == QString::fromUtf8 ("dsPreprocessor")) { ds = dsPreprocessor; }
else if (s == QString::fromUtf8 ("dsImport")) { ds = dsImport; }
else if (s == QString::fromUtf8 ("dsVerbatimString")) { ds = dsVerbatimString; }
else if (s == QString::fromUtf8 ("dsSpecialString")) { ds = dsSpecialString; }
else if (s == QString::fromUtf8 ("dsSpecialString")) { ds = dsSpecialString; }
else if (s == QString::fromUtf8 ("dsSpecialChar")) { ds = dsSpecialChar; }
else if (s == QString::fromUtf8 ("dsAttribute")) { ds = dsAttribute; }
} }
attributes.set_styles (attribute_id, ds, format); attributes.set_styles (attribute_id, ds, format);
@ -1534,12 +1561,26 @@ GenericSyntaxHighlighter::GenericSyntaxHighlighter (QObject *parent, QIODevice &
} else if (e.tagName () == QString::fromUtf8 ("contexts")) { } else if (e.tagName () == QString::fromUtf8 ("contexts")) {
// first analyze the list of contexts and their dependencies
std::map<QString, QDomElement> contexts_by_name;
for (QDomNode nn = e.firstChild(); !nn.isNull(); nn = nn.nextSibling()) { for (QDomNode nn = e.firstChild(); !nn.isNull(); nn = nn.nextSibling()) {
if (nn.isElement()) { if (nn.isElement()) {
QDomElement ee = nn.toElement (); QDomElement ee = nn.toElement ();
if (ee.tagName () == QString::fromUtf8 ("context")) { if (ee.tagName () == QString::fromUtf8 ("context")) {
QString context_name = ee.attributeNode (QString::fromUtf8 ("name")).value (); QString context_name = ee.attributeNode (QString::fromUtf8 ("name")).value ();
m_contexts.insert (context_name, parse_context (ee, m_contexts, m_lists, *mp_attributes)); contexts_by_name[context_name] = ee;
}
}
}
for (QDomNode nn = e.firstChild(); !nn.isNull(); nn = nn.nextSibling()) {
if (nn.isElement()) {
QDomElement ee = nn.toElement ();
if (ee.tagName () == QString::fromUtf8 ("context")) {
QString context_name = ee.attributeNode (QString::fromUtf8 ("name")).value ();
m_contexts.insert (context_name, parse_context (ee, contexts_by_name, m_contexts, m_lists, *mp_attributes));
} }
} }
} }

View File

@ -562,6 +562,17 @@ enum def_style {
dsOthers, dsOthers,
dsRegionMarker, dsRegionMarker,
dsString, dsString,
dsOperator,
dsControlFlow,
dsBuiltIn,
dsVariable,
dsExtension,
dsPreprocessor,
dsImport,
dsVerbatimString,
dsSpecialString,
dsSpecialChar,
dsAttribute,
dsLast dsLast
}; };

View File

@ -164,9 +164,9 @@ MacroController::initialized (lay::PluginRoot *root)
connect (&m_temp_macros, SIGNAL (menu_needs_update ()), this, SLOT (macro_collection_changed ())); connect (&m_temp_macros, SIGNAL (menu_needs_update ()), this, SLOT (macro_collection_changed ()));
connect (&m_temp_macros, SIGNAL (macro_collection_changed (lym::MacroCollection *)), this, SLOT (macro_collection_changed ())); connect (&m_temp_macros, SIGNAL (macro_collection_changed (lym::MacroCollection *)), this, SLOT (macro_collection_changed ()));
mp_mw = dynamic_cast <lay::MainWindow *> (root); mp_mw = lay::MainWindow::instance ();
if (mp_mw) { if (mp_mw) {
mp_macro_editor = new lay::MacroEditorDialog (mp_mw, &lym::MacroCollection::root ()); mp_macro_editor = new lay::MacroEditorDialog (root, &lym::MacroCollection::root ());
mp_macro_editor->setModal (false); mp_macro_editor->setModal (false);
} }

View File

@ -227,10 +227,10 @@ public:
static lay::MacroEditorDialog *s_macro_editor_instance = 0; static lay::MacroEditorDialog *s_macro_editor_instance = 0;
MacroEditorDialog::MacroEditorDialog (lay::MainWindow *mw, lym::MacroCollection *root) MacroEditorDialog::MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection *root)
: QDialog (0 /*show as individual top widget*/, Qt::Window), : QDialog (0 /*show as individual top widget*/, Qt::Window),
lay::Plugin (mw, true), lay::Plugin (pr, true),
mp_plugin_root (mw), mp_plugin_root (pr),
mp_root (root), mp_root (root),
m_first_show (true), m_in_processing (false), m_debugging_on (true), m_first_show (true), m_in_processing (false), m_debugging_on (true),
mp_run_macro (0), mp_run_macro (0),

View File

@ -98,7 +98,7 @@ public:
/** /**
* @brief Constructor * @brief Constructor
*/ */
MacroEditorDialog (lay::MainWindow *parent, lym::MacroCollection *root); MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection *root);
/** /**
* @brief Destructor * @brief Destructor

View File

@ -443,8 +443,9 @@ MainWindow::instance ()
// ----------------------------------- // -----------------------------------
MainWindow::MainWindow (QApplication *app, const char *name) MainWindow::MainWindow (QApplication *app, lay::Plugin *plugin_parent, const char *name)
: QMainWindow (0), : QMainWindow (0),
lay::Plugin (plugin_parent),
m_text_progress (this, 10 /*verbosity threshold*/), m_text_progress (this, 10 /*verbosity threshold*/),
m_mode (std::numeric_limits<unsigned int>::max ()), m_mode (std::numeric_limits<unsigned int>::max ()),
mp_setup_form (0), mp_setup_form (0),
@ -473,7 +474,7 @@ MainWindow::MainWindow (QApplication *app, const char *name)
} }
mw_instance = this; mw_instance = this;
mp_setup_form = new SettingsForm (0, this, "setup_form"), mp_setup_form = new SettingsForm (0, plugin_root (), "setup_form"),
db::LibraryManager::instance ().changed_event.add (this, &MainWindow::libraries_changed); db::LibraryManager::instance ().changed_event.add (this, &MainWindow::libraries_changed);
@ -1082,13 +1083,13 @@ void
MainWindow::dock_widget_visibility_changed (bool /*visible*/) MainWindow::dock_widget_visibility_changed (bool /*visible*/)
{ {
if (sender () == mp_lp_dock_widget) { if (sender () == mp_lp_dock_widget) {
config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ()));
} else if (sender () == mp_hp_dock_widget) { } else if (sender () == mp_hp_dock_widget) {
config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ()));
} else if (sender () == mp_navigator_dock_widget) { } else if (sender () == mp_navigator_dock_widget) {
config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ()));
} else if (sender () == mp_layer_toolbox_dock_widget) { } else if (sender () == mp_layer_toolbox_dock_widget) {
config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ()));
} }
} }
@ -1283,7 +1284,7 @@ MainWindow::about_to_exec ()
lay::TipDialog::button_type button = lay::TipDialog::null_button; lay::TipDialog::button_type button = lay::TipDialog::null_button;
if (td.exec_dialog (button)) { if (td.exec_dialog (button)) {
if (button == lay::TipDialog::yes_button) { if (button == lay::TipDialog::yes_button) {
config_set (cfg_full_hier_new_cell, true); plugin_root ()->config_set (cfg_full_hier_new_cell, true);
} }
// Don't bother the user with more dialogs. // Don't bother the user with more dialogs.
return; return;
@ -1734,17 +1735,6 @@ MainWindow::configure (const std::string &name, const std::string &value)
apply_hidden (hidden); apply_hidden (hidden);
return true; return true;
} else if (name == cfg_background_color) {
if (mp_navigator) {
QColor color;
ColorConverter ().from_string (value, color);
mp_navigator->background_color (color);
}
// do not take - let others receive the background color events as well
return false;
} else if (name == cfg_initial_technology) { } else if (name == cfg_initial_technology) {
m_initial_technology = value; m_initial_technology = value;
@ -1818,10 +1808,10 @@ MainWindow::libraries_changed ()
void void
MainWindow::read_dock_widget_state () MainWindow::read_dock_widget_state ()
{ {
config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ()));
config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ()));
config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ()));
config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); plugin_root ()->config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ()));
} }
void void
@ -1934,7 +1924,7 @@ MainWindow::can_close ()
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) { for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls); lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
if (! pd->can_exit (this)) { if (! pd->can_exit (plugin_root ())) {
return false; return false;
} }
} }
@ -1979,8 +1969,8 @@ MainWindow::save_state_to_config ()
{ {
// save the dock widget state with all views closed (that state can be // save the dock widget state with all views closed (that state can be
// used for staring klayout without any layout) // used for staring klayout without any layout)
config_set (cfg_window_geometry, (const char *) saveGeometry ().toBase64 ().data ()); plugin_root ()->config_set (cfg_window_geometry, (const char *) saveGeometry ().toBase64 ().data ());
config_set (cfg_window_state, (const char *) saveState ().toBase64 ().data ()); plugin_root ()->config_set (cfg_window_state, (const char *) saveState ().toBase64 ().data ());
} }
void void
@ -2304,9 +2294,7 @@ MainWindow::intrinsic_mode_triggered ()
int mode = action->data ().toInt (); int mode = action->data ().toInt ();
if (lay::PluginRoot::instance ()) { plugin_root ()->select_mode (mode);
lay::PluginRoot::instance ()->select_mode (mode);
}
action->setChecked (true); action->setChecked (true);
@ -3405,13 +3393,13 @@ MainWindow::cm_pull_in ()
void void
MainWindow::cm_reader_options () MainWindow::cm_reader_options ()
{ {
mp_layout_load_options->edit_global_options (this, db::Technologies::instance ()); mp_layout_load_options->edit_global_options (plugin_root (), db::Technologies::instance ());
} }
void void
MainWindow::cm_writer_options () MainWindow::cm_writer_options ()
{ {
mp_layout_save_options->edit_global_options (this, db::Technologies::instance ()); mp_layout_save_options->edit_global_options (plugin_root (), db::Technologies::instance ());
} }
void void
@ -3680,7 +3668,7 @@ MainWindow::clone_current_view ()
} }
// create a new view // create a new view
view = new lay::LayoutView (current_view (), &m_manager, lay::ApplicationBase::instance ()->is_editable (), this, mp_view_stack); view = new lay::LayoutView (current_view (), &m_manager, lay::ApplicationBase::instance ()->is_editable (), plugin_root (), mp_view_stack);
connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ())); connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ()));
connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ())); connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ()));
connect (view, SIGNAL (edits_enabled_changed ()), this, SLOT (edits_enabled_changed ())); connect (view, SIGNAL (edits_enabled_changed ()), this, SLOT (edits_enabled_changed ()));
@ -4116,7 +4104,7 @@ MainWindow::add_mru (const std::string &fn_rel, const std::string &tech)
} }
} }
config_set (cfg_mru, config_str); plugin_root ()->config_set (cfg_mru, config_str);
} }
void void
@ -4169,7 +4157,7 @@ MainWindow::open_recent ()
return; return;
} }
if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, db::Technologies::instance ())) { if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (plugin_root (), db::Technologies::instance ())) {
return; return;
} }
@ -4218,7 +4206,7 @@ MainWindow::open (int mode)
return; return;
} }
if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, db::Technologies::instance ())) { if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (plugin_root (), db::Technologies::instance ())) {
return; return;
} }
@ -4289,7 +4277,7 @@ int
MainWindow::do_create_view () MainWindow::do_create_view ()
{ {
// create a new view // create a new view
lay::LayoutView *view = new lay::LayoutView (&m_manager, lay::ApplicationBase::instance ()->is_editable (), this, mp_view_stack); lay::LayoutView *view = new lay::LayoutView (&m_manager, lay::ApplicationBase::instance ()->is_editable (), plugin_root (), mp_view_stack);
connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ())); connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ()));
connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ())); connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ()));
@ -4866,8 +4854,7 @@ MainWindow::show_assistant_topic (const std::string &s, bool modal)
void void
MainWindow::cm_show_all_tips () MainWindow::cm_show_all_tips ()
{ {
config_set (cfg_tip_window_hidden, ""); plugin_root ()->config_set (cfg_tip_window_hidden, "");
config_finalize ();
} }
void void
@ -4899,7 +4886,7 @@ MainWindow::action_for_slot (const char *slot)
lay::Action * lay::Action *
MainWindow::create_config_action (const std::string &title, const std::string &cname, const std::string &cvalue) MainWindow::create_config_action (const std::string &title, const std::string &cname, const std::string &cvalue)
{ {
lay::ConfigureAction *ca = new lay::ConfigureAction(this, title, cname, cvalue); lay::ConfigureAction *ca = new lay::ConfigureAction(plugin_root (), title, cname, cvalue);
m_ca_collection.push_back (ca); m_ca_collection.push_back (ca);
return ca; return ca;
} }
@ -4907,7 +4894,7 @@ MainWindow::create_config_action (const std::string &title, const std::string &c
lay::Action * lay::Action *
MainWindow::create_config_action (const std::string &cname, const std::string &cvalue) MainWindow::create_config_action (const std::string &cname, const std::string &cvalue)
{ {
lay::ConfigureAction *ca = new lay::ConfigureAction(this, std::string (), cname, cvalue); lay::ConfigureAction *ca = new lay::ConfigureAction(plugin_root (), std::string (), cname, cvalue);
m_ca_collection.push_back (ca); m_ca_collection.push_back (ca);
return ca; return ca;
} }
@ -5605,11 +5592,8 @@ MainWindow::plugin_registered (lay::PluginDeclaration *cls)
// recreate all plugins // recreate all plugins
for (std::vector <lay::LayoutView *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) { for (std::vector <lay::LayoutView *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) {
(*vp)->create_plugins (this); (*vp)->create_plugins (plugin_root ());
} }
// re-establish the configuration
config_setup ();
} }
void void
@ -5619,13 +5603,55 @@ MainWindow::plugin_removed (lay::PluginDeclaration *cls)
// recreate all plugins except the one that got removed // recreate all plugins except the one that got removed
for (std::vector <lay::LayoutView *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) { for (std::vector <lay::LayoutView *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) {
(*vp)->create_plugins (this, cls); (*vp)->create_plugins (plugin_root (), cls);
}
}
// ------------------------------------------------------------
// Implementation of the PluginRootToMainWindow bride
PluginRootToMainWindow::PluginRootToMainWindow ()
: mp_main_window (0)
{
// .. nothing yet ..
}
void
PluginRootToMainWindow::attach_to (lay::MainWindow *main_window)
{
mp_main_window = main_window;
}
void
PluginRootToMainWindow::plugin_registered (lay::PluginDeclaration *cls)
{
if (mp_main_window.get ()) {
mp_main_window->plugin_registered (cls);
} }
// re-establish the configuration // re-establish the configuration
config_setup (); config_setup ();
} }
void
PluginRootToMainWindow::plugin_removed (lay::PluginDeclaration *cls)
{
if (mp_main_window.get ()) {
mp_main_window->plugin_removed (cls);
}
// re-establish the configuration
config_setup ();
}
void
PluginRootToMainWindow::select_mode (int mode)
{
if (mp_main_window.get ()) {
mp_main_window->select_mode (mode);
}
}
// ------------------------------------------------------------ // ------------------------------------------------------------
// Implementation of the "help about" dialog // Implementation of the "help about" dialog

View File

@ -120,8 +120,8 @@ private:
class LAY_PUBLIC MainWindow class LAY_PUBLIC MainWindow
: public QMainWindow, : public QMainWindow,
public lay::AbstractMenuProvider, public lay::Plugin,
public lay::PluginRoot public lay::AbstractMenuProvider
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -134,7 +134,7 @@ public:
/** /**
* @brief Constructor * @brief Constructor
*/ */
MainWindow (QApplication *app = 0, const char *name = "main_window"); MainWindow (QApplication *app = 0, lay::Plugin *parent_plugin = 0, const char *name = "main_window");
/** /**
* @brief Destructor * @brief Destructor
@ -551,7 +551,7 @@ public:
void show_macro_editor (const std::string &cat = std::string (), bool add = false); void show_macro_editor (const std::string &cat = std::string (), bool add = false);
/** /**
* @brief Reimplementation of the plugin interface: handle a generic menu request * @brief Handles a generic menu request
*/ */
void menu_activated (const std::string &symbol); void menu_activated (const std::string &symbol);
@ -870,6 +870,8 @@ protected:
void do_update_file_menu (); void do_update_file_menu ();
private: private:
friend class PluginRootToMainWindow;
TextProgressDelegate m_text_progress; TextProgressDelegate m_text_progress;
// Main menu // Main menu
@ -973,14 +975,33 @@ private:
void update_dock_widget_state (); void update_dock_widget_state ();
void read_dock_widget_state (); void read_dock_widget_state ();
virtual void plugin_registered (lay::PluginDeclaration *cls); void plugin_registered (lay::PluginDeclaration *cls);
virtual void plugin_removed (lay::PluginDeclaration *cls); void plugin_removed (lay::PluginDeclaration *cls);
void libraries_changed (); void libraries_changed ();
void apply_key_bindings (); void apply_key_bindings ();
void apply_hidden (const std::vector<std::pair <std::string, bool> > &hidden); void apply_hidden (const std::vector<std::pair <std::string, bool> > &hidden);
}; };
class LAY_PUBLIC PluginRootToMainWindow
: public lay::PluginRoot
{
public:
PluginRootToMainWindow ();
void attach_to (lay::MainWindow *main_window);
virtual void plugin_registered (lay::PluginDeclaration *cls);
virtual void plugin_removed (lay::PluginDeclaration *cls);
virtual void select_mode (int mode);
private:
PluginRootToMainWindow (const PluginRootToMainWindow &);
PluginRootToMainWindow &operator= (const PluginRootToMainWindow &);
tl::weak_ptr<MainWindow> mp_main_window;
};
} }
namespace tl { namespace tl {

View File

@ -58,7 +58,7 @@ public:
mp_box (0), mp_box (0),
m_color (0) m_color (0)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
~NavigatorService () ~NavigatorService ()
@ -70,6 +70,25 @@ public:
drag_cancel (); drag_cancel ();
} }
void background_color_changed ()
{
QColor c = mp_view->background_color ();
// replace by "real" background color if required
if (! c.isValid ()) {
c = mp_view->palette ().color (QPalette::Normal, QPalette::Base);
}
QColor contrast;
if (c.green () > 128) {
contrast = QColor (0, 0, 0);
} else {
contrast = QColor (255, 255, 255);
}
set_colors (c, contrast);
}
bool mouse_release_event (const db::DPoint & /*p*/, unsigned int /*buttons*/, bool /*prio*/) bool mouse_release_event (const db::DPoint & /*p*/, unsigned int /*buttons*/, bool /*prio*/)
{ {
if (mp_box) { if (mp_box) {
@ -349,10 +368,10 @@ public:
tl::Object::detach_from_all_events (); tl::Object::detach_from_all_events ();
mp_source_view = source_view; mp_source_view = source_view;
mp_source_view->viewport_changed_event.add (this, &NavigatorService::update_marker);
if (mp_source_view) { mp_view->background_color_changed_event.add (this, &NavigatorService::background_color_changed);
mp_source_view->viewport_changed_event.add (this, &NavigatorService::update_marker); background_color_changed ();
}
update_marker (); update_marker ();
@ -447,11 +466,8 @@ Navigator::Navigator (MainWindow *main_window)
mp_menu_bar->setFrameShape (QFrame::NoFrame); mp_menu_bar->setFrameShape (QFrame::NoFrame);
mp_menu_bar->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred); mp_menu_bar->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
mp_view = new LayoutView (0, false, mp_main_window, this, "navigator", LayoutView::LV_Naked + LayoutView::LV_NoZoom + LayoutView::LV_NoServices + LayoutView::LV_NoGrid); mp_view = 0;
mp_view->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); mp_service = 0;
mp_view->setMinimumWidth (100);
mp_view->setMinimumHeight (100);
mp_view->hide ();
mp_placeholder_label = new QLabel (this); mp_placeholder_label = new QLabel (this);
mp_placeholder_label->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); mp_placeholder_label->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
@ -461,9 +477,8 @@ Navigator::Navigator (MainWindow *main_window)
QVBoxLayout *layout = new QVBoxLayout (this); QVBoxLayout *layout = new QVBoxLayout (this);
layout->addWidget (mp_menu_bar); layout->addWidget (mp_menu_bar);
layout->addWidget (mp_view);
layout->addWidget (mp_placeholder_label); layout->addWidget (mp_placeholder_label);
layout->setStretchFactor (mp_view, 1); layout->setStretchFactor (mp_placeholder_label, 1);
layout->setMargin (0); layout->setMargin (0);
layout->setSpacing (0); layout->setSpacing (0);
setLayout (layout); setLayout (layout);
@ -473,9 +488,6 @@ Navigator::Navigator (MainWindow *main_window)
do_update_menu (); do_update_menu ();
connect (mp_main_window->menu (), SIGNAL (changed ()), this, SLOT (menu_changed ())); connect (mp_main_window->menu (), SIGNAL (changed ()), this, SLOT (menu_changed ()));
mp_service = new NavigatorService (mp_view);
mp_view->view_object_widget ()->activate (mp_service);
} }
Navigator::~Navigator () Navigator::~Navigator ()
@ -586,8 +598,8 @@ Navigator::showEvent (QShowEvent *)
void void
Navigator::closeEvent (QCloseEvent *) Navigator::closeEvent (QCloseEvent *)
{ {
mp_main_window->config_set (cfg_show_navigator, "false"); lay::PluginRoot::instance ()->config_set (cfg_show_navigator, "false");
mp_main_window->config_finalize (); lay::PluginRoot::instance ()->config_end ();
} }
void void
@ -637,6 +649,14 @@ Navigator::view_closed (int index)
} }
} }
void
Navigator::resizeEvent (QResizeEvent *)
{
if (mp_view) {
mp_view->setGeometry (mp_placeholder_label->geometry ());
}
}
void void
Navigator::attach_view (LayoutView *view) Navigator::attach_view (LayoutView *view)
{ {
@ -649,8 +669,24 @@ Navigator::attach_view (LayoutView *view)
mp_source_view = view; mp_source_view = view;
delete mp_service;
mp_service = 0;
LayoutView *old_view = mp_view;
mp_view = 0;
if (mp_source_view) { if (mp_source_view) {
mp_view = new LayoutView (0, false, mp_source_view, this, "navigator", LayoutView::LV_Naked + LayoutView::LV_NoZoom + LayoutView::LV_NoServices + LayoutView::LV_NoGrid);
mp_view->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
mp_view->setMinimumWidth (100);
mp_view->setMinimumHeight (100);
mp_view->setGeometry (mp_placeholder_label->geometry ());
mp_view->show ();
mp_service = new NavigatorService (mp_view);
mp_view->view_object_widget ()->activate (mp_service);
mp_source_view->cellviews_changed_event.add (this, &Navigator::content_changed); mp_source_view->cellviews_changed_event.add (this, &Navigator::content_changed);
mp_source_view->cellview_changed_event.add (this, &Navigator::content_changed_with_int); mp_source_view->cellview_changed_event.add (this, &Navigator::content_changed_with_int);
mp_source_view->geom_changed_event.add (this, &Navigator::content_changed); mp_source_view->geom_changed_event.add (this, &Navigator::content_changed);
@ -662,60 +698,36 @@ Navigator::attach_view (LayoutView *view)
image_plugin->images_changed_event.add (this, &Navigator::content_changed); image_plugin->images_changed_event.add (this, &Navigator::content_changed);
} }
mp_view->show (); // update the list of frozen flags per view
mp_placeholder_label->hide (); std::set <lay::LayoutView *> all_views;
} else { for (std::map <lay::LayoutView *, NavigatorFrozenViewInfo>::const_iterator f = m_frozen_list.begin (); f != m_frozen_list.end (); ++f) {
mp_view->hide (); all_views.insert (f->first);
mp_placeholder_label->show ();
}
// update the list of frozen flags per view
std::set <lay::LayoutView *> all_views;
for (std::map <lay::LayoutView *, NavigatorFrozenViewInfo>::const_iterator f = m_frozen_list.begin (); f != m_frozen_list.end (); ++f) {
all_views.insert (f->first);
}
for (unsigned int i = 0; i < mp_main_window->views (); ++i) {
lay::LayoutView *view = mp_main_window->view (i);
if (m_frozen_list.find (view) != m_frozen_list.end ()) {
all_views.erase (view);
} }
for (unsigned int i = 0; i < mp_main_window->views (); ++i) {
lay::LayoutView *view = mp_main_window->view (i);
if (m_frozen_list.find (view) != m_frozen_list.end ()) {
all_views.erase (view);
}
}
for (std::set <lay::LayoutView *>::const_iterator v = all_views.begin (); v != all_views.end (); ++v) {
all_views.erase (*v);
}
Action freeze_action = mp_main_window->menu ()->action (freeze_action_path);
freeze_action.set_checked (m_frozen_list.find (mp_source_view) != m_frozen_list.end ());
// Hint: this must happen before update ()
mp_service->attach_view (mp_source_view);
update ();
} }
for (std::set <lay::LayoutView *>::const_iterator v = all_views.begin (); v != all_views.end (); ++v) { delete old_view;
all_views.erase (*v);
}
Action freeze_action = mp_main_window->menu ()->action (freeze_action_path);
freeze_action.set_checked (m_frozen_list.find (mp_source_view) != m_frozen_list.end ());
// Hint: this must happen before update ()
mp_service->attach_view (mp_source_view);
update ();
}
}
void
Navigator::background_color (QColor c)
{
// replace by "real" background color if required
if (! c.isValid ()) {
c = palette ().color (QPalette::Normal, QPalette::Base);
}
QColor contrast;
if (c.green () > 128) {
contrast = QColor (0, 0, 0);
} else {
contrast = QColor (255, 255, 255);
}
if (mp_service) {
mp_service->set_colors (c, contrast);
} }
} }
@ -738,16 +750,13 @@ Navigator::update_layers ()
void void
Navigator::update () Navigator::update ()
{ {
if (! mp_source_view || m_frozen_list.find (mp_source_view) == m_frozen_list.end ()) { if (! mp_view || ! mp_source_view) {
return;
if (! mp_source_view) { }
mp_view->clear_cellviews ();
mp_view->clear_layers ();
} else {
mp_view->select_cellviews (mp_source_view->cellview_list ());
mp_view->set_properties (mp_source_view->get_properties ());
}
if (m_frozen_list.find (mp_source_view) == m_frozen_list.end ()) {
mp_view->select_cellviews (mp_source_view->cellview_list ());
mp_view->set_properties (mp_source_view->get_properties ());
} else { } else {
mp_view->select_cellviews (mp_source_view->cellview_list ()); mp_view->select_cellviews (mp_source_view->cellview_list ());
mp_view->set_properties (m_frozen_list [mp_source_view].layer_properties); mp_view->set_properties (m_frozen_list [mp_source_view].layer_properties);
@ -759,7 +768,7 @@ Navigator::update ()
img_target->clear_images (); img_target->clear_images ();
if (m_show_images) { if (m_show_images) {
img::Service *img_source = (mp_source_view ? mp_source_view->get_plugin<img::Service> () : 0); img::Service *img_source = (mp_source_view->get_plugin<img::Service> ());
if (img_source) { if (img_source) {
for (img::ImageIterator i = img_source->begin_images (); ! i.at_end (); ++i) { for (img::ImageIterator i = img_source->begin_images (); ! i.at_end (); ++i) {
img_target->insert_image (*i); img_target->insert_image (*i);

View File

@ -83,13 +83,13 @@ public:
void freeze_clicked (); void freeze_clicked ();
void all_hier_levels (bool f); void all_hier_levels (bool f);
void show_images (bool f); void show_images (bool f);
void background_color (QColor c);
static void init_menu (AbstractMenu &menu); static void init_menu (AbstractMenu &menu);
protected: protected:
virtual void closeEvent (QCloseEvent *event); virtual void closeEvent (QCloseEvent *event);
virtual void showEvent (QShowEvent *event); virtual void showEvent (QShowEvent *event);
virtual void resizeEvent (QResizeEvent *event);
private slots: private slots:
void menu_changed (); void menu_changed ();
@ -121,6 +121,7 @@ private:
void layers_changed (int); void layers_changed (int);
void viewport_changed (); void viewport_changed ();
void hier_levels_changed (); void hier_levels_changed ();
void update_background_color ();
void content_changed_with_int (int) void content_changed_with_int (int)
{ {

View File

@ -36,14 +36,21 @@ namespace lay
static const std::string cfg_salt_manager_window_state ("salt-manager-window-state"); static const std::string cfg_salt_manager_window_state ("salt-manager-window-state");
SaltController::SaltController () SaltController::SaltController ()
: mp_salt_dialog (0), mp_mw (0), m_file_watcher (0), : mp_salt_dialog (0), mp_mw (0), mp_plugin_root (0), m_file_watcher (0),
dm_sync_file_watcher (this, &SaltController::sync_file_watcher), dm_sync_file_watcher (this, &SaltController::sync_file_watcher),
dm_sync_files (this, &SaltController::sync_files) dm_sync_files (this, &SaltController::sync_files)
{ {
} }
void void
SaltController::initialized (lay::PluginRoot *root) SaltController::initialize (lay::PluginRoot *root)
{
mp_mw = lay::MainWindow::instance ();
mp_plugin_root = root;
}
void
SaltController::initialized (lay::PluginRoot * /*root*/)
{ {
if (! m_file_watcher) { if (! m_file_watcher) {
m_file_watcher = new tl::FileSystemWatcher (this); m_file_watcher = new tl::FileSystemWatcher (this);
@ -51,8 +58,6 @@ SaltController::initialized (lay::PluginRoot *root)
connect (m_file_watcher, SIGNAL (fileRemoved (const QString &)), this, SLOT (file_watcher_triggered ())); connect (m_file_watcher, SIGNAL (fileRemoved (const QString &)), this, SLOT (file_watcher_triggered ()));
} }
mp_mw = dynamic_cast <lay::MainWindow *> (root);
connect (&m_salt, SIGNAL (collections_changed ()), this, SIGNAL (salt_changed ())); connect (&m_salt, SIGNAL (collections_changed ()), this, SIGNAL (salt_changed ()));
} }
@ -128,11 +133,9 @@ SaltController::show_editor ()
if (mp_salt_dialog) { if (mp_salt_dialog) {
if (mp_mw) { std::string s = mp_plugin_root->config_get (cfg_salt_manager_window_state);
std::string s = mp_mw->config_get (cfg_salt_manager_window_state); if (! s.empty ()) {
if (! s.empty ()) { lay::restore_dialog_state (mp_salt_dialog, s);
lay::restore_dialog_state (mp_salt_dialog, s);
}
} }
// while running the dialog, don't watch file events - that would interfere with // while running the dialog, don't watch file events - that would interfere with
@ -141,9 +144,7 @@ SaltController::show_editor ()
mp_salt_dialog->exec (); mp_salt_dialog->exec ();
m_file_watcher->enable (true); m_file_watcher->enable (true);
if (mp_mw) { mp_plugin_root->config_set (cfg_salt_manager_window_state, lay::save_dialog_state (mp_salt_dialog));
mp_mw->config_set (cfg_salt_manager_window_state, lay::save_dialog_state (mp_salt_dialog));
}
sync_file_watcher (); sync_file_watcher ();

View File

@ -66,6 +66,11 @@ public:
*/ */
SaltController (); SaltController ();
/**
* @brief Reimplementation of the PluginDeclaration interface
*/
virtual void initialize (lay::PluginRoot *root);
/** /**
* @brief Reimplementation of the PluginDeclaration interface * @brief Reimplementation of the PluginDeclaration interface
*/ */
@ -186,6 +191,7 @@ signals:
private: private:
lay::SaltManagerDialog *mp_salt_dialog; lay::SaltManagerDialog *mp_salt_dialog;
lay::MainWindow *mp_mw; lay::MainWindow *mp_mw;
lay::PluginRoot * mp_plugin_root;
std::string m_salt_mine_url; std::string m_salt_mine_url;
lay::Salt m_salt; lay::Salt m_salt;
tl::FileSystemWatcher *m_file_watcher; tl::FileSystemWatcher *m_file_watcher;

View File

@ -40,9 +40,9 @@ namespace lay
// ------------------------------------------------------------- // -------------------------------------------------------------
SettingsForm::SettingsForm (QWidget *parent, lay::MainWindow *mw, const char *name) SettingsForm::SettingsForm (QWidget *parent, lay::PluginRoot *plugin_root, const char *name)
: QDialog (parent), Ui::SettingsForm (), : QDialog (parent), Ui::SettingsForm (),
mp_main_window (mw), m_finalize_recursion (false) mp_plugin_root (plugin_root), m_finalize_recursion (false)
{ {
setObjectName (QString::fromUtf8 (name)); setObjectName (QString::fromUtf8 (name));
@ -237,7 +237,7 @@ SettingsForm::setup ()
// setup the custom config pages // setup the custom config pages
for (std::vector <lay::ConfigPage *>::iterator cp = m_config_pages.begin (); cp != m_config_pages.end (); ++cp) { for (std::vector <lay::ConfigPage *>::iterator cp = m_config_pages.begin (); cp != m_config_pages.end (); ++cp) {
(*cp)->setup (mp_main_window); (*cp)->setup (mp_plugin_root);
} }
} }
@ -246,14 +246,14 @@ SettingsForm::commit ()
{ {
// commit the custom config pages // commit the custom config pages
for (std::vector <lay::ConfigPage *>::iterator cp = m_config_pages.begin (); cp != m_config_pages.end (); ++cp) { for (std::vector <lay::ConfigPage *>::iterator cp = m_config_pages.begin (); cp != m_config_pages.end (); ++cp) {
(*cp)->commit (mp_main_window); (*cp)->commit (mp_plugin_root);
} }
m_finalize_recursion = true; m_finalize_recursion = true;
try { try {
// config_end will make the main window call setup on the settings form. // config_end will make the main window call setup on the settings form.
// the recursion sentinel takes care of that. // the recursion sentinel takes care of that.
mp_main_window->config_end (); mp_plugin_root->config_end ();
m_finalize_recursion = false; m_finalize_recursion = false;
} catch (...) { } catch (...) {
m_finalize_recursion = false; m_finalize_recursion = false;

View File

@ -37,7 +37,7 @@
namespace lay namespace lay
{ {
class MainWindow; class PluginRoot;
class ConfigPage; class ConfigPage;
class SettingsForm class SettingsForm
@ -46,7 +46,7 @@ class SettingsForm
Q_OBJECT Q_OBJECT
public: public:
SettingsForm (QWidget *parent, lay::MainWindow *lv, const char *name); SettingsForm (QWidget *parent, lay::PluginRoot *plugin_root, const char *name);
void setup (); void setup ();
void commit (); void commit ();
@ -58,7 +58,7 @@ public slots:
void item_changed (QTreeWidgetItem *, QTreeWidgetItem *); void item_changed (QTreeWidgetItem *, QTreeWidgetItem *);
private: private:
lay::MainWindow *mp_main_window; lay::PluginRoot *mp_plugin_root;
std::vector <lay::ConfigPage *> m_config_pages; std::vector <lay::ConfigPage *> m_config_pages;
bool m_finalize_recursion; bool m_finalize_recursion;
}; };

View File

@ -50,7 +50,7 @@ std::string tech_string_from_name (const std::string &tn)
} }
TechnologyController::TechnologyController () TechnologyController::TechnologyController ()
: PluginDeclaration (), mp_editor (0), mp_mw (0), mp_active_technology (0) : PluginDeclaration (), mp_editor (0), mp_mw (0), mp_plugin_root (0), mp_active_technology (0)
{ {
m_configure_enabled = true; m_configure_enabled = true;
m_current_technology_updated = false; m_current_technology_updated = false;
@ -72,7 +72,8 @@ TechnologyController::instance ()
void void
TechnologyController::initialize (lay::PluginRoot *root) TechnologyController::initialize (lay::PluginRoot *root)
{ {
mp_mw = dynamic_cast <lay::MainWindow *> (root); mp_plugin_root = root;
mp_mw = lay::MainWindow::instance ();
if (mp_mw) { if (mp_mw) {
mp_editor = new lay::TechSetupDialog (mp_mw); mp_editor = new lay::TechSetupDialog (mp_mw);
mp_editor->setModal (false); mp_editor->setModal (false);
@ -192,7 +193,7 @@ TechnologyController::update_active_technology ()
#if 0 #if 0
// Hint with this implementation, the current technology follows the current layout. // Hint with this implementation, the current technology follows the current layout.
// Although that's a nice way to display the current technology, it's pretty confusing // Although that's a nice way to display the current technology, it's pretty confusing
lay::PluginRoot *pr = mp_mw; lay::PluginRoot *pr = mp_plugin_root;
if (pr) { if (pr) {
pr->config_set (cfg_initial_technology, active_tech); pr->config_set (cfg_initial_technology, active_tech);
} }
@ -203,7 +204,7 @@ void
TechnologyController::technologies_changed () TechnologyController::technologies_changed ()
{ {
// update the configuration to reflect the persisted technologies // update the configuration to reflect the persisted technologies
lay::PluginRoot *pr = mp_mw; lay::PluginRoot *pr = mp_plugin_root;
if (pr) { if (pr) {
m_configure_enabled = false; m_configure_enabled = false;
try { try {
@ -474,9 +475,7 @@ TechnologyController::show_editor ()
} }
if (mp_mw) { mp_plugin_root->config_set (cfg_tech_editor_window_state, lay::save_dialog_state (mp_editor));
mp_mw->config_set (cfg_tech_editor_window_state, lay::save_dialog_state (mp_editor));
}
} }
const std::string & const std::string &

View File

@ -132,6 +132,7 @@ private:
bool m_technologies_configured; bool m_technologies_configured;
lay::TechSetupDialog *mp_editor; lay::TechSetupDialog *mp_editor;
lay::MainWindow *mp_mw; lay::MainWindow *mp_mw;
lay::PluginRoot *mp_plugin_root;
std::vector<std::string> m_paths; std::vector<std::string> m_paths;
std::vector<db::Technology> m_temp_tech; std::vector<db::Technology> m_temp_tech;
db::Technology *mp_active_technology; db::Technology *mp_active_technology;

View File

@ -13,9 +13,10 @@
<!-- v2.06 decorator names can (and often do) contain periods --> <!-- v2.06 decorator names can (and often do) contain periods -->
<!-- v2.07 add support for %prog and co, see bug 142832 --> <!-- v2.07 add support for %prog and co, see bug 142832 -->
<!-- v2.08 add missing overloaders, new Python 3 statements, builtins, and keywords --> <!-- v2.08 add missing overloaders, new Python 3 statements, builtins, and keywords -->
<language name="Python" version="2.22" style="python" kateversion="2.4" section="Scripts" extensions="*.py;*.pyw;SConstruct;SConscript" mimetype="application/x-python;text/x-python" casesensitive="1" author="Michael Bueker" license=""> <!-- v2.29 recognize escape sequenzes correctly -->
<language name="Python" version="4" style="python" kateversion="5.0" section="Scripts" extensions="*.py;*.pyw;SConstruct;SConscript" mimetype="application/x-python;text/x-python" casesensitive="1" author="Michael Bueker" license="">
<highlighting> <highlighting>
<list name="prep"> <list name="import">
<item> import </item> <item> import </item>
<item> from </item> <item> from </item>
<item> as </item> <item> as </item>
@ -52,6 +53,8 @@
<item> while </item> <item> while </item>
<item> with </item> <item> with </item>
<item> yield </item> <item> yield </item>
<item> async </item>
<item> await </item>
</list> </list>
<list name="builtinfuncs"> <list name="builtinfuncs">
<item> __import__ </item> <item> __import__ </item>
@ -248,6 +251,11 @@
<item>__format__</item> <item>__format__</item>
<item>__next__</item> <item>__next__</item>
<item>__dir__</item> <item>__dir__</item>
<item>__await__</item>
<item>__aiter__</item>
<item>__anext__</item>
<item>__aenter__</item>
<item>__aexit__</item>
</list> </list>
<list name="exceptions"> <list name="exceptions">
<!-- <!--
@ -323,17 +331,17 @@
</list> </list>
<contexts> <contexts>
<context name="Normal" attribute="Normal Text" lineEndContext="#stay"> <context name="Normal" attribute="Normal Text" lineEndContext="#stay">
<keyword attribute="Preprocessor" String="prep" context="#stay"/> <keyword attribute="Import" String="import" context="#stay"/>
<keyword attribute="Definition Keyword" String="defs" context="#stay"/> <keyword attribute="Definition Keyword" String="defs" context="#stay"/>
<keyword attribute="Operator" String="operators" context="#stay"/> <keyword attribute="Operator Keyword" String="operators" context="#stay"/>
<keyword attribute="Command Keyword" String="commands" context="#stay"/>
<keyword attribute="Flow Control Keyword" String="flow" context="#stay"/> <keyword attribute="Flow Control Keyword" String="flow" context="#stay"/>
<keyword attribute="Builtin Function" String="builtinfuncs" context="#stay"/> <keyword attribute="Builtin Function" String="builtinfuncs" context="#stay"/>
<keyword attribute="Special Variable" String="specialvars" context="#stay"/> <keyword attribute="Special Variable" String="specialvars" context="#stay"/>
<keyword attribute="Extensions" String="bindings" context="#stay"/> <keyword attribute="Extensions" String="bindings" context="#stay"/>
<keyword attribute="Exceptions" String="exceptions" context="#stay"/> <keyword attribute="Exceptions" String="exceptions" context="#stay"/>
<keyword attribute="Overloaders" String="overloaders" context="#stay"/> <keyword attribute="Overloaders" String="overloaders" context="#stay"/>
<RegExpr attribute="Normal" String="[a-zA-Z_][a-zA-Z_0-9]{2,}" context="#stay"/> <RegExpr attribute="ClassNames" String="[A-Z][a-zA-Z_0-9]+" context="#stay"/>
<RegExpr attribute="Normal Text" String="[a-z_][a-zA-Z_][a-zA-Z_0-9]+" context="#stay"/>
<RegExpr attribute="Complex" String=" ((([0-9]*\.[0-9]+|[0-9]+\.)|([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.))[eE](\+|-)?[0-9]+)|[0-9]+)[jJ]" context="#stay"/> <RegExpr attribute="Complex" String=" ((([0-9]*\.[0-9]+|[0-9]+\.)|([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.))[eE](\+|-)?[0-9]+)|[0-9]+)[jJ]" context="#stay"/>
<Float attribute="Float" context="#stay" /> <Float attribute="Float" context="#stay" />
@ -353,15 +361,15 @@
<IncludeRules context="StringVariants" /> <IncludeRules context="StringVariants" />
<AnyChar attribute="Operator" String="+*/%\|=;\!&lt;&gt;!^&amp;~-" context="#stay"/>
<RegExpr attribute="Decorator" String="@[_a-zA-Z][\._a-zA-Z0-9]*" firstNonSpace="true"/> <RegExpr attribute="Decorator" String="@[_a-zA-Z][\._a-zA-Z0-9]*" firstNonSpace="true"/>
<AnyChar attribute="Operator" String="+*/%\|=;\!&lt;&gt;!^&amp;~-@" context="#stay"/>
</context> </context>
<context name="#CheckForString" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop"> <context name="#CheckForString" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<DetectSpaces/> <DetectSpaces/>
<LineContinue attribute="Normal Text" context="CheckForStringNext"/> <LineContinue attribute="Normal Text" context="CheckForStringNext"/>
</context> </context>
<context name="CheckForStringNext" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop"> <context name="CheckForStringNext" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<DetectSpaces/> <DetectSpaces/>
<LineContinue attribute="Normal Text" context="CheckForStringNext"/> <LineContinue attribute="Normal Text" context="CheckForStringNext"/>
@ -370,60 +378,40 @@
<context name="StringVariants" attribute="Normal Text" lineEndContext="#stay"> <context name="StringVariants" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces/> <DetectSpaces/>
<!-- ''' -->
<StringDetect attribute="String" String="'''" context="Tripple A-string" beginRegion="Tripple A-region"/>
<StringDetect attribute="String" String="u'''" insensitive="true" context="Tripple A-string" beginRegion="Tripple A-region"/>
<!-- """ -->
<StringDetect attribute="String" String="&quot;&quot;&quot;" context="Tripple Q-string" beginRegion="Tripple Q-region"/>
<StringDetect attribute="String" String="u&quot;&quot;&quot;" insensitive="true" context="Tripple Q-string" beginRegion="Tripple Q-region"/>
<!-- ' -->
<DetectChar attribute="String" char="'" context="Single A-string"/>
<Detect2Chars attribute="String" char="u" char1="'" insensitive="true" context="Single A-string"/>
<!-- " -->
<DetectChar attribute="String" char="&quot;" context="Single Q-string"/>
<Detect2Chars attribute="String" char="u" char1="&quot;" insensitive="true" context="Single Q-string"/>
<!-- ''' --> <RegExpr attribute="String" String="u?'''" insensitive="true" context="Triple A-string" beginRegion="Triple A-region"/>
<StringDetect attribute="Raw String" String="r'''" insensitive="true" context="Raw Tripple A-string" beginRegion="Tripple A-region"/> <RegExpr attribute="String" String="u?&quot;&quot;&quot;" insensitive="true" context="Triple Q-string" beginRegion="Triple Q-region"/>
<StringDetect attribute="Raw String" String="ur'''" insensitive="true" context="Raw Tripple A-string" beginRegion="Tripple A-region"/> <RegExpr attribute="String" String="u?'" insensitive="true" context="Single A-string"/>
<!-- """ --> <RegExpr attribute="String" String="u?&quot;" insensitive="true" context="Single Q-string"/>
<StringDetect attribute="Raw String" String="r&quot;&quot;&quot;" insensitive="true" context="Raw Tripple Q-string" beginRegion="Tripple Q-region"/>
<StringDetect attribute="Raw String" String="ur&quot;&quot;&quot;" insensitive="true" context="Raw Tripple Q-string" beginRegion="Tripple Q-region"/> <RegExpr attribute="Raw String" String="(u?r|ru)'''" insensitive="true" context="Raw Triple A-string" beginRegion="Triple A-region"/>
<!-- ' --> <RegExpr attribute="Raw String" String="(u?r|ru)&quot;&quot;&quot;" insensitive="true" context="Raw Triple Q-string" beginRegion="Triple Q-region"/>
<StringDetect attribute="Raw String" String="r'" insensitive="true" context="Raw A-string"/> <RegExpr attribute="Raw String" String="(u?r|ru)'" insensitive="true" context="Raw A-string"/>
<StringDetect attribute="Raw String" String="ur'" insensitive="true" context="Raw A-string"/> <RegExpr attribute="Raw String" String="(u?r|ru)&quot;" insensitive="true" context="Raw Q-string"/>
<!-- " -->
<StringDetect attribute="Raw String" String="r&quot;" insensitive="true" context="Raw Q-string"/> <StringDetect attribute="F-String" String="f'''" insensitive="true" context="Triple A-F-String" beginRegion="Triple A-region"/>
<StringDetect attribute="Raw String" String="ur&quot;" insensitive="true" context="Raw Q-string"/> <StringDetect attribute="F-String" String="f&quot;&quot;&quot;" insensitive="true" context="Triple Q-F-String" beginRegion="Triple Q-region"/>
<StringDetect attribute="F-String" String="f'" insensitive="true" context="Single A-F-String"/>
<StringDetect attribute="F-String" String="f&quot;" insensitive="true" context="Single Q-F-String"/>
<RegExpr attribute="Raw F-String" String="(fr|rf)'''" insensitive="true" context="Raw Triple A-F-String" beginRegion="Triple A-region"/>
<RegExpr attribute="Raw F-String" String="(fr|rf)&quot;&quot;&quot;" insensitive="true" context="Raw Triple Q-F-String" beginRegion="Triple Q-region"/>
<RegExpr attribute="Raw F-String" String="(fr|rf)'" insensitive="true" context="Raw A-F-String"/>
<RegExpr attribute="Raw F-String" String="(fr|rf)&quot;" insensitive="true" context="Raw Q-F-String"/>
</context> </context>
<context name="CommentVariants" attribute="Normal Text" lineEndContext="#stay"> <context name="CommentVariants" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces/> <DetectSpaces/>
<!-- ''' -->
<StringDetect attribute="Comment" String="'''" firstNonSpace="true" context="Tripple A-comment" beginRegion="Tripple A-region"/>
<StringDetect attribute="Comment" String="u'''" insensitive="true" firstNonSpace="true" context="Tripple A-comment" beginRegion="Tripple A-region"/>
<!-- """ -->
<StringDetect attribute="Comment" String="&quot;&quot;&quot;" firstNonSpace="true" context="Tripple Q-comment" beginRegion="Tripple Q-region"/>
<StringDetect attribute="Comment" String="u&quot;&quot;&quot;" insensitive="true" firstNonSpace="true" context="Tripple Q-comment" beginRegion="Tripple Q-region"/>
<!-- ' -->
<DetectChar attribute="Comment" char="'" firstNonSpace="true" context="Single A-comment"/>
<Detect2Chars attribute="Comment" char="u" char1="'" insensitive="true" firstNonSpace="true" context="Single A-comment"/>
<!-- " -->
<DetectChar attribute="Comment" char="&quot;" firstNonSpace="true" context="Single Q-comment"/>
<Detect2Chars attribute="Comment" char="u" char1="&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
<!-- ''' --> <RegExpr attribute="Comment" String="u?'''" insensitive="true" firstNonSpace="true" context="Triple A-comment" beginRegion="Triple A-region"/>
<StringDetect attribute="Comment" String="r'''" insensitive="true" firstNonSpace="true" context="Tripple A-comment" beginRegion="Tripple A-region"/> <RegExpr attribute="Comment" String="u?&quot;&quot;&quot;" insensitive="true" firstNonSpace="true" context="Triple Q-comment" beginRegion="Triple Q-region"/>
<StringDetect attribute="Comment" String="ur'''" insensitive="true" firstNonSpace="true" context="Tripple A-comment" beginRegion="Tripple A-region"/> <RegExpr attribute="Comment" String="u?'" insensitive="true" firstNonSpace="true" context="Single A-comment"/>
<!-- """ --> <RegExpr attribute="Comment" String="u?&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
<StringDetect attribute="Comment" String="r&quot;&quot;&quot;" insensitive="true" firstNonSpace="true" context="Tripple Q-comment" beginRegion="Tripple Q-region"/>
<StringDetect attribute="Comment" String="ur&quot;&quot;&quot;" insensitive="true" firstNonSpace="true" context="Tripple Q-comment" beginRegion="Tripple Q-region"/> <RegExpr attribute="Comment" String="(u?r|ru)'''" insensitive="true" firstNonSpace="true" context="Triple A-comment" beginRegion="Triple A-region"/>
<!-- ' --> <RegExpr attribute="Comment" String="(u?r|ru)&quot;&quot;&quot;" insensitive="true" firstNonSpace="true" context="Triple Q-comment" beginRegion="Triple Q-region"/>
<StringDetect attribute="Comment" String="r'" insensitive="true" firstNonSpace="true" context="Single A-comment"/> <RegExpr attribute="Comment" String="(u?r|ru)'" insensitive="true" firstNonSpace="true" context="Single A-comment"/>
<StringDetect attribute="Comment" String="ur'" insensitive="true" firstNonSpace="true" context="Single A-comment"/> <RegExpr attribute="Comment" String="(u?r|ru)&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
<!-- " -->
<StringDetect attribute="Comment" String="r&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
<StringDetect attribute="Comment" String="ur&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
</context> </context>
<context name="Dictionary" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true"> <context name="Dictionary" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true">
@ -432,14 +420,14 @@
<IncludeRules context="StringVariants" /> <IncludeRules context="StringVariants" />
<IncludeRules context="Normal" /> <IncludeRules context="Normal" />
</context> </context>
<context name="List" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true"> <context name="List" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true">
<DetectSpaces/> <DetectSpaces/>
<DetectChar attribute="Normal Text" char="]" context="#pop" endRegion="List"/> <DetectChar attribute="Normal Text" char="]" context="#pop" endRegion="List"/>
<IncludeRules context="StringVariants" /> <IncludeRules context="StringVariants" />
<IncludeRules context="Normal" /> <IncludeRules context="Normal" />
</context> </context>
<context name="Tuple" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true"> <context name="Tuple" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true">
<DetectSpaces/> <DetectSpaces/>
<DetectChar attribute="Normal Text" char=")" context="#pop" endRegion="Tuple"/> <DetectChar attribute="Normal Text" char=")" context="#pop" endRegion="Tuple"/>
@ -454,14 +442,14 @@
<IncludeRules context="##Modelines" /> <IncludeRules context="##Modelines" />
</context> </context>
<context name="Tripple A-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true"> <context name="Triple A-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true">
<StringDetect attribute="Comment" String="'''" context="#pop" endRegion="Tripple A-region"/> <StringDetect attribute="Comment" String="'''" context="#pop" endRegion="Triple A-region"/>
<IncludeRules context="##Alerts_indent" /> <IncludeRules context="##Alerts_indent" />
</context> </context>
<context name="Tripple Q-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true"> <context name="Triple Q-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCChar attribute="Comment" context="#stay"/> <HlCChar attribute="Comment" context="#stay"/>
<StringDetect attribute="Comment" String="&quot;&quot;&quot;" context="#pop" endRegion="Tripple Q-region"/> <StringDetect attribute="Comment" String="&quot;&quot;&quot;" context="#pop" endRegion="Triple Q-region"/>
<IncludeRules context="##Alerts_indent" /> <IncludeRules context="##Alerts_indent" />
</context> </context>
@ -493,89 +481,176 @@
--> -->
<RegExpr attribute="String Substitution" String="%((\([a-zA-Z0-9_]+\))?[#0\- +]?([1-9][0-9]*|\*)?(\.([1-9][0-9]*|\*))?[hlL]?[crsdiouxXeEfFgG%]|prog|default)" context="#stay"/> <RegExpr attribute="String Substitution" String="%((\([a-zA-Z0-9_]+\))?[#0\- +]?([1-9][0-9]*|\*)?(\.([1-9][0-9]*|\*))?[hlL]?[crsdiouxXeEfFgG%]|prog|default)" context="#stay"/>
<!-- http://docs.python.org/2/library/string.html#format-string-syntax: <!-- http://docs.python.org/2/library/string.html#format-string-syntax:
replacement_field ::= "{" field_name ["!" conversion] [":" format_spec] "}" replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name ::= (identifier | integer) ("." attribute_name | "[" element_index "]")* field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
attribute_name ::= identifier arg_name ::= [identifier | integer]
element_index ::= integer | index_string attribute_name ::= identifier
index_string ::= <any source character except "]"> + element_index ::= integer | index_string
conversion ::= "r" | "s" index_string ::= <any source character except "]"> +
format_spec ::= [[fill]align][sign][#][0][width][.precision][type] conversion ::= "r" | "s"
fill ::= <a character other than '}'> format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
align ::= "<" | ">" | "=" | "^" fill ::= <any character>
sign ::= "+" | "-" | " " align ::= "<" | ">" | "=" | "^"
width ::= integer sign ::= "+" | "-" | " "
precision ::= integer width ::= integer
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%" precision ::= integer
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
--> -->
<RegExpr attribute="String Substitution" String="\{([a-zA-Z0-9_]+|[0-9]+)(\.[a-zA-Z0-9_]+|\[[^ \]]+\])*(![rs])?(:([^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#stay"/> <RegExpr attribute="String Substitution" String="\{(([a-zA-Z0-9_]+|[0-9]+)(\.[a-zA-Z0-9_]+|\[[^ \]]+\])*)?(![rs])?(:([^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#stay"/>
<Detect2Chars attribute="String Substitution" char="{" char1="{" context="#stay" /> <Detect2Chars attribute="String Substitution" char="{" char1="{" context="#stay" />
<Detect2Chars attribute="String Substitution" char="}" char1="}" context="#stay" /> <Detect2Chars attribute="String Substitution" char="}" char1="}" context="#stay" />
</context> </context>
<context name="Tripple A-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true"> <!-- escape characters -->
<HlCStringChar attribute="String Char" context="#stay"/> <context name="stringescape" attribute="String Char" lineEndContext="#stay">
<IncludeRules context="stringformat"/> <!-- As this highlighting style is for both, Python 2 and 3,
<StringDetect attribute="String" String="'''" context="#pop#CheckForString" endRegion="Tripple A-region"/> we do not know if a normal string is “unicode” or not. So we
-->
<RegExpr attribute="String Char" String="\\[\\'&quot;abfnrtv]" context="#stay"/>
<RegExpr attribute="String Char" String="\\[0-7]{1,3}" context="#stay"/>
<RegExpr attribute="String Char" String="\\x[0-9A-Fa-f]{2}" context="#stay"/>
<RegExpr attribute="String Char" String="\\u[0-9A-Fa-f]{4}" context="#stay"/>
<RegExpr attribute="String Char" String="\\U[0-9A-Fa-f]{8}" context="#stay"/>
<RegExpr attribute="String Char" String="\\N\{[a-zA-Z0-9\- ]+\}" context="#stay"/>
</context> </context>
<context name="Raw Tripple A-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true"> <!-- f-literals -->
<context name="stringinterpolation" attribute="F-String" lineEndContext="#stay">
<Detect2Chars attribute="String Char" char="{" char1="{" context="#stay"/>
<DetectChar attribute="String Substitution" char="{" context="String Interpolation"/>
</context>
<context name="String Interpolation" attribute="String Substitution" lineEndContext="#stay">
<DetectChar attribute="Error" char="\" context="#pop"/>
<RegExpr attribute="String Substitution" String="(![rs])?(:([^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#pop"/>
<IncludeRules context="Normal"/> <!-- TODO: create expression context instead -->
</context>
<!--
It follows a Binary tree of string kinds (not even touching byte literals).
The levels are:
1. triple- vs. single-quoted
2. apostrophe vs. quotation mark
3. static vs. interpolated (f-literal)
4. escaped vs. raw
Adding byte literals wouldnt make the current 2⁴ into 2⁵ contexts, as there are no byte f-literals
-->
<!-- Triple-quoted A-strings -->
<context name="Triple A-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true">
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/>
</context>
<context name="Raw Triple A-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw String" context="#stay"/> <HlCStringChar attribute="Raw String" context="#stay"/>
<IncludeRules context="stringformat"/> <IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="'''" context="#pop#CheckForString" endRegion="Tripple A-region"/> <StringDetect attribute="Raw String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/>
</context> </context>
<context name="Tripple Q-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true"> <context name="Triple A-F-String" attribute="F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="String Char" context="#stay"/> <IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="F-String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/>
</context>
<context name="Raw Triple A-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="Raw F-String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/>
</context>
<!-- Triple-quoted Q-strings -->
<context name="Triple Q-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true">
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/> <IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="&quot;&quot;&quot;" context="#pop#CheckForString" endRegion="Tripple Q-region"/> <StringDetect attribute="String" String="&quot;&quot;&quot;" context="#pop#CheckForString" endRegion="Triple Q-region"/>
</context> </context>
<context name="Raw Tripple Q-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true"> <context name="Raw Triple Q-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw String" context="#stay"/> <HlCStringChar attribute="Raw String" context="#stay"/>
<IncludeRules context="stringformat"/> <IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="&quot;&quot;&quot;" context="#pop#CheckForString" endRegion="Tripple Q-region"/> <StringDetect attribute="Raw String" String="&quot;&quot;&quot;" context="#pop#CheckForString" endRegion="Triple Q-region"/>
</context>
<context name="Triple Q-F-String" attribute="F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="F-String" String="&quot;&quot;&quot;" context="#pop#CheckForString" endRegion="Triple Q-region"/>
</context>
<context name="Raw Triple Q-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="Raw F-String" String="&quot;&quot;&quot;" context="#pop#CheckForString" endRegion="Triple Q-region"/>
</context> </context>
<!-- Single-quoted A-strings -->
<context name="Single A-string" attribute="String" lineEndContext="#stay"> <context name="Single A-string" attribute="String" lineEndContext="#stay">
<HlCStringChar attribute="String Char" context="#stay"/> <IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/> <IncludeRules context="stringformat"/>
<DetectChar attribute="String" char="'" context="#pop#CheckForString"/> <DetectChar attribute="String" char="'" context="#pop#CheckForString"/>
</context> </context>
<context name="Single Q-string" attribute="String" lineEndContext="#stay">
<HlCStringChar attribute="String Char" context="#stay"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="String" char="&quot;" context="#pop#CheckForString"/>
</context>
<context name="Raw A-string" attribute="Raw String" lineEndContext="#stay"> <context name="Raw A-string" attribute="Raw String" lineEndContext="#stay">
<HlCStringChar attribute="Raw String" context="#stay"/> <HlCStringChar attribute="Raw String" context="#stay"/>
<IncludeRules context="stringformat"/> <IncludeRules context="stringformat"/>
<DetectChar attribute="Raw String" char="'" context="#pop#CheckForString"/> <DetectChar attribute="Raw String" char="'" context="#pop#CheckForString"/>
</context> </context>
<context name="Single A-F-String" attribute="F-String" lineEndContext="#stay">
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="F-String" char="'" context="#pop#CheckForString"/>
</context>
<context name="Raw A-F-String" attribute="Raw F-String" lineEndContext="#stay">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="Raw F-String" char="'" context="#pop#CheckForString"/>
</context>
<!-- Single-quoted Q-strings -->
<context name="Single Q-string" attribute="String" lineEndContext="#stay">
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="String" char="&quot;" context="#pop#CheckForString"/>
</context>
<context name="Raw Q-string" attribute="Raw String" lineEndContext="#stay"> <context name="Raw Q-string" attribute="Raw String" lineEndContext="#stay">
<HlCStringChar attribute="Raw String" context="#stay"/> <HlCStringChar attribute="Raw String" context="#stay"/>
<IncludeRules context="stringformat"/> <IncludeRules context="stringformat"/>
<DetectChar attribute="Raw String" char="&quot;" context="#pop#CheckForString"/> <DetectChar attribute="Raw String" char="&quot;" context="#pop#CheckForString"/>
</context> </context>
<context name="Single Q-F-String" attribute="F-String" lineEndContext="#stay">
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="F-String" char="&quot;" context="#pop#CheckForString"/>
</context>
<context name="Raw Q-F-String" attribute="Raw F-String" lineEndContext="#stay">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="Raw F-String" char="&quot;" context="#pop#CheckForString"/>
</context>
</contexts> </contexts>
<itemDatas> <itemDatas>
<itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false"/> <itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false"/>
<itemData name="Definition Keyword" defStyleNum="dsKeyword" spellChecking="false"/> <itemData name="Definition Keyword" defStyleNum="dsKeyword" spellChecking="false"/>
<itemData name="Operator" defStyleNum="dsNormal" bold="1" spellChecking="false"/> <itemData name="Operator" defStyleNum="dsOperator" spellChecking="false"/>
<itemData name="String Substitution" defStyleNum="dsOthers" color="#0057ae" selColor="#0057ae" spellChecking="false"/> <itemData name="Operator Keyword" defStyleNum="dsKeyword" spellChecking="false"/>
<itemData name="Command Keyword" defStyleNum="dsKeyword" spellChecking="false"/> <itemData name="Flow Control Keyword" defStyleNum="dsControlFlow" spellChecking="false"/>
<itemData name="Flow Control Keyword" defStyleNum="dsKeyword" spellChecking="false"/> <itemData name="Builtin Function" defStyleNum="dsBuiltIn" spellChecking="false"/>
<itemData name="Builtin Function" defStyleNum="dsDataType" spellChecking="false"/> <itemData name="Special Variable" defStyleNum="dsVariable" spellChecking="false"/>
<itemData name="Special Variable" defStyleNum="dsOthers" spellChecking="false"/> <itemData name="Extensions" defStyleNum="dsExtension" spellChecking="false"/>
<itemData name="Extensions" defStyleNum="dsOthers" color="#0095ff" selColor="#0095ff" bold="1" italic="0" spellChecking="false"/> <itemData name="Exceptions" defStyleNum="dsPreprocessor" spellChecking="false"/>
<itemData name="Exceptions" defStyleNum="dsOthers" color="#054d00" selColor="#054d00" bold="1" italic="0" spellChecking="false"/> <itemData name="Overloaders" defStyleNum="dsFunction" spellChecking="false"/>
<itemData name="Overloaders" defStyleNum="dsOthers" color="#000e52" selColor="#000e52" bold="1" italic="0" spellChecking="false"/> <itemData name="Import" defStyleNum="dsImport" spellChecking="false"/>
<itemData name="Preprocessor" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="String Char" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="Float" defStyleNum="dsFloat" spellChecking="false"/> <itemData name="Float" defStyleNum="dsFloat" spellChecking="false"/>
<itemData name="Int" defStyleNum="dsDecVal" spellChecking="false"/> <itemData name="Int" defStyleNum="dsDecVal" spellChecking="false"/>
<itemData name="Hex" defStyleNum="dsBaseN" spellChecking="false"/> <itemData name="Hex" defStyleNum="dsBaseN" spellChecking="false"/>
@ -583,8 +658,14 @@
<itemData name="Complex" defStyleNum="dsOthers" spellChecking="false"/> <itemData name="Complex" defStyleNum="dsOthers" spellChecking="false"/>
<itemData name="Comment" defStyleNum="dsComment"/> <itemData name="Comment" defStyleNum="dsComment"/>
<itemData name="String" defStyleNum="dsString"/> <itemData name="String" defStyleNum="dsString"/>
<itemData name="Raw String" defStyleNum="dsString"/> <itemData name="ClassNames" defStyleNum="dsOthers" color="#FCAD3D" selColor="#ffffff" bold="1" italic="0" spellChecking="false"/>
<itemData name="Decorator" defStyleNum="dsOthers" color="#8f6b32" selColor="#8f6b32" italic="0" spellChecking="false"/> <itemData name="Raw String" defStyleNum="dsVerbatimString"/>
<itemData name="F-String" defStyleNum="dsSpecialString"/>
<itemData name="Raw F-String" defStyleNum="dsVerbatimString"/>
<itemData name="String Char" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="String Substitution" defStyleNum="dsSpecialChar" spellChecking="false"/>
<itemData name="Decorator" defStyleNum="dsAttribute" spellChecking="false"/>
<itemData name="Error" defStyleNum="dsError"/>
</itemDatas> </itemDatas>
</highlighting> </highlighting>
<general> <general>

View File

@ -849,18 +849,28 @@ Class<gsi::ButtonStateNamespace> decl_ButtonState ("lay", "ButtonState",
); );
static std::vector<std::string> static std::vector<std::string>
get_config_names (lay::PluginRoot *view) get_config_names (lay::PluginRoot *root)
{ {
std::vector<std::string> names; std::vector<std::string> names;
view->get_config_names (names); root->get_config_names (names);
return names; return names;
} }
lay::PluginRoot *config_root_instance () static lay::PluginRoot *config_root_instance ()
{ {
return lay::PluginRoot::instance (); return lay::PluginRoot::instance ();
} }
static tl::Variant get_config (lay::PluginRoot *root, const std::string &name)
{
std::string value;
if (root->config_get (name, value)) {
return tl::Variant (value);
} else {
return tl::Variant ();
}
}
/** /**
* @brief Exposes the PluginRoot interface * @brief Exposes the PluginRoot interface
* *
@ -868,7 +878,7 @@ lay::PluginRoot *config_root_instance ()
* identify the plugin root node for configuration. The Plugin nature of this interface * identify the plugin root node for configuration. The Plugin nature of this interface
* is somewhat artificial and may be removed later. * is somewhat artificial and may be removed later.
* *
* TODO: this is a duplicate of the respective methods in LayoutView and MainWindow. * TODO: this is a duplicate of the respective methods in LayoutView and Application.
* This is intentional since we don't want to spend the only derivation path on this. * This is intentional since we don't want to spend the only derivation path on this.
* Once there is a mixin concept, provide a path through that concept. * Once there is a mixin concept, provide a path through that concept.
*/ */
@ -898,13 +908,13 @@ Class<lay::PluginRoot> decl_PluginRoot ("lay", "PluginRoot",
"exist. If it does and an error occured, the error message is printed\n" "exist. If it does and an error occured, the error message is printed\n"
"on stderr. In both cases, false is returned.\n" "on stderr. In both cases, false is returned.\n"
) + ) +
method ("get_config", (bool (lay::PluginRoot::*) (const std::string &, std::string &) const) &lay::PluginRoot::config_get, method_ext ("get_config", &get_config,
"@brief Get the value of a local configuration parameter\n" "@brief Gets the value of a local configuration parameter\n"
"\n" "\n"
"@args name\n" "@args name\n"
"@param name The name of the configuration parameter whose value shall be obtained (a string)\n" "@param name The name of the configuration parameter whose value shall be obtained (a string)\n"
"\n" "\n"
"@return The value of the parameter\n" "@return The value of the parameter or nil if there is no such parameter\n"
) + ) +
method ("set_config", (void (lay::PluginRoot::*) (const std::string &, const std::string &)) &lay::PluginRoot::config_set, method ("set_config", (void (lay::PluginRoot::*) (const std::string &, const std::string &)) &lay::PluginRoot::config_set,
"@brief Set a local configuration parameter with the given name to the given value\n" "@brief Set a local configuration parameter with the given name to the given value\n"
@ -936,11 +946,16 @@ Class<lay::PluginRoot> decl_PluginRoot ("lay", "PluginRoot",
), ),
"@brief Root of the configuration space in the plugin context\n" "@brief Root of the configuration space in the plugin context\n"
"\n" "\n"
"This class provides access to the root configuration space. This object provides access to the configuration space in the context " "This class provides access to the root configuration space in the context "
"of plugin programming.\n" "of plugin programming. You can use this class to obtain configuration parameters "
"Plugins are organized in a configuration tree. Configuration settings are propagated down to the individual plugins. " "from the configuration tree during plugin initialization. However, the "
"If there is a main window, the configuration root is identical with this object, so configuration settings " "preferred way of plugin configuration is through \\Plugin#configure.\n"
"applied in the configuration root are available to all views.\n" "\n"
"Currently, the application object provides an identical entry point for configuration modification. "
"For example, \"Application::instance.set_config\" is identical to \"PluginRoot::instance.set_config\". "
"Hence there is little motivation for the PluginRoot class currently and "
"this interface may be modified or removed in the future."
"\n"
"\n" "\n"
"This class has been introduced in version 0.25.\n" "This class has been introduced in version 0.25.\n"
); );

View File

@ -247,9 +247,9 @@ const int timer_interval = 500;
static LayoutView *ms_current = 0; static LayoutView *ms_current = 0;
LayoutView::LayoutView (db::Manager *manager, bool editable, lay::PluginRoot *root, QWidget *parent, const char *name, unsigned int options) LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin_parent, QWidget *parent, const char *name, unsigned int options)
: QFrame (parent), : QFrame (parent),
lay::Plugin (root), lay::Plugin (plugin_parent),
m_editable (editable), m_editable (editable),
m_options (options), m_options (options),
m_annotation_shapes (manager), m_annotation_shapes (manager),
@ -259,7 +259,7 @@ LayoutView::LayoutView (db::Manager *manager, bool editable, lay::PluginRoot *ro
tl::DeferredMethodScheduler::instance (); tl::DeferredMethodScheduler::instance ();
setObjectName (QString::fromUtf8 (name)); setObjectName (QString::fromUtf8 (name));
init (manager, root, parent); init (manager, plugin_root_maybe_null (), parent);
} }
LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool editable, lay::PluginRoot *root, QWidget *parent, const char *name, unsigned int options) LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool editable, lay::PluginRoot *root, QWidget *parent, const char *name, unsigned int options)
@ -537,7 +537,9 @@ LayoutView::init (db::Manager *mgr, lay::PluginRoot *root, QWidget * /*parent*/)
connect (mp_timer, SIGNAL (timeout ()), this, SLOT (timer ())); connect (mp_timer, SIGNAL (timeout ()), this, SLOT (timer ()));
mp_timer->start (timer_interval); mp_timer->start (timer_interval);
create_plugins (root); if (root) {
create_plugins (root);
}
m_new_layer_props.layer = 1; m_new_layer_props.layer = 1;
m_new_layer_props.datatype = 0; m_new_layer_props.datatype = 0;
@ -4468,6 +4470,8 @@ LayoutView::background_color (QColor c)
mp_canvas->set_colors (c, contrast, mp_canvas->active_color ()); mp_canvas->set_colors (c, contrast, mp_canvas->active_color ());
update_content (); update_content ();
background_color_changed_event ();
} }
void void

View File

@ -182,7 +182,7 @@ public:
/** /**
* @brief Constructor * @brief Constructor
*/ */
LayoutView (db::Manager *mgr, bool editable, lay::PluginRoot *root, QWidget *parent = 0, const char *name = "view", unsigned int options = (unsigned int) LV_Normal); LayoutView (db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, QWidget *parent = 0, const char *name = "view", unsigned int options = (unsigned int) LV_Normal);
/** /**
* @brief Constructor (clone from another view) * @brief Constructor (clone from another view)
@ -651,6 +651,11 @@ public:
*/ */
tl::Event viewport_changed_event; tl::Event viewport_changed_event;
/**
* @brief This event is triggered if the background color changed
*/
tl::Event background_color_changed_event;
/** /**
* @brief An event signalling that the layer list has changed. * @brief An event signalling that the layer list has changed.
* *

View File

@ -305,7 +305,7 @@ Plugin::config_set (const std::string &name, const std::string &value)
} }
} }
do_config_set (name, value); do_config_set (name, value, false);
// schedule a configuration finalization call (once for all config_set calls) // schedule a configuration finalization call (once for all config_set calls)
dm_finalize_config (); dm_finalize_config ();
@ -363,6 +363,25 @@ Plugin::get_config_names (std::vector<std::string> &names) const
} }
} }
PluginRoot *
Plugin::plugin_root ()
{
PluginRoot *pr = plugin_root_maybe_null ();
tl_assert (pr != 0);
return pr;
}
PluginRoot *
Plugin::plugin_root_maybe_null ()
{
Plugin *p = this;
while (p->mp_parent) {
p = p->mp_parent;
}
return dynamic_cast<PluginRoot *> (p);
}
void void
Plugin::do_config_setup (Plugin *target) Plugin::do_config_setup (Plugin *target)
{ {
@ -371,7 +390,7 @@ Plugin::do_config_setup (Plugin *target)
} }
// local configurations override the parent's configuration, i.e. are applied after the parents settings // local configurations override the parent's configuration, i.e. are applied after the parents settings
for (std::map<std::string, std::string>::const_iterator p = m_repository.begin (); p != m_repository.end (); ++p) { for (std::map<std::string, std::string>::const_iterator p = m_repository.begin (); p != m_repository.end (); ++p) {
target->do_config_set (p->first, p->second); target->do_config_set (p->first, p->second, false);
} }
} }
@ -385,8 +404,14 @@ Plugin::do_config_end ()
} }
bool bool
Plugin::do_config_set (const std::string &name, const std::string &value) Plugin::do_config_set (const std::string &name, const std::string &value, bool for_child)
{ {
if (for_child) {
// this is the case when we impose a configuration from the parent: in this case we
// have to remove it from the repository of local parameters.
m_repository.erase (name);
}
try { try {
if (configure (name, value)) { if (configure (name, value)) {
// taken by us - don't propagate to the children // taken by us - don't propagate to the children
@ -398,7 +423,7 @@ Plugin::do_config_set (const std::string &name, const std::string &value)
// propagate to all children (not only the first that takes it!) // propagate to all children (not only the first that takes it!)
for (tl::weak_collection<Plugin>::iterator c = m_children.begin (); c != m_children.end (); ++c) { for (tl::weak_collection<Plugin>::iterator c = m_children.begin (); c != m_children.end (); ++c) {
c->do_config_set (name, value); c->do_config_set (name, value, true);
} }
return false; return false;

View File

@ -532,7 +532,8 @@ public:
* *
* In order to make configuration changes effective, this method * In order to make configuration changes effective, this method
* must be called. It calls config_finalize recursively on the * must be called. It calls config_finalize recursively on the
* children. * children. In GUI-enabled applications this step is optional
* and is performed automatically through a timer.
*/ */
void config_end (); void config_end ();
@ -632,6 +633,19 @@ public:
*/ */
void get_config_names (std::vector<std::string> &names) const; void get_config_names (std::vector<std::string> &names) const;
/**
* @brief Gets the plugin root (the parent plugin not having another parent)
* The returned pointer is guaranteed to be non-zero.
*/
PluginRoot *plugin_root ();
/**
* @brief Gets the plugin root (the parent plugin not having another parent)
* This version may return null, if the plugin is instantiated without a
* root.
*/
PluginRoot *plugin_root_maybe_null ();
/** /**
* @brief Menu command handler * @brief Menu command handler
* *
@ -761,7 +775,7 @@ private:
/** /**
* @brief Do the actual set or pass to the children if not taken * @brief Do the actual set or pass to the children if not taken
*/ */
bool do_config_set (const std::string &name, const std::string &value); bool do_config_set (const std::string &name, const std::string &value, bool for_child);
/** /**
* @brief Recursively call config_finalize * @brief Recursively call config_finalize

View File

@ -213,6 +213,7 @@ public:
* 1: create LWPOLYLINE * 1: create LWPOLYLINE
* 2: decompose into SOLID * 2: decompose into SOLID
* 3: create HATCH * 3: create HATCH
* 4: create LINE: refer to 'void DXFWriter::write_polygon()' definition
*/ */
int polygon_mode; int polygon_mode;

View File

@ -507,7 +507,36 @@ DXFWriter::write_polygon (const db::Polygon &polygon, double sf)
} }
} }
} else if (m_options.polygon_mode == 4) {
//--------------------------------------------------------------------------------------
// Last modified by: Kazzz-S on October 21, 2018 (newly added)
//
// Description: When importing a DXF file comprising POLYLINEs or LWPOLYLINEs into
// Abaqus CAE, they are forcibly converted to points!
// *** This is a "specification" of Abaqus CAE. ***
// In contrast, LINEs are kept as lines, which will be then assembled into
// polygonal objects internally if required.
//--------------------------------------------------------------------------------------
for (unsigned int c = 0; c < polygon.holes () + 1; ++c) {
for (db::Polygon::polygon_contour_iterator p = polygon.contour (c).begin (); p != polygon.contour (c).end (); ++p) {
db::Polygon::polygon_contour_iterator q = p + 1;
if (q == polygon.contour (c).end ()) {
q = polygon.contour (c).begin ();
}
*this << 0 << endl << "LINE" << endl;
*this << 8 << endl; emit_layer (m_layer);
*this << 66 << endl << 1 << endl; // required by TrueView
*this << 10 << endl << (*p).x () * sf << endl;
*this << 20 << endl << (*p).y () * sf << endl;
*this << 11 << endl << (*q).x () * sf << endl;
*this << 21 << endl << (*q).y () * sf << endl;
}
}
} }
} }
void void

8
src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc Normal file → Executable file
View File

@ -361,7 +361,7 @@ gsi::ClassExt<db::LoadLayoutOptions> dxf_reader_options (
static void set_dxf_polygon_mode (db::SaveLayoutOptions *options, int mode) static void set_dxf_polygon_mode (db::SaveLayoutOptions *options, int mode)
{ {
if (mode < 0 || mode > 3) { if (mode < 0 || mode > 4) {
throw tl::Exception (tl::to_string (tr ("Invalid polygon mode"))); throw tl::Exception (tl::to_string (tr ("Invalid polygon mode")));
} }
@ -379,9 +379,9 @@ gsi::ClassExt<db::SaveLayoutOptions> dxf_writer_options (
gsi::method_ext ("dxf_polygon_mode=", &set_dxf_polygon_mode, gsi::method_ext ("dxf_polygon_mode=", &set_dxf_polygon_mode,
"@brief Specifies how to write polygons.\n" "@brief Specifies how to write polygons.\n"
"@args mode\n" "@args mode\n"
"The mode is 0 (write POLYLINE entities), 1 (write LWPOLYLINE entities), 2 (decompose into SOLID entities) or " "The mode is 0 (write POLYLINE entities), 1 (write LWPOLYLINE entities), 2 (decompose into SOLID entities), "
"or 3 (write HATCH entities).\n" "3 (write HATCH entities), or 4 (write LINE entities).\n"
"\nThis property has been added in version 0.21.3.\n" "\nThis property has been added in version 0.21.3. '4', in version 0.25.6.\n"
) + ) +
gsi::method_ext ("dxf_polygon_mode", &get_dxf_polygon_mode, gsi::method_ext ("dxf_polygon_mode", &get_dxf_polygon_mode,
"@brief Specifies how to write polygons.\n" "@brief Specifies how to write polygons.\n"

View File

@ -73,6 +73,11 @@
<string>Write HATCH entity</string> <string>Write HATCH entity</string>
</property> </property>
</item> </item>
<item>
<property name="text" >
<string>Write LINE entity</string>
</property>
</item>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -461,3 +461,26 @@ TEST(31)
run_test (_this, "t31.dxf.gz", "t31d_au.gds.gz", opt); run_test (_this, "t31.dxf.gz", "t31d_au.gds.gz", opt);
} }
// issue #198
TEST(32)
{
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("L11D0:1,L12D0:2");
opt.create_other_layers = false;
opt.polyline_mode = 3;
opt.contour_accuracy = 0.0;
run_test_public (_this, "round_path.dxf.gz", "t32a_au.gds.gz", opt);
opt.contour_accuracy = 0.1;
run_test_public (_this, "round_path.dxf.gz", "t32b_au.gds.gz", opt);
opt.contour_accuracy = 1.0;
run_test_public (_this, "round_path.dxf.gz", "t32c_au.gds.gz", opt);
opt.polyline_mode = 4;
run_test_public (_this, "round_path.dxf.gz", "t32d_au.gds.gz", opt);
opt.polyline_mode = 2;
run_test_public (_this, "round_path.dxf.gz", "t32e_au.gds.gz", opt);
}

View File

@ -168,11 +168,31 @@ init_pya_module ()
#endif #endif
PythonInterpreter::PythonInterpreter () static void reset_interpreter ()
{
delete sp_interpreter;
tl_assert (sp_interpreter == 0);
}
PythonInterpreter::PythonInterpreter (bool embedded)
: mp_current_console (0), mp_current_exec_handler (0), m_current_exec_level (0), : mp_current_console (0), mp_current_exec_handler (0), m_current_exec_level (0),
m_in_trace (false), m_block_exceptions (false), m_ignore_next_exception (false), m_in_trace (false), m_block_exceptions (false), m_ignore_next_exception (false),
mp_current_frame (NULL), mp_py3_app_name (0) mp_current_frame (NULL), mp_py3_app_name (0), m_embedded (embedded)
{ {
// Don't attempt any additional initialization in the standalone module case
if (! embedded) {
sp_interpreter = this;
// this monitor whether Python shuts down and deletes the interpreter's
// instance.
// NOTE: this assumes, the interpreter was created with new(!)
Py_AtExit (&reset_interpreter);
return;
}
tl::SelfTimer timer (tl::verbosity () >= 21, "Initializing Python"); tl::SelfTimer timer (tl::verbosity () >= 21, "Initializing Python");
std::string app_path; std::string app_path;
@ -316,11 +336,11 @@ PythonInterpreter::PythonInterpreter ()
m_stderr_channel = PythonRef (PYAChannelObject::create (gsi::Console::OS_stderr)); m_stderr_channel = PythonRef (PYAChannelObject::create (gsi::Console::OS_stderr));
m_stderr = PythonPtr (m_stderr_channel.get ()); m_stderr = PythonPtr (m_stderr_channel.get ());
sp_interpreter = this;
m_pya_module.reset (new pya::PythonModule ()); m_pya_module.reset (new pya::PythonModule ());
m_pya_module->init (pya_module_name, module); m_pya_module->init (pya_module_name, module);
m_pya_module->make_classes (); m_pya_module->make_classes ();
sp_interpreter = this;
} }
PythonInterpreter::~PythonInterpreter () PythonInterpreter::~PythonInterpreter ()
@ -330,11 +350,15 @@ PythonInterpreter::~PythonInterpreter ()
m_stdout = PythonPtr (); m_stdout = PythonPtr ();
m_stderr = PythonPtr (); m_stderr = PythonPtr ();
Py_Finalize (); if (m_embedded) {
Py_Finalize ();
if (mp_py3_app_name) {
PyMem_Free (mp_py3_app_name);
mp_py3_app_name = 0;
}
if (mp_py3_app_name) {
PyMem_Free (mp_py3_app_name);
mp_py3_app_name = 0;
} }
sp_interpreter = 0; sp_interpreter = 0;

View File

@ -101,8 +101,12 @@ class PYA_PUBLIC PythonInterpreter
public: public:
/** /**
* @brief The constructor * @brief The constructor
*
* If embedded is true, the interpreter is an embedded one. Only in this case, the
* Python interpreter is initialized. Otherwise, it is assumed the interpreter
* already exists and our application runs inside an external interpreter.
*/ */
PythonInterpreter (); PythonInterpreter (bool embedded = true);
/** /**
* @brief The destructor * @brief The destructor
@ -281,6 +285,7 @@ private:
PyFrameObject *mp_current_frame; PyFrameObject *mp_current_frame;
std::map<PyObject *, size_t> m_file_id_map; std::map<PyObject *, size_t> m_file_id_map;
wchar_t *mp_py3_app_name; wchar_t *mp_py3_app_name;
bool m_embedded;
std::auto_ptr<pya::PythonModule> m_pya_module; std::auto_ptr<pya::PythonModule> m_pya_module;
}; };

View File

@ -2198,6 +2198,12 @@ PythonModule::take_module ()
void void
PythonModule::init (const char *mod_name, const char *description) PythonModule::init (const char *mod_name, const char *description)
{ {
// create a (standalone) Python interpreter if we don't have one yet
// NOTE: Python itself will take care to remove this instance in this case.
if (! pya::PythonInterpreter::instance ()) {
new pya::PythonInterpreter (false);
}
// do some checks before we create the module // do some checks before we create the module
tl_assert (mod_name != 0); tl_assert (mod_name != 0);
tl_assert (mp_module.get () == 0); tl_assert (mp_module.get () == 0);

View File

@ -1,5 +1,5 @@
# klayout library definition file # klayout library definition file
__all__ = [ "tl", "db", "lay", "rdb", "QtCore", "QtGui", "QtXml", "QtSql", "QtNetwork", "QtDesigner" ] __all__ = [ "tl", "db", "rdb", "QtCore", "QtGui", "QtXml", "QtSql", "QtNetwork", "QtDesigner", "lay" ]

View File

@ -1,7 +1,8 @@
# klayout library definition file # klayout library definition file
__all__ = [ "tl", "db", "lay", "rdb", __all__ = [ "tl", "db", "rdb",
"QtCore", "QtGui", "QtNetwork", "QtSql", "QtWidgets", "QtDesigner", "QtCore", "QtGui", "QtNetwork", "QtSql", "QtWidgets", "QtDesigner",
"QtMultimedia", "QtPrintSupport", "QtSvg", "QtXmlPatterns", "QtXml" ] "QtMultimedia", "QtPrintSupport", "QtSvg", "QtXmlPatterns", "QtXml",
"lay" ]

View File

@ -0,0 +1,10 @@
import klayout
import importlib
__all__ = []
for m in klayout.__all__:
mod = importlib.import_module("klayout." + m)
for mm in mod.__all__:
globals()[mm] = getattr(mod, mm)

View File

@ -43,3 +43,22 @@ msvc {
} }
INSTALLS += init_target INSTALLS += init_target
# And also provide the pya compatibility module here
msvc {
QMAKE_POST_LINK += && (if not exist $$shell_path($$DESTDIR_PYMOD/../pya) $(MKDIR) $$shell_path($$DESTDIR_PYMOD/../pya)) && $(COPY) $$shell_path($$PWD/../distutils_src/pya/*.py) $$shell_path($$DESTDIR_PYMOD/../pya)
} else {
QMAKE_POST_LINK += && $(MKDIR) $$DESTDIR_PYMOD/../pya && $(COPY) $$PWD/../distutils_src/pya/*.py $$DESTDIR_PYMOD/../pya
}
# INSTALLS needs to be inside a lib or app templates.
modpyasrc_target.path = $$PREFIX/pymod/pya
# This would be nice:
# init_target.files += $$DESTDIR_PYMOD/pya/*
# but some Qt versions need this explicitly:
msvc {
modpyasrc_target.extra = $(INSTALL_PROGRAM) $$shell_path($$DESTDIR_PYMOD/../pya/*.py) $$shell_path($(INSTALLROOT)$$PREFIX/pymod/pya)
} else {
modpyasrc_target.extra = $(INSTALL_PROGRAM) $$DESTDIR_PYMOD/../pya/*.py $(INSTALLROOT)$$PREFIX/pymod/pya
}
INSTALLS += modpyasrc_target

View File

@ -23,3 +23,4 @@
#include "../pymodHelper.h" #include "../pymodHelper.h"
DEFINE_PYMOD(tlcore, "tl", "KLayout core module 'tl'") DEFINE_PYMOD(tlcore, "tl", "KLayout core module 'tl'")

View File

@ -109,6 +109,8 @@ PYMODTEST (import_QtXmlPatterns, "import_QtXmlPatterns.py")
#endif #endif
PYMODTEST (import_pya, "pya_tests.py")
#elif defined(HAVE_QT) #elif defined(HAVE_QT)
PYMODTEST (import_lay, "import_lay_noqt.py") PYMODTEST (import_lay, "import_lay_noqt.py")

View File

@ -975,20 +975,24 @@ private:
value_type *new_start = (value_type *) (new char [sizeof (value_type) * n]); value_type *new_start = (value_type *) (new char [sizeof (value_type) * n]);
size_type l = last (); size_type e = 0;
size_type i = first ();
memcpy ((void *)(new_start + i), (void *)(mp_start + i), (l - i) * sizeof (Value));
size_type e = size_type (mp_finish - mp_start); if (mp_start) {
e = size_type (mp_finish - mp_start);
size_type l = last ();
size_type i = first ();
memcpy ((void *)(new_start + i), (void *)(mp_start + i), (l - i) * sizeof (Value));
delete [] ((char *) mp_start);
}
if (mp_rdata) { if (mp_rdata) {
mp_rdata->reserve (n); mp_rdata->reserve (n);
} }
if (mp_start) {
delete [] ((char *) mp_start);
}
mp_start = new_start; mp_start = new_start;
mp_finish = mp_start + e; mp_finish = mp_start + e;
mp_capacity = mp_start + n; mp_capacity = mp_start + n;

BIN
testdata/dxf/round_path.dxf.gz vendored Normal file

Binary file not shown.

BIN
testdata/dxf/t32a_au.gds.gz vendored Normal file

Binary file not shown.

BIN
testdata/dxf/t32b_au.gds.gz vendored Normal file

Binary file not shown.

BIN
testdata/dxf/t32c_au.gds.gz vendored Normal file

Binary file not shown.

BIN
testdata/dxf/t32d_au.gds.gz vendored Normal file

Binary file not shown.

BIN
testdata/dxf/t32e_au.gds.gz vendored Normal file

Binary file not shown.

32
testdata/pymod/pya_tests.py vendored Normal file
View File

@ -0,0 +1,32 @@
import sys
import os
import unittest
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "python"))
# Include all tests from testdata/python
# Missing:
# - basic.py (Test classes not available yet)
# - qtbinding (No applicable because QApplication is missing)
import tlTest
import dbPCells
import dbLayoutTest
import dbPolygonTest
import dbReaders
import dbRegionTest
import dbTransTest
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(tlTest.TLTest)
suite = unittest.TestLoader().loadTestsFromTestCase(dbPCells.DBPCellTests)
suite = unittest.TestLoader().loadTestsFromTestCase(dbLayoutTest.DBLayoutTest)
suite = unittest.TestLoader().loadTestsFromTestCase(dbPolygonTest.DBPolygonTests)
suite = unittest.TestLoader().loadTestsFromTestCase(dbReaders.DBReadersTests)
suite = unittest.TestLoader().loadTestsFromTestCase(dbRegionTest.DBRegionTest)
suite = unittest.TestLoader().loadTestsFromTestCase(dbTransTest.DBTransTests)
if not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
sys.exit(1)