Skip to content

Commit

Permalink
Merge pull request OpenChemistry#1863 from ghutchis/alchemy
Browse files Browse the repository at this point in the history
Add a quick "change elements" command (e.g., setting to dummy)
  • Loading branch information
ghutchis authored Dec 15, 2024
2 parents 49a1c7e + 716b999 commit b938554
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 11 deletions.
19 changes: 8 additions & 11 deletions avogadro/qtplugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,26 @@ endfunction()

# Now to make the plugins.
add_subdirectory(3dmol)
add_subdirectory(applycolors)
add_subdirectory(alchemy)
add_subdirectory(aligntool)
add_subdirectory(apbs)
add_subdirectory(applycolors)
add_subdirectory(bondcentrictool)
add_subdirectory(bonding)
add_subdirectory(cartoons)
add_subdirectory(centroid)
add_subdirectory(configurepython)
add_subdirectory(coordinateeditor)
add_subdirectory(copypaste)
add_subdirectory(cp2kinput)
add_subdirectory(crystal)
add_subdirectory(customelements)
# add_subdirectory(dipole)
add_subdirectory(editor)
add_subdirectory(fetchpdb)
add_subdirectory(focus)
add_subdirectory(forcefield)
add_subdirectory(gamessinput)
add_subdirectory(hydrogens)
add_subdirectory(importpqr)
add_subdirectory(insertdna)
Expand All @@ -135,20 +141,11 @@ if(USE_SPGLIB)
add_subdirectory(spacegroup)
endif()
add_subdirectory(surfaces)
add_subdirectory(svg)
add_subdirectory(templatetool)
add_subdirectory(vibrations)
add_subdirectory(vrml)

# These should work after the QRegExp migration
add_subdirectory(apbs)
add_subdirectory(coordinateeditor)
add_subdirectory(cp2kinput)
add_subdirectory(forcefield)
add_subdirectory(gamessinput)

# The SVG library changed in Qt6
add_subdirectory(svg)

# Plugins that require VTK
if(USE_VTK)
add_subdirectory(coloropacitymap)
Expand Down
10 changes: 10 additions & 0 deletions avogadro/qtplugins/alchemy/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include_directories(${CMAKE_CURRENT_BINARY_DIR})

avogadro_plugin(Alchemy
"Change elements"
ExtensionPlugin
alchemy.h
Alchemy
"alchemy.cpp"
""
)
89 changes: 89 additions & 0 deletions avogadro/qtplugins/alchemy/alchemy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/******************************************************************************
This source file is part of the Avogadro project.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "alchemy.h"

#include <avogadro/core/elements.h>
#include <avogadro/qtgui/molecule.h>

#include <QAction>
#include <QtCore/QSettings>
#include <QtWidgets/QDialog>
#include <QtWidgets/QInputDialog>

#include <vector>

namespace Avogadro::QtPlugins {

using Core::Array;
using Core::Elements;

Alchemy::Alchemy(QObject* parent_)
: Avogadro::QtGui::ExtensionPlugin(parent_),
m_action(new QAction(tr("Change Elements…"), this)), m_molecule(nullptr)
{
m_action->setProperty("menu priority", 750);

connect(m_action, &QAction::triggered, this, &Alchemy::changeElements);
}

Alchemy::~Alchemy() {}

QList<QAction*> Alchemy::actions() const
{
QList<QAction*> result;
return result << m_action;
}

QStringList Alchemy::menuPath(QAction*) const
{
return QStringList() << tr("&Build");
}

void Alchemy::setMolecule(QtGui::Molecule* mol)
{
m_molecule = mol;
}

void Alchemy::changeElements()
{
if (!m_molecule)
return;

// assemble the list of elements
QStringList choices;
for (unsigned char i = 0; i < Elements::elementCount(); ++i) {
QString choice("%1: %2");
choice = choice.arg(i).arg(Elements::name(i));
choices << choice;
}

// get the element of the first selected atom
unsigned char firstElement = 0;
for (Index i = 0; i < m_molecule->atomCount(); ++i) {
if (m_molecule->atomSelected(i)) {
firstElement = m_molecule->atom(i).atomicNumber();
break;
}
}

bool ok = false;
QString currentChoice = QInputDialog::getItem(
qobject_cast<QWidget*>(parent()), tr("Change Elements"), tr("Element:"),
choices, static_cast<int>(firstElement), false, &ok);
if (!ok)
return;

unsigned char newElement = currentChoice.section(':', 0, 0).toUShort();
// loop through the selected atoms and change their elements
for (Index i = 0; i < m_molecule->atomCount(); ++i) {
if (m_molecule->atomSelected(i))
m_molecule->atom(i).setAtomicNumber(newElement);
}

m_molecule->emitChanged(QtGui::Molecule::Atoms);
}

} // namespace Avogadro::QtPlugins
57 changes: 57 additions & 0 deletions avogadro/qtplugins/alchemy/alchemy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/******************************************************************************
This source file is part of the Avogadro project.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#ifndef AVOGADRO_QTPLUGINS_ALCHEMY_H
#define AVOGADRO_QTPLUGINS_ALCHEMY_H

#include <avogadro/core/avogadrocore.h>
#include <avogadro/qtgui/extensionplugin.h>

#include <QtWidgets/QDialog>

namespace Ui {
class BondingDialog;
}

namespace Avogadro {
namespace QtPlugins {

/**
* @brief The Bonding class performs bonding operations on demand.
*/
class Alchemy : public QtGui::ExtensionPlugin
{
Q_OBJECT
public:
explicit Alchemy(QObject* parent_ = nullptr);
~Alchemy() override;

QString name() const override { return tr("Alchemy"); }

QString description() const override
{
return tr("Change elements of atoms.");
}

QList<QAction*> actions() const override;

QStringList menuPath(QAction* action) const override;

public slots:
void setMolecule(QtGui::Molecule* mol) override;

private slots:
void changeElements();

private:
QtGui::Molecule* m_molecule;

QAction* m_action;
};

} // namespace QtPlugins
} // namespace Avogadro

#endif // AVOGADRO_QTPLUGINS_ALCHEMY_H

0 comments on commit b938554

Please sign in to comment.