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