From e290ab0a049ec2babedc3cb0ff802c430ed8ee7c Mon Sep 17 00:00:00 2001 From: Paolo Marinelli Date: Tue, 21 Jan 2003 11:42:16 +0000 Subject: [PATCH] A first partial implementation of deleting is introduced. The user might 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 | 13 +- helm/DEVEL/mathml_editor/src/TPushParser.cc | 127 ++++++++++++++++++++ helm/DEVEL/mathml_editor/src/TPushParser.hh | 3 + helm/DEVEL/mathml_editor/src/TToken.hh | 3 +- helm/DEVEL/mathml_editor/test/guiGTK.c | 1 + helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl | 2 +- 6 files changed, 146 insertions(+), 3 deletions(-) diff --git a/helm/DEVEL/mathml_editor/src/TPushLexer.cc b/helm/DEVEL/mathml_editor/src/TPushLexer.cc index b94387787..4b24523da 100644 --- a/helm/DEVEL/mathml_editor/src/TPushLexer.cc +++ b/helm/DEVEL/mathml_editor/src/TPushLexer.cc @@ -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: diff --git a/helm/DEVEL/mathml_editor/src/TPushParser.cc b/helm/DEVEL/mathml_editor/src/TPushParser.cc index 20bb897b7..cfcce849f 100644 --- a/helm/DEVEL/mathml_editor/src/TPushParser.cc +++ b/helm/DEVEL/mathml_editor/src/TPushParser.cc @@ -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; } } diff --git a/helm/DEVEL/mathml_editor/src/TPushParser.hh b/helm/DEVEL/mathml_editor/src/TPushParser.hh index c104eb28c..c3cee66c8 100644 --- a/helm/DEVEL/mathml_editor/src/TPushParser.hh +++ b/helm/DEVEL/mathml_editor/src/TPushParser.hh @@ -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); diff --git a/helm/DEVEL/mathml_editor/src/TToken.hh b/helm/DEVEL/mathml_editor/src/TToken.hh index 1cb6ca15e..bf19fb187 100644 --- a/helm/DEVEL/mathml_editor/src/TToken.hh +++ b/helm/DEVEL/mathml_editor/src/TToken.hh @@ -22,7 +22,8 @@ struct TToken OTHER, ACTIVE, COMMENT, - CONTROL + CONTROL, + GDELETE }; TToken(TCat c) : category(c) { }; diff --git a/helm/DEVEL/mathml_editor/test/guiGTK.c b/helm/DEVEL/mathml_editor/test/guiGTK.c index 7b58ffbe8..d270f7448 100644 --- a/helm/DEVEL/mathml_editor/test/guiGTK.c +++ b/helm/DEVEL/mathml_editor/test/guiGTK.c @@ -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; diff --git a/helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl b/helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl index 8b237387f..c5c41e157 100644 --- a/helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl +++ b/helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl @@ -128,7 +128,7 @@ - + -- 2.39.2