]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/test/aux.cc
* added license and copyright to every source file
[helm.git] / helm / DEVEL / mathml_editor / test / aux.cc
1 /* Copyright (C) 2002-2003, Luca Padovani <luca.padovani@cs.unibo.it>,
2  *                    2003, Paolo Marinelli <pmarinel@cs.unibo.it>.
3  *
4  * This file is part of EdiTeX, an editor of mathematical
5  * expressions based on TeX syntax
6  * 
7  * EdiTeX is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * EdiTeX is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with EdiTeX; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  * 
21  * For details, see the EdiTeX World-Wide-Web page,
22  * http://helm.cs.unibo.it/editex, or send a mail to
23  * <luca.padovani@cs.unibo.it>
24  */
25 // Copyright (C) 2000-2002, Luca Padovani <luca.padovani@cs.unibo.it>.
26 //
27 // This file is part of GtkMathView, a Gtk widget for MathML.
28 // 
29 // GtkMathView is free software; you can redistribute it and/or
30 // modify it under the terms of the GNU General Public License
31 // as published by the Free Software Foundation; either version 2
32 // of the License, or (at your option) any later version.
33 //
34 // GtkMathView is distributed in the hope that it will be useful,
35 // but WITHOUT ANY WARRANTY; without even the implied warranty of
36 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37 // GNU General Public License for more details.
38 //
39 // You should have received a copy of the GNU General Public License
40 // along with GtkMathView; if not, write to the Free Software
41 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
42 // 
43 // For details, see the GtkMathView World-Wide-Web page,
44 // http://www.cs.unibo.it/helm/mml-widget, or send a mail to
45 // <luca.padovani@cs.unibo.it>
46
47 #include <config.h>
48 #include <assert.h>
49
50 #include <gdome.h>
51 #include <gdome-util.h>
52 #include <GdomeSmartDOM.hh>
53
54 //#include "gmetadom.hh"
55
56 namespace DOM = GdomeSmartDOM;
57
58 static unsigned
59 getDepth(const DOM::Element& elem)
60 {
61   unsigned length = 0;
62   DOM::Element p = elem;
63
64   while (p)
65     {
66       p = p.get_parentNode();
67       length++;
68     }
69
70   return length;
71 }
72
73 static DOM::Element
74 findCommonAncestor(const DOM::Element& first, const DOM::Element& last)
75 {
76   assert(first);
77   assert(last);
78
79   DOM::Element p(first);
80   DOM::Element q(last);
81
82   if (p != q)
83     {
84       unsigned pDepth = getDepth(p);
85       unsigned qDepth  = getDepth(q);
86
87       while (p && pDepth > qDepth)
88         {
89           p = p.get_parentNode();
90           pDepth--;
91         }
92
93       while (q && qDepth > pDepth)
94         {
95           q = q.get_parentNode();
96           qDepth--;
97         }
98
99       assert(pDepth == qDepth);
100
101       while (p && q && p != q)
102         {
103           p = p.get_parentNode();
104           q = q.get_parentNode();
105         }
106     }
107   
108   return p;
109 }
110
111 static void
112 findCommonSiblings(const DOM::Element& first, const DOM::Element& last,
113                    DOM::Element& firstS, DOM::Element& lastS)
114 {
115   assert(first);
116   assert(last);
117
118   DOM::Element p(first);
119   DOM::Element q(last);
120
121   if (p != q)
122     {
123       unsigned pDepth = getDepth(p);
124       unsigned qDepth  = getDepth(q);
125
126       while (p && pDepth > qDepth)
127         {
128           p = p.get_parentNode();
129           pDepth--;
130         }
131
132       while (q && qDepth > pDepth)
133         {
134           q = q.get_parentNode();
135           qDepth--;
136         }
137
138       assert(pDepth == qDepth);
139
140       while (p && q && p.get_parentNode() != q.get_parentNode())
141         {
142           p = p.get_parentNode();
143           q = q.get_parentNode();
144         }
145     }
146
147   firstS = p;
148   lastS = q;
149 }
150
151 static DOM::Element
152 findElementWithRef(const DOM::Element& el)
153 {
154   DOM::Element p = el;
155   while (p && !p.hasAttribute("xref")) p = p.get_parentNode();
156   return p;
157 }
158
159 static DOM::Node
160 leftmostChild(const DOM::Node& node)
161 {
162   if (!node) return node;
163
164   DOM::Node firstChild = node.get_firstChild();
165   if (!firstChild) return node;
166
167   return leftmostChild(firstChild);
168 }
169
170 static DOM::Node
171 rightmostChild(const DOM::Node& node)
172 {
173   if (!node) return node;
174
175   DOM::Node lastChild = node.get_lastChild();
176   if (!lastChild) return node;
177
178   return rightmostChild(lastChild);
179 }
180
181 static DOM::Node
182 leftSibling(const DOM::Node& node)
183 {
184   DOM::Node p = node;
185
186   if (!p) return p;
187
188   while (p.get_parentNode() && p.get_parentNode().get_firstChild() == p)
189     p = p.get_parentNode();
190
191   if (!p.get_parentNode()) return DOM::Node(0);
192
193   DOM::Node prevSibling = p.get_previousSibling();
194   assert(prevSibling);
195
196   return rightmostChild(prevSibling);
197 }
198
199 static DOM::Node
200 rightSibling(const DOM::Node& node)
201 {
202   DOM::Node p = node;
203
204   if (!p) return p;
205
206   DOM::Node firstChild = p.get_firstChild();
207   if (firstChild) return firstChild;
208
209   while (p.get_parentNode() && p.get_parentNode().get_lastChild() == p)
210     p = p.get_parentNode();
211
212   if (!p.get_parentNode()) return DOM::Node(0);
213
214   DOM::Node nextSibling = p.get_nextSibling();
215   assert(nextSibling);
216
217   return leftmostChild(nextSibling);
218 }
219
220 extern "C" GdomeElement*
221 find_common_ancestor(GdomeElement* first, GdomeElement* last)
222 {
223   if (GdomeNode* n = findCommonAncestor(DOM::Element(first), DOM::Element(last)).gdome_object())
224     {
225       GdomeElement* res = gdome_cast_el(n);
226       g_assert(res != NULL);
227       return res;
228     }
229   else
230     return NULL;
231 }
232
233 extern "C" void
234 find_common_siblings(GdomeElement* first, GdomeElement* last,
235                      GdomeElement** firstS, GdomeElement** lastS)
236 {
237   DOM::Element fs(0);
238   DOM::Element ls(0);
239
240   findCommonSiblings(DOM::Element(first), DOM::Element(last), fs, ls);
241
242   if (firstS != NULL) *firstS = gdome_cast_el(fs.gdome_object());
243   if (lastS != NULL) *lastS = gdome_cast_el(ls.gdome_object());
244 }
245
246 extern "C" GdomeElement*
247 find_element_with_ref(GdomeElement* elem)
248 {
249   if (GdomeNode* n = findElementWithRef(DOM::Element(elem)).gdome_object())
250     {
251       GdomeElement* res = gdome_cast_el(n);
252       g_assert(res != NULL);
253       return res;
254     }
255   else
256     return NULL;
257 }
258
259 extern "C" GdomeElement*
260 find_common_ancestor_with_ref(GdomeElement* first, GdomeElement* last)
261 {
262   if (GdomeNode* n = findElementWithRef(findCommonAncestor(DOM::Element(first), DOM::Element(last))).gdome_object())
263     {
264       GdomeElement* res = gdome_cast_el(n);
265       g_assert(res != NULL);
266       return res;
267     }
268   else
269     return NULL;
270 }
271
272 extern "C" void
273 delete_element(GdomeElement* elem)
274 {
275   DOM::Element p(elem);
276
277   DOM::Element parent = p.get_parentNode();
278   assert(parent);
279
280   parent.removeChild(p);
281 }
282