Skip to content

Commit

Permalink
Merge pull request cryos#124 from ghutchis/paste-to-insert
Browse files Browse the repository at this point in the history
Paste to insert
  • Loading branch information
cryos authored Nov 21, 2016
2 parents 2e73759 + f67d811 commit 79fc8b0
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 35 deletions.
25 changes: 25 additions & 0 deletions avogadro/qtgui/rwmolecule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,31 @@ void RWMolecule::modifyMolecule(const Molecule &newMolecule,
emitChanged(changes);
}

void RWMolecule::appendMolecule(const Molecule &mol,
const QString &undoText)
{
// We add atoms and bonds, nothing else
Molecule::MoleculeChanges changes =
(Molecule::Atoms | Molecule::Bonds | Molecule::Added);

beginMergeMode(undoText);
// loop through and add the atoms
Index offset = atomCount();
for(size_t i = 0; i < mol.atomCount(); ++i) {
Core::Atom atom = mol.atom(i);
addAtom(atom.atomicNumber(), atom.position3d());
}
// now loop through and add the bonds
for(size_t i = 0; i < mol.bondCount(); ++i) {
Core::Bond bond = mol.bond(i);
addBond(bond.atom1().index() + offset,
bond.atom2().index() + offset,
bond.order());
}
endMergeMode();
emitChanged(changes);
}

void RWMolecule::editUnitCell(Matrix3 cellMatrix,
CrystalTools::Options options)
{
Expand Down
10 changes: 10 additions & 0 deletions avogadro/qtgui/rwmolecule.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,16 @@ class AVOGADROQTGUI_EXPORT RWMolecule : public QObject
Molecule::MoleculeChanges changes,
const QString &undoText = "Modify Molecule");

/**
* Generic edit that adds @a newMolecule to the current molecule.
* Also sets the text for the undo command to be @a undoText. Changes are
* emitted.
* @param addMolecule The new molecule to be set.
* @param undoText The text description for the undo command.
*/
void appendMolecule(const Molecule &addMolecule,
const QString &undoText = "Append Molecule");

/**
* Edit the unit cell by replacing the current cell matrix with a new cell
* matrix. Changes are emitted.
Expand Down
82 changes: 49 additions & 33 deletions avogadro/qtplugins/copypaste/copypaste.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <avogadro/io/fileformatmanager.h>

#include <avogadro/qtgui/molecule.h>
#include <avogadro/qtgui/rwmolecule.h>

#include <QtCore/QMimeData>

Expand All @@ -34,24 +35,31 @@
namespace Avogadro {
namespace QtPlugins {

using namespace Avogadro::QtGui;

CopyPaste::CopyPaste(QObject *parent_) :
Avogadro::QtGui::ExtensionPlugin(parent_),
m_pastedFormat(NULL),
m_copyAction(new QAction(tr("Copy"), this)),
m_cutAction(new QAction(tr("Cut"), this)),
m_clearAction(new QAction(tr("Clear"), this)),
m_pasteAction(new QAction(tr("Paste"), this))
{
m_copyAction->setShortcut(QKeySequence("Ctrl+C"));
m_copyAction->setShortcut(QKeySequence::Copy);
m_copyAction->setIcon(QIcon::fromTheme("edit-copy"));
connect(m_copyAction, SIGNAL(triggered()), SLOT(copy()));

m_cutAction->setShortcut(QKeySequence("Ctrl+X"));
m_cutAction->setShortcut(QKeySequence::Cut);
m_cutAction->setIcon(QIcon::fromTheme("edit-cut"));
connect(m_cutAction, SIGNAL(triggered()), SLOT(cut()));

m_pasteAction->setShortcut(QKeySequence("Ctrl+V"));
m_pasteAction->setShortcut(QKeySequence::Paste);
m_pasteAction->setIcon(QIcon::fromTheme("edit-paste"));
connect(m_pasteAction, SIGNAL(triggered()), SLOT(paste()));

m_clearAction->setShortcut(QKeySequence::Delete);
m_clearAction->setIcon(QIcon::fromTheme("edit-clear"));
connect(m_clearAction, SIGNAL(triggered()), SLOT(clear()));
}

CopyPaste::~CopyPaste()
Expand All @@ -62,7 +70,8 @@ CopyPaste::~CopyPaste()
QList<QAction *> CopyPaste::actions() const
{
QList<QAction *> result;
return result << m_copyAction << m_cutAction << m_pasteAction;
return result << m_copyAction << m_cutAction
<< m_pasteAction << m_clearAction;
}

QStringList CopyPaste::menuPath(QAction *) const
Expand All @@ -75,32 +84,6 @@ void CopyPaste::setMolecule(QtGui::Molecule *mol)
m_molecule = mol;
}

bool CopyPaste::readMolecule(QtGui::Molecule &mol)
{
if (!m_pastedFormat)
return false;

bool success = m_pastedFormat->readString(
std::string(m_pastedData.constData(), m_pastedData.size()), mol);

if (!success) {
QMessageBox::warning(
qobject_cast<QWidget*>(this->parent()), tr("Error Pasting Molecule"),
tr("Error reading clipboard data.") + "\n"
+ tr("Detected format: %1\n%2", "file format description")
.arg(QString::fromStdString(m_pastedFormat->name()))
.arg(QString::fromStdString(m_pastedFormat->description()))+ "\n\n"
+ tr("Reader error:\n%1")
.arg(QString::fromStdString(m_pastedFormat->error())));
}

delete m_pastedFormat;
m_pastedFormat = NULL;
m_pastedData.clear();

return success;
}

bool CopyPaste::copy()
{
if (!m_molecule)
Expand Down Expand Up @@ -139,7 +122,14 @@ void CopyPaste::cut()
if (!copy())
return;

m_molecule->clearAtoms();
m_molecule->undoMolecule()->clearAtoms();
m_molecule->emitChanged(QtGui::Molecule::Atoms | QtGui::Molecule::Bonds
| QtGui::Molecule::Removed );
}

void CopyPaste::clear()
{
m_molecule->undoMolecule()->clearAtoms();
m_molecule->emitChanged(QtGui::Molecule::Atoms | QtGui::Molecule::Bonds
| QtGui::Molecule::Removed );
}
Expand All @@ -153,6 +143,9 @@ void CopyPaste::paste()
m_pastedData.clear();
}

if (!m_molecule)
return; // nothing to do

const QMimeData *mimeData(QApplication::clipboard()->mimeData());

if (!mimeData) {
Expand Down Expand Up @@ -180,8 +173,31 @@ void CopyPaste::paste()
m_pastedData = mimeData->text().toLatin1();
}

if (m_pastedFormat)
emit moleculeReady(1);
if (!m_pastedFormat)
return;

// we have a format, so try to insert the new bits into m_molecule
Avogadro::QtGui::Molecule mol(m_molecule->parent());
bool success = m_pastedFormat->readString(
std::string(m_pastedData.constData(), m_pastedData.size()), mol);

if (!success) {
QMessageBox::warning(
qobject_cast<QWidget*>(this->parent()), tr("Error Pasting Molecule"),
tr("Error reading clipboard data.") + "\n"
+ tr("Detected format: %1\n%2", "file format description")
.arg(QString::fromStdString(m_pastedFormat->name()))
.arg(QString::fromStdString(m_pastedFormat->description()))+ "\n\n"
+ tr("Reader error:\n%1")
.arg(QString::fromStdString(m_pastedFormat->error())));
}

// insert mol into m_molecule
m_molecule->undoMolecule()->appendMolecule(mol, "Paste Molecule");

delete m_pastedFormat;
m_pastedFormat = NULL;
m_pastedData.clear();
}

} // namespace QtPlugins
Expand Down
4 changes: 2 additions & 2 deletions avogadro/qtplugins/copypaste/copypaste.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ class CopyPaste : public QtGui::ExtensionPlugin
public slots:
void setMolecule(QtGui::Molecule *mol) AVO_OVERRIDE;

bool readMolecule(QtGui::Molecule &mol) AVO_OVERRIDE;

private slots:
bool copy(); // returns bool so cut can reuse implementation.
void cut();
void paste();
void clear();

private:
// Cached between emitting moleculeReady() and calling readMolecule().
Expand All @@ -69,6 +68,7 @@ private slots:

QAction *m_copyAction;
QAction *m_cutAction;
QAction *m_clearAction;
QAction *m_pasteAction;
};

Expand Down

0 comments on commit 79fc8b0

Please sign in to comment.