kalzium
drawcommand.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "drawcommand.h"
00028 #include <avogadro/primitive.h>
00029 #include <openbabel/obiter.h>
00030
00031 #include <QDebug>
00032
00033 using namespace OpenBabel;
00034
00035 namespace Avogadro {
00036
00038 void UnsetFlags(Molecule *mol)
00039 {
00040 mol->UnsetFlag(OB_AROMATIC_MOL);
00041 mol->UnsetFlag(OB_SSSR_MOL);
00042 mol->UnsetFlag(OB_RINGFLAGS_MOL);
00043 mol->UnsetFlag(OB_ATOMTYPES_MOL);
00044 mol->UnsetFlag(OB_RINGTYPES_MOL);
00045 mol->UnsetFlag(OB_CHIRALITY_MOL);
00046 mol->UnsetFlag(OB_HYBRID_MOL);
00047 mol->UnsetFlag(OB_IMPVAL_MOL);
00048 mol->UnsetFlag(OB_KEKULE_MOL);
00049 mol->UnsetFlag(OB_CLOSURE_MOL);
00050 mol->UnsetFlag(OB_H_ADDED_MOL);
00051 mol->UnsetFlag(OB_AROM_CORRECTED_MOL);
00052 }
00053
00055
00057
00058 class AddAtomDrawCommandPrivate {
00059 public:
00060 AddAtomDrawCommandPrivate() : molecule(0), atom(0), id(-1), prevId(false) {};
00061
00062 Molecule *molecule;
00063 Atom *atom;
00064 Eigen::Vector3d pos;
00065 unsigned int element;
00066
00067
00068 int adjustValence;
00069 unsigned long id;
00070 bool prevId;
00071 };
00072
00073 AddAtomDrawCommand::AddAtomDrawCommand(Molecule *molecule, const Eigen::Vector3d& pos, unsigned int element, int adjustValence) : d(new AddAtomDrawCommandPrivate)
00074 {
00075 setText(QObject::tr("Add Atom"));
00076 d->molecule = molecule;
00077 d->pos = pos;
00078 d->element = element;
00079 d->adjustValence = adjustValence;
00080 d->prevId = false;
00081 }
00082
00083 AddAtomDrawCommand::AddAtomDrawCommand(Molecule *molecule, Atom *atom, int adjustValence) : d(new AddAtomDrawCommandPrivate)
00084 {
00085 setText(QObject::tr("Add Atom"));
00086 d->molecule = molecule;
00087 d->pos = atom->pos();
00088 d->element = atom->GetAtomicNum();
00089 d->atom = atom;
00090 d->adjustValence = adjustValence;
00091 d->id = atom->id();
00092 d->prevId = true;
00093 }
00094
00095 AddAtomDrawCommand::~AddAtomDrawCommand()
00096 {
00097 delete d;
00098 }
00099
00100 void AddAtomDrawCommand::undo()
00101 {
00102 Atom *atom = d->molecule->getAtomById(d->id);
00103 if(atom)
00104 {
00105 d->molecule->BeginModify();
00106 if (d->adjustValence) {
00107 qDebug() << "Adjusting Atom valence";
00108 if (!atom->IsHydrogen())
00109 {
00110 d->molecule->DeleteHydrogens(atom);
00111 }
00112 }
00113 d->molecule->DeleteAtom(atom);
00114 d->molecule->EndModify();
00115
00116 }
00117 }
00118
00119 void AddAtomDrawCommand::redo()
00120 {
00121 if(d->atom) {
00122 if (d->adjustValence==1) {
00123 qDebug() << "Adjusting Atom valence";
00124 if (!d->atom->IsHydrogen()) {
00125 d->molecule->DeleteHydrogens(d->atom);
00126 d->molecule->AddHydrogens(d->atom);
00127 }
00128 }
00129 d->atom = 0;
00130 return;
00131 }
00132
00133 Atom *atom = 0;
00134 d->molecule->BeginModify();
00135 if(d->prevId)
00136 {
00137 atom = d->molecule->newAtom(d->id);
00138 }
00139 else
00140 {
00141 atom = d->molecule->newAtom();
00142 d->id = atom->id();
00143 d->prevId = true;
00144 }
00145 atom->setPos(d->pos);
00146 atom->SetAtomicNum(d->element);
00147 d->molecule->EndModify();
00148 if (d->adjustValence==1) {
00149 qDebug() << "Adjusting Atom valence";
00150 if (!atom->IsHydrogen()) {
00151 d->molecule->AddHydrogens(atom);
00152 }
00153 }
00154 atom->update();
00155 }
00156
00158
00160
00161 class DeleteAtomDrawCommandPrivate {
00162 public:
00163 DeleteAtomDrawCommandPrivate() : id(-1) {};
00164
00165 Molecule *molecule;
00166 Molecule moleculeCopy;
00167 unsigned long id;
00168 int adjustValence;
00169 };
00170
00171 DeleteAtomDrawCommand::DeleteAtomDrawCommand(Molecule *molecule, int index, int adjustValence) : d(new DeleteAtomDrawCommandPrivate)
00172 {
00173 setText(QObject::tr("Delete Atom"));
00174 d->molecule = molecule;
00175 d->moleculeCopy = (*(molecule));
00176 d->id = static_cast<Atom *>(molecule->GetAtom(index))->id();
00177 d->adjustValence = adjustValence;
00178 }
00179
00180 DeleteAtomDrawCommand::~DeleteAtomDrawCommand()
00181 {
00182 delete d;
00183 }
00184
00185 void DeleteAtomDrawCommand::undo()
00186 {
00187 *d->molecule = d->moleculeCopy;
00188 d->molecule->update();
00189 }
00190
00191 void DeleteAtomDrawCommand::redo()
00192 {
00193 Atom *atom = d->molecule->getAtomById(d->id);
00194 if(atom)
00195 {
00196 QList<OBAtom*> neighbors;
00197
00198 if (d->adjustValence) {
00199
00200 d->molecule->DeleteHydrogens(atom);
00201
00202
00203 FOR_NBORS_OF_ATOM(n, atom) {
00204 neighbors.append(&*n);
00205 d->molecule->DeleteHydrogens(&*n);
00206 }
00207 }
00208 d->molecule->DeleteAtom(atom);
00209
00210 if (d->adjustValence) {
00211
00212 foreach (OBAtom *n, neighbors)
00213 d->molecule->AddHydrogens(n);
00214 }
00215 d->molecule->update();
00216 }
00217 }
00218
00220
00222
00223 class AddBondDrawCommandPrivate {
00224 public:
00225 AddBondDrawCommandPrivate() : molecule(0), bond(0), id(-1), beginAtomId(-1), endAtomId(-1), prevId(false) {};
00226
00227 Molecule *molecule;
00228 Bond *bond;
00229 unsigned long id;
00230 unsigned int beginAtomId;
00231 unsigned int endAtomId;
00232 bool prevId;
00233 Eigen::Vector3d pos;
00234 unsigned int order;
00235 int adjustValence;
00236 };
00237
00238 AddBondDrawCommand::AddBondDrawCommand(Molecule *molecule, Atom *beginAtom, Atom *endAtom, unsigned int order, int adjustValence) : d(new AddBondDrawCommandPrivate)
00239 {
00240 setText(QObject::tr("Add Bond"));
00241 d->molecule = molecule;
00242 d->beginAtomId = beginAtom->id();
00243 d->endAtomId = endAtom->id();
00244 d->order = order;
00245 d->adjustValence = adjustValence;
00246 }
00247
00248 AddBondDrawCommand::AddBondDrawCommand(Molecule *molecule, Bond *bond, int adjustValence) : d(new AddBondDrawCommandPrivate)
00249 {
00250 setText(QObject::tr("Add Bond"));
00251 d->molecule = molecule;
00252 d->beginAtomId = static_cast<Atom*>(bond->GetBeginAtom())->id();
00253 d->endAtomId = static_cast<Atom*>(bond->GetEndAtom())->id();
00254 d->order = bond->GetBondOrder();
00255 d->bond = bond;
00256 d->prevId = true;
00257 d->id = bond->id();
00258 d->adjustValence = adjustValence;
00259 }
00260
00261 AddBondDrawCommand::~AddBondDrawCommand()
00262 {
00263 delete d;
00264 }
00265
00266 void AddBondDrawCommand::undo()
00267 {
00268 Bond *bond = d->molecule->getBondById(d->id);
00269 if(bond)
00270 {
00271 Atom *beginAtom = static_cast<Atom*>(bond->GetBeginAtom());
00272 Atom *endAtom = static_cast<Atom*>(bond->GetEndAtom());
00273
00274 d->molecule->BeginModify();
00275 d->molecule->DeleteBond(bond);
00276 d->molecule->EndModify();
00277 if (d->adjustValence) {
00278 if (!beginAtom->IsHydrogen()) {
00279 d->molecule->DeleteHydrogens(beginAtom);
00280 }
00281 if (!endAtom->IsHydrogen()) {
00282 d->molecule->DeleteHydrogens(endAtom);
00283 }
00284
00285 UnsetFlags(d->molecule);
00286
00287 if (!beginAtom->IsHydrogen()) {
00288 d->molecule->AddHydrogens(beginAtom);
00289 }
00290 if (!endAtom->IsHydrogen()) {
00291 d->molecule->AddHydrogens(endAtom);
00292 }
00293 }
00294 d->molecule->update();
00295 return;
00296 }
00297 }
00298
00299 void AddBondDrawCommand::redo()
00300 {
00301
00302 if(d->bond) {
00303 Atom *beginAtom = static_cast<Atom*>(d->bond->GetBeginAtom());
00304 Atom *endAtom = static_cast<Atom*>(d->bond->GetEndAtom());
00305 if (d->adjustValence) {
00306 if (!beginAtom->IsHydrogen()) {
00307 d->molecule->DeleteHydrogens(beginAtom);
00308 }
00309 if (!endAtom->IsHydrogen()) {
00310 d->molecule->DeleteHydrogens(endAtom);
00311 }
00312
00313 UnsetFlags(d->molecule);
00314
00315 if (!beginAtom->IsHydrogen()) {
00316 d->molecule->AddHydrogens(beginAtom);
00317 }
00318 if (!endAtom->IsHydrogen()) {
00319 d->molecule->AddHydrogens(endAtom);
00320 }
00321 }
00322 d->bond = 0;
00323 return;
00324 }
00325
00326 Atom *beginAtom = d->molecule->getAtomById(d->beginAtomId);
00327 Atom *endAtom = d->molecule->getAtomById(d->endAtomId);
00328
00329 if(!beginAtom || !endAtom)
00330 {
00331 return;
00332 }
00333
00334 d->molecule->BeginModify();
00335 Bond *bond;
00336 if(d->prevId)
00337 {
00338 bond = d->molecule->newBond(d->id);
00339 }
00340 else
00341 {
00342 bond = d->molecule->newBond();
00343 d->id = bond->id();
00344 d->prevId = true;
00345 }
00346 bond->SetBondOrder(d->order);
00347 bond->SetBegin(beginAtom);
00348 bond->SetEnd(endAtom);
00349 beginAtom->AddBond(bond);
00350 endAtom->AddBond(bond);
00351 d->molecule->EndModify();
00352 if (d->adjustValence) {
00353 if (!beginAtom->IsHydrogen())
00354 {
00355 d->molecule->DeleteHydrogens(beginAtom);
00356 }
00357 if (!endAtom->IsHydrogen())
00358 {
00359 d->molecule->DeleteHydrogens(endAtom);
00360 }
00361
00362 UnsetFlags(d->molecule);
00363
00364 if (!beginAtom->IsHydrogen())
00365 {
00366 d->molecule->AddHydrogens(endAtom);
00367 }
00368 if (!endAtom->IsHydrogen())
00369 {
00370 d->molecule->AddHydrogens(beginAtom);
00371 }
00372 }
00373 d->molecule->update();
00374 }
00375
00377
00379
00380 class DeleteBondDrawCommandPrivate {
00381 public:
00382 DeleteBondDrawCommandPrivate() : id(-1) {};
00383
00384 Molecule *molecule;
00385 Molecule moleculeCopy;
00386 unsigned long id;
00387 int adjustValence;
00388 };
00389
00390 DeleteBondDrawCommand::DeleteBondDrawCommand(Molecule *molecule, int index, int adjustValence) : d(new DeleteBondDrawCommandPrivate)
00391 {
00392 setText(QObject::tr("Delete Bond"));
00393 d->molecule = molecule;
00394 d->moleculeCopy = (*(molecule));
00395 d->id = static_cast<Bond *>(molecule->GetBond(index))->id();
00396 d->adjustValence = adjustValence;
00397 }
00398
00399 DeleteBondDrawCommand::~DeleteBondDrawCommand()
00400 {
00401 delete d;
00402 }
00403
00404 void DeleteBondDrawCommand::undo()
00405 {
00406 *d->molecule = d->moleculeCopy;
00407 d->molecule->update();
00408 }
00409
00410 void DeleteBondDrawCommand::redo()
00411 {
00412 Bond *bond = d->molecule->getBondById(d->id);
00413 if(bond)
00414 {
00415 d->molecule->DeleteBond(bond);
00416 if (d->adjustValence) {
00417 OBAtom *a1, *a2;
00418 a1 = bond->GetBeginAtom();
00419 a2 = bond->GetEndAtom();
00420 d->molecule->DeleteHydrogens(a1);
00421 d->molecule->DeleteHydrogens(a2);
00422
00423 UnsetFlags(d->molecule);
00424
00425 d->molecule->AddHydrogens(a1);
00426 d->molecule->AddHydrogens(a2);
00427 }
00428 d->molecule->update();
00429 }
00430 }
00431
00433
00435
00436 class ChangeElementDrawCommandPrivate {
00437 public:
00438 ChangeElementDrawCommandPrivate() : molecule(0), id(0) {};
00439
00440 Molecule *molecule;
00441 unsigned int newElement, oldElement;
00442 unsigned long id;
00443 int adjustValence;
00444 };
00445
00446 ChangeElementDrawCommand::ChangeElementDrawCommand(Molecule *molecule, Atom *atom, unsigned int oldElement, int adjustValence) : d(new ChangeElementDrawCommandPrivate)
00447 {
00448 setText(QObject::tr("Change Element"));
00449 d->molecule = molecule;
00450 d->newElement = atom->GetAtomicNum();
00451 d->oldElement = oldElement;
00452 d->id = atom->id();
00453 d->adjustValence = adjustValence;
00454 }
00455
00456 ChangeElementDrawCommand::~ChangeElementDrawCommand()
00457 {
00458 delete d;
00459 }
00460
00461 void ChangeElementDrawCommand::undo()
00462 {
00463 Atom *atom = d->molecule->getAtomById(d->id);
00464
00465 if(atom)
00466 {
00467
00468 d->molecule->BeginModify();
00469 atom->SetAtomicNum(d->oldElement);
00470 d->molecule->EndModify();
00471 d->molecule->update();
00472 if (d->adjustValence) {
00473 UnsetFlags(d->molecule);
00474 d->molecule->DeleteHydrogens(atom);
00475 d->molecule->AddHydrogens(atom);
00476 }
00477 }
00478 }
00479
00480 void ChangeElementDrawCommand::redo()
00481 {
00482 Atom *atom = d->molecule->getAtomById(d->id);
00483
00484 if(atom)
00485 {
00486
00487 d->molecule->BeginModify();
00488 atom->SetAtomicNum(d->newElement);
00489 d->molecule->EndModify();
00490 if (d->adjustValence) {
00491 UnsetFlags(d->molecule);
00492 d->molecule->DeleteHydrogens(atom);
00493 d->molecule->AddHydrogens(atom);
00494 }
00495 d->molecule->update();
00496 }
00497 }
00498
00500
00502
00503 class ChangeBondOrderDrawCommandPrivate {
00504 public:
00505 ChangeBondOrderDrawCommandPrivate() : molecule(0), id(-1) {};
00506
00507 Molecule *molecule;
00508 unsigned long id;
00509 unsigned int newBondOrder, oldBondOrder;
00510 int adjustValence;
00511 };
00512
00513 ChangeBondOrderDrawCommand::ChangeBondOrderDrawCommand(Molecule *molecule, Bond *bond, unsigned int oldBondOrder, int adjustValence) : d(new ChangeBondOrderDrawCommandPrivate)
00514 {
00515 setText(QObject::tr("Change Bond Order"));
00516 d->molecule = molecule;
00517 d->id = bond->id();
00518 d->newBondOrder = bond->GetBondOrder();
00519 d->oldBondOrder = oldBondOrder;
00520 d->adjustValence = adjustValence;
00521 }
00522
00523 ChangeBondOrderDrawCommand::~ChangeBondOrderDrawCommand()
00524 {
00525 delete d;
00526 }
00527
00528 void ChangeBondOrderDrawCommand::undo()
00529 {
00530 Bond *bond = d->molecule->getBondById(d->id);
00531 if(bond)
00532 {
00533
00534 d->molecule->BeginModify();
00535 bond->SetBondOrder(d->oldBondOrder);
00536 d->molecule->EndModify();
00537 if (d->adjustValence) {
00538 OBAtom *a1, *a2;
00539 a1 = bond->GetBeginAtom();
00540 a2 = bond->GetEndAtom();
00541 d->molecule->DeleteHydrogens(a1);
00542 d->molecule->DeleteHydrogens(a2);
00543
00544 UnsetFlags(d->molecule);
00545 d->molecule->AddHydrogens(a1);
00546 d->molecule->AddHydrogens(a2);
00547 }
00548 d->molecule->update();
00549 }
00550 }
00551
00552 void ChangeBondOrderDrawCommand::redo()
00553 {
00554 Bond *bond = d->molecule->getBondById(d->id);
00555 if(bond)
00556 {
00557
00558 d->molecule->BeginModify();
00559 bond->SetBondOrder(d->newBondOrder);
00560 d->molecule->EndModify();
00561 if (d->adjustValence) {
00562
00563 OBAtom *a1, *a2;
00564 a1 = bond->GetBeginAtom();
00565 a2 = bond->GetEndAtom();
00566 d->molecule->DeleteHydrogens(a1);
00567 d->molecule->DeleteHydrogens(a2);
00568
00569 UnsetFlags(d->molecule);
00570 d->molecule->AddHydrogens(a1);
00571 d->molecule->AddHydrogens(a2);
00572 }
00573 d->molecule->update();
00574 }
00575 }
00576
00578
00580
00581 class InsertFragmentCommandPrivate {
00582 public:
00583 InsertFragmentCommandPrivate() : molecule(0), generatedMolecule(0) {};
00584
00585 Molecule *molecule;
00586 Molecule moleculeCopy, generatedMolecule;
00587 };
00588
00589 InsertFragmentCommand::InsertFragmentCommand(Molecule *molecule, Molecule &generatedMolecule) : d(new InsertFragmentCommandPrivate)
00590 {
00591 setText(QObject::tr("Insert Fragment"));
00592 d->molecule = molecule;
00593 d->moleculeCopy = *molecule;
00594 d->generatedMolecule = generatedMolecule;
00595 }
00596
00597 InsertFragmentCommand::~InsertFragmentCommand()
00598 {
00599 delete d;
00600 }
00601
00602 void InsertFragmentCommand::undo()
00603 {
00604 *(d->molecule) = d->moleculeCopy;
00605 d->molecule->update();
00606 }
00607
00608 void InsertFragmentCommand::redo()
00609 {
00610 *(d->molecule) += d->generatedMolecule;
00611 d->molecule->update();
00612 }
00613
00614
00615 }