1 // Copyright (C) 2000-2002, Luca Padovani <luca.padovani@cs.unibo.it>.
3 // This file is part of GtkMathView, a Gtk widget for MathML.
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.
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.
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.
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>
27 #include <gdome-util.h>
28 #include <GdomeSmartDOM.hh>
30 //#include "gmetadom.hh"
32 namespace DOM = GdomeSmartDOM;
35 getDepth(const DOM::Element& elem)
38 DOM::Element p = elem;
42 p = p.get_parentNode();
50 findCommonAncestor(const DOM::Element& first, const DOM::Element& last)
55 DOM::Element p(first);
60 unsigned pDepth = getDepth(p);
61 unsigned qDepth = getDepth(q);
63 while (p && pDepth > qDepth)
65 p = p.get_parentNode();
69 while (q && qDepth > pDepth)
71 q = q.get_parentNode();
75 assert(pDepth == qDepth);
77 while (p && q && p != q)
79 p = p.get_parentNode();
80 q = q.get_parentNode();
88 findCommonSiblings(const DOM::Element& first, const DOM::Element& last,
89 DOM::Element& firstS, DOM::Element& lastS)
94 DOM::Element p(first);
99 unsigned pDepth = getDepth(p);
100 unsigned qDepth = getDepth(q);
102 while (p && pDepth > qDepth)
104 p = p.get_parentNode();
108 while (q && qDepth > pDepth)
110 q = q.get_parentNode();
114 assert(pDepth == qDepth);
116 while (p && q && p.get_parentNode() != q.get_parentNode())
118 p = p.get_parentNode();
119 q = q.get_parentNode();
128 findElementWithRef(const DOM::Element& el)
131 while (p && !p.hasAttribute("xref")) p = p.get_parentNode();
136 leftmostChild(const DOM::Node& node)
138 if (!node) return node;
140 DOM::Node firstChild = node.get_firstChild();
141 if (!firstChild) return node;
143 return leftmostChild(firstChild);
147 rightmostChild(const DOM::Node& node)
149 if (!node) return node;
151 DOM::Node lastChild = node.get_lastChild();
152 if (!lastChild) return node;
154 return rightmostChild(lastChild);
158 leftSibling(const DOM::Node& node)
164 while (p.get_parentNode() && p.get_parentNode().get_firstChild() == p)
165 p = p.get_parentNode();
167 if (!p.get_parentNode()) return DOM::Node(0);
169 DOM::Node prevSibling = p.get_previousSibling();
172 return rightmostChild(prevSibling);
176 rightSibling(const DOM::Node& node)
182 DOM::Node firstChild = p.get_firstChild();
183 if (firstChild) return firstChild;
185 while (p.get_parentNode() && p.get_parentNode().get_lastChild() == p)
186 p = p.get_parentNode();
188 if (!p.get_parentNode()) return DOM::Node(0);
190 DOM::Node nextSibling = p.get_nextSibling();
193 return leftmostChild(nextSibling);
196 extern "C" GdomeElement*
197 find_common_ancestor(GdomeElement* first, GdomeElement* last)
199 if (GdomeNode* n = findCommonAncestor(DOM::Element(first), DOM::Element(last)).gdome_object())
201 GdomeElement* res = gdome_cast_el(n);
202 g_assert(res != NULL);
210 find_common_siblings(GdomeElement* first, GdomeElement* last,
211 GdomeElement** firstS, GdomeElement** lastS)
216 findCommonSiblings(DOM::Element(first), DOM::Element(last), fs, ls);
218 if (firstS != NULL) *firstS = gdome_cast_el(fs.gdome_object());
219 if (lastS != NULL) *lastS = gdome_cast_el(ls.gdome_object());
222 extern "C" GdomeElement*
223 find_element_with_ref(GdomeElement* elem)
225 if (GdomeNode* n = findElementWithRef(DOM::Element(elem)).gdome_object())
227 GdomeElement* res = gdome_cast_el(n);
228 g_assert(res != NULL);
235 extern "C" GdomeElement*
236 find_common_ancestor_with_ref(GdomeElement* first, GdomeElement* last)
238 if (GdomeNode* n = findElementWithRef(findCommonAncestor(DOM::Element(first), DOM::Element(last))).gdome_object())
240 GdomeElement* res = gdome_cast_el(n);
241 g_assert(res != NULL);
249 delete_element(GdomeElement* elem)
251 DOM::Element p(elem);
253 DOM::Element parent = p.get_parentNode();
256 parent.removeChild(p);