From a0be1256bc216409978a0a4660cac0f76c16b07d Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 1 Jun 2024 20:17:56 +0200 Subject: [PATCH] Adding context menu of query to export selected items only --- src/lay/lay/laySearchReplaceDialog.cc | 172 +++++++++++++++++++++++--- src/lay/lay/laySearchReplaceDialog.h | 12 +- 2 files changed, 162 insertions(+), 22 deletions(-) diff --git a/src/lay/lay/laySearchReplaceDialog.cc b/src/lay/lay/laySearchReplaceDialog.cc index 3c4d81250..67fa17390 100644 --- a/src/lay/lay/laySearchReplaceDialog.cc +++ b/src/lay/lay/laySearchReplaceDialog.cc @@ -459,7 +459,7 @@ escape_csv (const std::string &s) } void -SearchReplaceResults::select_items (lay::LayoutViewBase *view, int cv_index) +SearchReplaceResults::select_items (lay::LayoutViewBase *view, int cv_index, const std::set *rows) { const lay::CellView &cv = view->cellview (cv_index); const db::Layout &layout = cv->layout (); @@ -469,6 +469,10 @@ SearchReplaceResults::select_items (lay::LayoutViewBase *view, int cv_index) int n_rows = int (size ()); for (int r = 0; r < n_rows; ++r) { + if (rows && rows->find (r) == rows->end ()) { + continue; + } + if (r < int (shapes ().size ())) { const SearchReplaceResults::QueryShapeResult &sr = shapes () [r]; @@ -519,7 +523,7 @@ SearchReplaceResults::select_items (lay::LayoutViewBase *view, int cv_index) } void -SearchReplaceResults::export_csv (const std::string &file) +SearchReplaceResults::export_csv (const std::string &file, const std::set *rows) { std::ofstream output (file.c_str ()); @@ -538,21 +542,25 @@ SearchReplaceResults::export_csv (const std::string &file) for (size_t r = 0; r < n_rows; ++r) { - for (size_t c = 0; c < n_columns; ++c) { - if (c) { - output << ","; - } - // TODO: optimize - output << escape_csv (tl::to_string (data (index (int (r), int (c), parent), Qt::DisplayRole).toString ())); - } + if (! rows || rows->find (r) != rows->end ()) { - output << std::endl; + for (size_t c = 0; c < n_columns; ++c) { + if (c) { + output << ","; + } + // TODO: optimize + output << escape_csv (tl::to_string (data (index (int (r), int (c), parent), Qt::DisplayRole).toString ())); + } + + output << std::endl; + + } } } void -SearchReplaceResults::export_layout (db::Layout &layout) +SearchReplaceResults::export_layout (db::Layout &layout, const std::set *rows) { if (! m_data_result.empty () || ! m_cell_result.empty () || ! m_inst_result.empty ()) { throw tl::Exception (tl::to_string (QObject::tr ("Query produces something other than shapes - such results cannot be converted to layout currently."))); @@ -561,7 +569,12 @@ SearchReplaceResults::export_layout (db::Layout &layout) db::Cell &top_cell = layout.cell (layout.add_cell ("RESULTS")); db::LayerMap insert_lm; - for (std::vector::const_iterator s = m_shape_result.begin (); s != m_shape_result.end (); ++s) { + int r = 0; + for (std::vector::const_iterator s = m_shape_result.begin (); s != m_shape_result.end (); ++s, ++r) { + + if (rows && rows->find (r) == rows->end ()) { + continue; + } unsigned int layer = s->layer_index; std::map::const_iterator lm = m_lp_map.find (layer); @@ -584,7 +597,7 @@ SearchReplaceResults::export_layout (db::Layout &layout) } void -SearchReplaceResults::export_rdb (rdb::Database &rdb, double dbu) +SearchReplaceResults::export_rdb (rdb::Database &rdb, double dbu, const std::set *rows) { if (! m_cell_result.empty ()) { @@ -595,7 +608,12 @@ SearchReplaceResults::export_rdb (rdb::Database &rdb, double dbu) rdb::Category *cat = rdb.create_category ("data"); rdb::Cell *cell = rdb.create_cell (rdb.top_cell_name ()); - for (std::vector::const_iterator v = m_data_result.begin (); v != m_data_result.end (); ++v) { + int r = 0; + for (std::vector::const_iterator v = m_data_result.begin (); v != m_data_result.end (); ++v, ++r) { + + if (rows && rows->find (r) == rows->end ()) { + continue; + } rdb::Item *item = rdb.create_item (cell->id (), cat->id ()); @@ -621,7 +639,12 @@ SearchReplaceResults::export_rdb (rdb::Database &rdb, double dbu) } } - for (std::vector::const_iterator i = m_inst_result.begin (); i != m_inst_result.end (); ++i) { + int r = 0; + for (std::vector::const_iterator i = m_inst_result.begin (); i != m_inst_result.end (); ++i, ++r) { + + if (rows && rows->find (r) == rows->end ()) { + continue; + } std::map, rdb::Cell *>::const_iterator v = cells_by_variant.find (std::make_pair (i->cell_index, db::CplxTrans (i->trans))); if (v == cells_by_variant.end ()) { @@ -649,7 +672,13 @@ SearchReplaceResults::export_rdb (rdb::Database &rdb, double dbu) // create categories std::map categories; - for (std::vector::const_iterator s = m_shape_result.begin (); s != m_shape_result.end (); ++s) { + + int r = 0; + for (std::vector::const_iterator s = m_shape_result.begin (); s != m_shape_result.end (); ++s, ++r) { + + if (rows && rows->find (r) == rows->end ()) { + continue; + } unsigned int layer = s->layer_index; std::map::const_iterator lm = m_lp_map.find (layer); @@ -670,7 +699,12 @@ SearchReplaceResults::export_rdb (rdb::Database &rdb, double dbu) } } - for (std::vector::const_iterator s = m_shape_result.begin (); s != m_shape_result.end (); ++s) { + r = 0; + for (std::vector::const_iterator s = m_shape_result.begin (); s != m_shape_result.end (); ++s, ++r) { + + if (rows && rows->find (r) == rows->end ()) { + continue; + } unsigned int layer = s->layer_index; std::map::const_iterator cm = categories.find (layer); @@ -812,9 +846,15 @@ SearchReplaceDialog::SearchReplaceDialog (lay::Dispatcher *root, LayoutViewBase menu->addAction (QObject::tr ("To CSV file"), this, SLOT (export_csv ())); menu->addAction (QObject::tr ("To report database"), this, SLOT (export_rdb ())); menu->addAction (QObject::tr ("To layout"), this, SLOT (export_layout ())); - menu->addAction (QObject::tr ("Select items"), this, SLOT (select_items ())); + menu->addAction (QObject::tr ("To selection"), this, SLOT (select_items ())); export_b->setMenu (menu); + results->addAction (QObject::tr ("Export to CSV file"), this, SLOT (sel_export_csv ())); + results->addAction (QObject::tr ("Export to report database"), this, SLOT (sel_export_rdb ())); + results->addAction (QObject::tr ("Export to layout"), this, SLOT (sel_export_layout ())); + results->addAction (QObject::tr ("Export to selection"), this, SLOT (sel_select_items ())); + results->setContextMenuPolicy (Qt::ActionsContextMenu); + bool editable = view->is_editable (); mode_tab->setTabEnabled (replace_mode_index, editable); mode_tab->setTabEnabled (delete_mode_index, editable); @@ -995,6 +1035,28 @@ SearchReplaceDialog::save_state () } } +void +SearchReplaceDialog::sel_select_items () +{ +BEGIN_PROTECTED + + int cv_index = m_last_query_cv_index; + const lay::CellView &cv = mp_view->cellview (cv_index); + if (! cv.is_valid ()) { + return; + } + + std::set rows; + QModelIndexList sel = results->selectionModel ()->selectedRows (0); + for (auto s = sel.begin (); s != sel.end (); ++s) { + rows.insert (s->row ()); + } + + m_model.select_items (view (), cv_index, &rows); + +END_PROTECTED +} + void SearchReplaceDialog::select_items () { @@ -1027,6 +1089,29 @@ BEGIN_PROTECTED END_PROTECTED } +void +SearchReplaceDialog::sel_export_csv () +{ +BEGIN_PROTECTED + + std::set rows; + QModelIndexList sel = results->selectionModel ()->selectedRows (0); + for (auto s = sel.begin (); s != sel.end (); ++s) { + rows.insert (s->row ()); + } + + std::string fn; + + lay::FileDialog file_dialog (this, tl::to_string (QObject::tr ("Export CSV")), tl::to_string (QObject::tr ("CSV Files (*.csv);;All Files (*)")), "csv"); + if (! file_dialog.get_save (fn)) { + return; + } + + m_model.export_csv (fn, &rows); + +END_PROTECTED +} + void SearchReplaceDialog::export_csv () { @@ -1066,6 +1151,38 @@ BEGIN_PROTECTED END_PROTECTED } +void +SearchReplaceDialog::sel_export_rdb () +{ +BEGIN_PROTECTED + + int cv_index = m_last_query_cv_index; + const lay::CellView &cv = mp_view->cellview (cv_index); + if (! cv.is_valid ()) { + return; + } + + std::set rows; + QModelIndexList sel = results->selectionModel ()->selectedRows (0); + for (auto s = sel.begin (); s != sel.end (); ++s) { + rows.insert (s->row ()); + } + + std::unique_ptr rdb (new rdb::Database ()); + + rdb->set_description (tl::to_string (QObject::tr ("Query results: ")) + m_last_query); + rdb->set_name ("query_results"); + rdb->set_generator ("query: " + m_last_query); + rdb->set_top_cell_name (cv->layout ().cell_name (cv.cell_index ())); + + m_model.export_rdb (*rdb, cv->layout ().dbu (), &rows); + + int rdb_index = mp_view->add_rdb (rdb.release ()); + mp_view->open_rdb_browser (rdb_index, cv_index); + +END_PROTECTED +} + void SearchReplaceDialog::export_rdb () { @@ -1108,6 +1225,25 @@ BEGIN_PROTECTED END_PROTECTED } +void +SearchReplaceDialog::sel_export_layout () +{ +BEGIN_PROTECTED + + std::set rows; + QModelIndexList sel = results->selectionModel ()->selectedRows (0); + for (auto s = sel.begin (); s != sel.end (); ++s) { + rows.insert (s->row ()); + } + + std::unique_ptr handle (new lay::LayoutHandle (new db::Layout (mp_view->manager ()), std::string ())); + handle->rename ("query_results"); + m_model.export_layout (handle->layout (), &rows); + mp_view->add_layout (handle.release (), true); + +END_PROTECTED +} + void SearchReplaceDialog::export_layout () { diff --git a/src/lay/lay/laySearchReplaceDialog.h b/src/lay/lay/laySearchReplaceDialog.h index 5ca3a224c..48f7ddd88 100644 --- a/src/lay/lay/laySearchReplaceDialog.h +++ b/src/lay/lay/laySearchReplaceDialog.h @@ -156,10 +156,10 @@ public: int rowCount (const QModelIndex &parent) const; void has_more (bool hm); - void export_csv (const std::string &file); - void export_layout (db::Layout &layout); - void export_rdb (rdb::Database &rdb, double dbu); - void select_items (LayoutViewBase *view, int cv_index); + void export_csv (const std::string &file, const std::set *rows = 0); + void export_layout (db::Layout &layout, const std::set *rows = 0); + void export_rdb (rdb::Database &rdb, double dbu, const std::set *rows = 0); + void select_items (LayoutViewBase *view, int cv_index, const std::set *rows = 0); private: std::vector m_data_result; @@ -241,6 +241,10 @@ private slots: void export_csv (); void export_rdb (); void export_layout (); + void sel_select_items (); + void sel_export_csv (); + void sel_export_rdb (); + void sel_export_layout (); private: std::string build_find_expression (QStackedWidget *prop_page, QComboBox *context);