WIP: refined solution - some bug fixes, XML file is backward compatible now

This commit is contained in:
Matthias Koefferlein
2022-09-25 16:33:23 +02:00
parent 8919916da9
commit 511f55d4da
10 changed files with 363 additions and 82 deletions
@@ -435,6 +435,16 @@ public:
m_symbols.clear ();
}
void clear_connections ()
{
m_connections.clear ();
}
void clear_symbols ()
{
m_symbols.clear ();
}
void erase (iterator p)
{
m_connections.erase (p);
@@ -524,7 +534,7 @@ public:
const_iterator end () const
{
return m_connectivity.begin ();
return m_connectivity.end ();
}
iterator begin ()
@@ -68,26 +68,94 @@ namespace tl
namespace
{
template <class Value>
struct FallbackXMLWriteAdapator
static const db::NetTracerConnectivity *
get_default (const db::NetTracerTechnologyComponent &tc)
{
FallbackXMLWriteAdapator (void (db::NetTracerConnectivity::*member) (const Value &))
: mp_member (member)
for (auto d = tc.begin (); d != tc.end (); ++d) {
if (d->name ().empty ()) {
return d.operator-> ();
}
}
if (tc.begin () != tc.end ()) {
return tc.begin ().operator-> ();
} else {
return 0;
}
}
template <class Value>
struct FallbackXMLWriteAdaptor
{
FallbackXMLWriteAdaptor (void (db::NetTracerConnectivity::*member) (const Value &), void (db::NetTracerConnectivity::*clear) ())
: mp_member (member), mp_clear (clear), mp_stack (0)
{
// .. nothing yet ..
}
void operator () (db::NetTracerTechnologyComponent &owner, tl::XMLReaderState &reader) const
{
if (owner.size () == 0) {
owner.push_back (db::NetTracerConnectivity ());
if (! mp_stack) {
mp_stack = const_cast<db::NetTracerConnectivity *> (get_default (owner));
if (! mp_stack) {
owner.push_back (db::NetTracerConnectivity ());
mp_stack = (owner.end () - 1).operator-> ();
}
(mp_stack->*mp_clear) ();
}
tl::XMLObjTag<Value> tag;
((*owner.begin ()).*mp_member) (*reader.back (tag));
(mp_stack->*mp_member) (*reader.back (tag));
}
private:
void (db::NetTracerConnectivity::*mp_member) (const Value &);
void (db::NetTracerConnectivity::*mp_clear) ();
mutable db::NetTracerConnectivity *mp_stack;
};
template <class Value, class Iter>
struct FallbackXMLReadAdaptor
{
typedef tl::pass_by_ref_tag tag;
FallbackXMLReadAdaptor (Iter (db::NetTracerConnectivity::*begin) () const, Iter (db::NetTracerConnectivity::*end) () const)
: mp_begin (begin), mp_end (end)
{
// .. nothing yet ..
}
Value operator () () const
{
return *m_iter;
}
bool at_end () const
{
return m_iter == m_end;
}
void start (const db::NetTracerTechnologyComponent &parent)
{
const db::NetTracerConnectivity *tn = get_default (parent);
if (! tn) {
m_iter = Iter ();
m_end = Iter ();
} else {
m_iter = (tn->*mp_begin) ();
m_end = (tn->*mp_end) ();
}
}
void next ()
{
++m_iter;
}
private:
Iter (db::NetTracerConnectivity::*mp_begin) () const;
Iter (db::NetTracerConnectivity::*mp_end) () const;
Iter m_iter, m_end;
};
}
@@ -113,20 +181,20 @@ public:
virtual tl::XMLElementBase *xml_element () const
{
return new db::TechnologyComponentXMLElement<NetTracerTechnologyComponent> (net_tracer_component_name (),
// Fallback readers for migrating pre-0.28 setups to 0.28
tl::XMLMember<NetTracerConnectionInfo, NetTracerTechnologyComponent, tl::XMLMemberDummyReadAdaptor <NetTracerConnectionInfo, NetTracerTechnologyComponent>, FallbackXMLWriteAdapator <NetTracerConnectionInfo>, tl::XMLStdConverter <NetTracerConnectionInfo> > (
tl::XMLMemberDummyReadAdaptor <NetTracerConnectionInfo, NetTracerTechnologyComponent> (),
FallbackXMLWriteAdapator <NetTracerConnectionInfo> (&NetTracerConnectivity::add), "connection") +
tl::XMLMember<NetTracerSymbolInfo, NetTracerTechnologyComponent, tl::XMLMemberDummyReadAdaptor <NetTracerSymbolInfo, NetTracerTechnologyComponent>, FallbackXMLWriteAdapator <NetTracerSymbolInfo>, tl::XMLStdConverter <NetTracerSymbolInfo> > (
tl::XMLMemberDummyReadAdaptor <NetTracerSymbolInfo, NetTracerTechnologyComponent> (),
FallbackXMLWriteAdapator <NetTracerSymbolInfo> (&NetTracerConnectivity::add_symbol), "symbols") +
// 0.28 definitions
tl::make_element ((NetTracerTechnologyComponent::const_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::begin, (NetTracerTechnologyComponent::const_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::end, (void (NetTracerTechnologyComponent::*) (const NetTracerConnectivity &)) &NetTracerTechnologyComponent::push_back, "connectivity",
tl::make_element ((NetTracerTechnologyComponent::const_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::begin, (NetTracerTechnologyComponent::const_iterator (NetTracerTechnologyComponent::*) () const) &NetTracerTechnologyComponent::end, (void (NetTracerTechnologyComponent::*) (const NetTracerConnectivity &)) &NetTracerTechnologyComponent::push_back, "stack",
tl::make_member (&NetTracerConnectivity::name, &NetTracerConnectivity::set_name, "name") +
tl::make_member (&NetTracerConnectivity::description, &NetTracerConnectivity::set_description, "description") +
tl::make_member ((NetTracerConnectivity::const_iterator (NetTracerConnectivity::*) () const) &NetTracerConnectivity::begin, (NetTracerConnectivity::const_iterator (NetTracerConnectivity::*) () const) &NetTracerConnectivity::end, &NetTracerConnectivity::add, "connection") +
tl::make_member ((NetTracerConnectivity::const_symbol_iterator (NetTracerConnectivity::*) () const) &NetTracerConnectivity::begin_symbols, (NetTracerConnectivity::const_symbol_iterator (NetTracerConnectivity::*) () const) &NetTracerConnectivity::end_symbols, &NetTracerConnectivity::add_symbol, "symbols")
)
) +
// Fallback readers for migrating pre-0.28 setups to 0.28 and backward compatibility
tl::XMLMember<NetTracerConnectionInfo, NetTracerTechnologyComponent, FallbackXMLReadAdaptor <NetTracerConnectionInfo, NetTracerConnectivity::const_iterator>, FallbackXMLWriteAdaptor <NetTracerConnectionInfo>, tl::XMLStdConverter <NetTracerConnectionInfo> > (
FallbackXMLReadAdaptor <NetTracerConnectionInfo, NetTracerConnectivity::const_iterator> (&NetTracerConnectivity::begin, &NetTracerConnectivity::end),
FallbackXMLWriteAdaptor <NetTracerConnectionInfo> (&NetTracerConnectivity::add, &NetTracerConnectivity::clear_connections), "connection") +
tl::XMLMember<NetTracerSymbolInfo, NetTracerTechnologyComponent, FallbackXMLReadAdaptor <NetTracerSymbolInfo, NetTracerConnectivity::const_symbol_iterator>, FallbackXMLWriteAdaptor <NetTracerSymbolInfo>, tl::XMLStdConverter <NetTracerSymbolInfo> > (
FallbackXMLReadAdaptor <NetTracerSymbolInfo, NetTracerConnectivity::const_symbol_iterator> (&NetTracerConnectivity::begin_symbols, &NetTracerConnectivity::end_symbols),
FallbackXMLWriteAdaptor <NetTracerSymbolInfo> (&NetTracerConnectivity::add_symbol, &NetTracerConnectivity::clear_symbols), "symbols")
);
}
};
@@ -20,6 +20,12 @@
<enum>Qt::Horizontal</enum>
</property>
<widget class="QFrame" name="frame_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@@ -39,8 +45,11 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="4" column="4">
<item row="4" column="5">
<widget class="QToolButton" name="move_down_pb">
<property name="toolTip">
<string>Move selected stacks up</string>
</property>
<property name="text">
<string>...</string>
</property>
@@ -50,32 +59,24 @@
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QToolButton" name="del_pb">
<item row="4" column="0" colspan="2">
<widget class="QToolButton" name="add_pb">
<property name="toolTip">
<string>Add new stack</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../icons/icons.qrc">
<normaloff>:/del_16px.png</normaloff>:/del_16px.png</iconset>
<normaloff>:/add_16px.png</normaloff>:/add_16px.png</iconset>
</property>
<property name="shortcut">
<string>Del</string>
<string>Return</string>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QToolButton" name="move_up_pb">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../icons/icons.qrc">
<normaloff>:/up_16px.png</normaloff>:/up_16px.png</iconset>
</property>
</widget>
</item>
<item row="2" column="1" colspan="5">
<item row="2" column="1" colspan="6">
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
@@ -85,19 +86,7 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="6">
<widget class="QLabel" name="label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Double-click to edit text</string>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2" colspan="6">
<item row="1" column="0" rowspan="2" colspan="7">
<widget class="QTreeWidget" name="stack_tree">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@@ -105,9 +94,18 @@
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="contextMenuPolicy">
<enum>Qt::ActionsContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Name</string>
@@ -120,7 +118,50 @@
</column>
</widget>
</item>
<item row="4" column="5">
<item row="4" column="3">
<widget class="QToolButton" name="del_pb">
<property name="toolTip">
<string>Remove selected stacks</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../icons/icons.qrc">
<normaloff>:/del_16px.png</normaloff>:/del_16px.png</iconset>
</property>
<property name="shortcut">
<string>Del</string>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QToolButton" name="move_up_pb">
<property name="toolTip">
<string>Move selected stacks down</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../icons/icons.qrc">
<normaloff>:/up_16px.png</normaloff>:/up_16px.png</iconset>
</property>
</widget>
</item>
<item row="3" column="0" colspan="7">
<widget class="QLabel" name="label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Double-click to edit text</string>
</property>
</widget>
</item>
<item row="4" column="6">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -133,24 +174,24 @@
</property>
</spacer>
</item>
<item row="4" column="0" colspan="2">
<widget class="QToolButton" name="add_pb">
<item row="0" column="0" colspan="7">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Technology Stacks</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QToolButton" name="clone_pb">
<property name="toolTip">
<string>Clone current stack</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../icons/icons.qrc">
<normaloff>:/add_16px.png</normaloff>:/add_16px.png</iconset>
</property>
<property name="shortcut">
<string>Return</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="6">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Technology Stacks</string>
<normaloff>:/clone_16px.png</normaloff>:/clone_16px.png</iconset>
</property>
</widget>
</item>
@@ -135,8 +135,20 @@ NetTracerTechComponentEditor::NetTracerTechComponentEditor (QWidget *parent)
{
Ui::NetTracerTechComponentEditor::setupUi (this);
QAction *action;
action = new QAction (QObject::tr ("Add Stack"), this);
connect (action, SIGNAL (triggered ()), this, SLOT (add_clicked ()));
stack_tree->addAction (action);
action = new QAction (QObject::tr ("Delete Selected Stacks"), this);
connect (action, SIGNAL (triggered ()), this, SLOT (delete_clicked ()));
stack_tree->addAction (action);
action = new QAction (QObject::tr ("Duplicate Stack"), this);
connect (action, SIGNAL (triggered ()), this, SLOT (clone_clicked ()));
stack_tree->addAction (action);
connect (add_pb, SIGNAL (clicked ()), this, SLOT (add_clicked ()));
connect (del_pb, SIGNAL (clicked ()), this, SLOT (del_clicked ()));
connect (clone_pb, SIGNAL (clicked ()), this, SLOT (clone_clicked ()));
connect (move_up_pb, SIGNAL (clicked ()), this, SLOT (move_up_clicked ()));
connect (move_down_pb, SIGNAL (clicked ()), this, SLOT (move_down_clicked ()));
@@ -154,6 +166,7 @@ NetTracerTechComponentEditor::commit ()
return;
}
commit_current ();
*data = m_data;
}
@@ -175,6 +188,11 @@ NetTracerTechComponentEditor::setup ()
stack_tree->setItemDelegateForColumn (1, new NetTracerTechComponentColumnDelegate (stack_tree, &m_data));
update ();
if (stack_tree->topLevelItemCount () > 0) {
stack_tree->setCurrentItem (stack_tree->topLevelItem (0));
}
current_item_changed (stack_tree->currentItem (), 0);
}
void
@@ -207,7 +225,47 @@ NetTracerTechComponentEditor::commit_current (QTreeWidgetItem *current)
}
}
void
static std::string
new_name (const db::NetTracerTechnologyComponent &data)
{
for (int i = 1; ; ++i) {
std::string n = "STACK" + tl::to_string (i);
bool found = false;
for (auto d = data.begin (); d != data.end () && ! found; ++d) {
found = (d->name () == n);
}
if (! found) {
return n;
}
}
return std::string ();
}
void
NetTracerTechComponentEditor::clone_clicked ()
{
// removes focus from the tree view - commits the data
add_pb->setFocus ();
commit_current ();
int row = stack_tree->currentItem () ? stack_tree->indexOfTopLevelItem (stack_tree->currentItem ()) : -1;
if (row < 0) {
m_data.push_back (db::NetTracerConnectivity ());
row = int (m_data.size () - 1);
} else {
row += 1;
m_data.insert (m_data.begin () + row, db::NetTracerConnectivity ());
m_data.begin ()[row] = m_data.begin ()[row - 1];
}
m_data.begin ()[row].set_name (new_name (m_data));
update ();
stack_tree->setCurrentItem (stack_tree->topLevelItem (row));
}
void
NetTracerTechComponentEditor::add_clicked ()
{
// removes focus from the tree view - commits the data
@@ -223,6 +281,8 @@ NetTracerTechComponentEditor::add_clicked ()
m_data.insert (m_data.begin () + row, db::NetTracerConnectivity ());
}
m_data.begin ()[row].set_name (new_name (m_data));
update ();
stack_tree->setCurrentItem (stack_tree->topLevelItem (row));
}
@@ -355,16 +415,12 @@ NetTracerTechComponentEditor::update ()
} else {
item->setData (0, Qt::DisplayRole, QVariant (tl::to_qstring (name)));
}
item->setData (1, Qt::DisplayRole, QVariant (tl::to_qstring (l->description ())));
item->setData (0, Qt::UserRole, QVariant (n));
}
item->setData (1, Qt::DisplayRole, QVariant (tl::to_qstring (l->description ())));
item->setData (1, Qt::UserRole, QVariant (n));
if (! stack_tree->currentItem () && stack_tree->topLevelItemCount () > 0) {
stack_tree->setCurrentItem (stack_tree->topLevelItem (0));
}
current_item_changed (stack_tree->currentItem (), 0);
}
}
@@ -62,6 +62,7 @@ public:
public slots:
void add_clicked ();
void clone_clicked ();
void del_clicked ();
void move_up_clicked ();
void move_down_clicked ();