1 // -*- C++ -*-
2 
3 /*
4  * GChemPaint library
5  * fragment.h
6  *
7  * Copyright (C) 2002-2011 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 #ifndef GCHEMPAINT_FRAGMENT_H
26 #define GCHEMPAINT_FRAGMENT_H
27 
28 #include "text-object.h"
29 #include <gccv/item-client.h>
30 #include <gccv/text-tag.h>
31 
32 namespace gccv {
33 	class Text;
34 }
35 
36 /*!\file*/
37 namespace gcp {
38 
39 extern gccv::Tag ChargeTag, StoichiometryTag;
40 
41 /*!
42 @brief Charge.
43 
44 TextTag class for charge. Text using this tag will appear as superscript and
45 interpreted as an electric charge.
46 */
47 class ChargeTextTag: public gccv::PositionTextTag
48 {
49 public:
50 /*!
51 @param size a default font size.
52 
53 Constructs a new ChargeTextTag.
54 */
55 	ChargeTextTag (double size);
56 /*!
57 The destructor.
58 */
59 	virtual ~ChargeTextTag ();
60 
61 /*!
62 @param tag a TextTag.
63 
64 Implementation of TextTag::Restrict for the ChargeTextTag class.
65 @return the new TextTag if \a this split or NULL.
66 */
67 	TextTag *Restrict (TextTag *tag);
68 };
69 
70 /*!
71 @brief Stoichiometry.
72 
73 TextTag class for stoichiometry. Text using this tag will appear as subscript
74 and interpreted as a stoichiometric index.
75 */
76 class StoichiometryTextTag: public gccv::PositionTextTag
77 {
78 public:
79 /*!
80 @param size a default font size.
81 
82 Constructs a new StoichiometryTextTag.
83 */
84 	StoichiometryTextTag (double size);
85 /*!
86 The destructor.
87 */
88 	virtual ~StoichiometryTextTag ();
89 
90 /*!
91 @param tag a TextTag.
92 
93 Implementation of TextTag::Restrict for the StoichiometryTextTag class.
94 @return the new TextTag if \a this split or NULL.
95 */
96 	TextTag *Restrict (TextTag *tag);
97 };
98 
99 class FragmentAtom;
100 class Atom;
101 
102 /*!\class Fragment gcp/fragment.h
103 \brief Atoms groups.
104 
105 Represents atoms groups displayed as a string. Currntly, the string is not
106 fully parsed, so that some non sense strings might be accepted. Anyway, this
107 will not always be the case in the future.
108 */
109 class Fragment: public TextObject
110 {
111 public:
112 /*!
113 The default constructor.
114 */
115 	Fragment ();
116 /*!
117 @param x the x position of the new fragment.
118 @param y the y position of the new fragment.
119 
120 Constructs a new fragment and position it. x and y are the position of the
121 main atom or residue in the fragment.
122 */
123 	Fragment (double x, double y);
124 /*!
125 The destructor.
126 */
127 	virtual ~Fragment ();
128 
129 /*!
130 Used to add a representation of the fragment in the view.
131 */
132 	void AddItem ();
133 /*!
134 Used to update a representation of the fragment in the view.
135 */
136 	void UpdateItem ();
137 /*!
138 @param state the selection state of the fragment.
139 
140 Used to set the selection state of the fragment inside the widget.
141 The values of state might be gcp::SelStateUnselected, gcp::SelStateSelected,
142 gcp::SelStateUpdating, or gcp::SelStateErasing.
143 */
144 	void SetSelected (int state);
145 /*!
146 @param xml the xmlDoc used to save the document.
147 
148 Used to save the fragment to the xmlDoc.
149 @return the xmlNode containing the serialized fragment.
150 */
151 	xmlNodePtr Save (xmlDocPtr xml) const;
152 /*!
153 @param xml the xmlDoc used for clipboard operations.
154 
155 Saves the currently selected text inside the fragment. This method is used by
156 the framework when editing the fragment.
157 @return the xmlNode containing the serialized selection.
158 */
159 	xmlNodePtr SaveSelection (xmlDocPtr xml) const;
160 /*!
161 @param node a pointer to the xmlNode containing the serialized fragment.
162 
163 Used to load a fragment in memory. The Fragment must already exist.
164 @return true on succes, false otherwise.
165 */
166 	bool Load (xmlNodePtr node);
167 /*!
168 @param save whether the text should be saved for undo/redo operations.
169 
170 Called after any change in the text.
171 */
172 	bool OnChanged (bool save);
173 /*!
174 Analyses the whole contents.
175 */
176 	void AnalContent ();
177 /*!
178 @param start the start fo the substring to parse, in bytes.
179 @param end the end fo the substring to parse, in bytes.
180 
181 Analyses a substring.
182 */
183 	void AnalContent (unsigned start, unsigned &end);
184 /*!
185 @param x the x coordinate
186 @param y the y coordinate
187 @param z the z coordinate (unused)
188 
189 @return a pointer to the Atom correpoding to the symbol at or near the position
190 defined by the coordinates passed as parameters, if any.
191 */
192 	Object* GetAtomAt (double x, double y, double z = 0.);
193 /*!
194 @param x the x component of the transation vector.
195 @param y the y component of the transation vector.
196 @param z the z component of the transation vector.
197 
198 Moves the fragment.
199 */
200 	void Move (double x, double y, double z = 0);
201 /*!
202 @param m the Matrix2D of the transformation.
203 @param x the x component of the center of the transformation.
204 @param y the y component of the center of the transformation.
205 
206 Moves and/or transform an object.
207 */
208 	void Transform2D (gcu::Matrix2D& m, double x, double y);
209 /*!
210 Called by the framework when the user changes the nature of an atom using the
211 element tool.
212 */
213 	void OnChangeAtom ();
214 /*!
215 @return the main atom, which might have a bond.
216 */
GetAtom()217 	Atom  *GetAtom () {return reinterpret_cast < Atom * > (m_Atom);}
GetAtom()218 	Atom const *GetAtom () const {return reinterpret_cast < Atom const * > (m_Atom);}
219 /*!
220 @param start the start position of the atomic symbol.
221 @param end the end position of the atomic symbol.
222 
223 @return the atomic number corresponding to the symbol starting at \a start, if any, or 0.
224 \a end is updated accordingly.
225 */
226 	int GetElementAtPos (unsigned start, unsigned &end);
227 /*!
228 @param pAtom the main atom which will get the local charge.
229 @param Pos the approximate position of the charge.
230 @param Angle the angle from horizontal left.
231 @param x the x position of the charge symbol.
232 @param y the y position of the charge symbol.
233 
234 If \a pAtom is not the main atom of the fragment, 0 is returned and \a Pos
235 is not updated.
236 On input \a Pos can be one of POSITION_E, POSITION_N,... or 0xff, in which case,
237 it will be given a default value. \a x and \a y are set to the position where the charge
238 sign should be displayed usding the alignment code returned by this method.
239 @return the anchor for the charge symbol. On error, gccv::AnchorCenter is used as
240 the returned value.
241 */
242 	gccv::Anchor GetChargePosition (FragmentAtom *pAtom, unsigned char &Pos, double Angle, double &x, double &y);
243 /*!
244 @param x the x position.
245 @param y the y position.
246 
247 This method finds an available position for drawing a charge sign or electrons and returns
248 it as a symbolic value (see POSITION_E, POSITION_N,...). The \a x and \a y are updated so
249 that they give the absolute position.
250 @return an available position.
251 */
252 	int GetAvailablePosition (double &x, double &y);
253 /*!
254 @param angle the angle at which a charge sign should be displayed.
255 @param x the x position.
256 @param y the y position.
257 
258 @return false and do not update the coordinates.
259 */
260 	bool GetPosition (double angle, double &x, double &y);
261 /*!
262 Validates the contents of the fragment text, and display error messages when necessary.
263 */
264 	bool Validate ();
265 /*!
266 @return the y coordinate at half height of a carbon atom symbol if any was present.
267 */
268 	double GetYAlign ();
269 
270 /*!
271 @param property the property id as defined in objprops.h
272 @param value the property value as a string
273 
274 Used when loading to set properties for the fragment. This method supports
275 GCU_PROP_POS2D, GCU_PROP_TEXT_TEXT, GCU_PROP_FRAGMENT_ATOM_START,
276 and GCU_PROP_FRAGMENT_ATOM_ID.
277 @return true if the property could be set, or if the property is not relevant, false otherwise.
278 */
279 	bool SetProperty (unsigned property, char const *value);
280 
281 /*!
282 @param property the property id as defined in objprops.h
283 
284 Used when saving to get properties from fragments.
285 */
286 	std::string GetProperty (unsigned property) const;
287 
288 /*!
289 Analyses the text in the fragment. This calls gcp::Fragment::AnalContent()
290 and updates the attribute list.
291 */
292 	bool Analyze ();
293 
294 /*!
295 Changes the order of the symbols if necessary when a bond is at an extremity
296 of the fragment.
297 @return true, if the order has been reversed.
298 */
299 	bool Update ();
300 
301 /*!
302 @return the gccv::Item used to represent the formal charge of the main atom.
303 */
304 	gccv::Item *GetChargeItem ();
305 
306 /*!
307 @return the localized object generic name.
308 */
309 	std::string Name ();
310 /*!
311 @param x a pointer to the double value which will receive the x coordinate of the Fragment.
312 @param y a pointer to the double value which will receive the y coordinate of the Fragment.
313 @param z a pointer to the double value which will receive the z coordinate of the Fragment or NULL for 2D representations.
314 
315 Retrieves the coordinates of this Arrow.
316 @return true if successful and false if an error occurs (if x or y is NULL).
317 */
318 	bool GetCoords (double *x, double *y, double *z = NULL) const;
319 /*!
320 @brief
321 
322 The validity state of a Fragment as it is currently evaluated by the framework.
323 The 0.12.x version don't do anything useful with it and all Fragment instances
324 are invalid.
325 */
326 	typedef enum {
327 /*!
328 Invalid Fragment or validity not checked.
329 */
330 		Invalid,
331 /*!
332 Valid Fragment, all symbols in the string can be interpreted.
333 */
334 		Valid,
335 /*!
336 Valid Fragment, with a known and reasonable 2D structure.
337 */
338 		Valid2D,
339 /*!
340 Valid Fragment, with a known and reasonable 3D structure.
341 */
342 		Valid3D
343 	} Validity;
344 
345 /*!
346 @brief Edition mode.
347 
348 Current edition mode for the fragment. Used to know how inserted symbolds need
349 to be interpreted.
350 */
351 	typedef enum {
352 /*!
353 Automatic mode, try to guess what each new symbol represent.
354 */
355 		AutoMode,
356 /*!
357 New characters are aligned on the base line.
358 */
359 		NormalMode,
360 /*!
361 New characters are subscripts, but are not related to stoichiometry.
362 */
363 		SubscriptMode,
364 /*!
365 New characters are superscripts, but are not related to charge.
366 */
367 		SuperscriptMode,
368 /*!
369 New characters are interpreted as charge and superscript.
370 */
371 		ChargeMode,
372 /*!
373 New characters are interpreted as stoichiometry and subscript.
374 */
375 		StoichiometryMode
376 	} FragmentMode;
377 
378 private:
379 	bool SavePortion (xmlDocPtr xml, xmlNodePtr node, unsigned start, unsigned end) const;
380 
381 private:
382 	FragmentAtom *m_Atom;
383 	unsigned m_BeginAtom, m_EndAtom;
384 	double m_lbearing;
385 	double m_CHeight;
386 	bool m_Inversable;
387 
388 /*!\fn GetValid()
389 @return the current Fragment::Validity for the Fragment instance.
390 */
391 GCU_RO_PROP (Validity, Valid)
392 /*!\fn SetMode(FragmentMode mode)
393 @param mode the nexw edition mode.
394 
395 Sets the current edition mode for the Fragment instance.
396 */
397 /*!\fn GetMode()
398 @return the current edition mode for the Fragment instance.
399 */
400 /*!\fn GetRefMode()
401 @return the current edition mode for the Fragment instance as a reference.
402 */
403 GCU_PROP (FragmentMode, Mode)
404 };
405 
406 }	//	namespace gcp
407 
408 #endif	//GCHEMPAINT_FRAGMENT_H
409