diff --git a/src/edt/edt/edtEditorOptionsPages.cc b/src/edt/edt/edtEditorOptionsPages.cc index 89f16ab0a..669ae0503 100644 --- a/src/edt/edt/edtEditorOptionsPages.cc +++ b/src/edt/edt/edtEditorOptionsPages.cc @@ -29,6 +29,7 @@ #include "edtConfig.h" #include "edtService.h" #include "edtEditorOptionsPages.h" +#include "edtPropertiesPageUtils.h" #include "tlExceptions.h" #include "layPlugin.h" #include "layLayoutView.h" @@ -196,24 +197,6 @@ END_PROTECTED_W (this) // ------------------------------------------------------------------ // Indicates an error on a line edit -static void indicate_error (QLineEdit *le, const tl::Exception *ex) -{ - // by the way, update the foreground color of the cell edit box as well (red, if not valid) - QPalette pl = le->palette (); - if (ex) { - pl.setColor (QPalette::Active, QPalette::Text, Qt::red); - pl.setColor (QPalette::Active, QPalette::Base, QColor (Qt::red).lighter (180)); - le->setToolTip (tl::to_qstring (ex->msg ())); - } else { - QWidget *pw = dynamic_cast (le->parent ()); - tl_assert (pw != 0); - pl.setColor (QPalette::Active, QPalette::Text, pw->palette ().color (QPalette::Text)); - pl.setColor (QPalette::Active, QPalette::Base, pw->palette ().color (QPalette::Base)); - le->setToolTip (QString ()); - } - le->setPalette (pl); -} - template static void configure_from_line_edit (lay::Dispatcher *dispatcher, QLineEdit *le, const std::string &cfg_name) { diff --git a/src/edt/edt/edtInstPropertiesPage.cc b/src/edt/edt/edtInstPropertiesPage.cc index fa791a381..84aaf83ca 100644 --- a/src/edt/edt/edtInstPropertiesPage.cc +++ b/src/edt/edt/edtInstPropertiesPage.cc @@ -65,6 +65,21 @@ InstPropertiesPage::InstPropertiesPage (edt::Service *service, db::Manager *mana connect (lib_cbx, SIGNAL (currentIndexChanged (int)), this, SLOT (library_changed (int))); connect (cell_name_le, SIGNAL (textChanged (const QString &)), this, SLOT (cell_name_changed (const QString &))); + connect (lib_cbx, SIGNAL (activated (int)), this, SIGNAL (edited ())); + connect (cell_name_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (array_grp, SIGNAL (clicked ()), this, SIGNAL (edited ())); + connect (rows_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (columns_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (row_x_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (row_y_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (column_x_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (column_y_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (pos_x_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (pos_y_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (angle_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (mag_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (mirror_cbx, SIGNAL (clicked ()), this, SIGNAL (edited ())); + QHBoxLayout *layout = new QHBoxLayout (pcell_tab); layout->setMargin (0); pcell_tab->setLayout (layout); @@ -125,12 +140,19 @@ BEGIN_PROTECTED } if (form.exec ()) { + + cell_name_le->blockSignals (true); if (form.selected_cell_is_pcell ()) { cell_name_le->setText (tl::to_qstring (layout->pcell_header (form.selected_pcell_id ())->get_name ())); } else if (layout->is_valid_cell_index (form.selected_cell_index ())) { cell_name_le->setText (tl::to_qstring (layout->cell_name (form.selected_cell_index ()))); } + cell_name_le->blockSignals (false); + update_pcell_parameters (); + + emit edited (); + } END_PROTECTED @@ -140,7 +162,9 @@ void InstPropertiesPage::show_props () { lay::UserPropertiesForm props_form (this); - 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_index]->cv_index (), m_prop_id)) { + emit edited (); + } } void @@ -222,6 +246,7 @@ InstPropertiesPage::update () db::cell_index_type def_cell_index = pos->back ().inst_ptr.cell_index (); const db::Cell &def_cell = def_layout->cell (def_cell_index); + lib_cbx->blockSignals (true); std::pair dl = def_layout->defining_library (def_cell_index); lib_cbx->set_technology_filter (cv->tech_name (), true); lib_cbx->set_current_library (dl.first); @@ -229,13 +254,16 @@ InstPropertiesPage::update () def_layout = &dl.first->layout (); def_cell_index = dl.second; } + lib_cbx->blockSignals (false); std::pair pci = def_layout->is_pcell_instance (def_cell_index); + cell_name_le->blockSignals (true); if (pci.first && def_layout->pcell_declaration (pci.second)) { cell_name_le->setText (tl::to_qstring (def_layout->pcell_header (pci.second)->get_name ())); } else { cell_name_le->setText (tl::to_qstring (def_layout->cell_name (def_cell_index))); } + cell_name_le->blockSignals (false); db::Vector rowv, columnv; unsigned long rows, columns; @@ -325,6 +353,9 @@ InstPropertiesPage::readonly () ChangeApplicator * InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & /*inst*/, double dbu) { + bool has_error = false; + bool has_pcell_error = false; + std::auto_ptr appl (new CombinedChangeApplicator ()); edt::Service::obj_iterator pos = m_selection_ptrs [m_index]; @@ -343,34 +374,69 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & layout = &cv->layout (); } - std::pair ci = layout->cell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); - std::pair pci = layout->pcell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); - if (! ci.first && ! pci.first) { - throw tl::Exception (tl::to_string (QObject::tr ("Not a valid cell name: %s")).c_str (), tl::to_string (cell_name_le->text ()).c_str ()); + try { + + std::pair ci = layout->cell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); + std::pair pci = layout->pcell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); + if (! ci.first && ! pci.first) { + throw tl::Exception (tl::to_string (QObject::tr ("Not a valid cell or PCell name: %s")).c_str (), tl::to_string (cell_name_le->text ()).c_str ()); + } + + indicate_error (cell_name_le, 0); + + } catch (tl::Exception &ex) { + indicate_error (cell_name_le, &ex); + has_error = true; } - db::cell_index_type inst_cell_index = ci.second; + try { - // instantiate the PCell - if (pci.first) { - tl_assert (mp_pcell_parameters != 0); - tl_assert (layout->pcell_declaration (pci.second) == mp_pcell_parameters->pcell_decl ()); - inst_cell_index = layout->get_pcell_variant (pci.second, mp_pcell_parameters->get_parameters ()); - } + std::pair ci = layout->cell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); + std::pair pci = layout->pcell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); + tl_assert (ci.first || pci.first); - // reference the library - if (lib) { - layout = & cv->layout (); - inst_cell_index = layout->get_lib_proxy (lib, inst_cell_index); - } + db::cell_index_type inst_cell_index = 0; - if (inst_cell_index != pos->back ().inst_ptr.cell_index ()) { - appl->add (new ChangeTargetCellApplicator (inst_cell_index)); + // instantiate the PCell + if (pci.first) { + tl_assert (mp_pcell_parameters != 0); + tl_assert (layout->pcell_declaration (pci.second) == mp_pcell_parameters->pcell_decl ()); + inst_cell_index = layout->get_pcell_variant (pci.second, mp_pcell_parameters->get_parameters ()); + } else { + inst_cell_index = ci.second; + } + + // reference the library + if (lib) { + layout = & cv->layout (); + inst_cell_index = layout->get_lib_proxy (lib, inst_cell_index); + } + + if (inst_cell_index != pos->back ().inst_ptr.cell_index ()) { + appl->add (new ChangeTargetCellApplicator (inst_cell_index)); + } + + } catch (tl::Exception &ex) { + has_pcell_error = true; } double x = 0.0, y = 0.0; - tl::from_string (tl::to_string (pos_x_le->text ()), x); - tl::from_string (tl::to_string (pos_y_le->text ()), y); + + try { + tl::from_string (tl::to_string (pos_x_le->text ()), x); + indicate_error (pos_x_le, 0); + } catch (tl::Exception &ex) { + indicate_error (pos_x_le, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (pos_y_le->text ()), y); + indicate_error (pos_y_le, 0); + } catch (tl::Exception &ex) { + indicate_error (pos_y_le, &ex); + has_error = true; + } db::DCplxTrans t; if (abs_cb->isChecked ()) { @@ -381,20 +447,32 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & bool mirror = mirror_cbx->isChecked (); double angle = 0.0; - tl::from_string (tl::to_string (angle_le->text ()), angle); + try { + tl::from_string (tl::to_string (angle_le->text ()), angle); + indicate_error (angle_le, 0); + } catch (tl::Exception &ex) { + indicate_error (angle_le, &ex); + has_error = true; + } double mag = 0.0; - tl::from_string (tl::to_string (mag_le->text ()), mag); + try { + tl::from_string (tl::to_string (mag_le->text ()), mag); + indicate_error (mag_le, 0); + } catch (tl::Exception &ex) { + indicate_error (mag_le, &ex); + has_error = true; + } angle -= (floor (angle / 360.0) + 1.0) * 360.0; while (angle < -1e-6) { angle += 360.0; } - db::CellInstArray::complex_trans_type tr = pos->back ().inst_ptr.complex_trans (); + db::CellInstArray::complex_trans_type trans = pos->back ().inst_ptr.complex_trans (); - if (fabs (angle - tr.angle ()) > 1e-6 || mirror != tr.is_mirror () || fabs (mag - tr.mag ()) > 1e-6 || ! disp.equal (tr.disp () * dbu)) { - appl->add (new ChangeInstanceTransApplicator (angle, tr.angle (), mirror, tr.is_mirror (), mag, tr.mag (), disp, tr.disp () * dbu)); + if (fabs (angle - trans.angle ()) > 1e-6 || mirror != trans.is_mirror () || fabs (mag - trans.mag ()) > 1e-6 || ! disp.equal (trans.disp () * dbu)) { + appl->add (new ChangeInstanceTransApplicator (angle, trans.angle (), mirror, trans.is_mirror (), mag, trans.mag (), disp, trans.disp () * dbu)); } db::CellInstArray::vector_type a_org, b_org; @@ -407,12 +485,53 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & double rx = 0.0, ry = 0.0; unsigned long rows = 0, cols = 0; - tl::from_string (tl::to_string (column_x_le->text ()), cx); - tl::from_string (tl::to_string (column_y_le->text ()), cy); - tl::from_string (tl::to_string (row_x_le->text ()), rx); - tl::from_string (tl::to_string (row_y_le->text ()), ry); - tl::from_string (tl::to_string (rows_le->text ()), rows); - tl::from_string (tl::to_string (columns_le->text ()), cols); + try { + tl::from_string (tl::to_string (column_x_le->text ()), cx); + indicate_error (column_x_le, 0); + } catch (tl::Exception &ex) { + indicate_error (column_x_le, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (column_y_le->text ()), cy); + indicate_error (column_y_le, 0); + } catch (tl::Exception &ex) { + indicate_error (column_y_le, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (row_x_le->text ()), rx); + indicate_error (row_x_le, 0); + } catch (tl::Exception &ex) { + indicate_error (row_x_le, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (row_y_le->text ()), ry); + indicate_error (row_y_le, 0); + } catch (tl::Exception &ex) { + indicate_error (row_y_le, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (rows_le->text ()), rows); + indicate_error (rows_le, 0); + } catch (tl::Exception &ex) { + indicate_error (rows_le, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (columns_le->text ()), cols); + indicate_error (columns_le, 0); + } catch (tl::Exception &ex) { + indicate_error (columns_le, &ex); + has_error = true; + } db::DVector rv = db::DVector (dpoint_from_dpoint (db::DPoint (rx, ry), dbu, du, t)); db::DVector cv = db::DVector (dpoint_from_dpoint (db::DPoint (cx, cy), dbu, du, t)); @@ -432,6 +551,14 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & } + if (has_error || has_pcell_error) { + throw tl::Exception (tl::to_string (tr ("At least one value and PCell parameter is not correct - see hightlighted entry fields or the PCell error indicator"))); + } else if (has_error) { + throw tl::Exception (tl::to_string (tr ("At least one value is not correct - see hightlighted entry fields"))); + } else if (has_pcell_error) { + throw tl::Exception (tl::to_string (tr ("At least one PCell parameter is not correct - see hightlighted entry fields or the PCell error indicator"))); + } + return appl.release (); } @@ -565,6 +692,9 @@ InstPropertiesPage::do_apply (bool current_only) size_t index = p - m_selection_ptrs.begin (); + // save previous selection so we can restore it + m_saved_selection.push_back (std::make_pair (index, new_sel[index])); + // change selection to new instance new_sel[index].back ().inst_ptr = new_inst; @@ -636,16 +766,13 @@ InstPropertiesPage::update_pcell_parameters () std::pair pc = layout->pcell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); std::pair cc = layout->cell_by_name (tl::to_string (cell_name_le->text ()).c_str ()); - // by the way, update the foreground color of the cell edit box as well (red, if not valid) - QPalette pl = cell_name_le->palette (); + // indicate an invalid cell name if (! pc.first && ! cc.first) { - pl.setColor (QPalette::Text, Qt::red); - pl.setColor (QPalette::Base, QColor (Qt::red).lighter (180)); + tl::Exception ex (tl::to_string (QObject::tr ("Not a valid cell or PCell name: %s")).c_str (), tl::to_string (cell_name_le->text ()).c_str ()); + indicate_error (cell_name_le, &ex); } else { - pl.setColor (QPalette::Text, palette ().color (QPalette::Text)); - pl.setColor (QPalette::Base, palette ().color (QPalette::Base)); + indicate_error (cell_name_le, 0); } - cell_name_le->setPalette (pl); if (pc.first && layout->pcell_declaration (pc.second)) { @@ -687,13 +814,13 @@ InstPropertiesPage::update_pcell_parameters () } mp_pcell_parameters = new PCellParametersPage (pcell_tab); + connect (mp_pcell_parameters, SIGNAL (edited ()), this, SIGNAL (edited ())); mp_pcell_parameters->setup (&cv->layout (), mp_service->view (), pos->cv_index (), layout->pcell_declaration (pc.second), parameters); pcell_tab->layout ()->addWidget (mp_pcell_parameters); } param_tab_widget->setTabEnabled (1, true); - param_tab_widget->setCurrentIndex (1); } else { @@ -705,8 +832,11 @@ InstPropertiesPage::update_pcell_parameters () mp_pcell_parameters = 0; - param_tab_widget->setCurrentIndex (0); + if (param_tab_widget->currentIndex () == 1) { + param_tab_widget->setCurrentIndex (0); + } param_tab_widget->setTabEnabled (1, false); + } } diff --git a/src/edt/edt/edtInstPropertiesPage.h b/src/edt/edt/edtInstPropertiesPage.h index f648482dc..ca4acb932 100644 --- a/src/edt/edt/edtInstPropertiesPage.h +++ b/src/edt/edt/edtInstPropertiesPage.h @@ -65,6 +65,7 @@ protected: bool m_enable_cb_callback; db::properties_id_type m_prop_id; edt::PCellParametersPage *mp_pcell_parameters; + std::list > m_saved_selection; virtual bool readonly (); virtual void apply (); diff --git a/src/edt/edt/edtPCellParametersPage.cc b/src/edt/edt/edtPCellParametersPage.cc index 670610982..f55ce5c28 100644 --- a/src/edt/edt/edtPCellParametersPage.cc +++ b/src/edt/edt/edtPCellParametersPage.cc @@ -22,6 +22,7 @@ #include "edtPCellParametersPage.h" +#include "edtPropertiesPageUtils.h" #include "layWidgets.h" #include "tlScriptError.h" @@ -38,24 +39,6 @@ namespace edt { -static void indicate_error (QLineEdit *le, const tl::Exception *ex) -{ - // by the way, update the foreground color of the cell edit box as well (red, if not valid) - QPalette pl = le->palette (); - if (ex) { - pl.setColor (QPalette::Active, QPalette::Text, Qt::red); - pl.setColor (QPalette::Active, QPalette::Base, QColor (Qt::red).lighter (180)); - le->setToolTip (tl::to_qstring (ex->msg ())); - } else { - QWidget *pw = dynamic_cast (le->parent ()); - tl_assert (pw != 0); - pl.setColor (QPalette::Active, QPalette::Text, pw->palette ().color (QPalette::Text)); - pl.setColor (QPalette::Active, QPalette::Base, pw->palette ().color (QPalette::Base)); - le->setToolTip (QString ()); - } - le->setPalette (pl); -} - static void set_value (const db::PCellParameterDeclaration &p, const db::Layout * /*layout*/, QWidget *widget, const tl::Variant &value) { if (p.get_choices ().empty ()) { diff --git a/src/edt/edt/edtPropertiesPageUtils.cc b/src/edt/edt/edtPropertiesPageUtils.cc index 1bb1c9477..8b1490af5 100644 --- a/src/edt/edt/edtPropertiesPageUtils.cc +++ b/src/edt/edt/edtPropertiesPageUtils.cc @@ -26,6 +26,8 @@ #include "dbShapes.h" #include "dbLayout.h" +#include + namespace edt { @@ -784,5 +786,24 @@ coords_to_string (const db::DPoint &dp, double dbu, bool du, const char *sep) return coord_to_string (dp.x (), dbu, du) + sep + coord_to_string (dp.y (), dbu, du); } +void +indicate_error (QLineEdit *le, const tl::Exception *ex) +{ + // by the way, update the foreground color of the cell edit box as well (red, if not valid) + QPalette pl = le->palette (); + if (ex) { + pl.setColor (QPalette::Active, QPalette::Text, Qt::red); + pl.setColor (QPalette::Active, QPalette::Base, QColor (Qt::red).lighter (180)); + le->setToolTip (tl::to_qstring (ex->msg ())); + } else { + QWidget *pw = dynamic_cast (le->parent ()); + tl_assert (pw != 0); + pl.setColor (QPalette::Active, QPalette::Text, pw->palette ().color (QPalette::Text)); + pl.setColor (QPalette::Active, QPalette::Base, pw->palette ().color (QPalette::Base)); + le->setToolTip (QString ()); + } + le->setPalette (pl); +} + } diff --git a/src/edt/edt/edtPropertiesPageUtils.h b/src/edt/edt/edtPropertiesPageUtils.h index fc43c71ae..8735e5074 100644 --- a/src/edt/edt/edtPropertiesPageUtils.h +++ b/src/edt/edt/edtPropertiesPageUtils.h @@ -33,6 +33,8 @@ #include +class QLineEdit; + namespace edt { @@ -478,6 +480,11 @@ db::Point point_from_dpoint (const db::DPoint &dp, double dbu, bool du, const db */ db::Coord coord_from_string (const char *txt, double dbu, bool du, const db::VCplxTrans &t); +/** + * @brief Configures a QLineEdit to indicate a format error + */ +void indicate_error (QLineEdit *le, const tl::Exception *ex); + } #endif diff --git a/src/laybasic/laybasic/layEditable.cc b/src/laybasic/laybasic/layEditable.cc index 8b75008f1..e09044dde 100644 --- a/src/laybasic/laybasic/layEditable.cc +++ b/src/laybasic/laybasic/layEditable.cc @@ -80,6 +80,11 @@ Editables::Editables (db::Manager *manager) Editables::~Editables () { cancel_edits (); + + if (mp_properties_dialog) { + delete mp_properties_dialog; + mp_properties_dialog = 0; + } } void @@ -610,9 +615,8 @@ Editables::cancel_edits () { // close the property dialog if (mp_properties_dialog) { - delete mp_properties_dialog; + mp_properties_dialog->hide (); } - mp_properties_dialog = 0; // cancel any edit operations for (iterator e = begin (); e != end (); ++e) { @@ -623,7 +627,10 @@ Editables::cancel_edits () void Editables::show_properties (QWidget *parent) { - cancel_edits (); + // re-create a new properties dialog + if (mp_properties_dialog) { + delete mp_properties_dialog; + } mp_properties_dialog = new lay::PropertiesDialog (parent, manager (), this); mp_properties_dialog->show (); } diff --git a/src/laybasic/laybasic/layProperties.h b/src/laybasic/laybasic/layProperties.h index 6c918b8c0..a8fba1677 100644 --- a/src/laybasic/laybasic/layProperties.h +++ b/src/laybasic/laybasic/layProperties.h @@ -48,6 +48,8 @@ class Editable; class LAYBASIC_PUBLIC PropertiesPage : public QFrame { +Q_OBJECT + public: /** * @brief The constructor attaching the properties page to a parent widget @@ -140,7 +142,7 @@ public: */ virtual void operator++ () = 0; - /** + /** * @brief Update the display * * This method is called by the dialog to transfer data from the @@ -219,6 +221,12 @@ public: return mp_manager; } +signals: + /** + * @brief This signal is emitted if a value has been changed + */ + void edited (); + private: db::Manager *mp_manager; lay::Editable *mp_editable; diff --git a/src/laybasic/laybasic/layPropertiesDialog.cc b/src/laybasic/laybasic/layPropertiesDialog.cc index 31bdb36ce..1c823c561 100644 --- a/src/laybasic/laybasic/layPropertiesDialog.cc +++ b/src/laybasic/laybasic/layPropertiesDialog.cc @@ -35,7 +35,7 @@ namespace lay PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager, lay::Editables *editables) : QDialog (0 /*parent*/), - mp_manager (manager), mp_editables (editables), m_index (-1) + mp_manager (manager), mp_editables (editables), m_index (-1), m_auto_applied (false), m_transaction_id (0) { mp_editables->enable_edits (false); @@ -49,6 +49,7 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager, mp_properties_pages.push_back (e->properties_page (mp_manager, content_frame)); if (mp_properties_pages.back ()) { mp_stack->addWidget (mp_properties_pages.back ()); + connect (mp_properties_pages.back (), SIGNAL (edited ()), this, SLOT (apply ())); } } @@ -130,8 +131,9 @@ PropertiesDialog::next_pressed () BEGIN_PROTECTED if (! mp_properties_pages [m_index]->readonly ()) { - db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes"))); + db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")), m_transaction_id); mp_properties_pages [m_index]->apply (); + m_transaction_id = t.id (); } // advance the current entry @@ -171,8 +173,9 @@ PropertiesDialog::prev_pressed () BEGIN_PROTECTED if (! mp_properties_pages [m_index]->readonly ()) { - db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes"))); + db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")), m_transaction_id); mp_properties_pages [m_index]->apply (); + m_transaction_id = t.id (); } if (mp_properties_pages [m_index]->at_begin ()) { @@ -256,30 +259,68 @@ PropertiesDialog::apply_to_all_pressed () { BEGIN_PROTECTED - db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes to all"))); + { + db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes to all")), m_transaction_id); - mp_properties_pages [m_index]->apply_to_all (); - mp_properties_pages [m_index]->update (); + mp_properties_pages [m_index]->apply_to_all (); + mp_properties_pages [m_index]->update (); + + m_transaction_id = t.id (); + } END_PROTECTED } -void +void +PropertiesDialog::apply () +{ +BEGIN_PROTECTED + + db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Auto-apply changes")), m_transaction_id); + + try { + + mp_properties_pages [m_index]->apply (); + mp_properties_pages [m_index]->update (); + + } catch (tl::Exception &) { + // we assume the page somehow indicates the error and does not apply the values + } + + m_transaction_id = t.id (); + +END_PROTECTED +} + +void PropertiesDialog::apply_pressed () { BEGIN_PROTECTED - db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes"))); + db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")), m_transaction_id); mp_properties_pages [m_index]->apply (); mp_properties_pages [m_index]->update (); + m_transaction_id = t.id (); + END_PROTECTED } void PropertiesDialog::cancel_pressed () { + // undo whatever we've done so far + if (m_transaction_id > 0) { + + // because undo does not maintain a valid selection we clear it + mp_editables->clear_selection (); + + mp_manager->undo (); + m_transaction_id = 0; + + } + // make sure that the property pages are no longer used .. disconnect (); // close the dialog @@ -293,11 +334,13 @@ BEGIN_PROTECTED if (! mp_properties_pages [m_index]->readonly ()) { - db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes"))); + db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")), m_transaction_id); mp_properties_pages [m_index]->apply (); mp_properties_pages [m_index]->update (); + m_transaction_id = t.id (); + } // make sure that the property pages are no longer used .. diff --git a/src/laybasic/laybasic/layPropertiesDialog.h b/src/laybasic/laybasic/layPropertiesDialog.h index c06efcb69..5dcb209b7 100644 --- a/src/laybasic/laybasic/layPropertiesDialog.h +++ b/src/laybasic/laybasic/layPropertiesDialog.h @@ -32,12 +32,11 @@ #include #include +#include + #include "ui_PropertiesDialog.h" -namespace db -{ - class Manager; -} +#include class QStackedLayout; @@ -74,13 +73,15 @@ public: ~PropertiesDialog (); private: - std::vector mp_properties_pages; + std::vector mp_properties_pages; db::Manager *mp_manager; lay::Editables *mp_editables; int m_index; QStackedLayout *mp_stack; lay::MainWindow *mp_mw; size_t m_objects, m_current_object; + bool m_auto_applied; + db::Manager::transaction_id_t m_transaction_id; void disconnect (); bool any_prev () const; @@ -88,6 +89,7 @@ private: void update_title (); public slots: + void apply (); void next_pressed (); void prev_pressed (); void apply_pressed ();