From 3003eb96e73f8ee6d35bbfad5ad46e200ceb5b60 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 26 Aug 2020 00:38:41 +0200 Subject: [PATCH] WIP: life updated on most shape properties, some bug fixes. --- src/edt/edt/edtInstPropertiesPage.cc | 88 ++-- src/edt/edt/edtInstPropertiesPage.h | 5 +- src/edt/edt/edtPropertiesPageUtils.cc | 2 +- src/edt/edt/edtPropertiesPageUtils.h | 2 +- src/edt/edt/edtPropertiesPages.cc | 477 +++++++++++++------ src/edt/edt/edtPropertiesPages.h | 21 +- src/laybasic/laybasic/PropertiesDialog.ui | 94 +++- src/laybasic/laybasic/layLayoutView.cc | 2 +- src/laybasic/laybasic/layProperties.h | 2 +- src/laybasic/laybasic/layPropertiesDialog.cc | 68 +-- src/laybasic/laybasic/layPropertiesDialog.h | 2 - 11 files changed, 482 insertions(+), 281 deletions(-) diff --git a/src/edt/edt/edtInstPropertiesPage.cc b/src/edt/edt/edtInstPropertiesPage.cc index 84aaf83ca..b3f8cc1c7 100644 --- a/src/edt/edt/edtInstPropertiesPage.cc +++ b/src/edt/edt/edtInstPropertiesPage.cc @@ -65,20 +65,42 @@ 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 ())); + if (! readonly ()) { + + 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 ())); + + } else { + + browse_pb->setEnabled (false); + cell_name_le->setReadOnly (true); + rows_le->setReadOnly (true); + columns_le->setReadOnly (true); + row_x_le->setReadOnly (true); + row_y_le->setReadOnly (true); + column_x_le->setReadOnly (true); + column_y_le->setReadOnly (true); + pos_x_le->setReadOnly (true); + pos_y_le->setReadOnly (true); + angle_le->setReadOnly (true); + mag_le->setReadOnly (true); + lib_cbx->setEnabled (false); + array_grp->setEnabled (false); + mirror_cbx->setEnabled (false); + + } QHBoxLayout *layout = new QHBoxLayout (pcell_tab); layout->setMargin (0); @@ -580,7 +602,7 @@ InstPropertiesPage::recompute_selection_ptrs (const std::vectorview ()->layer_snapshot (); unsigned int cv_index = m_selection_ptrs [m_index]->cv_index (); @@ -609,32 +631,7 @@ InstPropertiesPage::do_apply (bool current_only) bool relative_mode = false; if (! current_only && applicator->supports_relative_mode ()) { - - static bool s_relative_mode = true; - - QMessageBox mb (QMessageBox::Question, - tr ("Apply Changes To All"), - tr ("For this operation absolute or relative mode is available which affects the way parameters of the selected objects are changed:\n\n" - "In absolute mode, they will be set to the given value. In relative mode, they will be adjusted by the same amount.\n"), - QMessageBox::NoButton, this); - - mb.addButton (tr ("Cancel"), QMessageBox::RejectRole); - QPushButton *absolute = mb.addButton (tr ("Absolute"), QMessageBox::NoRole); - QPushButton *relative = mb.addButton (tr ("Relative"), QMessageBox::YesRole); - - mb.setDefaultButton (s_relative_mode ? relative : absolute); - - mb.exec (); - - if (mb.clickedButton () == absolute) { - s_relative_mode = relative_mode = false; - } else if (mb.clickedButton () == relative) { - s_relative_mode = relative_mode = true; - } else { - // Cancel pressed - return; - } - + relative_mode = relative; } // Note: using the apply-all scheme for applying a single change may look like overhead. @@ -692,9 +689,6 @@ 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; @@ -729,7 +723,7 @@ InstPropertiesPage::do_apply (bool current_only) void InstPropertiesPage::apply () { - do_apply (true); + do_apply (true, false); } bool @@ -739,9 +733,9 @@ InstPropertiesPage::can_apply_to_all () const } void -InstPropertiesPage::apply_to_all () +InstPropertiesPage::apply_to_all (bool relative) { - do_apply (false); + do_apply (false, relative); } void diff --git a/src/edt/edt/edtInstPropertiesPage.h b/src/edt/edt/edtInstPropertiesPage.h index ca4acb932..28394f4b3 100644 --- a/src/edt/edt/edtInstPropertiesPage.h +++ b/src/edt/edt/edtInstPropertiesPage.h @@ -65,13 +65,12 @@ 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 (); - virtual void apply_to_all (); + virtual void apply_to_all (bool relative); virtual bool can_apply_to_all () const; - void do_apply (bool current_only); + void do_apply (bool current_only, bool relative); virtual ChangeApplicator *create_applicator (db::Cell &cell, const db::Instance &inst, double dbu); protected slots: diff --git a/src/edt/edt/edtPropertiesPageUtils.cc b/src/edt/edt/edtPropertiesPageUtils.cc index 8b1490af5..801d0c57e 100644 --- a/src/edt/edt/edtPropertiesPageUtils.cc +++ b/src/edt/edt/edtPropertiesPageUtils.cc @@ -787,7 +787,7 @@ coords_to_string (const db::DPoint &dp, double dbu, bool du, const char *sep) } void -indicate_error (QLineEdit *le, const tl::Exception *ex) +indicate_error (QWidget *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 (); diff --git a/src/edt/edt/edtPropertiesPageUtils.h b/src/edt/edt/edtPropertiesPageUtils.h index 8735e5074..74a33b672 100644 --- a/src/edt/edt/edtPropertiesPageUtils.h +++ b/src/edt/edt/edtPropertiesPageUtils.h @@ -483,7 +483,7 @@ db::Coord coord_from_string (const char *txt, double dbu, bool du, const db::VCp /** * @brief Configures a QLineEdit to indicate a format error */ -void indicate_error (QLineEdit *le, const tl::Exception *ex); +void indicate_error (QWidget *le, const tl::Exception *ex); } diff --git a/src/edt/edt/edtPropertiesPages.cc b/src/edt/edt/edtPropertiesPages.cc index 8250241bb..2cf797f2e 100644 --- a/src/edt/edt/edtPropertiesPages.cc +++ b/src/edt/edt/edtPropertiesPages.cc @@ -24,6 +24,7 @@ #include "edtPropertiesPages.h" #include "edtPropertiesPageUtils.h" #include "edtDialogs.h" +#include "edtPropertiesPageUtils.h" #include "layDialogs.h" #include "layObjectInstPath.h" #include "layLayoutView.h" @@ -174,7 +175,7 @@ ShapePropertiesPage::recompute_selection_ptrs (const std::vector applicator; @@ -203,32 +204,7 @@ ShapePropertiesPage::do_apply (bool current_only) // Ask whether to use relative or absolute mode bool relative_mode = false; if (! current_only && applicator->supports_relative_mode ()) { - - static bool s_relative_mode = true; - - QMessageBox mb (QMessageBox::Question, - tr ("Apply Changes To All"), - tr ("For this operation absolute or relative mode is available which affects the way parameters of the selected objects are changed:\n\n" - "In absolute mode, they will be set to the given value. In relative mode, they will be adjusted by the same amount.\n"), - QMessageBox::NoButton, this); - - mb.addButton (tr ("Cancel"), QMessageBox::RejectRole); - QPushButton *absolute = mb.addButton (tr ("Absolute"), QMessageBox::NoRole); - QPushButton *relative = mb.addButton (tr ("Relative"), QMessageBox::YesRole); - - mb.setDefaultButton (s_relative_mode ? relative : absolute); - - mb.exec (); - - if (mb.clickedButton () == absolute) { - s_relative_mode = relative_mode = false; - } else if (mb.clickedButton () == relative) { - s_relative_mode = relative_mode = true; - } else { - // Cancel pressed - return; - } - + relative_mode = relative; } // Note: using the apply-all scheme for applying a single change may look like overhead. @@ -333,7 +309,7 @@ ShapePropertiesPage::do_apply (bool current_only) void ShapePropertiesPage::apply () { - do_apply (true); + do_apply (true, false); } bool @@ -343,9 +319,9 @@ ShapePropertiesPage::can_apply_to_all () const } void -ShapePropertiesPage::apply_to_all () +ShapePropertiesPage::apply_to_all (bool relative) { - do_apply (false); + do_apply (false, relative); } void @@ -391,7 +367,9 @@ void ShapePropertiesPage::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 (); + } } bool @@ -404,13 +382,19 @@ ShapePropertiesPage::readonly () // PolygonPropertiesPage implementation PolygonPropertiesPage::PolygonPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent) - : ShapePropertiesPage (service, manager, parent) + : ShapePropertiesPage (service, manager, parent), m_in_text_changed (false) { setupUi (this); setup (); connect (inst_pb, SIGNAL (clicked ()), this, SLOT (show_inst ())); connect (prop_pb, SIGNAL (clicked ()), this, SLOT (show_props ())); + + if (! readonly ()) { + connect (pointListEdit, SIGNAL (textChanged ()), this, SLOT (text_changed ())); + } else { + pointListEdit->setReadOnly (true); + } } void @@ -448,61 +432,87 @@ PolygonPropertiesPage::do_update (const db::Shape &shape, double dbu, const std: } - pointListEdit->setText (tl::to_qstring (ptlist)); + if (! m_in_text_changed) { + pointListEdit->blockSignals (true); + pointListEdit->setText (tl::to_qstring (ptlist)); + pointListEdit->blockSignals (false); + } + pointCountLabel->setText (tl::to_qstring (tl::sprintf (tl::to_string (QObject::tr ("(%lu points)")), poly.vertices ()))); } +void +PolygonPropertiesPage::text_changed () +{ + m_in_text_changed = true; + try { + emit edited (); + } catch (tl::Exception &) { + // ignore exceptions + } + m_in_text_changed = false; +} + ChangeApplicator * PolygonPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape &shape, double dbu) { - std::string text (tl::to_string (pointListEdit->toPlainText ())); - tl::Extractor ex (text.c_str ()); - - db::VCplxTrans t = db::CplxTrans (trans ()).inverted (); - bool du = dbu_units (); - db::Polygon poly; - if (*ex.skip () == '(') { + try { - db::DPolygon dp; - ex.read (dp); + std::string text (tl::to_string (pointListEdit->toPlainText ())); + tl::Extractor ex (text.c_str ()); - poly = db::Polygon (dp.transformed (db::DCplxTrans (t) * db::DCplxTrans (du ? 1.0 : 1.0 / dbu))); + db::VCplxTrans t = db::CplxTrans (trans ()).inverted (); + bool du = dbu_units (); - } else { + if (*ex.skip () == '(') { - unsigned int h = 0; - while (! ex.at_end ()) { + db::DPolygon dp; + ex.read (dp); - std::vector points; + poly = db::Polygon (dp.transformed (db::DCplxTrans (t) * db::DCplxTrans (du ? 1.0 : 1.0 / dbu))); - while (! ex.at_end () && ! ex.test ("/")) { + } else { - double dx = 0.0, dy = 0.0; - ex.read (dx); - ex.test (","); - ex.read (dy); - ex.test (";"); + unsigned int h = 0; + while (! ex.at_end ()) { - points.push_back (point_from_dpoint (db::DPoint (dx, dy), dbu, du, t)); + std::vector points; + + while (! ex.at_end () && ! ex.test ("/")) { + + double dx = 0.0, dy = 0.0; + ex.read (dx); + ex.test (","); + ex.read (dy); + ex.test (";"); + + points.push_back (point_from_dpoint (db::DPoint (dx, dy), dbu, du, t)); + + } + + if (points.size () < 3) { + throw tl::Exception (tl::to_string (QObject::tr ("Polygon must have at least three points"))); + } + + if (h == 0) { + poly.assign_hull (points.begin (), points.end (), false /*not compressed*/); + } else { + poly.insert_hole (points.begin (), points.end (), false /*not compressed*/); + } + + ++h; } - if (points.size () < 3) { - throw tl::Exception (tl::to_string (QObject::tr ("Polygon must have at least three points"))); - } - - if (h == 0) { - poly.assign_hull (points.begin (), points.end (), false /*not compressed*/); - } else { - poly.insert_hole (points.begin (), points.end (), false /*not compressed*/); - } - - ++h; - } + indicate_error (pointListEdit, 0); + + } catch (tl::Exception &ex) { + indicate_error (pointListEdit, &ex); + throw; } db::Polygon org_poly; @@ -525,15 +535,32 @@ BoxPropertiesPage::BoxPropertiesPage (edt::Service *service, db::Manager *manage setup (); mode_tab->setCurrentIndex (s_coordinateMode ? 0 : 1); - connect (mode_tab, SIGNAL (currentChanged (int)), this, SLOT (changed ())); - connect (x1_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); - connect (y1_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); - connect (x2_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); - connect (y2_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); - connect (w_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); - connect (h_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); - connect (cx_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); - connect (cy_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); + + if (! readonly ()) { + + connect (mode_tab, SIGNAL (currentChanged (int)), this, SLOT (changed ())); + connect (x1_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); + connect (y1_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); + connect (x2_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); + connect (y2_le_1, SIGNAL (editingFinished ()), this, SLOT (changed ())); + connect (w_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); + connect (h_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); + connect (cx_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); + connect (cy_le_2, SIGNAL (editingFinished ()), this, SLOT (changed ())); + + } else { + + x1_le_1->setReadOnly (true); + y1_le_1->setReadOnly (true); + x2_le_1->setReadOnly (true); + y2_le_1->setReadOnly (true); + w_le_2->setReadOnly (true); + h_le_2->setReadOnly (true); + cx_le_2->setReadOnly (true); + cy_le_2->setReadOnly (true); + + } + connect (inst_pb, SIGNAL (clicked ()), this, SLOT (show_inst ())); connect (prop_pb, SIGNAL (clicked ()), this, SLOT (show_props ())); } @@ -576,11 +603,44 @@ BoxPropertiesPage::get_box (int mode) const { if (mode == 0) { + bool has_error = false; double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0; - tl::from_string (tl::to_string (x1_le_1->text ()), x1); - tl::from_string (tl::to_string (y1_le_1->text ()), y1); - tl::from_string (tl::to_string (x2_le_1->text ()), x2); - tl::from_string (tl::to_string (y2_le_1->text ()), y2); + + try { + tl::from_string (tl::to_string (x1_le_1->text ()), x1); + indicate_error (x1_le_1, 0); + } catch (tl::Exception &ex) { + indicate_error (x1_le_1, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (y1_le_1->text ()), y1); + indicate_error (y1_le_1, 0); + } catch (tl::Exception &ex) { + indicate_error (y1_le_1, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (x2_le_1->text ()), x2); + indicate_error (x2_le_1, 0); + } catch (tl::Exception &ex) { + indicate_error (x2_le_1, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (y2_le_1->text ()), y2); + indicate_error (y2_le_1, 0); + } catch (tl::Exception &ex) { + indicate_error (y2_le_1, &ex); + has_error = true; + } + + if (has_error) { + throw tl::Exception (tl::to_string (tr ("Invalid values - see highlighted entry boxes"))); + } if (m_lr_swapped) { std::swap (x1, x2); @@ -603,11 +663,44 @@ BoxPropertiesPage::get_box (int mode) const } else { + bool has_error = false; double cx = 0.0, cy = 0.0, w = 0.0, h = 0.0; - tl::from_string (tl::to_string (cx_le_2->text ()), cx); - tl::from_string (tl::to_string (cy_le_2->text ()), cy); - tl::from_string (tl::to_string (w_le_2->text ()), w); - tl::from_string (tl::to_string (h_le_2->text ()), h); + + try { + tl::from_string (tl::to_string (cx_le_2->text ()), cx); + indicate_error (cx_le_2, 0); + } catch (tl::Exception &ex) { + indicate_error (cx_le_2, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (cy_le_2->text ()), cy); + indicate_error (cy_le_2, 0); + } catch (tl::Exception &ex) { + indicate_error (cy_le_2, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (w_le_2->text ()), w); + indicate_error (w_le_2, 0); + } catch (tl::Exception &ex) { + indicate_error (w_le_2, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (h_le_2->text ()), h); + indicate_error (h_le_2, 0); + } catch (tl::Exception &ex) { + indicate_error (h_le_2, &ex); + has_error = true; + } + + if (has_error) { + throw tl::Exception (tl::to_string (tr ("Invalid values - see highlighted entry boxes"))); + } db::VCplxTrans t = db::VCplxTrans (trans ().inverted ()); bool du = dbu_units (); @@ -664,6 +757,8 @@ BoxPropertiesPage::changed () set_box (get_box (m_tab_index)); } catch (...) { } + + emit edited (); } // ------------------------------------------------------------------------- @@ -677,6 +772,28 @@ TextPropertiesPage::TextPropertiesPage (edt::Service *service, db::Manager *mana connect (inst_pb, SIGNAL (clicked ()), this, SLOT (show_inst ())); connect (prop_pb, SIGNAL (clicked ()), this, SLOT (show_props ())); + + if (! readonly ()) { + + connect (text_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (x_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (y_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (size_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (orient_cbx, SIGNAL (activated (int)), this, SIGNAL (edited ())); + connect (halign_cbx, SIGNAL (activated (int)), this, SIGNAL (edited ())); + connect (valign_cbx, SIGNAL (activated (int)), this, SIGNAL (edited ())); + + } else { + + text_le->setReadOnly (true); + x_le->setReadOnly (true); + y_le->setReadOnly (true); + size_le->setReadOnly (true); + orient_cbx->setEnabled (false); + halign_cbx->setEnabled (false); + valign_cbx->setEnabled (false); + + } } void @@ -707,12 +824,28 @@ TextPropertiesPage::do_update (const db::Shape &shape, double dbu, const std::st ChangeApplicator * TextPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape &shape, double dbu) { + bool has_error = false; + db::VCplxTrans t = db::CplxTrans (trans ()).inverted (); bool du = dbu_units (); double x = 0.0, y = 0.0; - tl::from_string (tl::to_string (x_le->text ()), x); - tl::from_string (tl::to_string (y_le->text ()), y); + + try { + tl::from_string (tl::to_string (x_le->text ()), x); + indicate_error (x_le, 0); + } catch (tl::Exception &ex) { + indicate_error (x_le, &ex); + has_error = true; + } + + try { + tl::from_string (tl::to_string (y_le->text ()), y); + indicate_error (y_le, 0); + } catch (tl::Exception &ex) { + indicate_error (y_le, &ex); + has_error = true; + } db::Vector tp = db::Vector (point_from_dpoint (db::DPoint (x, y), dbu, du, t)); db::Trans tt (orient_cbx->currentIndex (), tp); @@ -739,7 +872,13 @@ TextPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape db::Coord size = 0; if (! size_le->text ().isEmpty ()) { - size = coord_from_string (tl::to_string (size_le->text ()).c_str (), dbu, du, t); + try { + size = coord_from_string (tl::to_string (size_le->text ()).c_str (), dbu, du, t); + indicate_error (size_le, 0); + } catch (tl::Exception &ex) { + indicate_error (size_le, &ex); + has_error = true; + } } if (size != org_text.size ()) { appl->add (new TextSizeChangeApplicator (size)); @@ -749,6 +888,10 @@ TextPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape appl->add (new TextStringChangeApplicator (str)); } + if (has_error) { + throw tl::Exception (tl::to_string (tr ("Invalid values - see highlighted entry boxes"))); + } + return appl.release (); } @@ -756,16 +899,22 @@ TextPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape // PathPropertiesPage implementation PathPropertiesPage::PathPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent) - : ShapePropertiesPage (service, manager, parent) + : ShapePropertiesPage (service, manager, parent), m_in_text_changed (false) { setupUi (this); setup (); connect (inst_pb, SIGNAL (clicked ()), this, SLOT (show_inst ())); connect (prop_pb, SIGNAL (clicked ()), this, SLOT (show_props ())); + + ptlist_le->setReadOnly (true); + width_le->setReadOnly (true); + start_ext_le->setReadOnly (true); + end_ext_le->setReadOnly (true); + round_cb->setEnabled (false); } -void +void PathPropertiesPage::do_update (const db::Shape &shape, double dbu, const std::string &lname) { layer_lbl->setText (tl::to_qstring (lname)); @@ -788,7 +937,12 @@ PathPropertiesPage::do_update (const db::Shape &shape, double dbu, const std::st } ptlist += coords_to_string (t * *pt, dbu, du); } - ptlist_le->setText (tl::to_qstring (ptlist)); + + if (! m_in_text_changed) { + ptlist_le->blockSignals (true); + ptlist_le->setText (tl::to_qstring (ptlist)); + ptlist_le->blockSignals (false); + } width_le->setText (tl::to_qstring (coord_to_string (t.ctrans (path.width ()), dbu, du))); start_ext_le->setText (tl::to_qstring (coord_to_string (t.ctrans (path.extensions ().first), dbu, du))); @@ -797,68 +951,16 @@ PathPropertiesPage::do_update (const db::Shape &shape, double dbu, const std::st } ChangeApplicator * -PathPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape &shape, double dbu) +PathPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape & /*shape*/, double /*dbu*/) { - db::VCplxTrans t = db::CplxTrans (trans ()).inverted (); - bool du = dbu_units (); - - std::string text (tl::to_string (ptlist_le->toPlainText ())); - tl::Extractor ex (text.c_str ()); - - std::vector points; - - while (! ex.at_end ()) { - - double dx = 0.0, dy = 0.0; - ex.read (dx); - ex.read (dy); - - points.push_back (point_from_dpoint (db::DPoint (dx, dy), dbu, du, t)); - - } - - if (points.size () < 1) { - throw tl::Exception (tl::to_string (QObject::tr ("The path must have at least one point"))); - } - - db::Coord w = coord_from_string (tl::to_string (width_le->text ()).c_str (), dbu, du, t); - db::Coord se = coord_from_string (tl::to_string (start_ext_le->text ()).c_str (), dbu, du, t); - db::Coord ee = coord_from_string (tl::to_string (end_ext_le->text ()).c_str (), dbu, du, t); - bool round = round_cb->isChecked (); - - std::auto_ptr appl; - - db::Path org_path; - shape.path (org_path); - std::vector org_points; - for (db::Path::iterator p = org_path.begin (); p != org_path.end (); ++p) { - org_points.push_back (*p); - } - - if (org_points != points) { - appl->add (new PathPointsChangeApplicator (points, org_points)); - } - if (w != org_path.width ()) { - appl->add (new PathWidthChangeApplicator (w, org_path.width ())); - } - if (se != org_path.extensions ().first) { - appl->add (new PathStartExtensionChangeApplicator (se)); - } - if (ee != org_path.extensions ().second) { - appl->add (new PathEndExtensionChangeApplicator (ee)); - } - if (round != org_path.round ()) { - appl->add (new PathRoundEndChangeApplicator (round)); - } - - return appl.release (); + return 0; } // ------------------------------------------------------------------------- // EditablePathPropertiesPage implementation EditablePathPropertiesPage::EditablePathPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent) - : ShapePropertiesPage (service, manager, parent) + : ShapePropertiesPage (service, manager, parent), m_in_text_changed (false) { setupUi (this); setup (); @@ -866,6 +968,12 @@ EditablePathPropertiesPage::EditablePathPropertiesPage (edt::Service *service, d connect (inst_pb, SIGNAL (clicked ()), this, SLOT (show_inst ())); connect (prop_pb, SIGNAL (clicked ()), this, SLOT (show_props ())); connect (type_cb, SIGNAL (currentIndexChanged (int)), this, SLOT (type_selected (int))); + + connect (ptlist_le, SIGNAL (textChanged ()), this, SLOT (text_changed ())); + connect (width_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (start_ext_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (end_ext_le, SIGNAL (editingFinished ()), this, SIGNAL (edited ())); + connect (type_cb, SIGNAL (activated (int)), this, SIGNAL (edited ())); } static int @@ -886,7 +994,19 @@ path_type_choice (const db::Path &path) } } -void +void +EditablePathPropertiesPage::text_changed () +{ + m_in_text_changed = true; + try { + emit edited (); + } catch (tl::Exception &) { + // ignore exceptions + } + m_in_text_changed = false; +} + +void EditablePathPropertiesPage::do_update (const db::Shape &shape, double dbu, const std::string &lname) { layer_lbl->setText (tl::to_qstring (lname)); @@ -909,7 +1029,12 @@ EditablePathPropertiesPage::do_update (const db::Shape &shape, double dbu, const } ptlist += coords_to_string (t * *pt, dbu, du); } - ptlist_le->setText (tl::to_qstring (ptlist)); + + if (! m_in_text_changed) { + ptlist_le->blockSignals (true); + ptlist_le->setText (tl::to_qstring (ptlist)); + ptlist_le->blockSignals (false); + } db::Coord w = path.width (); db::Coord se = path.extensions ().first; @@ -921,6 +1046,10 @@ EditablePathPropertiesPage::do_update (const db::Shape &shape, double dbu, const end_ext_le->setText (tl::to_qstring (coord_to_string (t.ctrans (ee), dbu, du))); int type_choice = path_type_choice (path); + if (type_cb->currentIndex () == 2) { + // keep "variable" mode, otherwise if's difficult to switch to it + type_choice = 2; + } type_cb->setCurrentIndex (type_choice); type_selected (type_choice); } @@ -928,6 +1057,8 @@ EditablePathPropertiesPage::do_update (const db::Shape &shape, double dbu, const ChangeApplicator * EditablePathPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db::Shape &shape, double dbu) { + bool has_error = false; + db::VCplxTrans t = db::CplxTrans (trans ()).inverted (); bool du = dbu_units (); @@ -936,22 +1067,38 @@ EditablePathPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db std::vector points; - while (! ex.at_end ()) { + try { - double dx = 0.0, dy = 0.0; - ex.read (dx); - ex.read (dy); + while (! ex.at_end ()) { - points.push_back (point_from_dpoint (db::DPoint (dx, dy), dbu, du, t)); + double dx = 0.0, dy = 0.0; + ex.read (dx); + ex.read (dy); + points.push_back (point_from_dpoint (db::DPoint (dx, dy), dbu, du, t)); + + } + + if (points.size () < 1) { + throw tl::Exception (tl::to_string (QObject::tr ("The path must have at least one point"))); + } + + indicate_error (ptlist_le, 0); + + } catch (tl::Exception &ex) { + indicate_error (ptlist_le, &ex); + has_error = true; } - if (points.size () < 1) { - throw tl::Exception (tl::to_string (QObject::tr ("The path must have at least one point"))); + db::Coord w = 0; + try { + w = coord_from_string (tl::to_string (width_le->text ()).c_str (), dbu, du, t); + indicate_error (width_le, 0); + } catch (tl::Exception &ex) { + indicate_error (width_le, &ex); + has_error = true; } - db::Coord w = coord_from_string (tl::to_string (width_le->text ()).c_str (), dbu, du, t); - db::Coord se = 0, ee = 0; switch (type_cb->currentIndex ()) { case 0: // flush @@ -961,8 +1108,20 @@ EditablePathPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db se = ee = std::numeric_limits ::min (); // force to half width break; case 2: // variable - se = coord_from_string (tl::to_string (start_ext_le->text ()).c_str (), dbu, du, t); - ee = coord_from_string (tl::to_string (end_ext_le->text ()).c_str (), dbu, du, t); + try { + se = coord_from_string (tl::to_string (start_ext_le->text ()).c_str (), dbu, du, t); + indicate_error (start_ext_le, 0); + } catch (tl::Exception &ex) { + indicate_error (start_ext_le, &ex); + has_error = true; + } + try { + ee = coord_from_string (tl::to_string (end_ext_le->text ()).c_str (), dbu, du, t); + indicate_error (end_ext_le, 0); + } catch (tl::Exception &ex) { + indicate_error (end_ext_le, &ex); + has_error = true; + } break; } @@ -989,6 +1148,10 @@ EditablePathPropertiesPage::create_applicator (db::Shapes & /*shapes*/, const db appl->add (new PathRoundEndChangeApplicator (type_cb->currentIndex () == 3)); } + if (has_error) { + throw tl::Exception (tl::to_string (tr ("Invalid values - see highlighted entry boxes"))); + } + return appl.release (); } diff --git a/src/edt/edt/edtPropertiesPages.h b/src/edt/edt/edtPropertiesPages.h index 5b612326c..42e283cc2 100644 --- a/src/edt/edt/edtPropertiesPages.h +++ b/src/edt/edt/edtPropertiesPages.h @@ -56,13 +56,15 @@ public: virtual void operator++ (); virtual void leave (); +protected: + virtual bool readonly (); + private: virtual void update (); virtual void apply (); - virtual void apply_to_all (); + virtual void apply_to_all (bool relative); virtual bool can_apply_to_all () const; - virtual void do_apply (bool current_only); - virtual bool readonly (); + virtual void do_apply (bool current_only, bool relative); void recompute_selection_ptrs (const std::vector &new_sel); protected: @@ -104,6 +106,12 @@ public: protected: virtual QCheckBox *dbu_checkbox () const { return dbu_cb; } virtual QCheckBox *abs_checkbox () const { return abs_cb; } + +public slots: + void text_changed (); + +private: + bool m_in_text_changed; }; class BoxPropertiesPage @@ -167,6 +175,9 @@ public: protected: virtual QCheckBox *dbu_checkbox () const { return dbu_cb; } virtual QCheckBox *abs_checkbox () const { return abs_cb; } + +private: + bool m_in_text_changed; }; class EditablePathPropertiesPage @@ -187,6 +198,10 @@ protected: public slots: void type_selected (int); + void text_changed (); + +private: + bool m_in_text_changed; }; } diff --git a/src/laybasic/laybasic/PropertiesDialog.ui b/src/laybasic/laybasic/PropertiesDialog.ui index dc1e57646..4edb7171e 100644 --- a/src/laybasic/laybasic/PropertiesDialog.ui +++ b/src/laybasic/laybasic/PropertiesDialog.ui @@ -17,7 +17,16 @@ 6 - + + 9 + + + 9 + + + 9 + + 9 @@ -54,7 +63,16 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -69,7 +87,7 @@ Previous - + :/left.png:/left.png @@ -89,7 +107,7 @@ Next - + :/right.png:/right.png @@ -97,6 +115,39 @@ + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + Change all + + + + + + + false + + + Relative + + + @@ -120,20 +171,6 @@ - - - - Apply - - - - - - - Apply To All - - - @@ -148,7 +185,24 @@ - + - + + + apply_to_all_cbx + toggled(bool) + relative_cbx + setEnabled(bool) + + + 260 + 372 + + + 320 + 372 + + + + diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index e1ff1d99d..fde47bc44 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -557,7 +557,7 @@ LayoutView::init (db::Manager *mgr, QWidget * /*parent*/) } - if (is_editable () && (m_options & LV_NoEditorOptionsPanel) == 0 && (m_options & LV_Naked) == 0) { + if ((m_options & LV_NoEditorOptionsPanel) == 0 && (m_options & LV_Naked) == 0) { mp_editor_options_frame = new QFrame (0); mp_editor_options_frame->setObjectName (QString::fromUtf8 ("editor_options_frame")); diff --git a/src/laybasic/laybasic/layProperties.h b/src/laybasic/laybasic/layProperties.h index a8fba1677..9eedcdafc 100644 --- a/src/laybasic/laybasic/layProperties.h +++ b/src/laybasic/laybasic/layProperties.h @@ -198,7 +198,7 @@ public: * If nothing was changed, the objects may be left untouched. * The dialog will start a transaction on the manager object. */ - virtual void apply_to_all () + virtual void apply_to_all (bool /*relative*/) { // default implementation is empty. } diff --git a/src/laybasic/laybasic/layPropertiesDialog.cc b/src/laybasic/laybasic/layPropertiesDialog.cc index 1c823c561..cc40f5aba 100644 --- a/src/laybasic/laybasic/layPropertiesDialog.cc +++ b/src/laybasic/laybasic/layPropertiesDialog.cc @@ -64,8 +64,8 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager, content_frame->setLayout (mp_stack); // disable the apply button for first .. - apply_button->setEnabled (false); - apply_to_all_button->setEnabled (false); + apply_to_all_cbx->setEnabled (false); + relative_cbx->setEnabled (false); ok_button->setEnabled (false); // as a proposal, the start button can be enabled in most cases @@ -87,22 +87,28 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager, // if at end disable the "Next" button and return (this may only happen at the first call) if (m_index >= int (mp_properties_pages.size ())) { + next_button->setEnabled (false); mp_stack->setCurrentWidget (dummy); - apply_button->setEnabled (false); - apply_to_all_button->setEnabled (false); + apply_to_all_cbx->setEnabled (false); + apply_to_all_cbx->setChecked (false); + relative_cbx->setEnabled (false); + relative_cbx->setChecked (false); ok_button->setEnabled (false); + } else { + next_button->setEnabled (any_next ()); mp_properties_pages [m_index]->update (); mp_stack->setCurrentWidget (mp_properties_pages [m_index]); - apply_button->setEnabled (! mp_properties_pages [m_index]->readonly ()); - apply_to_all_button->setEnabled (! mp_properties_pages [m_index]->readonly () && mp_properties_pages [m_index]->can_apply_to_all ()); + apply_to_all_cbx->setEnabled (! mp_properties_pages [m_index]->readonly () && mp_properties_pages [m_index]->can_apply_to_all ()); + apply_to_all_cbx->setChecked (false); + relative_cbx->setEnabled (apply_to_all_cbx->isEnabled () && apply_to_all_cbx->isChecked ()); + relative_cbx->setChecked (true); ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ()); + } - connect (apply_button, SIGNAL (clicked ()), this, SLOT (apply_pressed ())); - connect (apply_to_all_button, SIGNAL (clicked ()), this, SLOT (apply_to_all_pressed ())); connect (ok_button, SIGNAL (clicked ()), this, SLOT (ok_pressed ())); connect (cancel_button, SIGNAL (clicked ()), this, SLOT (cancel_pressed ())); connect (prev_button, SIGNAL (clicked ()), this, SLOT (prev_pressed ())); @@ -159,8 +165,8 @@ BEGIN_PROTECTED prev_button->setEnabled (true); next_button->setEnabled (any_next ()); - apply_button->setEnabled (! mp_properties_pages [m_index]->readonly ()); - apply_to_all_button->setEnabled (! mp_properties_pages [m_index]->readonly () && mp_properties_pages [m_index]->can_apply_to_all ()); + apply_to_all_cbx->setEnabled (! mp_properties_pages [m_index]->readonly () && mp_properties_pages [m_index]->can_apply_to_all ()); + relative_cbx->setEnabled (apply_to_all_cbx->isEnabled () && apply_to_all_cbx->isChecked ()); ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ()); mp_properties_pages [m_index]->update (); @@ -203,8 +209,8 @@ BEGIN_PROTECTED next_button->setEnabled (true); prev_button->setEnabled (any_prev ()); - apply_button->setEnabled (! mp_properties_pages [m_index]->readonly ()); - apply_to_all_button->setEnabled (! mp_properties_pages [m_index]->readonly () && mp_properties_pages [m_index]->can_apply_to_all ()); + apply_to_all_cbx->setEnabled (! mp_properties_pages [m_index]->readonly () && mp_properties_pages [m_index]->can_apply_to_all ()); + relative_cbx->setEnabled (apply_to_all_cbx->isEnabled () && apply_to_all_cbx->isChecked ()); ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ()); mp_properties_pages [m_index]->update (); @@ -254,23 +260,6 @@ PropertiesDialog::any_prev () const return (index >= 0); } -void -PropertiesDialog::apply_to_all_pressed () -{ -BEGIN_PROTECTED - - { - 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 (); - - m_transaction_id = t.id (); - } - -END_PROTECTED -} - void PropertiesDialog::apply () { @@ -280,7 +269,11 @@ BEGIN_PROTECTED try { - mp_properties_pages [m_index]->apply (); + if (apply_to_all_cbx->isChecked () && mp_properties_pages [m_index]->can_apply_to_all ()) { + mp_properties_pages [m_index]->apply_to_all (relative_cbx->isChecked ()); + } else { + mp_properties_pages [m_index]->apply (); + } mp_properties_pages [m_index]->update (); } catch (tl::Exception &) { @@ -292,21 +285,6 @@ BEGIN_PROTECTED END_PROTECTED } -void -PropertiesDialog::apply_pressed () -{ -BEGIN_PROTECTED - - 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 () { diff --git a/src/laybasic/laybasic/layPropertiesDialog.h b/src/laybasic/laybasic/layPropertiesDialog.h index 5dcb209b7..26a342dad 100644 --- a/src/laybasic/laybasic/layPropertiesDialog.h +++ b/src/laybasic/laybasic/layPropertiesDialog.h @@ -92,8 +92,6 @@ public slots: void apply (); void next_pressed (); void prev_pressed (); - void apply_pressed (); - void apply_to_all_pressed (); void cancel_pressed (); void ok_pressed ();