]> matita.cs.unibo.it Git - helm.git/commitdiff
A first partial implementation of deleting is introduced. The user might
authorPaolo Marinelli <paolo.marinelli@unibo.it>
Tue, 21 Jan 2003 11:42:16 +0000 (11:42 +0000)
committerPaolo Marinelli <paolo.marinelli@unibo.it>
Tue, 21 Jan 2003 11:42:16 +0000 (11:42 +0000)
want to delete in two ways: a deleting mode near to what he has actually
typed (textual mode) and a deleting mode near to what screen shows (graphical
mode). Only a partial implementation of the second mode is provided. The user
can delete a macro he is typing, a group, an identifier, a number, a
superscript and a subscript. To delete in graphical mode the user has to type
BACKSPACE.
Added the following private methods to TPushParser class:
  void do_gdelete(void)
  void gdelete_prev(void)
Added the entry GDELETE to the TCat enum defined in the TToken struct.

helm/DEVEL/mathml_editor/src/TPushLexer.cc
helm/DEVEL/mathml_editor/src/TPushParser.cc
helm/DEVEL/mathml_editor/src/TPushParser.hh
helm/DEVEL/mathml_editor/src/TToken.hh
helm/DEVEL/mathml_editor/test/guiGTK.c
helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl

index b943877870c0400a8c42f94d469feab5fbe8f4f2..4b24523da5e494c01ac2202bfbea438063fbf996 100644 (file)
@@ -31,7 +31,7 @@ TPushLexer::transaction(char ch, State newState)
     case '\t':
     case ' ': parser.push(TToken(TToken::SPACE, ch)); break;
     case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
-    case '%': parser.push(TToken(TToken::COMMENT)); break;
+    case '%': parser.push(TToken(TToken::COMMENT)); break;     
     default:
       if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch));
       else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch));
@@ -49,6 +49,7 @@ TPushLexer::push(char ch)
     case ACCEPT:
       if (ch == '\\') state = ESCAPE;
       else if (ch == '#') state = PARAMETER;
+      else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
       else transaction(ch, ACCEPT);
       break;
     case ESCAPE:
@@ -57,6 +58,10 @@ TPushLexer::push(char ch)
          buffer.push_back(ch);
          state = MACRO;
        }
+      else if (ch == '\b')
+        {
+         state = ACCEPT;
+       }
       else
        {
          parser.push(TToken(TToken::CONTROL, ch));
@@ -76,6 +81,11 @@ TPushLexer::push(char ch)
          buffer.erase();
          state = PARAMETER;
        }
+      else if (ch == '\b')
+       {
+         buffer.erase(buffer.length() - 1, 1);
+         if (buffer.length() == 0) state = ESCAPE;
+       }
       else if (isalpha(ch))
        buffer.push_back(ch);
       else
@@ -90,6 +100,7 @@ TPushLexer::push(char ch)
       if (ch == '\\') state = ESCAPE;
       else if (ch == '#') state = PARAMETER;
       else if (isspace(ch)) ;
+      else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
       else transaction(ch, ACCEPT);
       break;
     case PARAMETER:
index 20bb897b765bf0e8d5d532a1e5eeb221765820b1..cfcce849f887bd850c8669e09005cda3d860b518 100644 (file)
@@ -478,6 +478,132 @@ 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
+  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)
+        {
+         cursor.remove();
+         prev.replace(cursor);
+       }
+      else
+        {
+         ucs4val.erase(ucs4val.length() - 1, 1);
+         prev.element().setAttribute(DOM::GdomeString("val"), DOM::GdomeString(ucs4val));
+       }
+    } // end of if (prev.is("i") || ...)
+  else if (prev.is("sp") || prev.is("sb"))
+    {
+      cursor.remove();
+      prev.append(cursor);
+      do_gdelete();
+    } // end of if (prev.is("sp") || prev.is("sb"))
+  else if (prev.isG())
+    {
+      cursor.remove();
+      prev.append(cursor);
+      do_gdelete();
+    }
+  else if (prev.isC())
+    {
+//      cursor.remove();
+//      prev.append(cursor);
+//      do_gdelete();
+    }
+  else 
+    {
+      // not handled
+    }
+  
+} // end of method
+
+void
+TPushParser::do_gdelete()
+{
+  // this function operates a graphical deleting
+  
+  TNode parent = cursor.parent();
+
+  // if no parent, do nothing
+  if (parent)
+    {
+      assert(parent);
+      if (parent.isG())
+        {
+         TNode prev = cursor.prev();
+         if (prev)
+           {
+             // 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();
+               }
+           }
+         else // no previous node is present
+           {
+             if (!parent.parent().is("math"))
+               {
+                 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();
+               }
+             else
+               {
+                 // nothing to do...i think
+               }
+           }
+       }
+      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
+         
+         TNode prev = cursor.prev();
+
+         if (!prev) cout << "qualcosa non va" << endl;
+         else
+           {
+             if (parent.first().next() == cursor) // there's only an element preceding the cursor
+               {
+                 cursor.remove();
+                 parent.replace(prev);
+                 prev.parent().append(cursor);
+               }
+             else // there are two elements preceding the cursor
+               {
+                 gdelete_prev();
+               }
+           }
+       }
+      else
+        {
+         // not handled: no control for tables, ...
+       }
+    }
+  else
+    {
+      // do nothing ??
+    }
+
+} // end of method
+
 void
 TPushParser::process(const TToken& token)
 {
@@ -498,6 +624,7 @@ TPushParser::process(const TToken& token)
     case TToken::ACTIVE: do_active(token.value); break;
     case TToken::COMMENT: do_comment(); break;
     case TToken::CONTROL: do_control(token.value); break;
+    case TToken::GDELETE: do_gdelete(); break;
     }
 }
 
index c104eb28c4c3a49ccfff0078fea5f53fd2cb5273..c3cee66c89c900309213664483ee2611325d8224 100644 (file)
@@ -27,6 +27,8 @@ private:
 
   std::string PRIME(void) const;
   bool isPrimes(const TNode&) const;
+  
+  void gdelete_prev(void);
 
   void do_begin(void);
   void do_end(void);
@@ -43,6 +45,7 @@ private:
   void do_active(const std::string&);
   void do_comment(void);
   void do_control(const std::string&);
+  void do_gdelete(void);
 
   void do_cr(void);
   void do_apostrophe(void);
index 1cb6ca15e5848a8f9827d1fde8e52e9ab51910c4..bf19fb187a12897fdfd32eab6175dea2adb195c4 100644 (file)
@@ -22,7 +22,8 @@ struct TToken
       OTHER,
       ACTIVE,
       COMMENT,
-      CONTROL
+      CONTROL,
+      GDELETE
     };
 
   TToken(TCat c) : category(c) { };
index 7b58ffbe895522c9d95b0d12ba74e0cce69066fc..d270f744822881681613e187543c496e4133d110 100644 (file)
@@ -564,6 +564,7 @@ key_press_event(gpointer context,
   case GDK_End:
   case GDK_KP_End:
     break;
+  case GDK_BackSpace: push_char(context, event->keyval); break;
   default:
     if (event->keyval < 0x80) push_char(context, event->keyval);
     return FALSE;
index 8b237387f4bc3bd4a99ca7de90bfc7bd87fecfde..c5c41e1575a18fe074a010dcb464bada780c7298 100644 (file)
         </xsl:attribute>
       </xsl:if>
       <xsl:apply-templates select="*[1]/*[1]"/>
-      <xsl:apply-templates select="*[1]"/>
+      <xsl:apply-templates select="*[2]"/>
       <xsl:apply-templates select="*[1]/*[2]"/>
     </m:msubsup>
   </xsl:template>