24#include <tqpointarray.h>
29#include "bracketelement.h"
30#include "elementvisitor.h"
32#include "formulacursor.h"
33#include "formulaelement.h"
34#include "sequenceelement.h"
36KFORMULA_NAMESPACE_BEGIN
38SingleContentElement::SingleContentElement(
BasicElement* parent )
49 content->setParent(
this );
53SingleContentElement::~SingleContentElement()
64 if ( content->isTextOnly() ) {
67 return content->getCharacter();
71 const LuPixelPoint& point,
const LuPixelPoint& parentOrigin )
75 LuPixelPoint myPos(parentOrigin.x() + getX(),
76 parentOrigin.y() + getY());
78 e = content->
goToPos(cursor, handled, point, myPos);
89 content->dispatchFontCommand( cmd );
95 getParent()->moveLeft(cursor,
this);
99 if (from == getParent()) {
100 content->moveLeft(cursor,
this);
103 getParent()->moveLeft(cursor,
this);
111 getParent()->moveRight(cursor,
this);
115 if (from == getParent()) {
116 content->moveRight(cursor,
this);
119 getParent()->moveRight(cursor,
this);
126 getParent()->moveUp(cursor,
this);
131 getParent()->moveDown(cursor,
this);
135 TQPtrList<BasicElement>& removedChildren,
136 Direction direction )
138 switch (cursor->getPos()) {
140 BasicElement* parent = getParent();
141 parent->selectChild(cursor,
this);
142 parent->remove(cursor, removedChildren, direction);
148 if (direction == beforeCursor) {
149 content->moveLeft(cursor,
this);
152 content->moveRight(cursor,
this);
163 if (child == content) {
164 cursor->
setTo(
this, contentPos);
172 TQDomDocument doc = element.ownerDocument();
174 TQDomElement con = doc.createElement(
"CONTENT");
175 con.appendChild(content->getElementDom(doc));
176 element.appendChild(con);
185 if ( !
buildChild( content, node,
"CONTENT" ) ) {
186 kdWarning( DEBUGID ) <<
"Empty content in " <<
getTagName() << endl;
189 node = node.nextSibling();
200 int nodeCounter = content->buildMathMLChild( node );
201 if ( nodeCounter == -1 ) {
202 kdWarning( DEBUGID) <<
"Empty content in SingleContentElement\n";
209void SingleContentElement::writeMathMLContent( TQDomDocument& doc, TQDomElement& element,
bool oasisFormat )
const
216BracketElement::BracketElement(SymbolType l, SymbolType r,
BasicElement* parent)
218 left( 0 ), right( 0 ),
219 leftType( l ), rightType( r ),
220 m_operator( false ), m_customLeft( false ), m_customRight( false )
225BracketElement::~BracketElement()
234 left( 0 ), right( 0 ),
235 leftType( other.leftType ), rightType( other.rightType ),
236 m_operator( other.m_operator ),
237 m_customLeft( other.m_customLeft ), m_customRight( other.m_customRight )
244 return visitor->visit(
this );
255 const LuPixelPoint& point,
const LuPixelPoint& parentOrigin )
259 LuPixelPoint myPos(parentOrigin.x() + getX(),
260 parentOrigin.y() + getY());
261 e = getContent()->
goToPos(cursor, handled, point, myPos);
267 luPixel dx = point.x() - myPos.x();
268 luPixel dy = point.y() - myPos.y();
270 if ((dx > getContent()->getX()+getContent()->getWidth()) ||
271 (dy > getContent()->getY()+getContent()->getHeight())) {
272 getContent()->moveEnd(cursor);
288 ContextStyle::IndexStyle istyle,
289 StyleAttributes& style )
291 SequenceElement* content = getContent();
292 content->calcSizes( context, tstyle, istyle, style );
297 left = context.fontStyle().createArtwork( leftType );
298 right = context.fontStyle().createArtwork( rightType );
301 double factor = style.sizeFactor();
302 if (content->isTextOnly()) {
303 left->calcSizes(context, tstyle, factor);
304 right->calcSizes(context, tstyle, factor);
306 setBaseline(TQMAX(content->getBaseline(),
307 TQMAX(left->getBaseline(), right->getBaseline())));
309 content->setY(getBaseline() - content->getBaseline());
310 left ->setY(getBaseline() - left ->getBaseline());
311 right ->setY(getBaseline() - right ->getBaseline());
314 setHeight(TQMAX(content->getY() + content->getHeight(),
315 TQMAX(left ->getY() + left ->getHeight(),
316 right->getY() + right->getHeight())));
320 luPixel contentHeight = 2 * TQMAX( content->axis( context, tstyle, factor ),
321 content->getHeight() - content->axis( context, tstyle, factor ) );
322 left->calcSizes( context, tstyle, factor, contentHeight );
323 right->calcSizes( context, tstyle, factor, contentHeight );
326 setHeight(TQMAX(contentHeight,
327 TQMAX(left->getHeight(), right->getHeight())));
330 content->setY(getHeight() / 2 - content->axis( context, tstyle, factor ));
331 setBaseline(content->getBaseline() + content->getY());
333 if ( left->isNormalChar() ) {
334 left->setY(getBaseline() - left->getBaseline());
337 left->setY((getHeight() - left->getHeight())/2);
339 if ( right->isNormalChar() ) {
340 right->setY(getBaseline() - right->getBaseline());
343 right->setY((getHeight() - right->getHeight())/2);
356 setWidth(left->getWidth() + content->getWidth() + right->getWidth());
357 content->setX(left->getWidth());
358 right ->setX(left->getWidth()+content->getWidth());
367void BracketElement::draw( TQPainter& painter,
const LuPixelRect& r,
370 ContextStyle::IndexStyle istyle,
371 StyleAttributes& style,
372 const LuPixelPoint& parentOrigin )
374 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
379 content->draw(painter, r, context, tstyle, istyle, style, myPos);
382 left->draw(painter, r, context, tstyle, style, myPos);
383 right->draw(painter, r, context, tstyle, style, myPos);
386 double factor = style.sizeFactor();
387 luPixel contentHeight = 2 * TQMAX(content->axis( context, tstyle, factor ),
388 content->getHeight() - content->axis( context, tstyle, factor ));
389 left->draw(painter, r, context, tstyle, style, contentHeight, myPos);
390 right->draw(painter, r, context, tstyle, style, contentHeight, myPos);
395 painter.setBrush( TQt::NoBrush );
396 painter.setPen( TQt::red );
398 context.layoutUnitToPixelY( myPos.y()+left->getY() ),
400 context.layoutUnitToPixelY( left->getHeight() ) );
402 context.layoutUnitToPixelY( myPos.y()+right->getY() ),
404 context.layoutUnitToPixelY( right->getHeight() ) );
415 element.setAttribute(
"LEFT", leftType);
416 element.setAttribute(
"RIGHT", rightType);
428 TQString leftStr = element.attribute(
"LEFT");
429 if(!leftStr.isNull()) {
430 leftType =
static_cast<SymbolType
>(leftStr.toInt());
432 TQString rightStr = element.attribute(
"RIGHT");
433 if(!rightStr.isNull()) {
434 rightType =
static_cast<SymbolType
>(rightStr.toInt());
449 if ( element.tagName().lower() ==
"mo" ) {
454 leftType = LeftRoundBracket;
455 rightType = RightRoundBracket;
456 TQString openStr = element.attribute(
"open" ).stripWhiteSpace();
457 if ( !openStr.isNull() ) {
459 if ( openStr ==
"[" )
460 leftType = LeftSquareBracket;
461 else if ( openStr ==
"]" )
462 leftType = RightSquareBracket;
463 else if ( openStr ==
"{" )
464 leftType = LeftCurlyBracket;
465 else if ( openStr ==
"}" )
466 leftType = RightCurlyBracket;
467 else if ( openStr ==
"<" )
468 leftType = LeftCornerBracket;
469 else if ( openStr ==
">" )
470 leftType = RightCornerBracket;
471 else if ( openStr ==
"(" )
472 leftType = LeftRoundBracket;
473 else if ( openStr ==
")" )
474 leftType = RightRoundBracket;
475 else if ( openStr ==
"/" )
476 leftType = SlashBracket;
477 else if ( openStr ==
"\\" )
478 leftType = BackSlashBracket;
480 leftType = LeftRoundBracket;
482 TQString closeStr = element.attribute(
"close" ).stripWhiteSpace();
483 if ( !closeStr.isNull() ) {
484 m_customRight =
true;
485 if ( closeStr ==
"[" )
486 rightType = LeftSquareBracket;
487 else if ( closeStr ==
"]" )
488 rightType = RightSquareBracket;
489 else if ( closeStr ==
"{" )
490 rightType = LeftCurlyBracket;
491 else if ( closeStr ==
"}" )
492 rightType = RightCurlyBracket;
493 else if ( closeStr ==
"<" )
494 rightType = LeftCornerBracket;
495 else if ( closeStr ==
">" )
496 rightType = RightCornerBracket;
497 else if ( closeStr ==
"(" )
498 rightType = LeftRoundBracket;
499 else if ( closeStr ==
")" )
500 rightType = RightRoundBracket;
501 else if ( closeStr ==
"/" )
502 rightType = SlashBracket;
503 else if ( closeStr ==
"\\" )
504 rightType = BackSlashBracket;
506 rightType = LeftRoundBracket;
508 m_separators = element.attribute(
"separators" ).simplifyWhiteSpace();
523 node = node.parentNode();
524 TQDomNode open = node;
525 TQDomNode parent = node.parentNode();
526 if ( ! operatorType( node,
true ) )
528 int nodeNum = searchOperator( node );
531 if ( nodeNum == 0 ) {
534 else if ( nodeNum == 1 ) {
536 node = node.nextSibling();
538 }
while ( ! node.isElement() );
541 nodeCounter += nodeNum;
542 kdWarning() <<
"NodeNum: " << nodeNum << endl;
543 TQDomDocument doc = node.ownerDocument();
544 TQDomElement de = doc.createElement(
"mrow" );
547 TQDomNode n = node.nextSibling();
548 de.appendChild( node.toElement() );
550 }
while ( ++i < nodeNum );
551 parent.insertAfter( de, open );
553 kdWarning() << doc.toString() << endl;
559 while ( ! node.isNull() && ! node.isElement() )
560 node = node.nextSibling();
561 TQDomNode next = node.nextSibling();
562 while ( ! next.isNull() && ! next.isElement() )
563 next = next.nextSibling();
564 if ( ! next.isNull()) {
565 TQDomDocument doc = node.ownerDocument();
566 TQDomNode parent = node.parentNode();
567 TQString ns = parent.prefix();
568 TQDomElement de = doc.createElementNS( ns,
"mrow" );
570 while ( ! node.isNull() ) {
571 TQDomNode no = node.nextSibling();
572 while ( ! no.isNull() && ! no.isElement() )
573 no = no.nextSibling();
574 de.appendChild( node.toElement() );
575 if ( ! no.isNull() && ( m_separators.isNull() || ! m_separators.isEmpty() ) ) {
576 TQDomElement sep = doc.createElementNS( ns,
"mo" );
577 de.appendChild( sep );
578 if ( m_separators.isNull() ) {
579 sep.appendChild( doc.createTextNode(
"," ) );
582 if ( m_separators.at( pos ).isSpace() ) {
585 sep.appendChild( doc.createTextNode( TQString ( m_separators.at( pos ) ) ) );
587 if ( pos < m_separators.length() - 1 ) {
593 parent.appendChild( de );
594 node = parent.firstChild();
595 while ( ! node.isElement() )
596 node = node.nextSibling();
601 if ( contentNumber == -1 )
603 nodeCounter += contentNumber;
604 for (
int i = 0; i < contentNumber; i++ ) {
605 if ( node.isNull() ) {
608 node = node.nextSibling();
612 int operatorNumber = operatorType( node,
false );
613 if ( operatorNumber == -1 ) {
616 nodeCounter += operatorNumber;
618 kdDebug( DEBUGID ) <<
"Number of bracket nodes: " << nodeCounter << endl;
625 cs=getContent()->toLatex();
626 ls=
"\\left"+latexString(leftType) +
" ";
627 rs=
" \\right"+latexString(rightType);
632TQString BracketElement::latexString(
char type)
656 return "\\backslash";
661TQString BracketElement::formulaString()
663 return "(" + getContent()->formulaString() +
")";
666int BracketElement::operatorType( TQDomNode& node,
bool open )
669 SymbolType* type =
open ? &leftType : &rightType;
670 while ( ! node.isNull() && ! node.isElement() ) {
671 node = node.nextSibling();
674 if ( node.isElement() ) {
675 TQDomElement e = node.toElement();
676 TQDomNode child = e.firstChild();
677 if ( child.isEntityReference() ) {
678 kdWarning() <<
"Entity Reference\n";
679 TQString
name = node.nodeName();
692 if ( name ==
"LeftAngleBracket" ) {
693 *type = LeftCornerBracket;
695 else if ( name ==
"RightAngleBracket" ) {
696 *type = RightCornerBracket;
700 *type = LeftRoundBracket;
703 *type = RightRoundBracket;
707 TQString s = e.text();
710 *type =
static_cast<SymbolType
>( TQString::number( s.at( 0 ).latin1() ).toInt() );
719int BracketElement::searchOperator(
const TQDomNode& node )
722 for (
int i = -2; ! n.isNull(); n = n.nextSibling() ) {
723 if ( n.isElement() ) {
725 TQDomElement e = n.toElement();
726 if ( e.tagName().lower() ==
"mo" ) {
728 TQString form = e.attribute(
"form" );
730 if ( ! form.isNull() ) {
731 f = form.stripWhiteSpace().lower();
733 TQString fence = e.attribute(
"fence" );
734 if ( ! fence.isNull() ) {
735 if ( fence.stripWhiteSpace().lower() ==
"false" ) {
738 if ( ! f.isNull() ) {
739 if ( f ==
"postfix" ) {
749 TQDomNode child = e.firstChild();
751 if ( child.isText() )
752 name = child.toText().data().stripWhiteSpace();
753 else if ( child.isEntityReference() )
754 name = child.nodeName();
760 || name ==
"CloseCurlyDoubleQuote"
761 || name ==
"CloseCurlyQuote"
762 || name ==
"RightAngleBracket"
763 || name ==
"RightCeiling"
764 || name ==
"RightDoubleBracket"
765 || name ==
"RightFloor" ) {
766 if ( f.isNull() || f ==
"postfix" )
772 || name ==
"LeftAngleBracket"
773 || name ==
"LeftCeiling"
774 || name ==
"LeftDoubleBracket"
775 || name ==
"LeftFloor"
776 || name ==
"OpenCurlyQuote" ) {
777 if ( ! f.isNull() && f ==
"postfix" )
787void BracketElement::writeMathMLAttributes( TQDomElement& element )
const
789 if ( left->getType() != LeftRoundBracket ||
790 right->getType() != RightRoundBracket )
792 element.setAttribute(
"open", TQString( TQChar( leftType ) ) );
793 element.setAttribute(
"close", TQString( TQChar( rightType ) ) );
795 if ( ! m_separators.isNull() ) {
796 element.setAttribute(
"separators", m_separators );
805OverlineElement::~OverlineElement()
817 return visitor->visit(
this );
829 ContextStyle::IndexStyle istyle,
830 StyleAttributes& style )
832 SequenceElement* content = getContent();
833 content->calcSizes(context, tstyle,
834 context.convertIndexStyleLower(istyle), style );
837 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, style.sizeFactor() ) );
840 setWidth( content->getWidth() );
841 setHeight( content->getHeight() + distY );
844 content->setY( distY );
845 setBaseline(content->getBaseline() + content->getY());
848void OverlineElement::draw( TQPainter& painter,
const LuPixelRect& r,
851 ContextStyle::IndexStyle istyle,
852 StyleAttributes& style,
853 const LuPixelPoint& parentOrigin )
855 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
860 content->draw( painter, r, context, tstyle,
861 context.convertIndexStyleLower( istyle ), style, myPos );
863 luPixel x = myPos.x();
864 luPixel y = myPos.y();
866 double factor = style.sizeFactor();
867 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) );
870 painter.setPen( TQPen( context.getDefaultColor(),
871 context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) );
873 painter.drawLine( context.layoutUnitToPixelX( x ),
874 context.layoutUnitToPixelY( y+distY/3 ),
875 context.layoutUnitToPixelX( x+content->getWidth() ),
876 context.layoutUnitToPixelY( y+distY/3 ) );
882 return "\\overline{" + getContent()->toLatex() +
"}";
885TQString OverlineElement::formulaString()
887 return getContent()->formulaString();
892 TQDomElement de = doc.createElement( oasisFormat ?
"math:mover" :
"mover" );
894 TQDomElement op = doc.createElement( oasisFormat ?
"math:mo" :
"mo" );
896 op.appendChild( doc.createEntityReference(
"OverBar" ) );
897 de.appendChild( op );
898 parent.appendChild( de );
902UnderlineElement::UnderlineElement(
BasicElement* parent )
907UnderlineElement::~UnderlineElement()
920 return visitor->visit(
this );
932 ContextStyle::IndexStyle istyle,
933 StyleAttributes& style )
935 SequenceElement* content = getContent();
936 double factor = style.sizeFactor();
937 content->calcSizes(context, tstyle,
938 context.convertIndexStyleLower(istyle), style );
941 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) );
944 setWidth( content->getWidth() );
945 setHeight( content->getHeight() + distY );
949 setBaseline(content->getBaseline() + content->getY());
952void UnderlineElement::draw( TQPainter& painter,
const LuPixelRect& r,
955 ContextStyle::IndexStyle istyle,
956 StyleAttributes& style,
957 const LuPixelPoint& parentOrigin )
959 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
964 content->draw( painter, r, context, tstyle,
965 context.convertIndexStyleLower( istyle ), style, myPos );
967 luPixel x = myPos.x();
968 luPixel y = myPos.y();
973 double factor = style.sizeFactor();
974 painter.setPen( TQPen( context.getDefaultColor(),
975 context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) );
977 painter.drawLine( context.layoutUnitToPixelX( x ),
978 context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ),
979 context.layoutUnitToPixelX( x+content->getWidth() ),
980 context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ) );
986 return "\\underline{" + getContent()->toLatex() +
"}";
989TQString UnderlineElement::formulaString()
991 return getContent()->formulaString();
996 TQDomElement de = doc.createElement( oasisFormat ?
"math:munder" :
"munder" );
998 TQDomElement op = doc.createElement( oasisFormat ?
"math:mo" :
"mo" );
1000 op.appendChild( doc.createEntityReference(
"UnderBar" ) );
1001 de.appendChild( op );
1002 parent.appendChild( de );
1005KFORMULA_NAMESPACE_END
Basis of every formula element.
virtual FormulaElement * formula()
Provide fast access to the rootElement for each child.
bool buildChild(SequenceElement *child, TQDomNode node, TQString name)
Returns if the SequenceElement could be constructed from the nodes first child.
virtual bool readAttributesFromMathMLDom(const TQDomElement &element)
Reads our attributes from the MathML element.
virtual bool readContentFromDom(TQDomNode &node)
Reads our content from the node.
virtual int readContentFromMathMLDom(TQDomNode &node)
Reads our content from the MathML node.
virtual TQString getTagName() const
Returns the tag name of this element type.
virtual bool readAttributesFromDom(TQDomElement element)
Reads our attributes from the element.
virtual BasicElement * goToPos(FormulaCursor *, bool &handled, const LuPixelPoint &point, const LuPixelPoint &parentOrigin)
Sets the cursor and returns the element the point is in.
virtual void writeDom(TQDomElement element)
Appends our attributes to the dom element.
virtual void writeMathML(TQDomDocument &doc, TQDomNode &parent, bool oasisFormat=false) const
Same as above, just MathML.
A left and/or right bracket around one child.
virtual BasicElement * goToPos(FormulaCursor *, bool &handled, const LuPixelPoint &point, const LuPixelPoint &parentOrigin)
Sets the cursor and returns the element the point is in.
virtual void writeDom(TQDomElement element)
Draws the whole element including its children.
virtual TQString toLatex()
virtual void entered(SequenceElement *child)
The cursor has entered one of our child sequences.
virtual bool accept(ElementVisitor *visitor)
Visit this element.
virtual bool readAttributesFromMathMLDom(const TQDomElement &element)
Reads our attributes from the MathML element.
virtual bool readAttributesFromDom(TQDomElement element)
Reads our attributes from the element.
virtual void calcSizes(const ContextStyle &context, ContextStyle::TextStyle tstyle, ContextStyle::IndexStyle istyle, StyleAttributes &style)
Calculates our width and height and our children's parentPosition.
virtual int readContentFromMathMLDom(TQDomNode &node)
Reads our content from the MathML node.
Contains all the style information for the formela.
TextStyle
Textstyles like in TeX.
Base for all font commands that act on the current selection.
int layoutUnitToPixelX(int lupix) const
The "layout unit pixel" -> "[zoomed] view pixel" conversions.
A line above the content.
virtual TQString toLatex()
Draws the whole element including its children.
virtual void entered(SequenceElement *child)
The cursor has entered one of our child sequences.
virtual void writeMathML(TQDomDocument &doc, TQDomNode &parent, bool oasisFormat=false) const
Same as above, just MathML.
virtual bool accept(ElementVisitor *visitor)
Visit this element.
virtual void calcSizes(const ContextStyle &context, ContextStyle::TextStyle tstyle, ContextStyle::IndexStyle istyle, StyleAttributes &style)
Calculates our width and height and our children's parentPosition.
The element that contains a number of children.
virtual bool isTextOnly() const
The base of (all) elements that contain just one content element.
virtual bool readContentFromDom(TQDomNode &node)
Reads our content from the node.
virtual void writeDom(TQDomElement element)
Appends our attributes to the dom element.
virtual BasicElement * goToPos(FormulaCursor *, bool &handled, const LuPixelPoint &point, const LuPixelPoint &parentOrigin)
Sets the cursor and returns the element the point is in.
virtual TQChar getCharacter() const
virtual void normalize(FormulaCursor *, Direction)
Moves the cursor to a normal place where new elements might be inserted.
virtual SequenceElement * getMainChild()
Removes the child.
virtual void selectChild(FormulaCursor *cursor, BasicElement *child)
Sets the cursor to select the child.
virtual void dispatchFontCommand(FontCommand *cmd)
Dispatch this FontCommand to all our TextElement children.
virtual int readContentFromMathMLDom(TQDomNode &node)
Reads our content from the MathML node.
virtual void remove(FormulaCursor *, TQPtrList< BasicElement > &, Direction)
Enters this element while moving to the left starting inside the element `from'.
A line below the content.
virtual bool accept(ElementVisitor *visitor)
Visit this element.
virtual void writeMathML(TQDomDocument &doc, TQDomNode &parent, bool oasisFormat=false) const
Same as above, just MathML.
virtual TQString toLatex()
Draws the whole element including its children.
virtual void entered(SequenceElement *child)
The cursor has entered one of our child sequences.
virtual void calcSizes(const ContextStyle &context, ContextStyle::TextStyle tstyle, ContextStyle::IndexStyle istyle, StyleAttributes &style)
Calculates our width and height and our children's parentPosition.
TDEAction * open(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
const char * name(StdAction id)