diff --git a/src/ant/ant/antPropertiesPage.cc b/src/ant/ant/antPropertiesPage.cc index 964deaf08..ae2f47b2d 100644 --- a/src/ant/ant/antPropertiesPage.cc +++ b/src/ant/ant/antPropertiesPage.cc @@ -375,8 +375,9 @@ PropertiesPage::count () const void PropertiesPage::select_entries (const std::vector &entries) { - tl_assert (entries.size () == 1); - m_index = entries.front (); + if (! entries.empty ()) { + m_index = entries.front (); + } } std::string diff --git a/src/edt/edt/edtPropertiesPages.cc b/src/edt/edt/edtPropertiesPages.cc index 35bbb25fb..9cd05e123 100644 --- a/src/edt/edt/edtPropertiesPages.cc +++ b/src/edt/edt/edtPropertiesPages.cc @@ -283,7 +283,7 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative, bool commit) } } - int new_layer = layer_selector ()->current_layer (); + int new_layer = layer_selector ()->current_layer_ensure (); if (new_layer >= 0 && int (pos->layer ()) != new_layer) { unsigned int gs_layer = cv->layout ().guiding_shape_layer (); ChangeLayerApplicator *cla = new ChangeLayerApplicator (cv_index, (unsigned int) new_layer); diff --git a/src/img/img/imgPropertiesPage.cc b/src/img/img/imgPropertiesPage.cc index 77da34a13..a662394a0 100644 --- a/src/img/img/imgPropertiesPage.cc +++ b/src/img/img/imgPropertiesPage.cc @@ -181,9 +181,10 @@ PropertiesPage::count () const void PropertiesPage::select_entries (const std::vector &entries) { - tl_assert (entries.size () == 1); - m_index = entries.front (); - invalidate (); + if (! entries.empty ()) { + m_index = entries.front (); + invalidate (); + } } std::string diff --git a/src/layui/layui/layPropertiesDialog.cc b/src/layui/layui/layPropertiesDialog.cc index 0c87081a0..6f6cc3fd9 100644 --- a/src/layui/layui/layPropertiesDialog.cc +++ b/src/layui/layui/layPropertiesDialog.cc @@ -235,10 +235,11 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager, m_current_object = 0; // look for next usable editable + m_object_indexes.resize (mp_properties_pages.size ()); if (m_index >= int (mp_properties_pages.size ())) { m_index = -1; } else { - m_object_indexes.push_back (0); + m_object_indexes [m_index].push_back (0); } update_title (); @@ -383,6 +384,7 @@ BEGIN_PROTECTED delete *p; } else { mp_properties_pages.push_back (*p); + (*p)->set_page_set (this); } } } @@ -398,10 +400,11 @@ BEGIN_PROTECTED // look for next usable editable m_index = 0; m_object_indexes.clear (); + m_object_indexes.resize (mp_properties_pages.size ()); if (m_index >= int (mp_properties_pages.size ())) { m_index = -1; } else { - m_object_indexes.push_back (0); + m_object_indexes [m_index].push_back (0); } mp_tree_model->end_reset_model (); @@ -436,6 +439,7 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI } m_object_indexes.clear (); + m_object_indexes.resize (mp_properties_pages.size ()); if (! index.isValid ()) { @@ -462,56 +466,66 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI } + m_index = -1; + + auto selection = mp_ui->tree->selectionModel ()->selectedIndexes (); + + // establish a single-selection on the current item if (mp_tree_model->parent (index).isValid ()) { + int oi = mp_tree_model->object_index (index); + int pi = mp_tree_model->page_index (index); + m_index = pi; + m_object_indexes [pi].push_back (size_t (oi)); + } - m_index = mp_tree_model->page_index (index); + // establish individual selections for the other items + // as far as allowed by "can_apply_to_all" + for (auto i = selection.begin (); i != selection.end (); ++i) { + if (*i != index && mp_tree_model->parent (*i).isValid ()) { + int oi = mp_tree_model->object_index (*i); + int pi = mp_tree_model->page_index (*i); + if (mp_properties_pages [pi]->can_apply_to_all ()) { + m_object_indexes [pi].push_back (size_t (oi)); + } + } + } - if (mp_properties_pages [m_index]->can_apply_to_all ()) { + // establish group node selection as current item -> translate into "all" for "can_apply_to_all" pages + // or first item unless an item is explicitly selected. + if (! mp_tree_model->parent (index).isValid ()) { + int pi = index.row (); + m_index = pi; + m_object_indexes [pi].clear (); + if (mp_properties_pages [pi]->can_apply_to_all ()) { + for (size_t oi = 0; oi < mp_properties_pages [pi]->count (); ++oi) { + m_object_indexes [pi].push_back (oi); + } + } else if (mp_properties_pages [pi]->count () > 0 && m_object_indexes [pi].empty ()) { + m_object_indexes [pi].push_back (0); + } + } - m_object_indexes.push_back (size_t (mp_tree_model->object_index (index))); - - auto selection = mp_ui->tree->selectionModel ()->selectedIndexes (); - for (auto i = selection.begin (); i != selection.end (); ++i) { - if (mp_tree_model->parent (*i).isValid () && mp_tree_model->page_index (*i) == m_index) { - int oi = mp_tree_model->object_index (*i); - if (oi != int (m_object_indexes.front ())) { - m_object_indexes.push_back (size_t (oi)); - } + // establish group node selection for other items -> translate into "all" for "can_apply_to_all" pages + for (auto i = selection.begin (); i != selection.end (); ++i) { + if (*i != index && ! mp_tree_model->parent (*i).isValid ()) { + int pi = i->row (); + m_object_indexes [pi].clear (); + if (mp_properties_pages [pi]->can_apply_to_all ()) { + for (size_t oi = 0; oi < mp_properties_pages [pi]->count (); ++oi) { + m_object_indexes[pi].push_back (oi); } } - - } else { - - m_object_indexes.push_back (size_t (mp_tree_model->object_index (index))); - } - - } else { - - m_index = index.row (); - - if (mp_properties_pages [m_index]->can_apply_to_all ()) { - - for (size_t oi = 0; oi < mp_properties_pages [m_index]->count (); ++oi) { - m_object_indexes.push_back (oi); - } - - } else if (mp_properties_pages [m_index]->count () > 0) { - - m_object_indexes.push_back (0); - - } - } } - if (! m_object_indexes.empty ()) { + if (m_index >= 0 && ! m_object_indexes [m_index].empty ()) { m_current_object = 0; for (int i = 0; i < m_index; ++i) { m_current_object += mp_properties_pages [i]->count (); } - m_current_object += int (m_object_indexes.front ()); + m_current_object += int (m_object_indexes [m_index].front ()); } else { m_current_object = -1; } @@ -552,7 +566,10 @@ PropertiesDialog::update_controls () mp_ui->ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ()); mp_ui->tree->setEnabled (true); - mp_properties_pages [m_index]->select_entries (m_object_indexes); + for (int i = 0; i < int (mp_properties_pages.size ()); ++i) { + mp_properties_pages [i]->select_entries (m_object_indexes [i]); + } + mp_properties_pages [m_index]->update (); } @@ -563,7 +580,7 @@ PropertiesDialog::next_pressed () { BEGIN_PROTECTED - if (m_object_indexes.empty ()) { + if (m_index < 0 || m_object_indexes [m_index].empty ()) { return; } @@ -576,7 +593,7 @@ BEGIN_PROTECTED } // advance the current entry - int object_index = int (m_object_indexes.front ()); + int object_index = int (m_object_indexes [m_index].front ()); ++object_index; // look for next usable editable if at end @@ -593,7 +610,8 @@ BEGIN_PROTECTED } m_object_indexes.clear (); - m_object_indexes.push_back (object_index); + m_object_indexes.resize (mp_properties_pages.size ()); + m_object_indexes [m_index].push_back (object_index); ++m_current_object; update_title (); @@ -611,7 +629,7 @@ PropertiesDialog::prev_pressed () { BEGIN_PROTECTED - if (m_object_indexes.empty ()) { + if (m_index < 0 || m_object_indexes [m_index].empty ()) { return; } @@ -624,7 +642,7 @@ BEGIN_PROTECTED } // advance the current entry - int object_index = int (m_object_indexes.front ()); + int object_index = int (m_object_indexes [m_index].front ()); if (object_index == 0) { // look for last usable editable if at end @@ -643,7 +661,8 @@ BEGIN_PROTECTED --object_index; m_object_indexes.clear (); - m_object_indexes.push_back (object_index); + m_object_indexes.resize (mp_properties_pages.size ()); + m_object_indexes [m_index].push_back (object_index); --m_current_object; update_title (); @@ -669,12 +688,12 @@ PropertiesDialog::update_title () bool PropertiesDialog::any_next () const { - if (m_object_indexes.empty ()) { + if (m_index < 0 || m_object_indexes [m_index].empty ()) { return false; } int index = m_index; - if (m_object_indexes.front () + 1 >= mp_properties_pages [index]->count ()) { + if (m_object_indexes [m_index].front () + 1 >= mp_properties_pages [index]->count ()) { ++index; } @@ -685,12 +704,12 @@ PropertiesDialog::any_next () const bool PropertiesDialog::any_prev () const { - if (m_object_indexes.empty ()) { + if (m_index < 0 || m_object_indexes [m_index].empty ()) { return false; } int index = m_index; - if (m_object_indexes.front () == 0) { + if (m_object_indexes [m_index].front () == 0) { --index; } diff --git a/src/layui/layui/layPropertiesDialog.h b/src/layui/layui/layPropertiesDialog.h index c4b563d52..6eccc164e 100644 --- a/src/layui/layui/layPropertiesDialog.h +++ b/src/layui/layui/layPropertiesDialog.h @@ -95,7 +95,7 @@ private: db::Manager *mp_manager; lay::Editables *mp_editables; int m_index, m_prev_index; - std::vector m_object_indexes; + std::vector > m_object_indexes; QStackedLayout *mp_stack; QLabel *mp_none; lay::MainWindow *mp_mw; diff --git a/src/layui/layui/layWidgets.cc b/src/layui/layui/layWidgets.cc index 59ffec027..74c47d22c 100644 --- a/src/layui/layui/layWidgets.cc +++ b/src/layui/layui/layWidgets.cc @@ -514,7 +514,7 @@ struct LayerSelectionComboBoxPrivateData }; LayerSelectionComboBox::LayerSelectionComboBox (QWidget *parent) - : QComboBox (parent), dm_update_layer_list (this, &LayerSelectionComboBox::do_update_layer_list) + : QComboBox (parent), dm_update_layer_list (this, &LayerSelectionComboBox::do_update_layer_list), m_ignore_layer_list_changed (false) { mp_private = new LayerSelectionComboBoxPrivateData (); mp_private->no_layer_available = false; @@ -651,7 +651,9 @@ LayerSelectionComboBox::set_view (lay::LayoutViewBase *view, int cv_index, bool void LayerSelectionComboBox::on_layer_list_changed (int) { - update_layer_list (); + if (! m_ignore_layer_list_changed) { + update_layer_list (); + } } void @@ -795,8 +797,8 @@ LayerSelectionComboBox::set_current_layer (const db::LayerProperties &props) setCurrentIndex (-1); } -void -LayerSelectionComboBox::set_current_layer (int l) +const db::Layout * +LayerSelectionComboBox::layout () const { const db::Layout *layout = mp_private->layout; if (! layout && mp_private->view) { @@ -805,9 +807,22 @@ LayerSelectionComboBox::set_current_layer (int l) layout = & cv->layout (); } } + return layout; +} - if (l >= 0 && layout && layout->is_valid_layer ((unsigned int) l)) { - mp_private->last_props = layout->get_properties ((unsigned int) l); +db::Layout * +LayerSelectionComboBox::layout () +{ + return const_cast (((const LayerSelectionComboBox *) this)->layout ()); +} + +void +LayerSelectionComboBox::set_current_layer (int l) +{ + const db::Layout *ly = layout (); + + if (l >= 0 && ly && ly->is_valid_layer ((unsigned int) l)) { + mp_private->last_props = ly->get_properties ((unsigned int) l); } if (l < 0) { @@ -821,6 +836,12 @@ LayerSelectionComboBox::set_current_layer (int l) } } +bool +LayerSelectionComboBox::is_no_layer_selected () const +{ + return currentIndex () < 0; +} + int LayerSelectionComboBox::current_layer () const { @@ -832,7 +853,40 @@ LayerSelectionComboBox::current_layer () const } } -db::LayerProperties +int +LayerSelectionComboBox::current_layer_ensure () +{ + int i = currentIndex (); + if (i < 0 || i > int (mp_private->layers.size ())) { + + return -1; + + } else if (mp_private->layers [i].second < 0) { + + db::Layout *ly = layout (); + if (! ly) { + return -1; + } + + m_ignore_layer_list_changed = true; + try { + unsigned int l = ly->insert_layer (mp_private->layers [i].first); + mp_private->layers [i].second = l; + m_ignore_layer_list_changed = false; + return l; + } catch (...) { + m_ignore_layer_list_changed = false; + throw; + } + + } else { + + return mp_private->layers [i].second; + + } +} + +db::LayerProperties LayerSelectionComboBox::current_layer_props () const { int i = currentIndex (); diff --git a/src/layui/layui/layWidgets.h b/src/layui/layui/layWidgets.h index b5261d9d8..ccba0d32c 100644 --- a/src/layui/layui/layWidgets.h +++ b/src/layui/layui/layWidgets.h @@ -300,13 +300,37 @@ public: */ void set_current_layer (int l); + /** + * @brief Gets a valid indicating whether a layer is selected + * + * This method returns true if "no layer" is selected + */ + bool is_no_layer_selected () const; + /** * @brief Get the current layer (index) + * + * NOTE: this method returns -1 if no layer is selected or + * the current layer does not exist. Use "is_no_layer_selected" + * for a value telling whether no layer is selected (true) + * or a not-yet-existing layer is selected (false). */ int current_layer () const; + /** + * @brief Get the current layer (index) and makes sure it exists + * + * This method ensures that the layer is created if it does not + * exist yet. It returns -1 on "no layer" (if enabled). + */ + int current_layer_ensure (); + /** * @brief Get the current layer properties + * + * If "no layer" is selected, this method returns the last properties set + * with "set_current_layer". Use "is_no_layer_selected" to get + * a value indicating whether the "no layer" entry is selected. */ db::LayerProperties current_layer_props () const; @@ -323,10 +347,13 @@ protected slots: private: LayerSelectionComboBoxPrivateData *mp_private; tl::DeferredMethod dm_update_layer_list; + bool m_ignore_layer_list_changed; void on_layer_list_changed (int); void update_layer_list (); void do_update_layer_list (); + db::Layout *layout (); + const db::Layout *layout () const; }; /**