Convenience: copy cells now has an option to mute the dialog (shallow/deep) and the dialog is only shown if there are subcells

This commit is contained in:
Matthias Koefferlein 2024-07-20 00:03:43 +02:00
parent ee07e4b3b9
commit 915cc53195
13 changed files with 241 additions and 68 deletions

View File

@ -462,7 +462,7 @@ Service::copy_selected ()
for (EditableSelectionIterator r = begin_selection (); ! r.at_end () && ! need_to_ask_for_copy_mode; ++r) {
if (r->is_cell_inst ()) {
const db::Cell &cell = view ()->cellview (r->cv_index ())->layout ().cell (r->back ().inst_ptr.cell_index ());
if (! cell.is_proxy ()) {
if (! cell.is_proxy () && ! cell.is_leaf ()) {
need_to_ask_for_copy_mode = true;
}
}

View File

@ -122,6 +122,7 @@ public:
options.push_back (std::pair<std::string, std::string> (cfg_line_style_palette, lay::LineStylePalette ().to_string ()));
options.push_back (std::pair<std::string, std::string> (cfg_no_stipple, "false"));
options.push_back (std::pair<std::string, std::string> (cfg_markers_visible, "true"));
options.push_back (std::pair<std::string, std::string> (cfg_copy_cell_mode, "-1"));
}
};

View File

@ -132,6 +132,7 @@ static const std::string cfg_default_font_size ("default-font-size");
static const std::string cfg_hide_empty_layers ("hide-empty-layers");
static const std::string cfg_test_shapes_in_view ("test-shapes-in-view");
static const std::string cfg_copy_cell_mode ("copy-cell-mode");
static const std::string cfg_flat_cell_list ("flat-cell-list");
static const std::string cfg_split_cell_list ("split-cell-list");
static const std::string cfg_cell_list_sorting ("cell-list-sorting");

View File

@ -1,46 +1,41 @@
<ui version="4.0" >
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CopyCellModeDialog</class>
<widget class="QDialog" name="CopyCellModeDialog" >
<property name="geometry" >
<widget class="QDialog" name="CopyCellModeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>178</height>
<width>546</width>
<height>198</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Copy Cell Options</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Copy Cell Mode</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin" stdset="0">
<number>9</number>
</property>
<item>
<widget class="QRadioButton" name="shallow_rb" >
<property name="text" >
<widget class="QRadioButton" name="shallow_rb">
<property name="text">
<string>Shallow copy (don't copy subcells)</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="deep_rb" >
<property name="text" >
<widget class="QRadioButton" name="deep_rb">
<property name="text">
<string>Deep copy (include subcells)</string>
</property>
</widget>
@ -48,12 +43,19 @@
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="dont_ask_cbx">
<property name="text">
<string>Don't ask again (you can always reset this in Setup: Application/Cells page)</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>382</width>
<height>31</height>
@ -62,12 +64,12 @@
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
@ -86,11 +88,11 @@
<receiver>CopyCellModeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
@ -102,11 +104,11 @@
<receiver>CopyCellModeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LayoutViewConfigPage8</class>
<widget class="QWidget" name="LayoutViewConfigPage8">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>414</width>
<height>46</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Cell copy mode</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="hier_copy_mode_cbx">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Shallow mode (cell only)</string>
</property>
</item>
<item>
<property name="text">
<string>Deep mode (cell and subcells)</string>
</property>
</item>
<item>
<property name="text">
<string>Ask</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -579,7 +579,7 @@ CopyCellModeDialog::~CopyCellModeDialog ()
}
bool
CopyCellModeDialog::exec_dialog (int &copy_mode)
CopyCellModeDialog::exec_dialog (int &copy_mode, bool &dont_ask)
{
QRadioButton *buttons [] = { mp_ui->shallow_rb, mp_ui->deep_rb };
@ -592,6 +592,7 @@ CopyCellModeDialog::exec_dialog (int &copy_mode)
if (buttons [i]->isChecked ()) {
copy_mode = i;
}
dont_ask = mp_ui->dont_ask_cbx->isChecked ();
}
return true;
} else {

View File

@ -233,7 +233,7 @@ public:
*
* The mode is either 0 (for shallow), 1 (for deep)
*/
bool exec_dialog (int &copy_mode);
bool exec_dialog (int &copy_mode, bool &dont_ask_again);
private:
Ui::CopyCellModeDialog *mp_ui;

View File

@ -218,6 +218,7 @@ HierarchyControlPanel::HierarchyControlPanel (lay::LayoutViewBase *view, QWidget
m_flat (false),
m_split_mode (false),
m_sorting (CellTreeModel::ByName),
m_cell_copy_mode (-1),
m_do_update_content_dm (this, &HierarchyControlPanel::do_update_content),
m_do_full_update_content_dm (this, &HierarchyControlPanel::do_full_update_content)
{
@ -398,6 +399,12 @@ HierarchyControlPanel::clear_all ()
mp_cell_lists.clear ();
}
void
HierarchyControlPanel::set_cell_copy_mode (int m)
{
m_cell_copy_mode = m;
}
void
HierarchyControlPanel::set_flat (bool f)
{
@ -1002,6 +1009,47 @@ HierarchyControlPanel::has_focus () const
return m_active_index >= 0 && m_active_index < int (mp_cell_lists.size ()) && mp_cell_lists [m_active_index]->hasFocus ();
}
bool
HierarchyControlPanel::ask_for_cell_copy_mode (const db::Layout &layout, const std::vector<cell_path_type> &paths, int &cell_copy_mode)
{
bool needs_to_ask = false;
cell_copy_mode = 0;
if (m_cell_copy_mode < 0) { // ask
// check if there is a cell that we have to ask for
for (std::vector<cell_path_type>::const_iterator p = paths.begin (); p != paths.end (); ++p) {
if (! p->empty ()) {
const db::Cell &cell = layout.cell (p->back ());
if (! cell.is_proxy () && ! cell.is_leaf ()) {
needs_to_ask = true;
}
}
}
} else {
cell_copy_mode = m_cell_copy_mode;
}
if (needs_to_ask) {
bool dont_ask_again = false;
lay::CopyCellModeDialog mode_dialog (this);
if (! mode_dialog.exec_dialog (cell_copy_mode, dont_ask_again)) {
return false;
}
if (dont_ask_again) {
view ()->dispatcher ()->config_set (cfg_copy_cell_mode, tl::to_string (cell_copy_mode));
view ()->dispatcher ()->config_end ();
}
}
return true;
}
void
HierarchyControlPanel::cut ()
{
@ -1017,34 +1065,25 @@ HierarchyControlPanel::cut ()
}
// first copy
bool needs_to_ask = false;
db::Layout &layout = m_cellviews [m_active_index]->layout ();
if (! layout.is_editable ()) {
return;
}
// collect the called cells of the cells to copy, so we don't copy a cell twice
db::Clipboard::instance ().clear ();
// don't copy the cells which would be copied anyway
int cut_mode = 1; // 0: shallow, 1: deep
if (! ask_for_cell_copy_mode (layout, paths, cut_mode)) {
return;
}
// collect the called cells of the cells to copy, so we don't copy a cell twice
std::set<db::cell_index_type> called_cells;
for (std::vector<cell_path_type>::const_iterator p = paths.begin (); p != paths.end (); ++p) {
if (! p->empty ()) {
const db::Cell &cell = layout.cell (p->back ());
cell.collect_called_cells (called_cells);
if (cell.cell_instances () > 0) {
needs_to_ask = true;
}
}
}
int cut_mode = 1; // 0: shallow, 1: deep
if (needs_to_ask) {
lay::CopyCellModeDialog mode_dialog (this);
if (! mode_dialog.exec_dialog (cut_mode)) {
return;
}
}
@ -1115,34 +1154,25 @@ HierarchyControlPanel::copy ()
return;
}
bool needs_to_ask = false;
db::Layout &layout = m_cellviews [m_active_index]->layout ();
// collect the called cells of the cells to copy, so we don't copy a cell twice
db::Clipboard::instance ().clear ();
// don't copy the cells which would be copied anyway
int copy_mode = 1; // 0: shallow, 1: deep
if (! ask_for_cell_copy_mode (layout, paths, copy_mode)) {
return;
}
// collect the called cells of the cells to copy, so we don't copy a cell twice
std::set<db::cell_index_type> called_cells;
for (std::vector<cell_path_type>::const_iterator p = paths.begin (); p != paths.end (); ++p) {
if (! p->empty ()) {
const db::Cell &cell = layout.cell (p->back ());
cell.collect_called_cells (called_cells);
if (cell.cell_instances () > 0) {
needs_to_ask = true;
}
}
}
int copy_mode = 1; // 0: shallow, 1: deep
if (needs_to_ask) {
lay::CopyCellModeDialog mode_dialog (this);
if (! mode_dialog.exec_dialog (copy_mode)) {
return;
}
}
// actually copy
for (std::vector<cell_path_type>::const_iterator p = paths.begin (); p != paths.end (); ++p) {
if (! p->empty () && called_cells.find (p->back ()) == called_cells.end ()) {
db::ClipboardValue<lay::CellClipboardData> *cd = new db::ClipboardValue<lay::CellClipboardData> ();

View File

@ -219,6 +219,12 @@ public:
*/
void paste ();
/**
* @brief Selects cell copy mode
* 0: shallow, 1: deep, -1: ask
*/
void set_cell_copy_mode (int m);
/**
* @brief Return true, if the panel has a selection
*/
@ -308,6 +314,7 @@ private:
QSplitter *mp_splitter;
tl::Color m_background_color;
tl::Color m_text_color;
int m_cell_copy_mode;
tl::DeferredMethod<HierarchyControlPanel> m_do_update_content_dm;
tl::DeferredMethod<HierarchyControlPanel> m_do_full_update_content_dm;
std::unique_ptr<QStyle> mp_tree_style;
@ -336,6 +343,9 @@ private:
// clears all widgets of the cell lists
void clear_all ();
// ask for cell copy mode
bool ask_for_cell_copy_mode (const db::Layout &layout, const std::vector<cell_path_type> &paths, int &cell_copy_mode);
};
} // namespace lay

View File

@ -42,6 +42,7 @@
#include "ui_LayoutViewConfigPage6.h"
#include "ui_LayoutViewConfigPage6a.h"
#include "ui_LayoutViewConfigPage7.h"
#include "ui_LayoutViewConfigPage8.h"
#include "laySelectStippleForm.h"
#include "laySelectLineStyleForm.h"
@ -1529,6 +1530,37 @@ LayoutViewConfigPage7::commit (lay::Dispatcher *root)
root->config_set (cfg_initial_hier_depth, mp_ui->def_depth->value ());
}
// ------------------------------------------------------------
// LayoutConfigPage8 implementation
LayoutViewConfigPage8::LayoutViewConfigPage8 (QWidget *parent)
: lay::ConfigPage (parent)
{
mp_ui = new Ui::LayoutViewConfigPage8 ();
mp_ui->setupUi (this);
}
LayoutViewConfigPage8::~LayoutViewConfigPage8 ()
{
delete mp_ui;
mp_ui = 0;
}
void
LayoutViewConfigPage8::setup (lay::Dispatcher *root)
{
int cpm = -1;
root->config_get (cfg_copy_cell_mode, cpm);
mp_ui->hier_copy_mode_cbx->setCurrentIndex ((cpm < 0 || cpm > 1) ? 2 : cpm);
}
void
LayoutViewConfigPage8::commit (lay::Dispatcher *root)
{
int cpm = mp_ui->hier_copy_mode_cbx->currentIndex ();
root->config_set (cfg_copy_cell_mode, (cpm < 0 || cpm > 1) ? -1 : cpm);
}
// ------------------------------------------------------------
// The dummy plugin declaration to register the configuration options
@ -1554,6 +1586,7 @@ public:
pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Application|Tracking")), new LayoutViewConfigPage2d (parent)));
pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Application|Layer Properties")), new LayoutViewConfigPage5 (parent)));
pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Application|Units")), new LayoutViewConfigPage3c (parent)));
pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Application|Cells")), new LayoutViewConfigPage8 (parent)));
pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Navigation|New Cell")), new LayoutViewConfigPage3a (parent)));
pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Navigation|Zoom And Pan")), new LayoutViewConfigPage3b (parent)));

View File

@ -50,6 +50,7 @@ namespace Ui {
class LayoutViewConfigPage6;
class LayoutViewConfigPage6a;
class LayoutViewConfigPage7;
class LayoutViewConfigPage8;
}
namespace lay
@ -355,6 +356,22 @@ private:
Ui::LayoutViewConfigPage7 *mp_ui;
};
class LayoutViewConfigPage8
: public lay::ConfigPage
{
Q_OBJECT
public:
LayoutViewConfigPage8 (QWidget *parent);
~LayoutViewConfigPage8 ();
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage8 *mp_ui;
};
}
#endif

View File

@ -40,6 +40,7 @@ FORMS = \
LayoutViewConfigPage6.ui \
LayoutViewConfigPage7.ui \
LayoutViewConfigPage.ui \
LayoutViewConfigPage8.ui \
LibraryCellSelectionForm.ui \
LoadLayoutOptionsDialog.ui \
MarkerBrowserConfigPage2.ui \

View File

@ -938,6 +938,14 @@ LayoutView::configure (const std::string &name, const std::string &value)
}
return true;
} else if (name == cfg_copy_cell_mode) {
if (mp_hierarchy_panel) {
int m = 0;
tl::from_string (value, m);
mp_hierarchy_panel->set_cell_copy_mode (m);
}
} else if (name == cfg_cell_list_sorting) {
if (mp_hierarchy_panel) {