1 // -*- C++ -*-
2
3 /*
4 * GChemPaint arrows plugin
5 * retrosynthesisstep.cc
6 *
7 * Copyright (C) 2005-2010 Jean Bréfort <jean.brefort@normalesup.org>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 3 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 * USA
23 */
24
25 #include "config.h"
26 #include "retrosynthesisstep.h"
27 #include "retrosynthesis.h"
28 #include "retrosynthesisarrow.h"
29 #include <gcp/application.h>
30 #include <gcp/molecule.h>
31 #include <gcp/document.h>
32 #include <gcu/objprops.h>
33 #include <glib/gi18n-lib.h>
34
35 TypeId RetrosynthesisStepType;
36
gcpRetrosynthesisStep()37 gcpRetrosynthesisStep::gcpRetrosynthesisStep (): gcp::Step (RetrosynthesisStepType)
38 {
39 SetId ("rss1");
40 Molecule = NULL;
41 }
42
~gcpRetrosynthesisStep()43 gcpRetrosynthesisStep::~gcpRetrosynthesisStep ()
44 {
45 if (IsLocked ())
46 return;
47 gcp::Document *pDoc = reinterpret_cast<gcp::Document *> (GetDocument ());
48 gcp::Operation *pOp = pDoc->GetCurrentOperation ();
49 gcpRetrosynthesis *rs = reinterpret_cast<gcpRetrosynthesis *> (GetParent ());
50 if (!rs)
51 return;
52 map<string, Object *>::iterator i;
53 Object *Child, *Group = rs->GetGroup ();
54 while (HasChildren ()) {
55 Child = GetFirstChild (i);
56 GetParent ()->GetParent ()->AddChild (Child);
57 if (pOp && !Group)
58 pOp->AddObject (Child, 1);
59 }
60 }
61
gcpRetrosynthesisStep(gcpRetrosynthesis * synthesis,gcp::Molecule * molecule)62 gcpRetrosynthesisStep::gcpRetrosynthesisStep (gcpRetrosynthesis *synthesis, gcp::Molecule* molecule) throw (std::invalid_argument): gcp::Step (RetrosynthesisStepType)
63 {
64 if (!synthesis || !molecule)
65 throw invalid_argument ("NULL argument to gcpRetrosynthesisStep constructor!");
66 SetId ("rss1");
67 synthesis->AddChild (this);
68 GetDocument ()->EmptyTranslationTable();
69 AddChild (molecule);
70 Molecule = molecule;
71 Arrow = NULL;
72 }
73
AddArrow(gcpRetrosynthesisArrow * arrow,gcpRetrosynthesisStep * step,bool start)74 void gcpRetrosynthesisStep::AddArrow (gcpRetrosynthesisArrow *arrow, gcpRetrosynthesisStep *step, bool start) throw (std::invalid_argument)
75 {
76 if (start) {
77 if (Arrows[step])
78 throw invalid_argument (_("Only one arrow can link two given steps."));
79 Arrows[step] = arrow;
80 } else {
81 Arrow = arrow;
82 Precursor = step;
83 }
84 }
85
Load(xmlNodePtr node)86 bool gcpRetrosynthesisStep::Load(xmlNodePtr node)
87 {
88 if (Object::Load (node)) {
89 if (GetChildrenNumber () != 1)
90 return false;
91 map<string, Object*>::iterator i;
92 Molecule = reinterpret_cast<gcp::Molecule *> (GetFirstChild (i));
93 GetDocument ()->ObjectLoaded (this);
94 return true;
95 }
96 return false;
97 }
98
GetYAlign()99 double gcpRetrosynthesisStep::GetYAlign ()
100 {
101 return (Molecule)? Molecule->GetYAlign (): 0.;
102 }
103
RemoveArrow(G_GNUC_UNUSED gcpRetrosynthesisArrow * arrow,gcpRetrosynthesisStep * step)104 void gcpRetrosynthesisStep::RemoveArrow (G_GNUC_UNUSED gcpRetrosynthesisArrow *arrow, gcpRetrosynthesisStep *step)
105 {
106 if (step == Precursor) {
107 Precursor = NULL;
108 Arrow = NULL;
109 } else
110 Arrows.erase (step);
111 }
112
OnSignal(G_GNUC_UNUSED SignalId Signal,G_GNUC_UNUSED Object * Child)113 bool gcpRetrosynthesisStep::OnSignal (G_GNUC_UNUSED SignalId Signal, G_GNUC_UNUSED Object *Child)
114 {
115 if (GetChildrenNumber () != 1) {
116 delete GetParent ();
117 return false;
118 }
119 return true;
120 }
121
SetProperty(unsigned property,char const * value)122 bool gcpRetrosynthesisStep::SetProperty (unsigned property, char const *value)
123 {
124 gcu::Document *doc = GetDocument ();
125 switch (property) {
126 case GCU_PROP_MOLECULE: {
127 if (doc == NULL)
128 return false;
129 if (Molecule != NULL && !strcmp (Molecule->GetId (), value)) {
130 break;
131 }
132 gcu::Object *new_child = doc->GetDescendant (value);
133 gcp::Application *app = static_cast <gcp::Application * > (doc->GetApplication ());
134 std::set < TypeId > const &rules = app->GetRules (RetrosynthesisStepType, RuleMayContain);
135 if (new_child != NULL && rules.find (new_child->GetType ()) != rules.end ()) {
136 if (Molecule != NULL)
137 Molecule->SetParent (doc);
138 Molecule = dynamic_cast < gcp::Molecule * > (new_child);
139 if (Molecule)
140 AddChild (Molecule);
141 }
142 break;
143 }
144 }
145 return true;
146 }
147
Name()148 std::string gcpRetrosynthesisStep::Name ()
149 {
150 return _("Retrosynthesis step");
151 }
152