mirror of https://github.com/KLayout/klayout.git
320 lines
9.1 KiB
C++
320 lines
9.1 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2017 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
#include "layPropertiesDialog.h"
|
|
|
|
#include "tlLog.h"
|
|
#include "layEditable.h"
|
|
#include "layProperties.h"
|
|
#include "tlExceptions.h"
|
|
|
|
#include <QStackedLayout>
|
|
|
|
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_editables->enable_edits (false);
|
|
|
|
setObjectName (QString::fromUtf8 ("properties_dialog"));
|
|
|
|
Ui::PropertiesDialog::setupUi (this);
|
|
|
|
mp_stack = new QStackedLayout;
|
|
|
|
for (lay::Editables::iterator e = mp_editables->begin (); e != mp_editables->end (); ++e) {
|
|
mp_properties_pages.push_back (e->properties_page (content_frame));
|
|
if (mp_properties_pages.back ()) {
|
|
mp_stack->addWidget (mp_properties_pages.back ());
|
|
}
|
|
}
|
|
|
|
// Necessary to maintain the page order for UI regression testing of 0.18 vs. 0.19 (because tl::Collection has changed to order) ..
|
|
std::reverse (mp_properties_pages.begin (), mp_properties_pages.end ());
|
|
|
|
// Add a label as a dummy
|
|
QLabel *dummy = new QLabel (QObject::tr ("No object with properties to display"), content_frame);
|
|
dummy->setAlignment (Qt::AlignHCenter | Qt::AlignVCenter);
|
|
mp_stack->addWidget (dummy);
|
|
|
|
content_frame->setLayout (mp_stack);
|
|
|
|
// disable the apply button for first ..
|
|
apply_button->setEnabled (false);
|
|
apply_to_all_button->setEnabled (false);
|
|
ok_button->setEnabled (false);
|
|
|
|
// as a proposal, the start button can be enabled in most cases
|
|
prev_button->setEnabled (true);
|
|
|
|
// count the total number of objects
|
|
m_objects = mp_editables->selection_size ();
|
|
m_current_object = 0;
|
|
|
|
update_title ();
|
|
|
|
// look for next usable editable
|
|
while (m_index < int (mp_properties_pages.size ()) &&
|
|
(m_index < 0 || mp_properties_pages [m_index] == 0 || mp_properties_pages [m_index]->at_end ())) {
|
|
++m_index;
|
|
}
|
|
|
|
prev_button->setEnabled (false);
|
|
|
|
// 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);
|
|
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 ());
|
|
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 ()));
|
|
connect (next_button, SIGNAL (clicked ()), this, SLOT (next_pressed ()));
|
|
}
|
|
|
|
PropertiesDialog::~PropertiesDialog ()
|
|
{
|
|
disconnect ();
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::disconnect ()
|
|
{
|
|
mp_editables->enable_edits (true);
|
|
|
|
for (std::vector <lay::PropertiesPage *>::iterator p = mp_properties_pages.begin (); p != mp_properties_pages.end (); ++p) {
|
|
delete *p;
|
|
}
|
|
mp_properties_pages.clear ();
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::next_pressed ()
|
|
{
|
|
BEGIN_PROTECTED
|
|
|
|
if (! mp_properties_pages [m_index]->readonly ()) {
|
|
db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")));
|
|
mp_properties_pages [m_index]->apply ();
|
|
}
|
|
|
|
// advance the current entry
|
|
++(*mp_properties_pages [m_index]);
|
|
|
|
// look for next usable editable if at end
|
|
if (mp_properties_pages [m_index]->at_end ()) {
|
|
mp_properties_pages [m_index]->leave ();
|
|
++m_index;
|
|
while (m_index < int (mp_properties_pages.size ()) &&
|
|
(mp_properties_pages [m_index] == 0 || ! mp_properties_pages [m_index]->front_checked ())) {
|
|
++m_index;
|
|
}
|
|
// because we checked that there are any further elements, this should not happen:
|
|
if (m_index >= int (mp_properties_pages.size ())) {
|
|
return;
|
|
}
|
|
mp_stack->setCurrentWidget (mp_properties_pages [m_index]);
|
|
}
|
|
|
|
++m_current_object;
|
|
update_title ();
|
|
|
|
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 ());
|
|
ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ());
|
|
mp_properties_pages [m_index]->update ();
|
|
|
|
END_PROTECTED
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::prev_pressed ()
|
|
{
|
|
BEGIN_PROTECTED
|
|
|
|
if (! mp_properties_pages [m_index]->readonly ()) {
|
|
db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")));
|
|
mp_properties_pages [m_index]->apply ();
|
|
}
|
|
|
|
if (mp_properties_pages [m_index]->at_begin ()) {
|
|
|
|
// look for last usable editable if at end
|
|
mp_properties_pages [m_index]->leave ();
|
|
--m_index;
|
|
while (m_index >= 0 &&
|
|
(mp_properties_pages [m_index] == 0 || ! mp_properties_pages [m_index]->back_checked ())) {
|
|
--m_index;
|
|
}
|
|
// because we checked that there are any further elements, this should not happen:
|
|
if (m_index < 0) {
|
|
return;
|
|
}
|
|
mp_stack->setCurrentWidget (mp_properties_pages [m_index]);
|
|
|
|
}
|
|
|
|
// decrement the current entry
|
|
--(*mp_properties_pages [m_index]);
|
|
|
|
--m_current_object;
|
|
update_title ();
|
|
|
|
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 ());
|
|
ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ());
|
|
mp_properties_pages [m_index]->update ();
|
|
|
|
END_PROTECTED
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::update_title ()
|
|
{
|
|
setWindowTitle (tl::to_qstring (tl::to_string (QObject::tr ("Object Properties - ")) + tl::to_string (m_current_object + 1) + tl::to_string (QObject::tr (" of ")) + tl::to_string (m_objects)));
|
|
}
|
|
|
|
bool
|
|
PropertiesDialog::any_next () const
|
|
{
|
|
// test-advance
|
|
int index = m_index;
|
|
++(*mp_properties_pages [index]);
|
|
if (mp_properties_pages [index]->at_end ()) {
|
|
++index;
|
|
while (index < int (mp_properties_pages.size ()) &&
|
|
(mp_properties_pages [index] == 0 || ! mp_properties_pages [index]->front_checked ())) {
|
|
++index;
|
|
}
|
|
}
|
|
|
|
// return true, if not at end
|
|
bool ret = (index < int (mp_properties_pages.size ()));
|
|
--(*mp_properties_pages [m_index]);
|
|
return ret;
|
|
}
|
|
|
|
bool
|
|
PropertiesDialog::any_prev () const
|
|
{
|
|
// test-decrement
|
|
int index = m_index;
|
|
if (mp_properties_pages [index]->at_begin ()) {
|
|
--index;
|
|
while (index >= 0 &&
|
|
(mp_properties_pages [index] == 0 || ! mp_properties_pages [index]->back_checked ())) {
|
|
--index;
|
|
}
|
|
}
|
|
|
|
// return true, if not at the beginning
|
|
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")));
|
|
|
|
mp_properties_pages [m_index]->apply_to_all ();
|
|
mp_properties_pages [m_index]->update ();
|
|
|
|
END_PROTECTED
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::apply_pressed ()
|
|
{
|
|
BEGIN_PROTECTED
|
|
|
|
db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")));
|
|
|
|
mp_properties_pages [m_index]->apply ();
|
|
mp_properties_pages [m_index]->update ();
|
|
|
|
END_PROTECTED
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::cancel_pressed ()
|
|
{
|
|
// make sure that the property pages are no longer used ..
|
|
disconnect ();
|
|
// close the dialog
|
|
done (0);
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::ok_pressed ()
|
|
{
|
|
BEGIN_PROTECTED
|
|
|
|
if (! mp_properties_pages [m_index]->readonly ()) {
|
|
|
|
db::Transaction t (mp_manager, tl::to_string (QObject::tr ("Apply changes")));
|
|
|
|
mp_properties_pages [m_index]->apply ();
|
|
mp_properties_pages [m_index]->update ();
|
|
|
|
}
|
|
|
|
// make sure that the property pages are no longer used ..
|
|
disconnect ();
|
|
QDialog::accept ();
|
|
|
|
END_PROTECTED
|
|
}
|
|
|
|
void
|
|
PropertiesDialog::reject ()
|
|
{
|
|
// make sure that the property pages are no longer used ..
|
|
disconnect ();
|
|
QDialog::reject ();
|
|
}
|
|
|
|
}
|
|
|