From 1daa6bdd4afd62a8f693bc7b470ed7caefc2c7f8 Mon Sep 17 00:00:00 2001 From: Geoff Hutchison Date: Sun, 9 Apr 2023 19:04:16 -0400 Subject: [PATCH] Implement clipboard insertion for ligands Signed-off-by: Geoff Hutchison --- .../qtplugins/templatetool/templatetool.cpp | 316 ++++++++++-------- .../templatetool/templatetoolwidget.cpp | 43 ++- 2 files changed, 219 insertions(+), 140 deletions(-) diff --git a/avogadro/qtplugins/templatetool/templatetool.cpp b/avogadro/qtplugins/templatetool/templatetool.cpp index 8263872e4f..c40bbd79d8 100644 --- a/avogadro/qtplugins/templatetool/templatetool.cpp +++ b/avogadro/qtplugins/templatetool/templatetool.cpp @@ -13,69 +13,69 @@ #include #include +#include +#include #include #include -#include #include #include -#include #include +#include #include #include #include #include +#include +#include #include #include #include #include -#include +#include #include #include +#include #include +#include #include -#include #include namespace { const unsigned char INVALID_ATOMIC_NUMBER = - std::numeric_limits::max(); + std::numeric_limits::max(); } namespace Avogadro { namespace QtPlugins { +using QtGui::Molecule; using QtGui::RWAtom; using QtGui::RWBond; -using QtGui::Molecule; using QtGui::RWMolecule; using QtOpenGL::GLWidget; +using Avogadro::Core::Elements; +using Avogadro::Io::CjsonFormat; using Avogadro::Rendering::GeometryNode; using Avogadro::Rendering::GroupNode; using Avogadro::Rendering::Identifier; using Avogadro::Rendering::TextLabel2D; using Avogadro::Rendering::TextLabel3D; using Avogadro::Rendering::TextProperties; -using Avogadro::Core::Elements; -using Avogadro::Io::CjsonFormat; -TemplateTool::TemplateTool(QObject *parent_) - : QtGui::ToolPlugin(parent_), - m_activateAction(new QAction(this)), - m_molecule(NULL), - m_glWidget(NULL), - m_renderer(NULL), +TemplateTool::TemplateTool(QObject* parent_) + : QtGui::ToolPlugin(parent_), m_activateAction(new QAction(this)), + m_molecule(NULL), m_glWidget(NULL), m_renderer(NULL), m_toolWidget(new TemplateToolWidget(qobject_cast(parent_))), m_pressedButtons(Qt::NoButton), - m_clickedAtomicNumber(INVALID_ATOMIC_NUMBER), - m_bondAdded(false), + m_clickedAtomicNumber(INVALID_ATOMIC_NUMBER), m_bondAdded(false), m_fixValenceLater(false) { m_activateAction->setText(tr("Template")); @@ -83,16 +83,14 @@ TemplateTool::TemplateTool(QObject *parent_) reset(); } -TemplateTool::~TemplateTool() -{ -} +TemplateTool::~TemplateTool() {} -QWidget *TemplateTool::toolWidget() const +QWidget* TemplateTool::toolWidget() const { return m_toolWidget; } -QUndoCommand *TemplateTool::mousePressEvent(QMouseEvent *e) +QUndoCommand* TemplateTool::mousePressEvent(QMouseEvent* e) { clearKeyPressBuffer(); if (!m_renderer) @@ -109,32 +107,31 @@ QUndoCommand *TemplateTool::mousePressEvent(QMouseEvent *e) m_clickedObject = m_renderer->hit(e->pos().x(), e->pos().y()); switch (m_clickedObject.type) { - case Rendering::InvalidType: - emptyLeftClick(e); - return NULL; - case Rendering::AtomType: - atomLeftClick(e); - return NULL; - default: - break; + case Rendering::InvalidType: + emptyLeftClick(e); + return NULL; + case Rendering::AtomType: + atomLeftClick(e); + return NULL; + default: + break; } - } - else if (m_pressedButtons & Qt::RightButton) { + } else if (m_pressedButtons & Qt::RightButton) { m_clickedObject = m_renderer->hit(e->pos().x(), e->pos().y()); switch (m_clickedObject.type) { - case Rendering::AtomType: - atomRightClick(e); - return NULL; - default: - break; + case Rendering::AtomType: + atomRightClick(e); + return NULL; + default: + break; } } return NULL; } -QUndoCommand *TemplateTool::mouseReleaseEvent(QMouseEvent *e) +QUndoCommand* TemplateTool::mouseReleaseEvent(QMouseEvent* e) { if (!m_renderer) return NULL; @@ -149,19 +146,19 @@ QUndoCommand *TemplateTool::mouseReleaseEvent(QMouseEvent *e) return NULL; switch (e->button()) { - case Qt::LeftButton: - case Qt::RightButton: - reset(); - e->accept(); - break; - default: - break; + case Qt::LeftButton: + case Qt::RightButton: + reset(); + e->accept(); + break; + default: + break; } return NULL; } -QUndoCommand *TemplateTool::mouseMoveEvent(QMouseEvent *e) +QUndoCommand* TemplateTool::mouseMoveEvent(QMouseEvent* e) { if (!m_renderer) return NULL; @@ -173,7 +170,7 @@ QUndoCommand *TemplateTool::mouseMoveEvent(QMouseEvent *e) return NULL; } -QUndoCommand *TemplateTool::keyPressEvent(QKeyEvent *e) +QUndoCommand* TemplateTool::keyPressEvent(QKeyEvent* e) { if (e->text().isEmpty()) return NULL; @@ -184,17 +181,16 @@ QUndoCommand *TemplateTool::keyPressEvent(QKeyEvent *e) if (m_keyPressBuffer.isEmpty()) QTimer::singleShot(2000, this, SLOT(clearKeyPressBuffer())); - m_keyPressBuffer.append(m_keyPressBuffer.isEmpty() - ? e->text().toUpper() - : e->text().toLower()); + m_keyPressBuffer.append(m_keyPressBuffer.isEmpty() ? e->text().toUpper() + : e->text().toLower()); if (m_keyPressBuffer.size() >= 3) { clearKeyPressBuffer(); return NULL; } - int atomicNum = Core::Elements::atomicNumberFromSymbol( - m_keyPressBuffer.toStdString()); + int atomicNum = + Core::Elements::atomicNumberFromSymbol(m_keyPressBuffer.toStdString()); if (atomicNum != Avogadro::InvalidElement) m_toolWidget->setAtomicNumber(static_cast(atomicNum)); @@ -202,11 +198,9 @@ QUndoCommand *TemplateTool::keyPressEvent(QKeyEvent *e) return NULL; } -void TemplateTool::draw(Rendering::GroupNode&) -{ -} +void TemplateTool::draw(Rendering::GroupNode&) {} -void TemplateTool::updatePressedButtons(QMouseEvent *e, bool release) +void TemplateTool::updatePressedButtons(QMouseEvent* e, bool release) { /// @todo Use modifier keys on mac if (release) @@ -258,9 +252,10 @@ void TemplateTool::reset() emit drawablesChanged(); } -void TemplateTool::emptyLeftClick(QMouseEvent *e) +void TemplateTool::emptyLeftClick(QMouseEvent* e) { - QFile templ(":/templates/centers/" + m_toolWidget->coordinationString() + ".cjson"); + QFile templ(":/templates/centers/" + m_toolWidget->coordinationString() + + ".cjson"); if (!templ.open(QFile::ReadOnly | QFile::Text)) return; QTextStream templateStream(&templ); @@ -269,7 +264,7 @@ void TemplateTool::emptyLeftClick(QMouseEvent *e) Molecule templateMolecule; if (!ff.readString(templateStream.readAll().toStdString(), templateMolecule)) return; - + m_toolWidget->selectedUIDs().clear(); // Add an atom at the clicked position @@ -290,16 +285,18 @@ void TemplateTool::emptyLeftClick(QMouseEvent *e) } for (size_t i = 0; i < templateMolecule.atomCount(); i++) { - Vector3 pos = templateMolecule.atomPosition3d(i) - center + atomPos.cast(); + Vector3 pos = + templateMolecule.atomPosition3d(i) - center + atomPos.cast(); templateMolecule.setAtomPosition3d(i, pos); } size_t firstIndex = m_molecule->atomCount(); m_molecule->appendMolecule(templateMolecule, tr("Insert Template")); - Molecule::MoleculeChanges changes = Molecule::Atoms | Molecule::Bonds | Molecule::Added; + Molecule::MoleculeChanges changes = + Molecule::Atoms | Molecule::Bonds | Molecule::Added; - //m_fixValenceLater = true; // add hydrogens + // m_fixValenceLater = true; // add hydrogens m_fixValenceLater = false; // Update the clicked object @@ -313,25 +310,31 @@ void TemplateTool::emptyLeftClick(QMouseEvent *e) e->accept(); } -Vector3 rotateLigandCoords(Vector3 in, Vector3 centerVector, Vector3 outVector) { +Vector3 rotateLigandCoords(Vector3 in, Vector3 centerVector, Vector3 outVector) +{ if (centerVector.norm() == 0.0 || outVector.norm() == 0.0) return in; Vector3 axis = centerVector.cross(outVector); - if (axis.norm() < 1e-12) { // vectors are parallel, let's pick an arbitrary perpendicular axis - Matrix3 rotx = Eigen::AngleAxisd(M_PI / 2.0, Vector3(1.0, 0.0, 0.0)).toRotationMatrix(); - Matrix3 roty = Eigen::AngleAxisd(M_PI / 2.0, Vector3(0.0, 1.0, 0.0)).toRotationMatrix(); + if (axis.norm() < 1e-12) { // vectors are parallel, let's pick an arbitrary + // perpendicular axis + Matrix3 rotx = + Eigen::AngleAxisd(M_PI / 2.0, Vector3(1.0, 0.0, 0.0)).toRotationMatrix(); + Matrix3 roty = + Eigen::AngleAxisd(M_PI / 2.0, Vector3(0.0, 1.0, 0.0)).toRotationMatrix(); axis = centerVector.cross(rotx * outVector); if (axis.norm() < 1e-12) axis = centerVector.cross(roty * outVector); } axis.normalize(); - double cosine = centerVector.dot(outVector) / centerVector.norm() / outVector.norm(); - double angle = (abs(cosine) < 1.0)? acos(cosine) : 0.0; + double cosine = + centerVector.dot(outVector) / centerVector.norm() / outVector.norm(); + double angle = (abs(cosine) < 1.0) ? acos(cosine) : 0.0; Matrix3 rot = Eigen::AngleAxisd(angle, axis).toRotationMatrix(); return rot * in; } -Matrix3 applyKabsch(std::vector templatePoints, std::vector moleculePoints) +Matrix3 applyKabsch(std::vector templatePoints, + std::vector moleculePoints) { assert(templatePoints.size() == moleculePoints.size()); MatrixX TP(templatePoints.size(), 3); @@ -353,21 +356,70 @@ Matrix3 applyKabsch(std::vector templatePoints, std::vector mo void TemplateTool::atomLeftClick(QMouseEvent*) { size_t selectedIndex = m_clickedObject.index; - if (m_molecule->atom(selectedIndex).isValid() - && m_molecule->atomicNumber(selectedIndex) == 1) { - m_toolWidget->selectedUIDs().push_back(m_molecule->atomUniqueId(selectedIndex)); - if (static_cast(m_toolWidget->selectedUIDs().size()) != m_toolWidget->denticity()) + if (m_molecule->atom(selectedIndex).isValid() && + m_molecule->atomicNumber(selectedIndex) == 1) { + m_toolWidget->selectedUIDs().push_back( + m_molecule->atomUniqueId(selectedIndex)); + if (static_cast(m_toolWidget->selectedUIDs().size()) != + m_toolWidget->denticity()) return; - - QFile templ(":/templates/ligands/" + m_toolWidget->ligandString() + ".cjson"); - if (!templ.open(QFile::ReadOnly | QFile::Text)) - return; - QTextStream templateStream(&templ); - CjsonFormat ff; + // Get the ligand template + // - check if we should use the clipboard + // - otherwise use the template Molecule templateMolecule; - if (!ff.readString(templateStream.readAll().toStdString(), templateMolecule)) - return; + if (m_toolWidget->ligandString() == "Clipboard") { + const QMimeData* mimeData(QApplication::clipboard()->mimeData()); + + if (!mimeData) { + return; + } + + // Try to find a reader that can handle the available mime-types. + Io::FileFormatManager& mgr = Io::FileFormatManager::instance(); + QStringList mimeTypes(mimeData->formats()); + Io::FileFormat* pastedFormat = nullptr; + QByteArray pastedData; + Io::FileFormat::Operations ops(Io::FileFormat::Read | + Io::FileFormat::String); + foreach (const QString& mimeType, mimeTypes) { + if ((pastedFormat = + mgr.newFormatFromMimeType(mimeType.toStdString(), ops))) { + pastedData = mimeData->data(mimeType); + break; + } + } + + // No mime-type match, default to cjson. + if (!pastedFormat && mimeData->hasText()) { + pastedFormat = new Io::CjsonFormat; + pastedData = mimeData->text().toLatin1(); + } + + if (pastedFormat == nullptr) + return; + + // we have a format, so try to insert the new bits into the molecule + bool success = pastedFormat->readString( + std::string(pastedData.constData(), pastedData.size()), + templateMolecule); + + if (!success) + return; + + } else { + QFile templ(":/templates/ligands/" + m_toolWidget->ligandString() + + ".cjson"); + if (!templ.open(QFile::ReadOnly | QFile::Text)) + return; + QTextStream templateStream(&templ); + + CjsonFormat ff; + + if (!ff.readString(templateStream.readAll().toStdString(), + templateMolecule)) + return; + } // Find dummy atom in template and get all necessary info size_t templateDummyIndex = 0; @@ -376,7 +428,7 @@ void TemplateTool::atomLeftClick(QMouseEvent*) for (size_t i = 0; i < templateMolecule.atomCount(); i++) { if (templateMolecule.atomicNumber(i) == 0) { templateDummyIndex = i; - for (const auto &bond: templateMolecule.bonds(i)) { + for (const auto& bond : templateMolecule.bonds(i)) { size_t newIndex = bond.getOtherAtom(i).index(); templateLigandIndices.push_back(newIndex); templateLigandUIDs.push_back(templateMolecule.atomUniqueId(newIndex)); @@ -386,86 +438,87 @@ void TemplateTool::atomLeftClick(QMouseEvent*) } // Find center atom in molecule and get all necessary info - size_t moleculeCenterIndex = m_molecule->bonds(selectedIndex)[0] - .getOtherAtom(selectedIndex).index(); + size_t moleculeCenterIndex = + m_molecule->bonds(selectedIndex)[0].getOtherAtom(selectedIndex).index(); size_t moleculeCenterUID = m_molecule->atomUniqueId(moleculeCenterIndex); Vector3 moleculeLigandOutVector(0.0, 0.0, 0.0); - for (size_t UID: m_toolWidget->selectedUIDs()) { + for (size_t UID : m_toolWidget->selectedUIDs()) { size_t index = m_molecule->atomByUniqueId(UID).index(); Vector3 newPos = m_molecule->atomPosition3d(index); - moleculeLigandOutVector += newPos - m_molecule->atomPosition3d(moleculeCenterIndex); + moleculeLigandOutVector += + newPos - m_molecule->atomPosition3d(moleculeCenterIndex); } - + // Estimate and try to realize bond distances Vector3 displacement(0.0, 0.0, 0.0); for (size_t i = 0; i < templateLigandIndices.size(); i++) { - unsigned char ligandAtomicNumber = templateMolecule.atomicNumber(templateLigandIndices[i]); - ligandAtomicNumber = (ligandAtomicNumber == 0)? 6 : ligandAtomicNumber; + unsigned char ligandAtomicNumber = + templateMolecule.atomicNumber(templateLigandIndices[i]); + ligandAtomicNumber = (ligandAtomicNumber == 0) ? 6 : ligandAtomicNumber; // Estimate as the sum of covalent radii - double bondDistance = Elements::radiusCovalent(ligandAtomicNumber) - + Elements::radiusCovalent(m_molecule->atomicNumber(moleculeCenterIndex)); - Vector3 inVector = templateMolecule.atomPosition3d(templateDummyIndex) - - templateMolecule.atomPosition3d(templateLigandIndices[i]); + double bondDistance = + Elements::radiusCovalent(ligandAtomicNumber) + + Elements::radiusCovalent(m_molecule->atomicNumber(moleculeCenterIndex)); + Vector3 inVector = + templateMolecule.atomPosition3d(templateDummyIndex) - + templateMolecule.atomPosition3d(templateLigandIndices[i]); Vector3 correctionVector = inVector; correctionVector.normalize(); correctionVector *= bondDistance - inVector.norm(); displacement += correctionVector; } displacement *= 1.0 / templateLigandIndices.size(); - Vector3 newPos = templateMolecule.atomPosition3d(templateDummyIndex) + displacement; + Vector3 newPos = + templateMolecule.atomPosition3d(templateDummyIndex) + displacement; templateMolecule.setAtomPosition3d(templateDummyIndex, newPos); - + // Translate template so dummy atom is brought to center atom for (size_t i = 0; i < templateMolecule.atomCount(); i++) { if (i != templateDummyIndex) { templateMolecule.setAtomPosition3d( - i, - templateMolecule.atomPosition3d(i) - - templateMolecule.atomPosition3d(templateDummyIndex) - + m_molecule->atomPosition3d(moleculeCenterIndex) - ); + i, templateMolecule.atomPosition3d(i) - + templateMolecule.atomPosition3d(templateDummyIndex) + + m_molecule->atomPosition3d(moleculeCenterIndex)); } } - + // Create arrays with the points to align and apply Kabsch algorithm std::vector templateLigandPositions; - for (size_t index: templateLigandIndices) - templateLigandPositions.push_back(templateMolecule.atomPosition3d(index) - - m_molecule->atomPosition3d(moleculeCenterIndex)); + for (size_t index : templateLigandIndices) + templateLigandPositions.push_back( + templateMolecule.atomPosition3d(index) - + m_molecule->atomPosition3d(moleculeCenterIndex)); std::vector moleculeLigandPositions; - for (size_t UID: m_toolWidget->selectedUIDs()) - moleculeLigandPositions.push_back(m_molecule->atomPosition3d( - m_molecule->atomByUniqueId(UID).index() - ) - m_molecule->atomPosition3d(moleculeCenterIndex)); - Matrix3 rotation = applyKabsch(templateLigandPositions, moleculeLigandPositions); + for (size_t UID : m_toolWidget->selectedUIDs()) + moleculeLigandPositions.push_back( + m_molecule->atomPosition3d(m_molecule->atomByUniqueId(UID).index()) - + m_molecule->atomPosition3d(moleculeCenterIndex)); + Matrix3 rotation = + applyKabsch(templateLigandPositions, moleculeLigandPositions); for (size_t i = 0; i < templateMolecule.atomCount(); i++) { if (i != templateDummyIndex) { templateMolecule.setAtomPosition3d( - i, - rotation * (templateMolecule.atomPosition3d(i) - - m_molecule->atomPosition3d(moleculeCenterIndex)) - + m_molecule->atomPosition3d(moleculeCenterIndex) - ); + i, rotation * (templateMolecule.atomPosition3d(i) - + m_molecule->atomPosition3d(moleculeCenterIndex)) + + m_molecule->atomPosition3d(moleculeCenterIndex)); } } - + // Rotate partially aligned template to align "out" vectors Vector3 templateLigandOutVector(0.0, 0.0, 0.0); - for (size_t index: templateLigandIndices) { + for (size_t index : templateLigandIndices) { Vector3 pos = templateMolecule.atomPosition3d(index); - templateLigandOutVector += pos - m_molecule->atomPosition3d(moleculeCenterIndex); + templateLigandOutVector += + pos - m_molecule->atomPosition3d(moleculeCenterIndex); } for (size_t i = 0; i < templateMolecule.atomCount(); i++) { if (templateMolecule.atomicNumber(i) != 0) { templateMolecule.setAtomPosition3d( i, - rotateLigandCoords( - templateMolecule.atomPosition3d(i) - - m_molecule->atomPosition3d(moleculeCenterIndex), - templateLigandOutVector, - moleculeLigandOutVector - ) + m_molecule->atomPosition3d(moleculeCenterIndex) - ); + rotateLigandCoords(templateMolecule.atomPosition3d(i) - + m_molecule->atomPosition3d(moleculeCenterIndex), + templateLigandOutVector, moleculeLigandOutVector) + + m_molecule->atomPosition3d(moleculeCenterIndex)); } } @@ -478,28 +531,29 @@ void TemplateTool::atomLeftClick(QMouseEvent*) } std::vector templateNewLigandIndices; - for (size_t UID: templateLigandUIDs) { + for (size_t UID : templateLigandUIDs) { auto atom = templateMolecule.atomByUniqueId(UID); if (atom.isValid()) templateNewLigandIndices.push_back(atom.index()); } - + // Remove selected atoms and insert ligand - for (size_t UID: m_toolWidget->selectedUIDs()) + for (size_t UID : m_toolWidget->selectedUIDs()) m_molecule->removeAtom(m_molecule->atomByUniqueId(UID).index()); size_t moleculeBaseIndex = m_molecule->atomCount(); m_molecule->appendMolecule(templateMolecule, tr("Insert Ligand")); // Create new bonds - size_t moleculeCenterNewIndex = m_molecule->atomByUniqueId(moleculeCenterUID).index(); - for (size_t index: templateNewLigandIndices) + size_t moleculeCenterNewIndex = + m_molecule->atomByUniqueId(moleculeCenterUID).index(); + for (size_t index : templateNewLigandIndices) m_molecule->addBond(index + moleculeBaseIndex, moleculeCenterNewIndex); - + m_toolWidget->selectedUIDs().clear(); } } -void TemplateTool::atomRightClick(QMouseEvent *e) +void TemplateTool::atomRightClick(QMouseEvent* e) { e->accept(); m_molecule->removeAtom(m_clickedObject.index); @@ -512,5 +566,5 @@ void TemplateTool::atomLeftDrag(QMouseEvent*) return; } -} // namespace QtOpenGL +} // namespace QtPlugins } // namespace Avogadro diff --git a/avogadro/qtplugins/templatetool/templatetoolwidget.cpp b/avogadro/qtplugins/templatetool/templatetoolwidget.cpp index 578045d191..602b12aa6a 100644 --- a/avogadro/qtplugins/templatetool/templatetoolwidget.cpp +++ b/avogadro/qtplugins/templatetool/templatetoolwidget.cpp @@ -10,10 +10,14 @@ #include +#include + #include #include +#include + +#include -#include namespace { // The ItemData of the "Other" entry in the combo box @@ -23,6 +27,17 @@ const int ELEMENT_SELECTOR_TAG = 255; namespace Avogadro { namespace QtPlugins { +enum LigandType { + Monodentate = 0, + Bidentate = 1, + Tridentate = 2, + Tetradentate = 3, + Hexadentate = 4, + Haptic = 5, + FunctionalGroup = 6, + Clipboard = 7 +}; + TemplateToolWidget::TemplateToolWidget(QWidget* parent_) : QWidget(parent_), m_ui(new Ui::TemplateToolWidget), m_elementSelector(NULL), m_currentElement(26) @@ -62,7 +77,7 @@ TemplateToolWidget::TemplateToolWidget(QWidget* parent_) << "7-pbp" << "8-sqa"; - typeChanged(0); + typeChanged(LigandType::Monodentate); } TemplateToolWidget::~TemplateToolWidget() @@ -122,6 +137,9 @@ unsigned char TemplateToolWidget::ligand() const QString TemplateToolWidget::ligandString() const { + // tell us if we are using the clipboard + if (m_ui->typeComboBox->currentIndex() == LigandType::Clipboard) + return "Clipboard"; return m_ligands.at(m_ui->ligandComboBox->currentIndex()); } @@ -152,7 +170,7 @@ void TemplateToolWidget::typeChanged(int index) m_ligands = QStringList(); QStringList ligandNames; switch (index) { - case 0: // Monodentate + case LigandType::Monodentate: // Monodentate ligandNames << "ammine" << "aqua" << "carbonyl" @@ -167,7 +185,7 @@ void TemplateToolWidget::typeChanged(int index) << "1-thiol"; m_denticity = 1; break; - case 1: // Bidentate + case LigandType::Bidentate: // Bidentate ligandNames << "acetylacetonate" << "bipyridine" << "ethylenediamine"; @@ -176,12 +194,12 @@ void TemplateToolWidget::typeChanged(int index) << "2-ethylenediamine"; m_denticity = 2; break; - case 2: // Tridentate + case LigandType::Tridentate: // Tridentate ligandNames << "terpyridine"; m_ligands << "3-terpyridine"; m_denticity = 3; break; - case 3: // Tetradentate + case LigandType::Tetradentate: // Tetradentate ligandNames << "phthalocyanine" << "porphin" << "salen"; @@ -190,12 +208,12 @@ void TemplateToolWidget::typeChanged(int index) << "4-salen"; m_denticity = 4; break; - case 4: // Hexadentate + case LigandType::Hexadentate: // Hexadentate ligandNames << "edta"; m_ligands << "6-edta"; m_denticity = 6; break; - case 5: // Haptic + case LigandType::Haptic: // Haptic ligandNames << "η2-ethylene" << "η5-cyclopentyl" << "η6-benzene"; @@ -204,7 +222,7 @@ void TemplateToolWidget::typeChanged(int index) << "eta6-benzene"; m_denticity = 1; break; - case 6: // Functional Groups + case LigandType::FunctionalGroup: // Functional Groups ligandNames << "amide" << "carboxylate" << "ester" @@ -214,8 +232,15 @@ void TemplateToolWidget::typeChanged(int index) m_ligands = ligandNames; m_denticity = 1; break; + case LigandType::Clipboard: // Clipboard + ligandNames << "clipboard"; + m_ligands = ligandNames; + // technically, we should check the clipboard + m_denticity = 1; + break; } m_ui->ligandComboBox->addItems(ligandNames); + ligandChanged(0); } void TemplateToolWidget::elementChanged(int index)