diff --git a/src/plugins/tools/net_tracer/lay_plugin/NetTracerConnectivityEditor.ui b/src/plugins/tools/net_tracer/lay_plugin/NetTracerConnectivityEditor.ui new file mode 100644 index 000000000..62af9ff85 --- /dev/null +++ b/src/plugins/tools/net_tracer/lay_plugin/NetTracerConnectivityEditor.ui @@ -0,0 +1,343 @@ + + + NetTracerConnectivityEditor + + + + 0 + 0 + 572 + 449 + + + + Form + + + + 6 + + + 9 + + + + + Qt::Vertical + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + + + <html>Connectivity (<a href="int:/about/connectivity.xml">See here for details</a>)</html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 6 + + + + + ... + + + + :/down_16px.png:/down_16px.png + + + + + + + ... + + + + :/del_16px.png:/del_16px.png + + + Del + + + + + + + QAbstractItemView::AllEditTriggers + + + true + + + QAbstractItemView::SelectRows + + + 3 + + + + + + + + + + ... + + + + :/add_16px.png:/add_16px.png + + + Return + + + + + + + Qt::Vertical + + + + 20 + 131 + + + + + + + + ... + + + + :/up_16px.png:/up_16px.png + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + + + <html>Computed and symbolic layers (<a href="int:/about/symbolic_layers.xml">See here for details</a>)</html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 6 + + + + + ... + + + + :/down_16px.png:/down_16px.png + + + + + + + ... + + + + :/del_16px.png:/del_16px.png + + + Del + + + + + + + QAbstractItemView::AllEditTriggers + + + true + + + QAbstractItemView::SelectRows + + + 2 + + + + + + + + + ... + + + + :/add_16px.png:/add_16px.png + + + Return + + + + + + + Qt::Vertical + + + + 20 + 131 + + + + + + + + ... + + + + :/up_16px.png:/up_16px.png + + + + + + + + + + + + + + + + + diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerTechComponentEditor.cc b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerTechComponentEditor.cc new file mode 100644 index 000000000..3d8293d78 --- /dev/null +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerTechComponentEditor.cc @@ -0,0 +1,310 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2022 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "layNetTracerTechComponentEditor.h" +#include "layNetTracerConfig.h" + +#include "layConfigurationDialog.h" +#include "laybasicConfig.h" +#include "layConverters.h" +#include "layFinder.h" +#include "layLayoutView.h" +#include "layTechSetupDialog.h" +#include "layFileDialog.h" +#include "layQtTools.h" +#include "tlExceptions.h" +#include "tlXMLWriter.h" +#include "tlUtils.h" +#include "gsiDecl.h" + +#include +#include +#include +#include +#include + +#include +#include + +namespace lay +{ + +// @@@ TODO: edit on double-click + +// ----------------------------------------------------------------------------------- +// NetTracerTechComponentEditor implementation + +NetTracerTechComponentEditor::NetTracerTechComponentEditor (QWidget *parent) + : TechnologyComponentEditor (parent) +{ + Ui::NetTracerTechComponentEditor::setupUi (this); + + connect (add_pb, SIGNAL (clicked ()), this, SLOT (add_clicked ())); + connect (del_pb, SIGNAL (clicked ()), this, SLOT (del_clicked ())); + connect (move_up_pb, SIGNAL (clicked ()), this, SLOT (move_up_clicked ())); + connect (move_down_pb, SIGNAL (clicked ()), this, SLOT (move_down_clicked ())); + + stack_tree->header ()->setHighlightSections (false); + stack_tree->header ()->setStretchLastSection (true); + + connect (stack_tree, SIGNAL (currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT (current_item_changed(QTreeWidgetItem *, QTreeWidgetItem *))); + connect (stack_tree, SIGNAL (itemChanged(QTreeWidgetItem *, int)), this, SLOT (item_changed(QTreeWidgetItem *, int))); +} + +void +NetTracerTechComponentEditor::commit () +{ + db::NetTracerTechnologyComponent *data = dynamic_cast (tech_component ()); + if (! data) { + return; + } + + *data = m_data; +} + +void +NetTracerTechComponentEditor::setup () +{ + db::NetTracerTechnologyComponent *data = dynamic_cast (tech_component ()); + if (! data) { + return; + } + + m_data = *data; + + if (m_data.size () == 0) { + m_data.push_back (db::NetTracerConnectivity ()); + } + + update (); +} + +void +NetTracerTechComponentEditor::item_changed (QTreeWidgetItem *item, int column) +{ + int row = stack_tree->indexOfTopLevelItem (item); + if (row >= 0 && row < int (m_data.size ())) { + if (column == 0) { + std::string n = tl::to_string (item->data (column, Qt::EditRole)); + m_data.begin ()[row].set_name (n); + if (n.empty ()) { + item->setData (column, Qt::DisplayRole, tr ("(default)")); + } else { + item->setData (column, Qt::DisplayRole, tl::to_qstring (n)); + } + } + if (column == 1) { + m_data.begin ()[row].set_description (tl::to_string (item->data (column, Qt::EditRole))); + } + } +} + +void +NetTracerTechComponentEditor::current_item_changed (QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + commit_current (previous); + + int row = current ? stack_tree->indexOfTopLevelItem (current) : -1; + if (row < 0 || row >= int (m_data.size ())) { + connectivity_editor_widget->set_connectivity (db::NetTracerConnectivity ()); + connectivity_editor_widget->hide (); + } else { + connectivity_editor_widget->set_connectivity (m_data.begin ()[row]); + connectivity_editor_widget->show (); + } +} + +void +NetTracerTechComponentEditor::commit_current () +{ + commit_current (stack_tree->currentItem ()); +} + +void +NetTracerTechComponentEditor::commit_current (QTreeWidgetItem *current) +{ + int row = current ? stack_tree->indexOfTopLevelItem (current) : -1; + if (row >= 0 && row < int (m_data.size ())) { + m_data.begin () [row] = connectivity_editor_widget->get_connectiviy (); + } +} + +void +NetTracerTechComponentEditor::add_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 ()); + } + + update (); + stack_tree->setCurrentItem (stack_tree->topLevelItem (row)); +} + +void +NetTracerTechComponentEditor::del_clicked () +{ + // removes focus from the tree view - commits the data + del_pb->setFocus (); + commit_current (); + + std::set selected_rows; + QModelIndexList selected_indices = stack_tree->selectionModel ()->selectedIndexes (); + for (auto i = selected_indices.begin (); i != selected_indices.end (); ++i) { + selected_rows.insert (i->row ()); + } + + stack_tree->setCurrentIndex (QModelIndex ()); + + int offset = 0; + for (std::set::const_iterator r = selected_rows.begin (); r != selected_rows.end (); ++r) { + m_data.erase (m_data.begin () + (*r - offset)); + ++offset; + } + + update (); +} + +void +NetTracerTechComponentEditor::move_up_clicked () +{ + // removes focus from the tree view - commits the data + move_up_pb->setFocus (); + commit_current (); + + std::set selected_rows; + QModelIndexList selected_indices = stack_tree->selectionModel ()->selectedIndexes (); + for (auto i = selected_indices.begin (); i != selected_indices.end (); ++i) { + selected_rows.insert (i->row ()); + } + + QTreeWidgetItem *current = stack_tree->currentItem (); + int n_current = current ? current->data (0, Qt::UserRole).toInt () : -1; + + stack_tree->setCurrentIndex (QModelIndex ()); + + int n = 0; + for (db::NetTracerTechnologyComponent::iterator l = m_data.begin (); l != m_data.end (); ++l, ++n) { + if (selected_rows.find (n + 1) != selected_rows.end () && selected_rows.find (n) == selected_rows.end ()) { + std::swap (m_data.begin () [n + 1], m_data.begin () [n]); + selected_rows.erase (n + 1); + selected_rows.insert (n); + if (n_current == n + 1) { + n_current = n; + } + } + } + + update (); + + // select the new items + for (std::set ::const_iterator s = selected_rows.begin (); s != selected_rows.end (); ++s) { + stack_tree->selectionModel ()->select (stack_tree->model ()->index (*s, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); + } + + if (n_current >= 0) { + stack_tree->selectionModel ()->select (stack_tree->model ()->index (n_current, 0), QItemSelectionModel::Current | QItemSelectionModel::Rows); + } +} + +void +NetTracerTechComponentEditor::move_down_clicked () +{ + // removes focus from the tree view - commits the data + move_down_pb->setFocus (); + commit_current (); + + std::set selected_rows; + QModelIndexList selected_indices = stack_tree->selectionModel ()->selectedIndexes (); + for (auto i = selected_indices.begin (); i != selected_indices.end (); ++i) { + selected_rows.insert (i->row ()); + } + + QTreeWidgetItem *current = stack_tree->currentItem (); + int n_current = current ? current->data (0, Qt::UserRole).toInt () : -1; + + stack_tree->setCurrentIndex (QModelIndex ()); + + int n = int (m_data.size ()); + for (db::NetTracerTechnologyComponent::iterator l = m_data.end (); l != m_data.begin (); ) { + --l; + --n; + if (selected_rows.find (n - 1) != selected_rows.end () && selected_rows.find (n) == selected_rows.end ()) { + std::swap (m_data.begin () [n - 1], m_data.begin () [n]); + selected_rows.erase (n - 1); + selected_rows.insert (n); + if (n_current == n - 1) { + n_current = n; + } + } + } + + update (); + + // select the new items + for (std::set ::const_iterator s = selected_rows.begin (); s != selected_rows.end (); ++s) { + stack_tree->selectionModel ()->select (stack_tree->model ()->index (*s, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); + } + + if (n_current >= 0) { + stack_tree->selectionModel ()->select (stack_tree->model ()->index (n_current, 0), QItemSelectionModel::Current | QItemSelectionModel::Rows); + } +} + +void +NetTracerTechComponentEditor::update () +{ + stack_tree->clear (); + stack_tree->clearSelection (); + + int n = 0; + for (db::NetTracerTechnologyComponent::iterator l = m_data.begin (); l != m_data.end (); ++l, ++n) { + + QTreeWidgetItem *item = new QTreeWidgetItem (stack_tree); + item->setFlags (item->flags () | Qt::ItemIsEditable); + + if (l->name ().empty ()) { + item->setData (0, Qt::DisplayRole, QVariant (tr ("(default)"))); + } else { + item->setData (0, Qt::DisplayRole, QVariant (tl::to_qstring (l->name ()))); + } + item->setData (0, Qt::EditRole, QVariant (tl::to_qstring (l->name ()))); + item->setData (1, Qt::DisplayRole, QVariant (tl::to_qstring (l->description ()))); + + item->setData (0, Qt::UserRole, QVariant (n)); + + } + + current_item_changed (0, 0); +} + +} + diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerTechComponentEditor.h b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerTechComponentEditor.h new file mode 100644 index 000000000..db802fe6b --- /dev/null +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerTechComponentEditor.h @@ -0,0 +1,81 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2022 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + + +#ifndef HDR_layNetTracerTechComponentEditor +#define HDR_layNetTracerTechComponentEditor + +#include "ui_NetTracerTechComponentEditor.h" + +#include "dbNetTracer.h" +#include "dbNetTracerIO.h" +#include "dbTechnology.h" + +#include "layNetTracerConfig.h" +#include "layBrowser.h" +#include "layPlugin.h" +#include "layViewObject.h" +#include "layMarker.h" +#include "layTechnology.h" + +#include "tlObject.h" + +namespace db +{ + class NetTracerTechnologyComponent; +} + +namespace lay +{ + +class NetTracerTechComponentEditor + : public lay::TechnologyComponentEditor, + public Ui::NetTracerTechComponentEditor +{ +Q_OBJECT + +public: + NetTracerTechComponentEditor (QWidget *parent); + + void commit (); + void setup (); + +public slots: + void add_clicked (); + void del_clicked (); + void move_up_clicked (); + void move_down_clicked (); + void current_item_changed (QTreeWidgetItem *current, QTreeWidgetItem *previous); + void item_changed (QTreeWidgetItem *item, int column); +private: + db::NetTracerTechnologyComponent m_data; + + void update (); + void commit_current (QTreeWidgetItem *current); + void commit_current (); +}; + +} + +#endif +