/* 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 "laySaltManagerDialog.h" #include "laySaltModel.h" #include "laySaltGrainPropertiesDialog.h" #include "laySalt.h" #include "ui_SaltGrainTemplateSelectionDialog.h" #include "tlString.h" #include "tlExceptions.h" #include #include #include #include #include #include #include #include #include namespace lay { // -------------------------------------------------------------------------------------- /** * @brief A tiny dialog to select a template and a name for the grain */ class SaltGrainTemplateSelectionDialog : public QDialog, private Ui::SaltGrainTemplateSelectionDialog { public: SaltGrainTemplateSelectionDialog (QWidget *parent, lay::Salt *salt) : QDialog (parent), mp_salt (salt) { Ui::SaltGrainTemplateSelectionDialog::setupUi (this); m_salt_templates.add_location (":/salt_templates"); salt_view->setModel (new SaltModel (this, &m_salt_templates)); salt_view->setItemDelegate (new SaltItemDelegate (this)); salt_view->setCurrentIndex (salt_view->model ()->index (0, 0, QModelIndex ())); } lay::SaltGrain templ () const { SaltModel *model = dynamic_cast (salt_view->model ()); tl_assert (model != 0); SaltGrain *g = model->grain_from_index (salt_view->currentIndex ()); tl_assert (g != 0); return *g; } std::string name () const { return tl::to_string (name_edit->text ()); } void accept () { name_alert->clear (); std::string name = tl::to_string (name_edit->text ().simplified ()); if (name.empty ()) { name_alert->error () << tr ("Name must not be empty"); } else if (! SaltGrain::valid_name (name)) { name_alert->error () << tr ("Name is not valid (must be composed of letters, digits or underscores.\nGroups and names need to be separated with slashes."); } else { // check, if this name does not exist yet for (Salt::flat_iterator g = mp_salt->begin_flat (); g != mp_salt->end_flat (); ++g) { if ((*g)->name () == name) { name_alert->error () << tr ("A package with this name already exists"); return; } } QDialog::accept (); } } private: lay::Salt m_salt_templates; lay::Salt *mp_salt; }; // -------------------------------------------------------------------------------------- // SaltManager implementation // @@@ lay::Salt salt; static bool salt_initialized = false; void make_salt () { if (!salt_initialized) { salt_initialized = true; salt.add_location (tl::to_string (QDir::homePath () + QString::fromUtf8("/.klayout/salt"))); } } lay::Salt *get_salt () { salt = lay::Salt (); salt_initialized = false; make_salt (); return &salt; } // @@@ // @@@ lay::Salt salt_mine; void make_salt_mine () { salt_mine.load ("/home/matthias/salt.mine"); } lay::Salt *get_salt_mine () { make_salt_mine(); return &salt_mine; } // @@@ SaltManagerDialog::SaltManagerDialog (QWidget *parent) : QDialog (parent), m_current_changed_enabled (true) { Ui::SaltManagerDialog::setupUi (this); mp_properties_dialog = new lay::SaltGrainPropertiesDialog (this); connect (edit_button, SIGNAL (clicked ()), this, SLOT (edit_properties ())); connect (create_button, SIGNAL (clicked ()), this, SLOT (create_grain ())); connect (delete_button, SIGNAL (clicked ()), this, SLOT (delete_grain ())); mp_salt = get_salt (); mp_salt_mine = get_salt_mine (); SaltModel *model; model = new SaltModel (this, mp_salt); salt_view->setModel (model); salt_view->setItemDelegate (new SaltItemDelegate (this)); model = new SaltModel (this, mp_salt_mine); salt_mine_view->setModel (model); salt_mine_view->setItemDelegate (new SaltItemDelegate (this)); mode_tab->setCurrentIndex (mp_salt->is_empty () ? 1 : 0); connect (mode_tab, SIGNAL (currentChanged (int)), this, SLOT (mode_changed ())); connect (mp_salt, SIGNAL (collections_changed ()), this, SLOT (salt_changed ())); connect (mp_salt_mine, SIGNAL (collections_changed ()), this, SLOT (salt_mine_changed ())); salt_changed (); salt_mine_changed (); connect (salt_view->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_changed ())); connect (salt_mine_view->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (mine_current_changed ())); // @@@ } void SaltManagerDialog::mode_changed () { // keeps the splitters in sync if (mode_tab->currentIndex () == 1) { splitter_new->setSizes (splitter->sizes ()); } else if (mode_tab->currentIndex () == 0) { splitter->setSizes (splitter_new->sizes ()); } } void SaltManagerDialog::edit_properties () { SaltGrain *g = current_grain (); if (g) { if (mp_properties_dialog->exec_dialog (g, mp_salt)) { current_changed (); } } } void SaltManagerDialog::create_grain () { BEGIN_PROTECTED SaltGrainTemplateSelectionDialog temp_dialog (this, mp_salt); if (temp_dialog.exec ()) { SaltGrain target; target.set_name (temp_dialog.name ()); if (mp_salt->create_grain (temp_dialog.templ (), target)) { // select the new one SaltModel *model = dynamic_cast (salt_view->model ()); if (model) { for (int i = model->rowCount (QModelIndex ()); i > 0; ) { --i; QModelIndex index = model->index (i, 0, QModelIndex ()); SaltGrain *g = model->grain_from_index (index); if (g && g->name () == target.name ()) { salt_view->setCurrentIndex (index); break; } } } } else { throw tl::Exception (tl::to_string (tr ("Initialization of new package failed - see log window (File/Log Viewer) for details"))); } } END_PROTECTED } void SaltManagerDialog::delete_grain () { BEGIN_PROTECTED SaltGrain *g = current_grain (); if (! g) { throw tl::Exception (tl::to_string (tr ("No package selected to delete"))); } if (QMessageBox::question (this, tr ("Delete Package"), tr ("Are you sure to delete package '%1'?").arg (tl::to_qstring (g->name ())), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { mp_salt->remove_grain (*g); } END_PROTECTED } void SaltManagerDialog::salt_changed () { SaltModel *model = dynamic_cast (salt_view->model ()); if (! model) { return; } // NOTE: the disabling of the event handler prevents us from // letting the model connect to the salt's signal directly. m_current_changed_enabled = false; model->update (); m_current_changed_enabled = true; if (mp_salt->is_empty ()) { list_stack->setCurrentIndex (1); details_frame->hide (); } else { list_stack->setCurrentIndex (0); details_frame->show (); // select the first grain if (model->rowCount (QModelIndex ()) > 0) { salt_view->setCurrentIndex (model->index (0, 0, QModelIndex ())); } } current_changed (); } void SaltManagerDialog::current_changed () { SaltGrain *g = current_grain (); details_text->set_grain (g); if (!g) { details_frame->setEnabled (false); delete_button->setEnabled (false); } else { details_frame->setEnabled (true); delete_button->setEnabled (true); edit_button->setEnabled (! g->is_readonly ()); } } lay::SaltGrain * SaltManagerDialog::current_grain () { SaltModel *model = dynamic_cast (salt_view->model ()); return model ? model->grain_from_index (salt_view->currentIndex ()) : 0; } void SaltManagerDialog::salt_mine_changed () { SaltModel *model = dynamic_cast (salt_mine_view->model ()); if (! model) { return; } // NOTE: the disabling of the event handler prevents us from // letting the model connect to the salt's signal directly. m_current_changed_enabled = false; model->update (); m_current_changed_enabled = true; // select the first grain if (model->rowCount (QModelIndex ()) > 0) { salt_mine_view->setCurrentIndex (model->index (0, 0, QModelIndex ())); } mine_current_changed (); } void SaltManagerDialog::mine_current_changed () { SaltGrain *g = mine_current_grain (); details_new_text->set_grain (g); details_new_frame->setEnabled (g != 0); } lay::SaltGrain * SaltManagerDialog::mine_current_grain () { SaltModel *model = dynamic_cast (salt_mine_view->model ()); return model ? model->grain_from_index (salt_mine_view->currentIndex ()) : 0; } }