mirror of https://github.com/KLayout/klayout.git
Multi-selection in properties dialog: bugfixing and finalization
This commit is contained in:
parent
5144f239eb
commit
dc927717c2
|
|
@ -377,7 +377,7 @@ PropertiesPage::count () const
|
||||||
void
|
void
|
||||||
PropertiesPage::select_entries (const std::vector<size_t> &entries)
|
PropertiesPage::select_entries (const std::vector<size_t> &entries)
|
||||||
{
|
{
|
||||||
tl_assert (entries.size () == 1); // @@@
|
tl_assert (entries.size () == 1);
|
||||||
m_index = entries.front ();
|
m_index = entries.front ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,7 +523,7 @@ PropertiesPage::apply ()
|
||||||
{
|
{
|
||||||
ant::Object obj;
|
ant::Object obj;
|
||||||
get_object (obj);
|
get_object (obj);
|
||||||
mp_rulers->change_ruler (m_selection [m_index], obj); // @@@ multi-apply
|
mp_rulers->change_ruler (m_selection [m_index], obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertiesPage::get_object(ant::Object &obj)
|
void PropertiesPage::get_object(ant::Object &obj)
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ InstPropertiesPage::InstPropertiesPage (edt::Service *service, db::Manager *mana
|
||||||
for (edt::Service::obj_iterator s = service->selection ().begin (); s != service->selection ().end (); ++s) {
|
for (edt::Service::obj_iterator s = service->selection ().begin (); s != service->selection ().end (); ++s) {
|
||||||
m_selection_ptrs.push_back (s);
|
m_selection_ptrs.push_back (s);
|
||||||
}
|
}
|
||||||
m_index = 0;
|
|
||||||
m_prop_id = 0;
|
m_prop_id = 0;
|
||||||
mp_service->clear_highlights ();
|
mp_service->clear_highlights ();
|
||||||
|
|
||||||
|
|
@ -156,6 +155,10 @@ get_cell_or_pcell_ids_by_name (const db::Layout *layout, const std::string &name
|
||||||
void
|
void
|
||||||
InstPropertiesPage::browse_cell ()
|
InstPropertiesPage::browse_cell ()
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_PROTECTED
|
BEGIN_PROTECTED
|
||||||
|
|
||||||
// find the layout the cell has to be looked up: that is either the layout of the current instance or
|
// find the layout the cell has to be looked up: that is either the layout of the current instance or
|
||||||
|
|
@ -166,7 +169,7 @@ BEGIN_PROTECTED
|
||||||
lib = lib_cbx->current_library ();
|
lib = lib_cbx->current_library ();
|
||||||
layout = &lib->layout ();
|
layout = &lib->layout ();
|
||||||
} else {
|
} else {
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
||||||
layout = &cv->layout ();
|
layout = &cv->layout ();
|
||||||
}
|
}
|
||||||
|
|
@ -207,8 +210,12 @@ END_PROTECTED
|
||||||
void
|
void
|
||||||
InstPropertiesPage::show_props ()
|
InstPropertiesPage::show_props ()
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lay::UserPropertiesForm props_form (this);
|
lay::UserPropertiesForm props_form (this);
|
||||||
if (props_form.show (mp_service->view (), m_selection_ptrs [m_index]->cv_index (), m_prop_id)) {
|
if (props_form.show (mp_service->view (), m_selection_ptrs [m_indexes.front ()]->cv_index (), m_prop_id)) {
|
||||||
emit edited ();
|
emit edited ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,8 +242,7 @@ InstPropertiesPage::count () const
|
||||||
void
|
void
|
||||||
InstPropertiesPage::select_entries (const std::vector<size_t> &entries)
|
InstPropertiesPage::select_entries (const std::vector<size_t> &entries)
|
||||||
{
|
{
|
||||||
tl_assert (entries.size () == 1); // @@@
|
m_indexes = entries;
|
||||||
m_index = entries.front ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
|
@ -296,10 +302,14 @@ InstPropertiesPage::leave ()
|
||||||
void
|
void
|
||||||
InstPropertiesPage::update ()
|
InstPropertiesPage::update ()
|
||||||
{
|
{
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
tl_assert (pos->is_cell_inst ());
|
tl_assert (pos->is_cell_inst ());
|
||||||
|
|
||||||
mp_service->highlight (m_index);
|
mp_service->highlight (m_indexes);
|
||||||
|
|
||||||
m_enable_cb_callback = false;
|
m_enable_cb_callback = false;
|
||||||
dbu_cb->setChecked (mp_service->view ()->dbu_coordinates ());
|
dbu_cb->setChecked (mp_service->view ()->dbu_coordinates ());
|
||||||
|
|
@ -407,7 +417,11 @@ InstPropertiesPage::update ()
|
||||||
void
|
void
|
||||||
InstPropertiesPage::show_cell ()
|
InstPropertiesPage::show_cell ()
|
||||||
{
|
{
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
|
|
||||||
lay::CellView::unspecific_cell_path_type path (mp_service->view ()->cellview (pos->cv_index ()).combined_unspecific_path ());
|
lay::CellView::unspecific_cell_path_type path (mp_service->view ()->cellview (pos->cv_index ()).combined_unspecific_path ());
|
||||||
for (lay::ObjectInstPath::iterator p = pos->begin (); p != pos->end (); ++p) {
|
for (lay::ObjectInstPath::iterator p = pos->begin (); p != pos->end (); ++p) {
|
||||||
|
|
@ -420,8 +434,12 @@ InstPropertiesPage::show_cell ()
|
||||||
void
|
void
|
||||||
InstPropertiesPage::show_inst ()
|
InstPropertiesPage::show_inst ()
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InstantiationForm inst_form (this);
|
InstantiationForm inst_form (this);
|
||||||
inst_form.show (mp_service->view (), *m_selection_ptrs [m_index]);
|
inst_form.show (mp_service->view (), *m_selection_ptrs [m_indexes.front ()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -433,12 +451,14 @@ InstPropertiesPage::readonly ()
|
||||||
ChangeApplicator *
|
ChangeApplicator *
|
||||||
InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & /*inst*/, double dbu)
|
InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & /*inst*/, double dbu)
|
||||||
{
|
{
|
||||||
|
tl_assert (! m_indexes.empty ());
|
||||||
|
|
||||||
bool has_error = false;
|
bool has_error = false;
|
||||||
bool has_pcell_error = false;
|
bool has_pcell_error = false;
|
||||||
|
|
||||||
std::unique_ptr<CombinedChangeApplicator> appl (new CombinedChangeApplicator ());
|
std::unique_ptr<CombinedChangeApplicator> appl (new CombinedChangeApplicator ());
|
||||||
|
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
||||||
|
|
||||||
bool du = dbu_cb->isChecked ();
|
bool du = dbu_cb->isChecked ();
|
||||||
|
|
@ -732,13 +752,17 @@ InstPropertiesPage::recompute_selection_ptrs (const std::vector<lay::ObjectInstP
|
||||||
void
|
void
|
||||||
InstPropertiesPage::do_apply (bool current_only, bool relative)
|
InstPropertiesPage::do_apply (bool current_only, bool relative)
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lay::LayerState layer_state = mp_service->view ()->layer_snapshot ();
|
lay::LayerState layer_state = mp_service->view ()->layer_snapshot ();
|
||||||
unsigned int cv_index = m_selection_ptrs [m_index]->cv_index ();
|
unsigned int cv_index = m_selection_ptrs [m_indexes.front ()]->cv_index ();
|
||||||
|
|
||||||
std::unique_ptr<ChangeApplicator> applicator;
|
std::unique_ptr<ChangeApplicator> applicator;
|
||||||
|
|
||||||
{
|
{
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
tl_assert (pos->is_cell_inst ());
|
tl_assert (pos->is_cell_inst ());
|
||||||
|
|
||||||
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
||||||
|
|
@ -766,7 +790,7 @@ InstPropertiesPage::do_apply (bool current_only, bool relative)
|
||||||
// But it avoids issues with duplicate selections of the same instance which may happen when
|
// But it avoids issues with duplicate selections of the same instance which may happen when
|
||||||
// an instance is selected multiple times through different hierarchy branches.
|
// an instance is selected multiple times through different hierarchy branches.
|
||||||
|
|
||||||
db::Instance current = m_selection_ptrs [m_index]->back ().inst_ptr;
|
db::Instance current = m_selection_ptrs [m_indexes.front ()]->back ().inst_ptr;
|
||||||
|
|
||||||
std::vector<lay::ObjectInstPath> new_sel;
|
std::vector<lay::ObjectInstPath> new_sel;
|
||||||
new_sel.reserve (m_selection_ptrs.size ());
|
new_sel.reserve (m_selection_ptrs.size ());
|
||||||
|
|
@ -780,9 +804,10 @@ InstPropertiesPage::do_apply (bool current_only, bool relative)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
for (std::vector<edt::Service::obj_iterator>::const_iterator p = m_selection_ptrs.begin (); p != m_selection_ptrs.end (); ++p) {
|
for (auto ii = m_indexes.begin (); ii != m_indexes.end (); ++ii) {
|
||||||
|
|
||||||
edt::Service::obj_iterator pos = *p;
|
size_t index = *ii;
|
||||||
|
edt::Service::obj_iterator pos = m_selection_ptrs [*ii];
|
||||||
|
|
||||||
// only update objects from the same layout - this is not practical limitation but saves a lot of effort for
|
// only update objects from the same layout - this is not practical limitation but saves a lot of effort for
|
||||||
// managing different property id's etc.
|
// managing different property id's etc.
|
||||||
|
|
@ -815,8 +840,6 @@ InstPropertiesPage::do_apply (bool current_only, bool relative)
|
||||||
|
|
||||||
if (new_inst != pos->back ().inst_ptr) {
|
if (new_inst != pos->back ().inst_ptr) {
|
||||||
|
|
||||||
size_t index = p - m_selection_ptrs.begin ();
|
|
||||||
|
|
||||||
// change selection to new instance
|
// change selection to new instance
|
||||||
new_sel[index].back ().inst_ptr = new_inst;
|
new_sel[index].back ().inst_ptr = new_inst;
|
||||||
|
|
||||||
|
|
@ -869,6 +892,10 @@ InstPropertiesPage::apply_to_all (bool relative)
|
||||||
void
|
void
|
||||||
InstPropertiesPage::update_pcell_parameters ()
|
InstPropertiesPage::update_pcell_parameters ()
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
db::Layout *layout;
|
db::Layout *layout;
|
||||||
|
|
||||||
// find the layout the cell has to be looked up: that is either the layout of the current instance or
|
// find the layout the cell has to be looked up: that is either the layout of the current instance or
|
||||||
|
|
@ -879,7 +906,7 @@ InstPropertiesPage::update_pcell_parameters ()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
||||||
layout = &cv->layout ();
|
layout = &cv->layout ();
|
||||||
|
|
||||||
|
|
@ -903,7 +930,7 @@ InstPropertiesPage::update_pcell_parameters ()
|
||||||
|
|
||||||
std::vector<tl::Variant> parameters;
|
std::vector<tl::Variant> parameters;
|
||||||
|
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
||||||
db::Cell &cell = cv->layout ().cell (pos->cell_index ());
|
db::Cell &cell = cv->layout ().cell (pos->cell_index ());
|
||||||
std::pair<bool, db::pcell_id_type> pci = cell.is_pcell_instance (pos->back ().inst_ptr);
|
std::pair<bool, db::pcell_id_type> pci = cell.is_pcell_instance (pos->back ().inst_ptr);
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<edt::Service::obj_iterator> m_selection_ptrs;
|
std::vector<edt::Service::obj_iterator> m_selection_ptrs;
|
||||||
unsigned int m_index;
|
std::vector<size_t> m_indexes;
|
||||||
edt::Service *mp_service;
|
edt::Service *mp_service;
|
||||||
bool m_enable_cb_callback;
|
bool m_enable_cb_callback;
|
||||||
db::properties_id_type m_prop_id;
|
db::properties_id_type m_prop_id;
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ ShapePropertiesPage::ShapePropertiesPage (const std::string &description, edt::S
|
||||||
for (edt::Service::obj_iterator s = service->selection ().begin (); s != service->selection ().end (); ++s) {
|
for (edt::Service::obj_iterator s = service->selection ().begin (); s != service->selection ().end (); ++s) {
|
||||||
m_selection_ptrs.push_back (s);
|
m_selection_ptrs.push_back (s);
|
||||||
}
|
}
|
||||||
m_index = 0;
|
|
||||||
m_prop_id = 0;
|
m_prop_id = 0;
|
||||||
mp_service->clear_highlights ();
|
mp_service->clear_highlights ();
|
||||||
}
|
}
|
||||||
|
|
@ -82,8 +81,7 @@ ShapePropertiesPage::count () const
|
||||||
void
|
void
|
||||||
ShapePropertiesPage::select_entries (const std::vector<size_t> &entries)
|
ShapePropertiesPage::select_entries (const std::vector<size_t> &entries)
|
||||||
{
|
{
|
||||||
tl_assert (entries.size () == 1); // @@@
|
m_indexes = entries;
|
||||||
m_index = entries.front ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lay::LayoutViewBase *
|
lay::LayoutViewBase *
|
||||||
|
|
@ -166,8 +164,8 @@ ShapePropertiesPage::abs_trans () const
|
||||||
db::ICplxTrans
|
db::ICplxTrans
|
||||||
ShapePropertiesPage::trans () const
|
ShapePropertiesPage::trans () const
|
||||||
{
|
{
|
||||||
if (abs_trans ()) {
|
if (abs_trans () && ! m_indexes.empty ()) {
|
||||||
return m_selection_ptrs[m_index]->trans ();
|
return m_selection_ptrs[m_indexes.front ()]->trans ();
|
||||||
} else {
|
} else {
|
||||||
return db::ICplxTrans ();
|
return db::ICplxTrans ();
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +188,7 @@ END_PROTECTED
|
||||||
void
|
void
|
||||||
ShapePropertiesPage::update ()
|
ShapePropertiesPage::update ()
|
||||||
{
|
{
|
||||||
mp_service->highlight (m_index);
|
mp_service->highlight (m_indexes);
|
||||||
|
|
||||||
update_shape ();
|
update_shape ();
|
||||||
}
|
}
|
||||||
|
|
@ -215,12 +213,16 @@ ShapePropertiesPage::recompute_selection_ptrs (const std::vector<lay::ObjectInst
|
||||||
void
|
void
|
||||||
ShapePropertiesPage::do_apply (bool current_only, bool relative)
|
ShapePropertiesPage::do_apply (bool current_only, bool relative)
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ChangeApplicator> applicator;
|
std::unique_ptr<ChangeApplicator> applicator;
|
||||||
|
|
||||||
unsigned int cv_index = m_selection_ptrs [m_index]->cv_index ();
|
unsigned int cv_index = m_selection_ptrs [m_indexes.front ()]->cv_index ();
|
||||||
|
|
||||||
{
|
{
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
tl_assert (! pos->is_cell_inst ());
|
tl_assert (! pos->is_cell_inst ());
|
||||||
|
|
||||||
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
||||||
|
|
@ -249,7 +251,7 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative)
|
||||||
// But it avoids issues with duplicate selections of the same shape which may happen when
|
// But it avoids issues with duplicate selections of the same shape which may happen when
|
||||||
// a shape is selected multiple times through different hierarchy branches.
|
// a shape is selected multiple times through different hierarchy branches.
|
||||||
|
|
||||||
db::Shape current = m_selection_ptrs [m_index]->shape ();
|
db::Shape current = m_selection_ptrs [m_indexes.front ()]->shape ();
|
||||||
|
|
||||||
std::vector<lay::ObjectInstPath> new_sel;
|
std::vector<lay::ObjectInstPath> new_sel;
|
||||||
new_sel.reserve (m_selection_ptrs.size ());
|
new_sel.reserve (m_selection_ptrs.size ());
|
||||||
|
|
@ -263,11 +265,10 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
for (std::vector<edt::Service::obj_iterator>::const_iterator p = m_selection_ptrs.begin (); p != m_selection_ptrs.end (); ++p) {
|
for (auto i = m_indexes.begin (); i != m_indexes.end (); ++i) {
|
||||||
|
|
||||||
size_t index = p - m_selection_ptrs.begin ();
|
size_t index = *i;
|
||||||
|
edt::Service::obj_iterator pos = m_selection_ptrs [*i];
|
||||||
edt::Service::obj_iterator pos = *p;
|
|
||||||
|
|
||||||
// only update objects from the same layout - this is not practical limitation but saves a lot of effort for
|
// only update objects from the same layout - this is not practical limitation but saves a lot of effort for
|
||||||
// managing different property id's etc.
|
// managing different property id's etc.
|
||||||
|
|
@ -365,7 +366,11 @@ ShapePropertiesPage::apply_to_all (bool relative)
|
||||||
void
|
void
|
||||||
ShapePropertiesPage::update_shape ()
|
ShapePropertiesPage::update_shape ()
|
||||||
{
|
{
|
||||||
edt::Service::obj_iterator pos = m_selection_ptrs [m_index];
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()];
|
||||||
|
|
||||||
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ());
|
||||||
double dbu = cv->layout ().dbu ();
|
double dbu = cv->layout ().dbu ();
|
||||||
|
|
@ -397,15 +402,23 @@ ShapePropertiesPage::update_shape ()
|
||||||
void
|
void
|
||||||
ShapePropertiesPage::show_inst ()
|
ShapePropertiesPage::show_inst ()
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InstantiationForm inst_form (this);
|
InstantiationForm inst_form (this);
|
||||||
inst_form.show (mp_service->view (), *m_selection_ptrs [m_index]);
|
inst_form.show (mp_service->view (), *m_selection_ptrs [m_indexes.front ()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShapePropertiesPage::show_props ()
|
ShapePropertiesPage::show_props ()
|
||||||
{
|
{
|
||||||
|
if (m_indexes.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lay::UserPropertiesForm props_form (this);
|
lay::UserPropertiesForm props_form (this);
|
||||||
if (props_form.show (mp_service->view (), m_selection_ptrs [m_index]->cv_index (), m_prop_id)) {
|
if (props_form.show (mp_service->view (), m_selection_ptrs [m_indexes.front ()]->cv_index (), m_prop_id)) {
|
||||||
emit edited ();
|
emit edited ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ private:
|
||||||
protected:
|
protected:
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
std::vector<edt::Service::obj_iterator> m_selection_ptrs;
|
std::vector<edt::Service::obj_iterator> m_selection_ptrs;
|
||||||
unsigned int m_index;
|
std::vector<size_t> m_indexes;
|
||||||
edt::Service *mp_service;
|
edt::Service *mp_service;
|
||||||
bool m_enable_cb_callback;
|
bool m_enable_cb_callback;
|
||||||
db::properties_id_type m_prop_id;
|
db::properties_id_type m_prop_id;
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view, db::ShapeIter
|
||||||
m_hier_copy_mode (-1),
|
m_hier_copy_mode (-1),
|
||||||
m_indicate_secondary_selection (false),
|
m_indicate_secondary_selection (false),
|
||||||
m_seq (0),
|
m_seq (0),
|
||||||
|
m_highlights_selected (false),
|
||||||
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
|
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
|
||||||
{
|
{
|
||||||
mp_view->geom_changed_event.add (this, &edt::Service::selection_to_view);
|
mp_view->geom_changed_event.add (this, &edt::Service::selection_to_view);
|
||||||
|
|
@ -97,6 +98,7 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
|
||||||
m_hier_copy_mode (-1),
|
m_hier_copy_mode (-1),
|
||||||
m_indicate_secondary_selection (false),
|
m_indicate_secondary_selection (false),
|
||||||
m_seq (0),
|
m_seq (0),
|
||||||
|
m_highlights_selected (false),
|
||||||
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
|
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
|
||||||
{
|
{
|
||||||
mp_view->geom_changed_event.add (this, &edt::Service::selection_to_view);
|
mp_view->geom_changed_event.add (this, &edt::Service::selection_to_view);
|
||||||
|
|
@ -271,28 +273,36 @@ Service::configure (const std::string &name, const std::string &value)
|
||||||
void
|
void
|
||||||
Service::clear_highlights ()
|
Service::clear_highlights ()
|
||||||
{
|
{
|
||||||
for (std::vector<lay::ViewObject *>::iterator r = m_markers.begin (); r != m_markers.end (); ++r) {
|
m_highlights_selected = true;
|
||||||
(*r)->visible (false);
|
m_selected_highlights.clear ();
|
||||||
}
|
apply_highlights ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Service::restore_highlights ()
|
Service::restore_highlights ()
|
||||||
{
|
{
|
||||||
for (std::vector<lay::ViewObject *>::iterator r = m_markers.begin (); r != m_markers.end (); ++r) {
|
m_highlights_selected = false;
|
||||||
(*r)->visible (true);
|
m_selected_highlights.clear ();
|
||||||
}
|
apply_highlights ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Service::highlight (unsigned int n)
|
Service::highlight (const std::vector<size_t> &n)
|
||||||
|
{
|
||||||
|
m_highlights_selected = true;
|
||||||
|
m_selected_highlights = std::set<size_t> (n.begin (), n.end ());
|
||||||
|
apply_highlights ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Service::apply_highlights ()
|
||||||
{
|
{
|
||||||
for (std::vector<lay::ViewObject *>::iterator r = m_markers.begin (); r != m_markers.end (); ++r) {
|
for (std::vector<lay::ViewObject *>::iterator r = m_markers.begin (); r != m_markers.end (); ++r) {
|
||||||
(*r)->visible (n-- == 0);
|
(*r)->visible (! m_highlights_selected || m_selected_highlights.find (r - m_markers.begin ()) != m_selected_highlights.end ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Service::cut ()
|
Service::cut ()
|
||||||
{
|
{
|
||||||
if (has_selection () && view ()->is_editable ()) {
|
if (has_selection () && view ()->is_editable ()) {
|
||||||
|
|
@ -1597,6 +1607,8 @@ Service::do_selection_to_view ()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply_highlights ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,10 @@ public:
|
||||||
*/
|
*/
|
||||||
void restore_highlights ();
|
void restore_highlights ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Highlight a certain object
|
* @brief Highlights a group of objects
|
||||||
*/
|
*/
|
||||||
void highlight (unsigned int n);
|
void highlight (const std::vector<size_t> &n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief "delete" operation
|
* @brief "delete" operation
|
||||||
|
|
@ -616,6 +616,10 @@ private:
|
||||||
bool m_indicate_secondary_selection;
|
bool m_indicate_secondary_selection;
|
||||||
unsigned long m_seq;
|
unsigned long m_seq;
|
||||||
|
|
||||||
|
// selective highlights
|
||||||
|
bool m_highlights_selected;
|
||||||
|
std::set<size_t> m_selected_highlights;
|
||||||
|
|
||||||
// Deferred method to update the selection
|
// Deferred method to update the selection
|
||||||
tl::DeferredMethod<edt::Service> dm_selection_to_view;
|
tl::DeferredMethod<edt::Service> dm_selection_to_view;
|
||||||
|
|
||||||
|
|
@ -646,6 +650,11 @@ private:
|
||||||
*/
|
*/
|
||||||
void display_status (bool transient);
|
void display_status (bool transient);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Apply highlight selection
|
||||||
|
*/
|
||||||
|
void apply_highlights ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void copy_selected (unsigned int inst_mode);
|
void copy_selected (unsigned int inst_mode);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ PropertiesPage::count () const
|
||||||
void
|
void
|
||||||
PropertiesPage::select_entries (const std::vector<size_t> &entries)
|
PropertiesPage::select_entries (const std::vector<size_t> &entries)
|
||||||
{
|
{
|
||||||
tl_assert (entries.size () == 1); // @@@
|
tl_assert (entries.size () == 1);
|
||||||
m_index = entries.front ();
|
m_index = entries.front ();
|
||||||
invalidate ();
|
invalidate ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,6 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns true, if the properties page supports "apply all"
|
* @brief Returns true, if the properties page supports "apply all"
|
||||||
* @@@ TODO: remove
|
|
||||||
*/
|
*/
|
||||||
virtual bool can_apply_to_all () const
|
virtual bool can_apply_to_all () const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -58,14 +58,14 @@ public:
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
if (index.internalId () < mp_dialog->properties_pages ().size ()) {
|
if (index.internalId () < mp_dialog->properties_pages ().size ()) {
|
||||||
return tl::to_qstring (mp_dialog->properties_pages () [index.internalId ()]->description (index.row ()));
|
return tl::to_qstring (mp_dialog->properties_pages () [index.internalId ()]->description (index.row ()));
|
||||||
} else {
|
} else if (index.row () < int (mp_dialog->properties_pages ().size ())) {
|
||||||
return tl::to_qstring (mp_dialog->properties_pages () [index.row ()]->description ());
|
return tl::to_qstring (mp_dialog->properties_pages () [index.row ()]->description ());
|
||||||
}
|
}
|
||||||
} else if (role == Qt::DecorationRole) {
|
} else if (role == Qt::DecorationRole) {
|
||||||
QIcon icon;
|
QIcon icon;
|
||||||
if (index.internalId () < mp_dialog->properties_pages ().size ()) {
|
if (index.internalId () < mp_dialog->properties_pages ().size ()) {
|
||||||
icon = mp_dialog->properties_pages () [index.internalId ()]->icon (index.row (), m_icon_width, m_icon_height);
|
icon = mp_dialog->properties_pages () [index.internalId ()]->icon (index.row (), m_icon_width, m_icon_height);
|
||||||
} else {
|
} else if (index.row () < int (mp_dialog->properties_pages ().size ())) {
|
||||||
icon = mp_dialog->properties_pages () [index.row ()]->icon (m_icon_width, m_icon_height);
|
icon = mp_dialog->properties_pages () [index.row ()]->icon (m_icon_width, m_icon_height);
|
||||||
}
|
}
|
||||||
if (! icon.isNull ()) {
|
if (! icon.isNull ()) {
|
||||||
|
|
@ -217,13 +217,16 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager,
|
||||||
mp_ui->tree->header()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
mp_ui->tree->header()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
mp_ui->tree->expandAll ();
|
mp_ui->tree->expandAll ();
|
||||||
|
|
||||||
|
if (mp_properties_pages.empty ()) {
|
||||||
|
mp_ui->tree->hide ();
|
||||||
|
}
|
||||||
|
|
||||||
m_signals_enabled = false;
|
m_signals_enabled = false;
|
||||||
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index, 0));
|
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index, 0));
|
||||||
m_signals_enabled = true;
|
m_signals_enabled = true;
|
||||||
|
|
||||||
update_controls ();
|
update_controls ();
|
||||||
|
|
||||||
// @@@ save this status!
|
|
||||||
mp_ui->apply_to_all_cbx->setChecked (false);
|
mp_ui->apply_to_all_cbx->setChecked (false);
|
||||||
mp_ui->relative_cbx->setChecked (true);
|
mp_ui->relative_cbx->setChecked (true);
|
||||||
|
|
||||||
|
|
@ -262,7 +265,7 @@ PropertiesDialog::apply_to_all_pressed ()
|
||||||
if (mp_ui->apply_to_all_cbx->isChecked ()) {
|
if (mp_ui->apply_to_all_cbx->isChecked ()) {
|
||||||
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index));
|
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index));
|
||||||
} else if (! m_object_indexes.empty ()) {
|
} else if (! m_object_indexes.empty ()) {
|
||||||
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index, m_object_indexes.front ()));
|
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index, int (m_object_indexes.front ())));
|
||||||
}
|
}
|
||||||
m_signals_enabled = true;
|
m_signals_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
@ -294,21 +297,21 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI
|
||||||
|
|
||||||
if (mp_properties_pages [m_index]->can_apply_to_all ()) {
|
if (mp_properties_pages [m_index]->can_apply_to_all ()) {
|
||||||
|
|
||||||
m_object_indexes.push_back (mp_tree_model->object_index (index));
|
m_object_indexes.push_back (size_t (mp_tree_model->object_index (index)));
|
||||||
|
|
||||||
auto selection = mp_ui->tree->selectionModel ()->selectedIndexes ();
|
auto selection = mp_ui->tree->selectionModel ()->selectedIndexes ();
|
||||||
for (auto i = selection.begin (); i != selection.end (); ++i) {
|
for (auto i = selection.begin (); i != selection.end (); ++i) {
|
||||||
if (mp_tree_model->parent (*i).isValid () && mp_tree_model->page_index (*i) == m_index) {
|
if (mp_tree_model->parent (*i).isValid () && mp_tree_model->page_index (*i) == m_index) {
|
||||||
int oi = mp_tree_model->object_index (*i);
|
int oi = mp_tree_model->object_index (*i);
|
||||||
if (oi != m_object_indexes.front ()) {
|
if (oi != int (m_object_indexes.front ())) {
|
||||||
m_object_indexes.push_back (oi);
|
m_object_indexes.push_back (size_t (oi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
m_object_indexes.push_back (mp_tree_model->object_index (index));
|
m_object_indexes.push_back (size_t (mp_tree_model->object_index (index)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,8 +320,16 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI
|
||||||
m_index = index.row ();
|
m_index = index.row ();
|
||||||
mp_ui->apply_to_all_cbx->setChecked (mp_properties_pages [m_index]->can_apply_to_all ());
|
mp_ui->apply_to_all_cbx->setChecked (mp_properties_pages [m_index]->can_apply_to_all ());
|
||||||
|
|
||||||
for (int oi = 0; oi < mp_properties_pages [m_index]->count (); ++oi) {
|
if (mp_properties_pages [m_index]->can_apply_to_all ()) {
|
||||||
m_object_indexes.push_back (oi);
|
|
||||||
|
for (size_t oi = 0; oi < mp_properties_pages [m_index]->count (); ++oi) {
|
||||||
|
m_object_indexes.push_back (oi);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
m_object_indexes.push_back (size_t (mp_tree_model->object_index (index)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -330,7 +341,7 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI
|
||||||
for (int i = 0; i < m_index; ++i) {
|
for (int i = 0; i < m_index; ++i) {
|
||||||
m_current_object += mp_properties_pages [i]->count ();
|
m_current_object += mp_properties_pages [i]->count ();
|
||||||
}
|
}
|
||||||
m_current_object += m_object_indexes.front ();
|
m_current_object += int (m_object_indexes.front ());
|
||||||
} else {
|
} else {
|
||||||
m_current_object = -1;
|
m_current_object = -1;
|
||||||
}
|
}
|
||||||
|
|
@ -373,7 +384,7 @@ PropertiesDialog::update_controls ()
|
||||||
mp_ui->ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ());
|
mp_ui->ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ());
|
||||||
mp_ui->tree->setEnabled (true);
|
mp_ui->tree->setEnabled (true);
|
||||||
|
|
||||||
mp_properties_pages [m_index]->select_entry (m_object_indexes);
|
mp_properties_pages [m_index]->select_entries (m_object_indexes);
|
||||||
mp_properties_pages [m_index]->update ();
|
mp_properties_pages [m_index]->update ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -397,7 +408,7 @@ BEGIN_PROTECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance the current entry
|
// advance the current entry
|
||||||
int object_index = m_object_indexes.front ();
|
int object_index = int (m_object_indexes.front ());
|
||||||
++object_index;
|
++object_index;
|
||||||
|
|
||||||
// look for next usable editable if at end
|
// look for next usable editable if at end
|
||||||
|
|
@ -445,7 +456,7 @@ BEGIN_PROTECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance the current entry
|
// advance the current entry
|
||||||
int object_index = m_object_indexes.front ();
|
int object_index = int (m_object_indexes.front ());
|
||||||
if (object_index == 0) {
|
if (object_index == 0) {
|
||||||
|
|
||||||
// look for last usable editable if at end
|
// look for last usable editable if at end
|
||||||
|
|
@ -494,15 +505,9 @@ PropertiesDialog::any_next () const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for the next applicable page
|
|
||||||
// @@@ Pages should not be empty
|
|
||||||
int index = m_index;
|
int index = m_index;
|
||||||
if (m_object_indexes.front () + 1 >= int (mp_properties_pages [index]->count ())) {
|
if (m_object_indexes.front () + 1 >= mp_properties_pages [index]->count ()) {
|
||||||
++index;
|
++index;
|
||||||
while (index < int (mp_properties_pages.size ()) &&
|
|
||||||
(mp_properties_pages [index] == 0 || mp_properties_pages [index]->count () == 0)) {
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true, if not at end
|
// return true, if not at end
|
||||||
|
|
@ -516,15 +521,9 @@ PropertiesDialog::any_prev () const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for the next applicable page
|
|
||||||
// @@@ Pages should not be empty
|
|
||||||
int index = m_index;
|
int index = m_index;
|
||||||
if (m_object_indexes.front () == 0) {
|
if (m_object_indexes.front () == 0) {
|
||||||
--index;
|
--index;
|
||||||
while (index >= 0 &&
|
|
||||||
(mp_properties_pages [index] == 0 || mp_properties_pages [index]->count () == 0)) {
|
|
||||||
--index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true, if not at the beginning
|
// return true, if not at the beginning
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ private:
|
||||||
db::Manager *mp_manager;
|
db::Manager *mp_manager;
|
||||||
lay::Editables *mp_editables;
|
lay::Editables *mp_editables;
|
||||||
int m_index, m_prev_index;
|
int m_index, m_prev_index;
|
||||||
std::vector<int> m_object_indexes;
|
std::vector<size_t> m_object_indexes;
|
||||||
QStackedLayout *mp_stack;
|
QStackedLayout *mp_stack;
|
||||||
QLabel *mp_none;
|
QLabel *mp_none;
|
||||||
lay::MainWindow *mp_mw;
|
lay::MainWindow *mp_mw;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue