void OpenBabel::onPerceiveBondsFinished(const QByteArray &output)
{
  m_progress->setLabelText(tr("Updating molecule from CML..."));

  // CML --> molecule
  Core::Molecule mol;
  if (!Io::FileFormatManager::instance().readString(mol, output.constData(),
                                                    "cml")) {
    m_progress->reset();
    QMessageBox::critical(qobject_cast<QWidget*>(parent()),
                          tr("Error"),
                          tr("Error interpreting obabel CML output."),
                          QMessageBox::Ok);
    return;
  }

  /// @todo cache a pointer to the current molecule in the above slot, and
  /// verify that we're still operating on the same molecule.

  // Check that the atom count hasn't changed:
  if (mol.atomCount() != m_molecule->atomCount()) {
    m_progress->reset();
    QMessageBox::critical(qobject_cast<QWidget*>(parent()),
                          tr("Error"),
                          tr("Number of atoms in obabel output (%1) does not "
                             "match the number of atoms in the original "
                             "molecule (%2).")
                          .arg(mol.atomCount()).arg(m_molecule->atomCount()),
                          QMessageBox::Ok);
    return;
  }

  m_molecule->clearBonds();
  for (size_t i = 0; i < mol.bondCount(); ++i) {
    Avogadro::Core::Bond bond = mol.bond(i);
    m_molecule->addBond(m_molecule->atom(bond.atom1().index()),
                        m_molecule->atom(bond.atom2().index()),
                        bond.order());
  }

  m_molecule->emitChanged(Molecule::Bonds | Molecule::Added |
                          Molecule::Removed | Molecule::Modified);
  m_progress->reset();
}
void OpenBabel::onHydrogenOperationFinished(const QByteArray &mdl)
{
  m_progress->setLabelText(tr("Reading obabel output..."));

  // MDL --> molecule
  Core::Molecule mol;
  if (!Io::FileFormatManager::instance().readString(mol, mdl.constData(),
                                                    "mol")) {
    m_progress->reset();
    qWarning() << "Bad MDL: " << mdl;
    QMessageBox::critical(qobject_cast<QWidget*>(parent()),
                          tr("Error"),
                          tr("Error interpreting obabel MDL output."),
                          QMessageBox::Ok);
    return;
  }

  /// @todo cache a pointer to the current molecule in the above slot, and
  /// verify that we're still operating on the same molecule.

  // Update molecule
  m_molecule->clearAtoms();
  for (Index i = 0; i < mol.atomCount(); ++i) {
    Core::Atom atom = mol.atom(i);
    m_molecule->addAtom(atom.atomicNumber()).setPosition3d(atom.position3d());
  }
  for (Index i = 0; i < mol.bondCount(); ++i) {
    Core::Bond bond = mol.bond(i);
    m_molecule->addBond(m_molecule->atom(bond.atom1().index()),
                        m_molecule->atom(bond.atom2().index()),
                        bond.order());
  }

  m_molecule->emitChanged(Molecule::Atoms | Molecule::Bonds | Molecule::Added |
                          Molecule::Removed | Molecule::Modified);

  m_progress->reset();
}