]> matita.cs.unibo.it Git - helm.git/commitdiff
Added some controls concerning the graphical deleting.
authorPaolo Marinelli <paolo.marinelli@unibo.it>
Mon, 27 Jan 2003 16:34:49 +0000 (16:34 +0000)
committerPaolo Marinelli <paolo.marinelli@unibo.it>
Mon, 27 Jan 2003 16:34:49 +0000 (16:34 +0000)
Now, it's possible to delete a macro which accepts (delimited or not delimited)
arguments.
To meet this goal, the following source files have been modified:
   src/TNode.*
     added a new public method: void TNode::replace(const TNode& first, TNode& last)
       This method is used to replace a node with the nodes between
       first (included) and last (not included).
   src/TPushParser.*
     Some code lines have been added to handle the graphical deleting of
     macro which accepts arguments.
     Added new private method: void TPushParser::rgreplace_futher(void)
       This method is used in TPushParser::gdelete_prev() and
       TPushParser::do_gdelete() methods. This method replaces a
       group with id having the cursor as unic child, with the
       cursor. Then, it repeats the control.
   dictionary.xml
     a new entry is avaible to test the deleting of a macro which is
     "leftOpen".

helm/DEVEL/mathml_editor/dictionary.xml
helm/DEVEL/mathml_editor/src/TNode.cc
helm/DEVEL/mathml_editor/src/TNode.hh
helm/DEVEL/mathml_editor/src/TPushParser.cc
helm/DEVEL/mathml_editor/src/TPushParser.hh
helm/DEVEL/mathml_editor/test/editor.cc
helm/DEVEL/mathml_editor/test/guiGTK.c
helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl

index 664100c6236cbde67ea56378421e0196ff7bc88b..023bcdbe16b0cc99717f1515a72b993ae5a65ed7 100644 (file)
   <entry name="underbrace"   pattern="#1" limits="1"/>
   <entry name="cases"        pattern="#1" table="1"/>
 
+  <!-- MACRO for testing  -->
+  <entry name="paolo"        pattern="{"/>
+
 </dictionary>
index 4235f3728f4d449e8cb8c4e9a3bce74b64f8cf1d..4523ced5d73bd7572d6f18e6fecc05a20fb4b0c3 100644 (file)
@@ -129,6 +129,22 @@ TNode::replace(const TNode& newNode) const
   parent.replaceChild(newNode.node, node);
 }
 
+void
+TNode::replace(const TNode& first, const TNode& last) const
+{
+  assert(node);
+  assert(first);
+
+  TNode p = first;
+  while (p != last)
+    {
+      TNode next = p.next();
+      insert(p);
+      p = next;
+    }
+  remove();
+}
+
 void
 TNode::insert(const TNode& newNode) const
 {
index dde315d36a05d787740afc8120353d11992e2151..b2c68fa6973a76e7a6d48f8c2eb57b6f9a067425 100644 (file)
@@ -52,6 +52,7 @@ public:
   //void  advance(const TNode&) const;
   void  remove(void) const;
   void  replace(const TNode&) const;
+  void  replace(const TNode&, const TNode&) const;
   void  insert(const TNode&) const;
   void  append(const TNode&) const;
   void  append(const TNode&, const TNode&) const;
index cfcce849f887bd850c8669e09005cda3d860b518..a063668e0ae31dd03e44f2719733276aa52cda7a 100644 (file)
@@ -80,6 +80,7 @@ TPushParser::do_end()
       // closing brace for a right-open macro (like \over)
       cursor.remove();
       advance(parent.parent());
+      frames.pop();
     }
   else
     {
@@ -410,6 +411,11 @@ TPushParser::do_control(const std::string& name)
          {
            TNode m = doc.createC(name, nextId++);
            cursor.replace(m);
+           
+           cout << "ecco tutti i token del pattern della entry inserita" << endl;
+           for (unsigned i = 0; i < entry.pattern.size(); i++)
+             cout << entry.pattern[i].value << endl;
+           
            if (entry.leftOpen && entry.rightOpen)
              {
                assert(entry.pattern.empty());
@@ -446,6 +452,7 @@ TPushParser::do_control(const std::string& name)
                if (parent.isG())
                  {
                    frames.push(Frame(entry));
+                   cout << "do_control: valore di pos del frame inserito " << frames.top().pos << endl;
                    if (entry.paramDelimited(0))
                      {
                        TNode g = doc.createG();
@@ -481,16 +488,31 @@ TPushParser::do_control(const std::string& name)
 void
 TPushParser::gdelete_prev()
 {
-  // if in this function, the prev of cursor does exist, also the parent and we want a graphical deleting
+  // if in this function, the prev of cursor does exist, also the parent and we want a graphical deleting.
+
+  assert(cursor.prev());
+  assert(cursor.parent());
+
   TNode prev = cursor.prev();
   if (prev.is("i") || prev.is("o") || prev.is("n"))
     {
       // the control below is designed to handle the case in which val have more than one unicode character
       DOM::UCS4String ucs4val(prev.element().getAttribute("val"));
-      if (ucs4val.length() <= 1)
+      if ((ucs4val.length() <= 1) || prev.element().hasAttribute("name"))
         {
          cursor.remove();
          prev.replace(cursor);
+
+         if (cursor.parent().isC())
+           {
+             // in this case we have removed an element of a MACRO. 
+             // we can assert that this element was a non delimited argument
+             assert(!frames.empty());
+             Frame& frame = frames.top();
+             assert(frame.pos > 0);
+
+             frame.pos--;
+           }
        }
       else
         {
@@ -502,7 +524,7 @@ TPushParser::gdelete_prev()
     {
       cursor.remove();
       prev.append(cursor);
-      do_gdelete();
+      gdelete_prev();
     } // end of if (prev.is("sp") || prev.is("sb"))
   else if (prev.isG())
     {
@@ -512,9 +534,73 @@ TPushParser::gdelete_prev()
     }
   else if (prev.isC())
     {
-//      cursor.remove();
-//      prev.append(cursor);
-//      do_gdelete();
+      const TDictionary::Entry& entry = dictionary.find(prev["name"]);
+
+      // i start to remove a MACRO. The frame associated to this MACRO was 
+      // popped from the stack (i think). So, i re-push the frame in the stack,
+      // but the pos member should be set correctly
+      cout << "gdelete_prev: i have to start to delete a MACRO" << endl;
+      
+      // if the control element is leftOpen and rightOpen, the cursor should be placed after 
+      // the last child of the control element's last child
+      if (entry.rightOpen)
+        {
+         cout << "gdelte_prev(): i have to delete a control rightOpen, so i push an element in the stack" << endl;
+         Frame frame(entry);
+         frames.push(frame);
+         
+         cursor.remove();
+         prev.last().append(cursor);
+         do_gdelete();
+       }
+      else if (entry.leftOpen)
+        {
+         cout << "gdelete_prev: i have to delete a control element with leftOpen" << endl;
+         assert(prev.first());
+         assert(prev.first().isG());
+         assert(prev.first() == prev.last());
+         TNode g = prev.first();
+         g.remove();
+         prev.replace(g.first(), TNode());
+       }
+      else if (!entry.pattern.empty())
+        { 
+         // we have to start removing a MACRO which accepts arguments.
+         // a MACRO without child does not exist
+         
+         cout << "gdelete_prev: i have to remove a MACRO with argument" << endl;
+
+         assert(prev.size() >= 1);
+
+         if (prev.last().isG() && !prev.last().hasId())
+           {
+             // this means that the last child of the MACRO is a phantom group,
+             // which in turn means that it is a delimited argument
+             // so we have to ideally remove this delimiter
+             cursor.remove();
+             prev.last().append(cursor);
+             // i have to push a frame with a correct value of pos
+             Frame frame(entry);
+             frame.pos = entry.pattern.size() - 2;
+             frames.push(frame);
+           }
+         else
+           {
+             // in this case, the last child of the MACRO is 
+             // an argument which is NOT delimited, so i try to 
+             // remove it
+             cout << "gdelete_prev: i try to remove the last argumet of the MACRO" << endl;
+             cursor.remove();
+             prev.append(cursor); // now prev is the cursor's parent
+
+             Frame frame(entry);
+             frame.pos = entry.pattern.size();
+             frames.push(frame);
+             
+             gdelete_prev();
+
+           }
+       }
     }
   else 
     {
@@ -523,11 +609,45 @@ TPushParser::gdelete_prev()
   
 } // end of method
 
+void
+TPushParser::rgreplace_futher(void)
+{
+  // this function MUST only be invoked, when the cursor
+  // is the only child of a group with id. This function 
+  // replace the group with the cursor. But if the new parent
+  // is a group with id and the cursor is the only child of the 
+  // group, the new parent is replaced...and so on.
+  // r stands for recursive, g stands for graphical
+  assert(cursor.parent());
+  assert(cursor.parent().isG() && cursor.parent().hasId());
+
+  TNode parent = cursor.parent();
+
+  while (parent.isG() && parent.hasId() && (parent.first() == cursor))
+    {
+      parent.replace(cursor);
+      parent = cursor.parent();
+    }
+
+  if (parent.isC())
+    {
+      // in this case we have removed a MACRO's child. 
+      // I can assert that this MACRO accepts arguments.
+      assert(!frames.empty());
+      Frame& frame = frames.top();
+      assert(frame.pos > 0);
+      frame.pos--;
+    }
+}
+
 void
 TPushParser::do_gdelete()
 {
   // this function operates a graphical deleting
   
+  //if (!frames.empty())
+  //  cout << "do_gdelete: c'e' un frame aperto e il suo pos vale: " << frames.top().pos << endl;
+  
   TNode parent = cursor.parent();
 
   // if no parent, do nothing
@@ -541,57 +661,238 @@ TPushParser::do_gdelete()
            {
              // i try to delete the preceding element
              gdelete_prev();
-             
-             // if gdelete_prev has removed all parent's child, and the group has Id, it should be removed.
-             // this control should be re-done on the new parent and so on.
-             while ((parent.first() == cursor) && parent.isG() && parent.hasId())
-               {
-                 cursor.remove();
-                 parent.replace(cursor);
-                 parent = cursor.parent();
-               }
+
+             if ((parent.first() == cursor) && parent.isG() && parent.hasId())
+               rgreplace_futher();
+
            }
          else // no previous node is present
            {
-             if (!parent.parent().is("math"))
+             // if here, we are in a gruop whose only child is the cursor.
+             
+             if (!parent.hasId())
                {
-                 cursor.remove();
-                 parent.replace(cursor);
-                 
-                 // if the new parent is a group with Id, it should be removed
-                 if (cursor.parent().isG() && cursor.parent().hasId()) do_gdelete();
+                 // the parent is a phantom group
+                 assert(parent.parent());
+                 if (!parent.parent().is("math"))
+                   {
+                     TNode gfuther = parent.parent();
+
+                     // if the grand futher is a group with Id, it should be removed, 
+                     // but i don't know if it will never occur...
+                     if (gfuther.isG() && gfuther.hasId())
+                       {
+                         cursor.remove();
+                         parent.replace(cursor);
+
+                         // re-start the process
+                         do_gdelete();
+                       }
+                     else if (gfuther.isC())
+                       {
+                         // the grand futher is a control element: since the parent is a phantom group, 
+                         // the TML tree should be in a inconsistent state (once removed the parent).
+
+                         // being here means that there is a frame in the stack
+                         assert(!frames.empty());
+                         cout << "do_gdelete: i have to remove a phantom group whuch is a child of a MACRO" << endl;
+                         Frame& frame = frames.top();
+                         if (frame.entry.leftOpen && frame.entry.rightOpen)
+                           {
+                             // in this case, the cursor is in the second and last child 
+                             // of the MACRO. We can assert that the grand futher has two 
+                             // children. which are both phantom group
+                             cout << "do_gdelete: the MACRO is leftOpen and rigthOpen" << endl;
+                             assert(gfuther.size() == 2);
+                             assert((gfuther.last() == parent) && (gfuther.first().isG() && !gfuther.first().hasId()));
+                             assert(frame.pos == 0);
+                           
+                             TNode ggfuther = gfuther.parent();
+                             assert(ggfuther);
+                             cursor.remove();
+                             parent.remove();
+                             // i have to replace the gfuther with the elements of its first child
+                             gfuther.replace(gfuther.first().first(), TNode());
+                             cout << "do_gdelete: i have removed the control element, and replaced it with its first child" << endl;
+                             ggfuther.append(cursor);
+                             cout << "do_gdelete: cursor appended to the grand grand futher" << endl;
+
+                             // now we have the situation preceding the insertion of the MACRO leftOpen and rightOpen
+                             // this MACRO no longer exists.
+                             frames.pop();
+                           }
+                         else if (frame.entry.rightOpen)
+                           {
+                             // the user has inserted a MACRO rightOpen. Since the cursor is the 
+                             // only child of the MACRO, the user want to remove it. 
+                             // We can assert that cursor's parent is the only child of the MACRO
+                             cout << "do_gdelete: the MACRO is rightOpen only" << endl;
+                             assert(gfuther.size() == 1);
+                             assert(frame.pos == 0); // i think this assert has no sense
+                           
+                             cursor.remove();
+                             parent.remove();
+                             gfuther.replace(cursor);
+
+                             // now we have the situation preceding the MACRO rightOpen, so i have to pop the frame
+                             frames.pop();
+                           }
+                         else if (frame.entry.leftOpen)
+                           {
+                             // it' s an unpredicted situation
+                             cout << "it's a bad situation, maybe handlable, but unpredicted" << endl;
+                           }
+                         else if (!frame.entry.pattern.empty())
+                           {
+                             // the MACRO (the cursor's grand futher) accepts arguments.
+                             // we have to control if the cursor's uncle does exist.
+
+                             if (parent.prev())
+                               {
+                                 // in this case, we can assert that frame in the stack has 
+                                 // pos greater than 0
+                                 assert(frame.pos > 0);
+                               
+                                 // cursor's uncle does exist. we have to control 
+                                 // its nature (is it a phantom group?)
+                                 TNode uncle = parent.prev();
+                                 if (uncle.isG() && !uncle.hasId())
+                                   {
+                                     // the cursor's parent is a phantom group, so it was a 
+                                     // delimited argument of the MACRO and the corrisponding 
+                                     // delimeter is inserted. So, the action of deleting means
+                                     // removing this delimeter
+                                     cursor.remove();
+                                     parent.remove();
+                                     uncle.append(cursor);
+                                     frame.pos -= 2;
+                                   }
+                                 else
+                                   {
+                                     // the uncle was a NOT delimited argument. So i try to 
+                                     // remove it
+                                     cursor.remove();
+                                     parent.replace(cursor);
+                                 
+                                     parent = cursor.parent(); // i update the parent (it should be the MACRO)
+                                     assert(parent.isC());
+                                 
+                                     gdelete_prev();
+
+                                   }
+                               }
+                             else
+                               {
+                                 // cursor's parent is the only child of the MACRO, which accepts arguments
+                                 // i can assert that frame.pos == 0.
+                                 // In this case i can replace the MACRO with the cursor
+                                 assert(frame.pos == 0);
+
+                                 cursor.remove();
+                                 parent.remove();
+                                 gfuther.replace(cursor);
+
+                                 frames.pop();
+                               }
+                           
+                           }
+                       }
+                   }
+                 else // the grand futher is math
+                   {
+                     // nothing to do...i think
+                     assert(frames.empty());
+                   }
                }
              else
-               {
-                 // nothing to do...i think
+               { 
+                 // the parent is a group with id and has no elements other than cursor
+                 // so we replace it with the cursor.
+                 rgreplace_futher();
+
+                 // i have to re-start the process, because it' a graphical delete
+                 do_gdelete();
                }
            }
        }
       else if (parent.isC())
         {
-         // i think i have to implement different behaviors based on the attribute name and/or left-open
-       }
-      else if (parent.is("sp") || parent.is("sb"))
-        {
-         // being here means that a prev MUST exist
-         
+         // being here means that there is an open frame for the control element
+         // and this element is closed at either side (no leftOpen no rightOpen)
+         // and the MACRO was waiting for a non delimited argument, so 
+         // we can assert that frame.entry.pattern.size() >= 1
+         assert(!frames.empty());
+         Frame& frame = frames.top();
+
+         assert(frame.entry.pattern.size() >= 1);
+
+         cout << "do_gdelete: frames.top().pos = " << frames.top().pos << endl;
+
          TNode prev = cursor.prev();
 
-         if (!prev) cout << "qualcosa non va" << endl;
+         if (!prev)
+           {
+             // in this case we can replace the MACRO with the cursor 
+             // and pop the stack and we can assert that frame.pos == 0
+             assert(frame.pos == 0);
+             cursor.remove(); // it should not be necessary, but i'm not shure
+             parent.replace(cursor);
+             frames.pop();
+           }
          else
            {
-             if (parent.first().next() == cursor) // there's only an element preceding the cursor
+             // in this case the cursor has a preceding element 
+             // and there are differnt things based on the nature 
+             // of the prev: if it's a phantom group do something,
+             // else do something else
+             if (prev.isG() && !prev.hasId())
                {
+                 // in this case we have to append the cursor 
+                 // to the prev and decrement frame.pos of two units
+                 // because the prev is a delimited argument and the 
+                 // delimiter is inserted. So we ideally remove this delimiter
                  cursor.remove();
-                 parent.replace(prev);
-                 prev.parent().append(cursor);
+                 prev.append(cursor);
+                 frame.pos -=2;
                }
-             else // there are two elements preceding the cursor
+             else
                {
+                 // the prev is an non delimited argument, so we try to 
+                 // remove it.
                  gdelete_prev();
                }
            }
        }
+      else if (parent.is("sp") || parent.is("sb"))
+        {
+         // being here means that a prev MUST exist 
+         // and that there is only an element preceding the cursor.
+         // A sp's (or sb's) MUST NOT be a MACRO
+
+         assert(parent.size() == 2);
+         assert(parent.parent() && !parent.parent().isC());
+         
+         TNode prev = cursor.prev();
+         cursor.remove();
+         if (prev.isG() && !prev.hasId() && (prev.size() == 0))
+           {
+             prev.remove();
+             parent.replace(cursor);
+
+             // now, cursor should be the only parent's child
+             assert(cursor.parent().size() == 1);
+
+             if (cursor.parent().isG() && cursor.parent().hasId()) rgreplace_futher();
+           }
+         else
+           {
+             assert(prev.hasId());
+             parent.replace(prev);
+             prev.parent().append(cursor);
+             // now prev should have a preceding element
+             assert(cursor.parent().size() > 1);
+           } 
+       }
       else
         {
          // not handled: no control for tables, ...
@@ -599,7 +900,9 @@ TPushParser::do_gdelete()
     }
   else
     {
-      // do nothing ??
+      // the cursro has no parent!!!
+      // do nothing?
+      // emit an error? and if we want to emit an error, in which way?
     }
 
 } // end of method
@@ -632,9 +935,19 @@ void
 TPushParser::push(const TToken& token)
 {
   cerr << "TPushParser::push " << token.value << " (cat: " << token.category << ")" << endl;
+
+  if (token.category == TToken::GDELETE)
+    {
+      cout << "push: i have to process a token with category member = GDELETE" << endl;
+      process(token);
+    }
+  else
+    {
+
   TNode parent = cursor.parent();
   // If the cursor has no parent then it is detached from the editing
   // tree, which means this token will be ignored
+
   if (parent)
     // If the parent is a phantom group and the grand-parent is a
     // control sequence, there are two cases:
@@ -704,6 +1017,8 @@ TPushParser::push(const TToken& token)
        // or a fixed token
        Frame& frame = frames.top();
        assert(frame.pos < frame.entry.pattern.size());
+
+       cout << "push: il valore di pos del frame inserito prima e': " << frame.pos <<  endl;
        if (frame.entry.pattern[frame.pos].category == TToken::PARAMETER)
          {
            // As by the TeX parsing rules of undelimited parameters,
@@ -749,7 +1064,12 @@ TPushParser::push(const TToken& token)
       cout << "ignored token" << endl;
     }
 
+  } // this end corresponds to the else of the if (token.category == GDELETE)
+
   if (listener) listener->callback(doc);
+
+  if (frames.empty()) cout << "stack vuoto" << endl;
+  else cout << "stack non vuoto" << endl;
 }
 
 void
index c3cee66c89c900309213664483ee2611325d8224..951fb874ab79a0b85e805045cbf0b48410198548 100644 (file)
@@ -28,8 +28,6 @@ private:
   std::string PRIME(void) const;
   bool isPrimes(const TNode&) const;
   
-  void gdelete_prev(void);
-
   void do_begin(void);
   void do_end(void);
   void do_shift(void);
@@ -45,6 +43,8 @@ private:
   void do_active(const std::string&);
   void do_comment(void);
   void do_control(const std::string&);
+  void gdelete_prev(void);
+  void rgreplace_futher(void);
   void do_gdelete(void);
 
   void do_cr(void);
index 265d35e53477249bda2226930c436ce8e8a62666..8ee408a3db41777c1a0c9aa080c5175bf35d7f7e 100644 (file)
@@ -87,7 +87,7 @@ public:
        DOM::Document res = style.apply(doc.document(), dirtyId);
        assert(res);
        style.save(doc.document(), stdout);
-       style.save(res, stdout);
+       //style.save(res, stdout);
        if (result)
          {
            cout << "REPLACING A FRAGMENT OF THE DOCUMENT" << endl;
@@ -98,10 +98,13 @@ public:
            if (result.get_documentElement().getAttribute("xref") == root.getAttribute("xref"))
              {
                cout << "REPLACING ROOT" << endl;
+               result.replaceChild(result.importNode(root, true), result.get_documentElement());
+#if 0
                // the following remove should not be necessary
                // according to the spec replaceChild should work just fine
                result.removeChild(result.get_documentElement());
                result.appendChild(result.importNode(root, true));
+#endif
              }
            else
              try
@@ -130,6 +133,7 @@ public:
             if (GUI_load_document(gdome_cast_doc(static_cast<GdomeNode*>(result))) < 0)
              cerr << "c'e' stato un errore" << endl;
          }
+       style.save(result, stdout);
 
        doc.clearDirty();
       }
index d270f744822881681613e187543c496e4133d110..88b85f8b585145fc5ded90c713aa3cdd37690996 100644 (file)
@@ -1,4 +1,28 @@
-
+/*
+ * Copyright (C) 2000, Luca Padovani <luca.padovani@cs.unibo.it>.
+ * 
+ * This file is part of GtkMathView, a Gtk widget for MathML.
+ * 
+ * GtkMathView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * GtkMathView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GtkMathView; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * For details, see the GtkMathView World-Wide-Web page,
+ * http://cs.unibo.it/~lpadovan/mml-widget, or send a mail to
+ * <luca.padovani@cs.unibo.it>
+ */
+
+#include <config.h>
 #include <stdio.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
@@ -14,59 +38,52 @@ static GtkWidget* scrolled_area;
 static GtkWidget* status_bar;
 static GtkMenuItem* anti_aliasing_item;
 static GtkMenuItem* transparency_item;
-static GtkMenuItem* font_size_item;
 static GdkCursor* normal_cursor;
 static GdkCursor* link_cursor;  
 
 static gchar* doc_name = NULL;
 static GdomeElement* root_selected = NULL;
-static GdomeElement* first_selected = NULL;
-static GdomeElement* last_selected = NULL;
-static GdomeElement* cursor = NULL;
-static gboolean selecting = FALSE;
-static gboolean button_pressed = FALSE;
 
 static guint statusbar_context;
 
-static guint         edit_timeout_id;
-static GdomeElement* cursor_ptr = NULL;
-static gboolean      cursor_active = FALSE;
-
 static void create_widget_set(gpointer);
 static GtkWidget* get_main_menu(void);
-static void options_selection_mode(GtkWidget*, guint);
-static void options_font_size(GtkWidget*, guint);
+static void file_open(GtkWidget*, gpointer);
+static void file_re_open(GtkWidget*, gpointer);
+static void file_close(GtkWidget*, gpointer);
+static void options_font_manager(GtkWidget*, FontManagerId);
+static void options_set_font_size(GtkWidget*, gpointer);
+static void options_change_font_size(GtkWidget*, gboolean);
 static void options_verbosity(GtkWidget*, guint);
 static void options_anti_aliasing(GtkWidget*, gpointer);
 static void options_transparency(GtkWidget*, gpointer);
-static void edit_delete_selection(GtkWidget*, gpointer);
-static void edit_select_parent(GtkWidget*, gpointer);
+static void selection_delete(GtkWidget*, gpointer);
+static void selection_parent(GtkWidget*, gpointer);
+static void selection_reset(GtkWidget*, gpointer);
 static void help_about(GtkWidget*, gpointer);
 
-extern int edit_timeout(gpointer);
-extern void push_char(gpointer, gchar);
-
 static GtkItemFactoryEntry menu_items[] = {
   { "/_File",                          NULL,         NULL,          0, "<Branch>" },
+  { "/File/_Open...",                  "<control>O", file_open,     0, NULL },
+  { "/File/_Reopen",                   NULL,         file_re_open,  0, NULL },
+  { "/File/_Close",                    "<control>W", file_close,    0, NULL },
+  { "/File/sep1",                      NULL,         NULL,          0, "<Separator>" },
   { "/File/_Quit",                     "<control>Q", gtk_main_quit, 0, NULL },
 
-  { "/_Edit",                          NULL, NULL,                  0,  "<Branch>" },
-  { "/Edit/Delete Selection",          NULL, edit_delete_selection, 0,  NULL },
-  { "/Edit/Select Parent",             NULL, edit_select_parent,    0,  NULL },
+  { "/_Selection",                     NULL, NULL,                  0,  "<Branch>" },
+  { "/Selection/Reset",                NULL, selection_reset,       0, NULL },
+  { "/Selection/Delete",               NULL, selection_delete,      0, NULL },
+  { "/Selection/Select Parent",        NULL, selection_parent,      0, NULL },
 
   { "/_Options",                       NULL, NULL,                  0,  "<Branch>" },
-  { "/Options/_Selection Mode",        NULL, NULL,                  0,  "<Branch>" },
-  { "/Options/Selection Mode/_Structure", NULL, options_selection_mode, 0, "<RadioItem>" },
-  { "/Options/Selection Mode/_Linear",  NULL, options_selection_mode, 1, "/Options/Selection Mode/Structure" },
   { "/Options/Default _Font Size",     NULL, NULL,                  0,  "<Branch>" },
-  { "/Options/Default Font Size/8pt",  NULL, options_font_size,     8,  "<RadioItem>" },
-  { "/Options/Default Font Size/10pt", NULL, options_font_size,     10, "/Options/Default Font Size/8pt" },
-  { "/Options/Default Font Size/12pt", NULL, options_font_size,     12, "/Options/Default Font Size/8pt" },
-  { "/Options/Default Font Size/14pt", NULL, options_font_size,     14, "/Options/Default Font Size/8pt" },
-  { "/Options/Default Font Size/18pt", NULL, options_font_size,     18, "/Options/Default Font Size/8pt" },
-  { "/Options/Default Font Size/24pt", NULL, options_font_size,     24, "/Options/Default Font Size/8pt" },
-  { "/Options/Default Font Size/48pt", NULL, options_font_size,     48, "/Options/Default Font Size/8pt" },
-  { "/Options/Default Font Size/72pt", NULL, options_font_size,     72, "/Options/Default Font Size/8pt" },
+  { "/Options/Default Font Size/Set...", NULL, options_set_font_size, 0,  NULL },
+  { "/Options/Default Font Size/sep1", NULL, NULL,                  0,  "<Separator>" },
+  { "/Options/Default Font Size/Larger", NULL, options_change_font_size, TRUE, NULL },
+  { "/Options/Default Font Size/Smaller", NULL, options_change_font_size, FALSE, NULL },
+  { "/Options/Font Manager",           NULL, NULL,                  0,  "<Branch>" },
+  { "/Options/Font Manager/_GTK",      NULL, options_font_manager,  FONT_MANAGER_GTK, "<RadioItem>" },
+  { "/Options/Font Manager/_Type 1",   NULL, options_font_manager,  FONT_MANAGER_T1, "/Options/Font Manager/GTK" },
   { "/Options/Verbosity",              NULL, NULL,                  0,  "<Branch>" },
   { "/Options/Verbosity/_Errors",      NULL, options_verbosity,     0,  "<RadioItem>" },
   { "/Options/Verbosity/_Warnings",    NULL, options_verbosity,     1,  "/Options/Verbosity/Errors" },
@@ -116,31 +133,6 @@ load_error_msg(const char* name)
   g_free(msg);
 }
 
-static void
-cursor_off()
-{
-  if (cursor_active)
-    {
-      cursor_active = FALSE;
-      if (cursor_ptr != NULL &&
-         gtk_math_view_is_selected(main_area, cursor_ptr))
-       gtk_math_view_reset_selection(main_area, cursor_ptr);
-    }
-}
-
-static void
-cursor_on()
-{
-  if (!cursor_active)
-    {
-      cursor_active = FALSE;
-      if (cursor_ptr != NULL &&
-         !gtk_math_view_is_selected(main_area, cursor_ptr))
-       gtk_math_view_set_selection(main_area, cursor_ptr);
-      cursor_active = TRUE;
-    }
-}
-
 void
 GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpointer context)
 {
@@ -163,7 +155,6 @@ GUI_init(int* argc, char*** argv, char* title, guint width, guint height, gpoint
 void
 GUI_uninit()
 {
-  gtk_timeout_remove(edit_timeout_id);
 }
 
 int
@@ -182,22 +173,6 @@ GUI_load_document(GdomeDocument* doc)
   return 0;
 }
 
-int
-GUI_load_uri(const char* uri)
-{
-  GtkMathView* math_view;
-
-  g_return_val_if_fail(uri != NULL, -1);
-  g_return_val_if_fail(main_area != NULL, -1);
-  g_return_val_if_fail(GTK_IS_MATH_VIEW(main_area), -1);
-
-  math_view = GTK_MATH_VIEW(main_area);
-
-  if (!gtk_math_view_load_uri(math_view, uri)) return -1;
-
-  return 0;
-}
-
 void
 GUI_freeze()
 {
@@ -235,22 +210,87 @@ GUI_run()
   gtk_main();
 }
 
+void
+GUI_set_font_manager(FontManagerId id)
+{
+  gboolean t1;
+  GtkMathView* math_view;
+
+  g_return_if_fail(id != FONT_MANAGER_UNKNOWN);
+  g_return_if_fail(main_area != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
+
+  t1 = id == FONT_MANAGER_T1;
+
+  math_view = GTK_MATH_VIEW(main_area);
+
+  gtk_math_view_freeze(math_view);
+
+  if (id != gtk_math_view_get_font_manager_type(math_view))
+    gtk_math_view_set_font_manager_type(math_view, id);
+
+  gtk_widget_set_sensitive(anti_aliasing_item, t1);
+  gtk_widget_set_sensitive(transparency_item, t1);
+
+  if (t1)
+    {
+      gtk_math_view_set_anti_aliasing(math_view, GTK_CHECK_MENU_ITEM(anti_aliasing_item)->active);
+      gtk_math_view_set_transparency(math_view, GTK_CHECK_MENU_ITEM(transparency_item)->active);
+    }
+
+  gtk_math_view_thaw(math_view);
+}
+
 static void
-options_selection_mode(GtkWidget* widget, guint mode)
+store_filename(GtkFileSelection* selector, GtkWidget* user_data)
 {
+  gchar* selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION(user_data));
+  if (selected_filename != NULL)
+    GUI_load_document(selected_filename);
 }
 
 static void
-options_font_size(GtkWidget* widget, guint size)
+file_close(GtkWidget* widget, gpointer data)
 {
-  GtkMathView* math_view;
+  GUI_unload_document();
+}
 
-  g_return_if_fail(main_area != NULL);
-  g_return_if_fail(GTK_IS_MATH_VIEW(main_area));
+static void
+file_re_open(GtkWidget* widget, gpointer data)
+{
+  if (doc_name != NULL) {
+    GUI_load_document(doc_name);
+  }
+}
 
-  math_view = GTK_MATH_VIEW(main_area);
+static void
+file_open(GtkWidget* widget, gpointer data)
+{
+  GtkWidget* fs = gtk_file_selection_new("Open File");
+
+  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
+                     "clicked", GTK_SIGNAL_FUNC (store_filename), (gpointer) fs);
+                             
+  /* Ensure that the dialog box is destroyed when the user clicks a button. */
+     
+  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
+                            "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                            (gpointer) fs);
+
+  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(fs)->cancel_button),
+                            "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                            (gpointer) fs);
+     
+  /* Display that dialog */
+     
+  gtk_widget_show (fs);
+}
 
-  gtk_math_view_set_font_size(math_view, size);
+static void
+options_font_manager(GtkWidget* widget, FontManagerId id)
+{
+  g_return_if_fail(id != FONT_MANAGER_UNKNOWN);
+  GUI_set_font_manager(id);
 }
 
 static void
@@ -274,7 +314,7 @@ options_verbosity(GtkWidget* widget, guint level)
 }
 
 static void
-edit_delete_selection(GtkWidget* widget, gpointer data)
+selection_delete(GtkWidget* widget, gpointer data)
 {
   if (root_selected != NULL)
     {
@@ -290,12 +330,12 @@ edit_delete_selection(GtkWidget* widget, gpointer data)
 }
 
 static void
-edit_select_parent(GtkWidget* widget, gpointer data)
+selection_parent(GtkWidget* widget, gpointer data)
 {
   if (root_selected != NULL)
     {
       GdomeException exc = 0;
-      GdomeElement* parent = gdome_cast_el(gdome_n_parentNode(root_selected, &exc));
+      GdomeElement* parent = gdome_n_parentNode(root_selected, &exc);
       g_assert(exc == 0);
       gdome_el_unref(root_selected, &exc);
       g_assert(exc == 0);
@@ -304,6 +344,19 @@ edit_select_parent(GtkWidget* widget, gpointer data)
     }
 }
 
+static void
+selection_reset(GtkWidget* widget, gpointer data)
+{
+  if (root_selected != NULL)
+    {
+      GdomeException exc = 0;
+      gtk_math_view_reset_selection(GTK_MATH_VIEW(main_area), root_selected);
+      gdome_el_unref(root_selected, &exc);
+      g_assert(exc == 0);
+      root_selected = NULL;
+    }
+}
+
 static void
 help_about(GtkWidget* widget, gpointer data)
 {
@@ -312,7 +365,7 @@ help_about(GtkWidget* widget, gpointer data)
   GtkWidget* ok;
 
   dialog = gtk_dialog_new();
-  label = gtk_label_new("\n    MathML Viewer    \n    Copyright (C) 2000-2002 Luca Padovani    \n");
+  label = gtk_label_new("\n    MathML Viewer    \n    Copyright (C) 2000-2003 Luca Padovani    \n");
   ok = gtk_button_new_with_label("Close");
 
   gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
@@ -325,208 +378,152 @@ help_about(GtkWidget* widget, gpointer data)
   gtk_widget_show_all (dialog);
 }
 
-#if 0
-#if defined(HAVE_GMETADOM)
 static void
-element_changed(GtkMathView* math_view, GdomeElement* node)
+change_default_font_size(GtkSpinButton* widget, GtkSpinButton* spin)
 {
-  GdomeException exc;
-  GdomeDOMString* name;
-  GdomeDOMString* ns_uri;
-
-  g_return_if_fail(math_view != NULL);
-  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
-
-  name = gdome_str_mkref("href");
-  ns_uri = gdome_str_mkref(XLINK_NS_URI);
-
-  while (node != NULL && !gdome_el_hasAttributeNS(node, ns_uri, name, &exc))
-    node = gdome_cast_el(gdome_el_parentNode(node, &exc));
-
-  if (node != NULL && gdome_el_hasAttributeNS(node, ns_uri, name, &exc))
-    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, link_cursor);
-  else
-    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, normal_cursor);
-
-  gdome_str_unref(name);
-  gdome_str_unref(ns_uri);
+  g_return_if_fail(spin != NULL);
+  gtk_math_view_set_font_size( GTK_MATH_VIEW(main_area), gtk_spin_button_get_value_as_int(spin));
 }
-#endif
 
 static void
-#if defined(HAVE_GMETADOM)
-action_changed(GtkMathView* math_view, GdomeElement* node)
-#endif
+options_change_font_size(GtkWidget* widget, gboolean larger)
 {
-  g_return_if_fail(math_view != NULL);
-  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+  gfloat size = gtk_math_view_get_font_size (GTK_MATH_VIEW(main_area));
+  if (larger) size = size / 0.71;
+  else size = size * 0.71;
+  if (size < 1) size = 1;
+  gtk_math_view_set_font_size (GTK_MATH_VIEW(main_area), (gint) size + 0.5);
 }
 
 static void
-#if defined(HAVE_GMETADOM)
-selection_changed(GtkMathView* math_view, GdomeElement* node)
-#endif
+options_set_font_size(GtkWidget* widget, gpointer data)
 {
-  g_return_if_fail(math_view != NULL);
-  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
-  gtk_math_view_set_selection(math_view, node);
+  GtkWidget* dialog;
+  GtkWidget* label;
+  GtkWidget* ok;
+  GtkWidget* cancel;
+  GtkWidget* spin;
+  GtkObject* adj;
+
+  dialog = gtk_dialog_new();
+  label = gtk_label_new("Default font size:");
+  ok = gtk_button_new_with_label("OK");
+  cancel = gtk_button_new_with_label("Cancel");
 
-  cursor_off();
-  cursor_ptr = node;
-  cursor_on();
+  adj = gtk_adjustment_new (gtk_math_view_get_font_size (GTK_MATH_VIEW(main_area)), 1, 200, 1, 1, 1);
+  spin = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 1, 0);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE);
+
+  gtk_signal_connect (GTK_OBJECT (ok), "clicked",
+                     GTK_SIGNAL_FUNC (change_default_font_size), (gpointer) spin);
+
+  gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+  gtk_signal_connect_object (GTK_OBJECT (ok), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+  gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
+
+  gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 5);
+
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), ok);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), cancel);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), spin);
+
+  gtk_widget_show_all (dialog);
 }
 
+#if 0
 #if defined(HAVE_GMETADOM)
 static void
-clicked(GtkMathView* math_view, gpointer user_data)
+element_changed(GtkMathView* math_view, GdomeElement* elem)
 {
-  GdomeException exc;
-  GdomeDOMString* name;
-  GdomeDOMString* ns_uri;
-  GdomeElement* p;
+  GdomeDOMString* link = NULL;
 
   g_return_if_fail(math_view != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
 
-  name = gdome_str_mkref("href");
-  ns_uri = gdome_str_mkref(XLINK_NS_URI);
-
-  p = gtk_math_view_get_element(math_view);
-  while (p != NULL && !gdome_el_hasAttributeNS(p, ns_uri, name, &exc))
-    p = gdome_cast_el(gdome_el_parentNode(p, &exc));
+/*   printf("pointer is on %p\n", elem); */
 
-  if (p != NULL) {
-    GdomeDOMString* href = gdome_el_getAttributeNS(p, ns_uri, name, &exc);
-    g_assert(href != NULL);
+  link = find_hyperlink(elem, XLINK_NS_URI, "href");
+  if (link != NULL)
+    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, link_cursor);
+  else
+    gdk_window_set_cursor(GTK_WIDGET(math_view)->window, normal_cursor);
 
-    GUI_load_document(href->str);
-    gdome_str_unref(href);
-  } else if (gtk_math_view_get_action(math_view) != NULL)
-    gtk_math_view_action_toggle(math_view);
+  if (link != NULL)
+    gdome_str_unref(link);
 }
 #endif
 #endif
 
-static gint
-button_press_event(GtkWidget* widget,
-                  GdkEventButton* event,
-                  GtkMathView* math_view)
+static void
+selection_changed(GtkMathView* math_view, GdomeElement* first, GdomeElement* last)
 {
-  g_return_val_if_fail(event != NULL, FALSE);
-  g_return_val_if_fail(math_view != NULL, FALSE);
-  
-  if (event->button == 1)
-    {
-      GdomeException exc;
+  g_return_if_fail(math_view != NULL);
+  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));
+  g_return_if_fail(first != NULL);
+
+/*   printf("selection changed %p %p\n", first, last); */
 
-      cursor_off();
+  if (last != NULL)
+    {
+      GdomeException exc = 0;
 
       if (root_selected != NULL)
        {
-         gtk_math_view_reset_selection(math_view, root_selected);
          gdome_el_unref(root_selected, &exc);
          g_assert(exc == 0);
-         root_selected = NULL;
-       }
-
-      if (first_selected != NULL)
-       {
-         gdome_el_unref(first_selected, &exc);
-         g_assert(exc == 0);
        }
 
-      if (last_selected != NULL)
-       {
-         gdome_el_unref(last_selected, &exc);
-         g_assert(exc == 0);
-         last_selected = NULL;
-       }
-
-      first_selected = gtk_math_view_get_element_at(math_view, event->x, event->y);
-      button_pressed = TRUE;
-      selecting = FALSE;
+      root_selected = find_common_ancestor(first, last);
+/*       printf("selecting root %p\n", first, last, root_selected); */
+      gtk_math_view_set_selection(math_view, root_selected);
+      g_assert(exc == 0);
     }
-
-  return FALSE;
 }
 
-static gint
-motion_notify_event(GtkWidget* widget,
-                   GdkEventMotion* event,
-                   GtkMathView* math_view)
+#if 0
+#if defined(HAVE_GMETADOM)
+static void
+clicked(GtkMathView* math_view, GdomeElement* elem)
 {
-  g_return_val_if_fail(event != NULL, FALSE);
-  g_return_val_if_fail(math_view != NULL, FALSE);
-
-  if (button_pressed && first_selected != NULL)
-    {
-      GdomeException exc;
-      GdomeElement* el = gtk_math_view_get_element_at(math_view, event->x, event->y);
-      GdomeElement* root;
-
-      selecting = TRUE;
+  GdomeException exc;
+  GdomeDOMString* name;
+  GdomeDOMString* ns_uri;
+  GdomeElement* p;
 
-      if (el != NULL && el != last_selected)
-       {
-         if (last_selected != NULL)
-           {
-             gdome_el_unref(last_selected, &exc);
-             g_assert(exc == 0);
-           }
+  g_return_if_fail(math_view != NULL);
 
-         last_selected = el;
-       }
+  /* printf("clicked on %p\n", elem); */
 
-      if (last_selected != NULL)
+  if (elem != NULL)
+    {
+      GdomeElement* action;
+      GdomeDOMString* href = find_hyperlink(elem, XLINK_NS_URI, "href");
+      if (href != NULL)
        {
-         root = find_common_ancestor(first_selected, last_selected);
-         g_assert(root != NULL);
-
-         if (root != root_selected)
-           {
-             gtk_math_view_freeze(math_view);
-             if (root_selected != NULL)
-               {
-                 gtk_math_view_reset_selection(math_view, root_selected);
-                 gdome_el_unref(root_selected, &exc);
-                 g_assert(exc == 0);
-               }
-             root_selected = root;
-             gtk_math_view_set_selection(math_view, root_selected);
-             gtk_math_view_thaw(math_view);
-           }
-         else
-           {
-             gdome_el_unref(root, &exc);
-             g_assert(exc == 0);
-           }
+/*       printf("hyperlink %s\n", href->str); */
+         gdome_str_unref(href);
        }
-    }
-
-  return FALSE;
-}
 
-static gint
-button_release_event(GtkWidget* widget,
-                    GdkEventButton* event,
-                    GtkMathView* math_view)
-{
-  g_return_val_if_fail(event != NULL, FALSE);
-  g_return_val_if_fail(math_view != NULL, FALSE);
-  
-  if (event->button == 1)
-    {
-      if (!selecting)
+      action = find_self_or_ancestor(elem, MATHML_NS_URI, "maction");
+/*       printf("action? %p\n", action); */
+      if (action != NULL)
        {
-         cursor_ptr = first_selected;
-         cursor_on();
+         gtk_math_view_freeze(math_view);
+         action_toggle(action);
+         gtk_math_view_thaw(math_view);
+         gdome_el_unref(action, &exc);
+         g_assert(exc == 0);
        }
-
-      button_pressed = FALSE;
-      selecting = FALSE;
     }
-
-  return FALSE;
 }
+#endif
+#endif
 
 static gboolean
 key_press_event(gpointer context,
@@ -611,18 +608,6 @@ create_widget_set(gpointer context)
                             (gpointer) main_area);
 #endif
 
-  gtk_signal_connect_object (GTK_OBJECT (main_area),
-                            "button_press_event", GTK_SIGNAL_FUNC(button_press_event),
-                            (gpointer) main_area);
-
-  gtk_signal_connect_object (GTK_OBJECT (main_area),
-                            "button_release_event", GTK_SIGNAL_FUNC(button_release_event),
-                            (gpointer) main_area);
-
-  gtk_signal_connect_object (GTK_OBJECT (main_area),
-                            "motion_notify_event", GTK_SIGNAL_FUNC(motion_notify_event),
-                            (gpointer) main_area);
-
   gtk_signal_connect_object (GTK_OBJECT(window),
                             "key_press_event", GTK_SIGNAL_FUNC(key_press_event),
                             context);
@@ -650,9 +635,62 @@ create_widget_set(gpointer context)
 
   if (gtk_math_view_get_anti_aliasing(GTK_MATH_VIEW(main_area)))
     gtk_menu_item_activate(anti_aliasing_item);
+}
+
+#if 0
+static void
+create_widget_set()
+{
+  GtkWidget* main_vbox;
+  GtkWidget* menu_bar;
+
+  main_vbox = gtk_vbox_new(FALSE, 1);
+  gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
+  gtk_container_add(GTK_CONTAINER(window), main_vbox);
+  gtk_widget_show(main_vbox);
+
+  menu_bar = get_main_menu();
+  gtk_box_pack_start(GTK_BOX(main_vbox), menu_bar, FALSE, TRUE, 0);
+  gtk_widget_show(menu_bar);
 
-  gtk_menu_item_activate(font_size_item);
+  main_area = gtk_math_view_new(NULL, NULL);
+  gtk_widget_show(main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "selection_changed", GTK_SIGNAL_FUNC (selection_changed),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area),
+                            "element_changed", GTK_SIGNAL_FUNC (element_changed),
+                            (gpointer) main_area);
+
+  gtk_signal_connect_object (GTK_OBJECT (main_area), 
+                            "clicked", GTK_SIGNAL_FUNC(clicked),
+                            (gpointer) main_area);
+
+  gtk_widget_add_events(GTK_WIDGET(main_area),
+                       GDK_BUTTON_PRESS_MASK
+                       | GDK_BUTTON_RELEASE_MASK
+                       | GDK_POINTER_MOTION_MASK);
+
+  scrolled_area = gtk_scrolled_window_new(NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_area),
+                                GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+  gtk_widget_show(scrolled_area);
+  gtk_container_add(GTK_CONTAINER(scrolled_area), main_area);
+  gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_area, TRUE, TRUE, 0);
+
+  status_bar = gtk_statusbar_new();
+  gtk_widget_show(status_bar);
+  gtk_box_pack_start(GTK_BOX(main_vbox), status_bar, FALSE, TRUE, 0);
+  statusbar_context = gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar), "filename");
+
+  gtk_widget_show(main_vbox);
+
+  if (gtk_math_view_get_anti_aliasing(GTK_MATH_VIEW(main_area)))
+    gtk_menu_item_activate(anti_aliasing_item);
 }
+#endif
 
 GtkWidget*
 get_main_menu()
@@ -677,11 +715,5 @@ get_main_menu()
   menu_item = gtk_item_factory_get_widget(item_factory, "/Options/Transparency");
   transparency_item = GTK_MENU_ITEM(menu_item);
 
-  /* !!!BEWARE!!! the default font size must be kept aligned with the definition
-   * in math-engine-configuration.xml
-   */
-  menu_item = gtk_item_factory_get_widget(item_factory, "/Options/Default Font Size/12pt");
-  font_size_item = GTK_MENU_ITEM(menu_item);
-
   return gtk_item_factory_get_widget(item_factory, "<main>");
 }
index c5c41e1575a18fe074a010dcb464bada780c7298..69de8c52e38531b7d96f4bd4b48946b620530066 100644 (file)
       </xsl:if>
       <xsl:apply-templates select="*[1]"/>
       <m:mo stretchy="true">&#x0305;</m:mo>
-    </m:mover>>
+    </m:mover>
   </xsl:template>
 
   <xsl:template match="tml:c[@name='underline']">