00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qptrlist.h>
00022 #include <qpainter.h>
00023 #include <qpen.h>
00024 #include <qpointarray.h>
00025
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028
00029 #include "bracketelement.h"
00030 #include "elementvisitor.h"
00031 #include "fontstyle.h"
00032 #include "formulacursor.h"
00033 #include "formulaelement.h"
00034 #include "sequenceelement.h"
00035
00036 KFORMULA_NAMESPACE_BEGIN
00037
00038 SingleContentElement::SingleContentElement(BasicElement* parent )
00039 : BasicElement( parent )
00040 {
00041 content = new SequenceElement( this );
00042 }
00043
00044
00045 SingleContentElement::SingleContentElement( const SingleContentElement& other )
00046 : BasicElement( other )
00047 {
00048 content = new SequenceElement( other.content );
00049 content->setParent( this );
00050 }
00051
00052
00053 SingleContentElement::~SingleContentElement()
00054 {
00055 delete content;
00056 }
00057
00058
00059 QChar SingleContentElement::getCharacter() const
00060 {
00061
00062
00063
00064 if ( content->isTextOnly() ) {
00065 return '\\';
00066 }
00067 return content->getCharacter();
00068 }
00069
00070 BasicElement* SingleContentElement::goToPos( FormulaCursor* cursor, bool& handled,
00071 const LuPixelPoint& point, const LuPixelPoint& parentOrigin )
00072 {
00073 BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin);
00074 if (e != 0) {
00075 LuPixelPoint myPos(parentOrigin.x() + getX(),
00076 parentOrigin.y() + getY());
00077
00078 e = content->goToPos(cursor, handled, point, myPos);
00079 if (e != 0) {
00080 return e;
00081 }
00082 return this;
00083 }
00084 return 0;
00085 }
00086
00087 void SingleContentElement::dispatchFontCommand( FontCommand* cmd )
00088 {
00089 content->dispatchFontCommand( cmd );
00090 }
00091
00092 void SingleContentElement::moveLeft(FormulaCursor* cursor, BasicElement* from)
00093 {
00094 if (cursor->isSelectionMode()) {
00095 getParent()->moveLeft(cursor, this);
00096 }
00097 else {
00098
00099 if (from == getParent()) {
00100 content->moveLeft(cursor, this);
00101 }
00102 else {
00103 getParent()->moveLeft(cursor, this);
00104 }
00105 }
00106 }
00107
00108 void SingleContentElement::moveRight(FormulaCursor* cursor, BasicElement* from)
00109 {
00110 if (cursor->isSelectionMode()) {
00111 getParent()->moveRight(cursor, this);
00112 }
00113 else {
00114
00115 if (from == getParent()) {
00116 content->moveRight(cursor, this);
00117 }
00118 else {
00119 getParent()->moveRight(cursor, this);
00120 }
00121 }
00122 }
00123
00124 void SingleContentElement::moveUp(FormulaCursor* cursor, BasicElement* )
00125 {
00126 getParent()->moveUp(cursor, this);
00127 }
00128
00129 void SingleContentElement::moveDown(FormulaCursor* cursor, BasicElement* )
00130 {
00131 getParent()->moveDown(cursor, this);
00132 }
00133
00134 void SingleContentElement::remove( FormulaCursor* cursor,
00135 QPtrList<BasicElement>& removedChildren,
00136 Direction direction )
00137 {
00138 switch (cursor->getPos()) {
00139 case contentPos:
00140 BasicElement* parent = getParent();
00141 parent->selectChild(cursor, this);
00142 parent->remove(cursor, removedChildren, direction);
00143 }
00144 }
00145
00146 void SingleContentElement::normalize( FormulaCursor* cursor, Direction direction )
00147 {
00148 if (direction == beforeCursor) {
00149 content->moveLeft(cursor, this);
00150 }
00151 else {
00152 content->moveRight(cursor, this);
00153 }
00154 }
00155
00156 SequenceElement* SingleContentElement::getMainChild()
00157 {
00158 return content;
00159 }
00160
00161 void SingleContentElement::selectChild(FormulaCursor* cursor, BasicElement* child)
00162 {
00163 if (child == content) {
00164 cursor->setTo(this, contentPos);
00165 }
00166 }
00167
00168 void SingleContentElement::writeDom(QDomElement element)
00169 {
00170 BasicElement::writeDom(element);
00171
00172 QDomDocument doc = element.ownerDocument();
00173
00174 QDomElement con = doc.createElement("CONTENT");
00175 con.appendChild(content->getElementDom(doc));
00176 element.appendChild(con);
00177 }
00178
00179 bool SingleContentElement::readContentFromDom(QDomNode& node)
00180 {
00181 if (!BasicElement::readContentFromDom(node)) {
00182 return false;
00183 }
00184
00185 if ( !buildChild( content, node, "CONTENT" ) ) {
00186 kdWarning( DEBUGID ) << "Empty content in " << getTagName() << endl;
00187 return false;
00188 }
00189 node = node.nextSibling();
00190
00191 return true;
00192 }
00193
00194 int SingleContentElement::readContentFromMathMLDom( QDomNode& node )
00195 {
00196 if ( BasicElement::readContentFromMathMLDom( node ) == -1 ) {
00197 return -1;
00198 }
00199
00200 int nodeCounter = content->buildMathMLChild( node );
00201 if ( nodeCounter == -1 ) {
00202 kdWarning( DEBUGID) << "Empty content in SingleContentElement\n";
00203 return -1;
00204 }
00205
00206 return nodeCounter;
00207 }
00208
00209 void SingleContentElement::writeMathMLContent( QDomDocument& doc, QDomElement& element, bool oasisFormat ) const
00210 {
00211 content->writeMathML( doc, element, oasisFormat );
00212 }
00213
00214
00215
00216 BracketElement::BracketElement(SymbolType l, SymbolType r, BasicElement* parent)
00217 : SingleContentElement(parent),
00218 left( 0 ), right( 0 ),
00219 leftType( l ), rightType( r ),
00220 m_operator( false ), m_customLeft( false ), m_customRight( false )
00221 {
00222 }
00223
00224
00225 BracketElement::~BracketElement()
00226 {
00227 delete left;
00228 delete right;
00229 }
00230
00231
00232 BracketElement::BracketElement( const BracketElement& other )
00233 : SingleContentElement( other ),
00234 left( 0 ), right( 0 ),
00235 leftType( other.leftType ), rightType( other.rightType ),
00236 m_operator( other.m_operator ),
00237 m_customLeft( other.m_customLeft ), m_customRight( other.m_customRight )
00238 {
00239 }
00240
00241
00242 bool BracketElement::accept( ElementVisitor* visitor )
00243 {
00244 return visitor->visit( this );
00245 }
00246
00247
00248 void BracketElement::entered( SequenceElement* )
00249 {
00250 formula()->tell( i18n( "Delimited list" ) );
00251 }
00252
00253
00254 BasicElement* BracketElement::goToPos( FormulaCursor* cursor, bool& handled,
00255 const LuPixelPoint& point, const LuPixelPoint& parentOrigin )
00256 {
00257 BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin);
00258 if (e != 0) {
00259 LuPixelPoint myPos(parentOrigin.x() + getX(),
00260 parentOrigin.y() + getY());
00261 e = getContent()->goToPos(cursor, handled, point, myPos);
00262 if (e != 0) {
00263 return e;
00264 }
00265
00266
00267 luPixel dx = point.x() - myPos.x();
00268 luPixel dy = point.y() - myPos.y();
00269
00270 if ((dx > getContent()->getX()+getContent()->getWidth()) ||
00271 (dy > getContent()->getY()+getContent()->getHeight())) {
00272 getContent()->moveEnd(cursor);
00273 handled = true;
00274 return getContent();
00275 }
00276 return this;
00277 }
00278 return 0;
00279 }
00280
00281
00286 void BracketElement::calcSizes( const ContextStyle& context,
00287 ContextStyle::TextStyle tstyle,
00288 ContextStyle::IndexStyle istyle,
00289 StyleAttributes& style )
00290 {
00291 SequenceElement* content = getContent();
00292 content->calcSizes( context, tstyle, istyle, style );
00293
00294
00295 delete left;
00296 delete right;
00297 left = context.fontStyle().createArtwork( leftType );
00298 right = context.fontStyle().createArtwork( rightType );
00299
00300
00301 double factor = style.sizeFactor();
00302 if (content->isTextOnly()) {
00303 left->calcSizes(context, tstyle, factor);
00304 right->calcSizes(context, tstyle, factor);
00305
00306 setBaseline(QMAX(content->getBaseline(),
00307 QMAX(left->getBaseline(), right->getBaseline())));
00308
00309 content->setY(getBaseline() - content->getBaseline());
00310 left ->setY(getBaseline() - left ->getBaseline());
00311 right ->setY(getBaseline() - right ->getBaseline());
00312
00313
00314 setHeight(QMAX(content->getY() + content->getHeight(),
00315 QMAX(left ->getY() + left ->getHeight(),
00316 right->getY() + right->getHeight())));
00317 }
00318 else {
00319
00320 luPixel contentHeight = 2 * QMAX( content->axis( context, tstyle, factor ),
00321 content->getHeight() - content->axis( context, tstyle, factor ) );
00322 left->calcSizes( context, tstyle, factor, contentHeight );
00323 right->calcSizes( context, tstyle, factor, contentHeight );
00324
00325
00326 setHeight(QMAX(contentHeight,
00327 QMAX(left->getHeight(), right->getHeight())));
00328
00329
00330 content->setY(getHeight() / 2 - content->axis( context, tstyle, factor ));
00331 setBaseline(content->getBaseline() + content->getY());
00332
00333 if ( left->isNormalChar() ) {
00334 left->setY(getBaseline() - left->getBaseline());
00335 }
00336 else {
00337 left->setY((getHeight() - left->getHeight())/2);
00338 }
00339 if ( right->isNormalChar() ) {
00340 right->setY(getBaseline() - right->getBaseline());
00341 }
00342 else {
00343 right->setY((getHeight() - right->getHeight())/2);
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353 }
00354
00355
00356 setWidth(left->getWidth() + content->getWidth() + right->getWidth());
00357 content->setX(left->getWidth());
00358 right ->setX(left->getWidth()+content->getWidth());
00359 }
00360
00361
00367 void BracketElement::draw( QPainter& painter, const LuPixelRect& r,
00368 const ContextStyle& context,
00369 ContextStyle::TextStyle tstyle,
00370 ContextStyle::IndexStyle istyle,
00371 StyleAttributes& style,
00372 const LuPixelPoint& parentOrigin )
00373 {
00374 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00375
00376
00377
00378 SequenceElement* content = getContent();
00379 content->draw(painter, r, context, tstyle, istyle, style, myPos);
00380
00381 if (content->isTextOnly()) {
00382 left->draw(painter, r, context, tstyle, style, myPos);
00383 right->draw(painter, r, context, tstyle, style, myPos);
00384 }
00385 else {
00386 double factor = style.sizeFactor();
00387 luPixel contentHeight = 2 * QMAX(content->axis( context, tstyle, factor ),
00388 content->getHeight() - content->axis( context, tstyle, factor ));
00389 left->draw(painter, r, context, tstyle, style, contentHeight, myPos);
00390 right->draw(painter, r, context, tstyle, style, contentHeight, myPos);
00391 }
00392
00393
00394 #if 0
00395 painter.setBrush( Qt::NoBrush );
00396 painter.setPen( Qt::red );
00397 painter.drawRect( context.layoutUnitToPixelX( myPos.x()+left->getX() ),
00398 context.layoutUnitToPixelY( myPos.y()+left->getY() ),
00399 context.layoutUnitToPixelX( left->getWidth() ),
00400 context.layoutUnitToPixelY( left->getHeight() ) );
00401 painter.drawRect( context.layoutUnitToPixelX( myPos.x()+right->getX() ),
00402 context.layoutUnitToPixelY( myPos.y()+right->getY() ),
00403 context.layoutUnitToPixelX( right->getWidth() ),
00404 context.layoutUnitToPixelY( right->getHeight() ) );
00405 #endif
00406 }
00407
00408
00412 void BracketElement::writeDom(QDomElement element)
00413 {
00414 SingleContentElement::writeDom(element);
00415 element.setAttribute("LEFT", leftType);
00416 element.setAttribute("RIGHT", rightType);
00417 }
00418
00423 bool BracketElement::readAttributesFromDom(QDomElement element)
00424 {
00425 if (!BasicElement::readAttributesFromDom(element)) {
00426 return false;
00427 }
00428 QString leftStr = element.attribute("LEFT");
00429 if(!leftStr.isNull()) {
00430 leftType = static_cast<SymbolType>(leftStr.toInt());
00431 }
00432 QString rightStr = element.attribute("RIGHT");
00433 if(!rightStr.isNull()) {
00434 rightType = static_cast<SymbolType>(rightStr.toInt());
00435 }
00436 return true;
00437 }
00438
00443 bool BracketElement::readAttributesFromMathMLDom(const QDomElement& element)
00444 {
00445 if ( !BasicElement::readAttributesFromMathMLDom( element ) ) {
00446 return false;
00447 }
00448
00449 if ( element.tagName().lower() == "mo" ) {
00450 m_operator = true;
00451
00452 }
00453 else {
00454 leftType = LeftRoundBracket;
00455 rightType = RightRoundBracket;
00456 QString openStr = element.attribute( "open" ).stripWhiteSpace();
00457 if ( !openStr.isNull() ) {
00458 m_customLeft = true;
00459 if ( openStr == "[" )
00460 leftType = LeftSquareBracket;
00461 else if ( openStr == "]" )
00462 leftType = RightSquareBracket;
00463 else if ( openStr == "{" )
00464 leftType = LeftCurlyBracket;
00465 else if ( openStr == "}" )
00466 leftType = RightCurlyBracket;
00467 else if ( openStr == "<" )
00468 leftType = LeftCornerBracket;
00469 else if ( openStr == ">" )
00470 leftType = RightCornerBracket;
00471 else if ( openStr == "(" )
00472 leftType = LeftRoundBracket;
00473 else if ( openStr == ")" )
00474 leftType = RightRoundBracket;
00475 else if ( openStr == "/" )
00476 leftType = SlashBracket;
00477 else if ( openStr == "\\" )
00478 leftType = BackSlashBracket;
00479 else
00480 leftType = LeftRoundBracket;
00481 }
00482 QString closeStr = element.attribute( "close" ).stripWhiteSpace();
00483 if ( !closeStr.isNull() ) {
00484 m_customRight = true;
00485 if ( closeStr == "[" )
00486 rightType = LeftSquareBracket;
00487 else if ( closeStr == "]" )
00488 rightType = RightSquareBracket;
00489 else if ( closeStr == "{" )
00490 rightType = LeftCurlyBracket;
00491 else if ( closeStr == "}" )
00492 rightType = RightCurlyBracket;
00493 else if ( closeStr == "<" )
00494 rightType = LeftCornerBracket;
00495 else if ( closeStr == ">" )
00496 rightType = RightCornerBracket;
00497 else if ( closeStr == "(" )
00498 rightType = LeftRoundBracket;
00499 else if ( closeStr == ")" )
00500 rightType = RightRoundBracket;
00501 else if ( closeStr == "/" )
00502 rightType = SlashBracket;
00503 else if ( closeStr == "\\" )
00504 rightType = BackSlashBracket;
00505 else
00506 rightType = LeftRoundBracket;
00507 }
00508 m_separators = element.attribute( "separators" ).simplifyWhiteSpace();
00509 }
00510 return true;
00511 }
00512
00518 int BracketElement::readContentFromMathMLDom(QDomNode& node)
00519 {
00520 bool empty = false;
00521 int nodeCounter = 0;
00522 if ( m_operator ) {
00523 node = node.parentNode();
00524 QDomNode open = node;
00525 QDomNode parent = node.parentNode();
00526 if ( ! operatorType( node, true ) )
00527 return -1;
00528 int nodeNum = searchOperator( node );
00529 if ( nodeNum == -1 )
00530 return -1;
00531 if ( nodeNum == 0 ) {
00532 empty = true;
00533 }
00534 else if ( nodeNum == 1 ) {
00535 do {
00536 node = node.nextSibling();
00537 nodeCounter++;
00538 } while ( ! node.isElement() );
00539 }
00540 else {
00541 nodeCounter += nodeNum;
00542 kdWarning() << "NodeNum: " << nodeNum << endl;
00543 QDomDocument doc = node.ownerDocument();
00544 QDomElement de = doc.createElement( "mrow" );
00545 int i = 0;
00546 do {
00547 QDomNode n = node.nextSibling();
00548 de.appendChild( node.toElement() );
00549 node = n;
00550 } while ( ++i < nodeNum );
00551 parent.insertAfter( de, open );
00552 node = de;
00553 kdWarning() << doc.toString() << endl;
00554 }
00555 }
00556 else {
00557
00558
00559 while ( ! node.isNull() && ! node.isElement() )
00560 node = node.nextSibling();
00561 QDomNode next = node.nextSibling();
00562 while ( ! next.isNull() && ! next.isElement() )
00563 next = next.nextSibling();
00564 if ( ! next.isNull()) {
00565 QDomDocument doc = node.ownerDocument();
00566 QDomNode parent = node.parentNode();
00567 QString ns = parent.prefix();
00568 QDomElement de = doc.createElementNS( ns, "mrow" );
00569 uint pos = 0;
00570 while ( ! node.isNull() ) {
00571 QDomNode no = node.nextSibling();
00572 while ( ! no.isNull() && ! no.isElement() )
00573 no = no.nextSibling();
00574 de.appendChild( node.toElement() );
00575 if ( ! no.isNull() && ( m_separators.isNull() || ! m_separators.isEmpty() ) ) {
00576 QDomElement sep = doc.createElementNS( ns, "mo" );
00577 de.appendChild( sep );
00578 if ( m_separators.isNull() ) {
00579 sep.appendChild( doc.createTextNode( "," ) );
00580 }
00581 else {
00582 if ( m_separators.at( pos ).isSpace() ) {
00583 pos++;
00584 }
00585 sep.appendChild( doc.createTextNode( QString ( m_separators.at( pos ) ) ) );
00586 }
00587 if ( pos < m_separators.length() - 1 ) {
00588 pos++;
00589 }
00590 }
00591 node = no;
00592 }
00593 parent.appendChild( de );
00594 node = parent.firstChild();
00595 while ( ! node.isElement() )
00596 node = node.nextSibling();
00597 }
00598 }
00599 if ( ! empty ) {
00600 int contentNumber = inherited::readContentFromMathMLDom( node );
00601 if ( contentNumber == -1 )
00602 return -1;
00603 nodeCounter += contentNumber;
00604 for (int i = 0; i < contentNumber; i++ ) {
00605 if ( node.isNull() ) {
00606 return -1;
00607 }
00608 node = node.nextSibling();
00609 }
00610 }
00611 if ( m_operator ) {
00612 int operatorNumber = operatorType( node, false );
00613 if ( operatorNumber == -1 ) {
00614 return -1;
00615 }
00616 nodeCounter += operatorNumber;
00617 }
00618 kdDebug( DEBUGID ) << "Number of bracket nodes: " << nodeCounter << endl;
00619 return nodeCounter;
00620 }
00621
00622 QString BracketElement::toLatex()
00623 {
00624 QString ls,rs,cs;
00625 cs=getContent()->toLatex();
00626 ls="\\left"+latexString(leftType) + " ";
00627 rs=" \\right"+latexString(rightType);
00628
00629 return ls+cs+rs;
00630 }
00631
00632 QString BracketElement::latexString(char type)
00633 {
00634 switch (type) {
00635 case ']':
00636 return "]";
00637 case '[':
00638 return "[";
00639 case '{':
00640 return "\\{";
00641 case '}':
00642 return "\\}";
00643 case '(':
00644 return "(";
00645 case ')':
00646 return ")";
00647 case '|':
00648 return "|";
00649 case '<':
00650 return "\\langle";
00651 case '>':
00652 return "\\rangle";
00653 case '/':
00654 return "/";
00655 case '\\':
00656 return "\\backslash";
00657 }
00658 return ".";
00659 }
00660
00661 QString BracketElement::formulaString()
00662 {
00663 return "(" + getContent()->formulaString() + ")";
00664 }
00665
00666 int BracketElement::operatorType( QDomNode& node, bool open )
00667 {
00668 int counter = 1;
00669 SymbolType* type = open ? &leftType : &rightType;
00670 while ( ! node.isNull() && ! node.isElement() ) {
00671 node = node.nextSibling();
00672 counter++;
00673 }
00674 if ( node.isElement() ) {
00675 QDomElement e = node.toElement();
00676 QDomNode child = e.firstChild();
00677 if ( child.isEntityReference() ) {
00678 kdWarning() << "Entity Reference\n";
00679 QString name = node.nodeName();
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 if ( name == "LeftAngleBracket" ) {
00693 *type = LeftCornerBracket;
00694 }
00695 else if ( name == "RightAngleBracket" ) {
00696 *type = RightCornerBracket;
00697 }
00698 else {
00699 if ( open ) {
00700 *type = LeftRoundBracket;
00701 }
00702 else
00703 *type = RightRoundBracket;
00704 }
00705 }
00706 else {
00707 QString s = e.text();
00708 if ( s.isNull() )
00709 return -1;
00710 *type = static_cast<SymbolType>( QString::number( s.at( 0 ).latin1() ).toInt() );
00711 }
00712 }
00713 else {
00714 return -1;
00715 }
00716 return counter;
00717 }
00718
00719 int BracketElement::searchOperator( const QDomNode& node )
00720 {
00721 QDomNode n = node;
00722 for ( int i = -2; ! n.isNull(); n = n.nextSibling() ) {
00723 if ( n.isElement() ) {
00724 i++;
00725 QDomElement e = n.toElement();
00726 if ( e.tagName().lower() == "mo" ) {
00727
00728 QString form = e.attribute( "form" );
00729 QString f;
00730 if ( ! form.isNull() ) {
00731 f = form.stripWhiteSpace().lower();
00732 }
00733 QString fence = e.attribute( "fence" );
00734 if ( ! fence.isNull() ) {
00735 if ( fence.stripWhiteSpace().lower() == "false" ) {
00736 continue;
00737 }
00738 if ( ! f.isNull() ) {
00739 if ( f == "postfix" ) {
00740 return i;
00741 }
00742 else {
00743 continue;
00744 }
00745 }
00746 }
00747
00748
00749 QDomNode child = e.firstChild();
00750 QString name;
00751 if ( child.isText() )
00752 name = child.toText().data().stripWhiteSpace();
00753 else if ( child.isEntityReference() )
00754 name = child.nodeName();
00755 else
00756 continue;
00757 if ( name == ")"
00758 || name == "]"
00759 || name == "}"
00760 || name == "CloseCurlyDoubleQuote"
00761 || name == "CloseCurlyQuote"
00762 || name == "RightAngleBracket"
00763 || name == "RightCeiling"
00764 || name == "RightDoubleBracket"
00765 || name == "RightFloor" ) {
00766 if ( f.isNull() || f == "postfix" )
00767 return i;
00768 }
00769 if ( name == "("
00770 || name == "["
00771 || name == "{"
00772 || name == "LeftAngleBracket"
00773 || name == "LeftCeiling"
00774 || name == "LeftDoubleBracket"
00775 || name == "LeftFloor"
00776 || name == "OpenCurlyQuote" ) {
00777 if ( ! f.isNull() && f == "postfix" )
00778 return i;
00779 }
00780 }
00781 }
00782 }
00783 return -1;
00784 }
00785
00786
00787 void BracketElement::writeMathMLAttributes( QDomElement& element ) const
00788 {
00789 if ( left->getType() != LeftRoundBracket ||
00790 right->getType() != RightRoundBracket )
00791 {
00792 element.setAttribute( "open", QString( QChar( leftType ) ) );
00793 element.setAttribute( "close", QString( QChar( rightType ) ) );
00794 }
00795 if ( ! m_separators.isNull() ) {
00796 element.setAttribute( "separators", m_separators );
00797 }
00798 }
00799
00800 OverlineElement::OverlineElement( BasicElement* parent )
00801 : SingleContentElement( parent )
00802 {
00803 }
00804
00805 OverlineElement::~OverlineElement()
00806 {
00807 }
00808
00809 OverlineElement::OverlineElement( const OverlineElement& other )
00810 : SingleContentElement( other )
00811 {
00812 }
00813
00814
00815 bool OverlineElement::accept( ElementVisitor* visitor )
00816 {
00817 return visitor->visit( this );
00818 }
00819
00820
00821 void OverlineElement::entered( SequenceElement* )
00822 {
00823 formula()->tell( i18n( "Overline" ) );
00824 }
00825
00826
00827 void OverlineElement::calcSizes( const ContextStyle& context,
00828 ContextStyle::TextStyle tstyle,
00829 ContextStyle::IndexStyle istyle,
00830 StyleAttributes& style )
00831 {
00832 SequenceElement* content = getContent();
00833 content->calcSizes(context, tstyle,
00834 context.convertIndexStyleLower(istyle), style );
00835
00836
00837 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, style.sizeFactor() ) );
00838
00839
00840 setWidth( content->getWidth() );
00841 setHeight( content->getHeight() + distY );
00842
00843 content->setX( 0 );
00844 content->setY( distY );
00845 setBaseline(content->getBaseline() + content->getY());
00846 }
00847
00848 void OverlineElement::draw( QPainter& painter, const LuPixelRect& r,
00849 const ContextStyle& context,
00850 ContextStyle::TextStyle tstyle,
00851 ContextStyle::IndexStyle istyle,
00852 StyleAttributes& style,
00853 const LuPixelPoint& parentOrigin )
00854 {
00855 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00856
00857
00858
00859 SequenceElement* content = getContent();
00860 content->draw( painter, r, context, tstyle,
00861 context.convertIndexStyleLower( istyle ), style, myPos );
00862
00863 luPixel x = myPos.x();
00864 luPixel y = myPos.y();
00865
00866 double factor = style.sizeFactor();
00867 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) );
00868
00869
00870 painter.setPen( QPen( context.getDefaultColor(),
00871 context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) );
00872
00873 painter.drawLine( context.layoutUnitToPixelX( x ),
00874 context.layoutUnitToPixelY( y+distY/3 ),
00875 context.layoutUnitToPixelX( x+content->getWidth() ),
00876 context.layoutUnitToPixelY( y+distY/3 ) );
00877 }
00878
00879
00880 QString OverlineElement::toLatex()
00881 {
00882 return "\\overline{" + getContent()->toLatex() + "}";
00883 }
00884
00885 QString OverlineElement::formulaString()
00886 {
00887 return getContent()->formulaString();
00888 }
00889
00890 void OverlineElement::writeMathML( QDomDocument& doc, QDomNode& parent, bool oasisFormat ) const
00891 {
00892 QDomElement de = doc.createElement( oasisFormat ? "math:mover" : "mover" );
00893 SingleContentElement::writeMathML( doc, de, oasisFormat );
00894 QDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" );
00895
00896 op.appendChild( doc.createEntityReference( "OverBar" ) );
00897 de.appendChild( op );
00898 parent.appendChild( de );
00899 }
00900
00901
00902 UnderlineElement::UnderlineElement( BasicElement* parent )
00903 : SingleContentElement( parent )
00904 {
00905 }
00906
00907 UnderlineElement::~UnderlineElement()
00908 {
00909 }
00910
00911
00912 UnderlineElement::UnderlineElement( const UnderlineElement& other )
00913 : SingleContentElement( other )
00914 {
00915 }
00916
00917
00918 bool UnderlineElement::accept( ElementVisitor* visitor )
00919 {
00920 return visitor->visit( this );
00921 }
00922
00923
00924 void UnderlineElement::entered( SequenceElement* )
00925 {
00926 formula()->tell( i18n( "Underline" ) );
00927 }
00928
00929
00930 void UnderlineElement::calcSizes( const ContextStyle& context,
00931 ContextStyle::TextStyle tstyle,
00932 ContextStyle::IndexStyle istyle,
00933 StyleAttributes& style )
00934 {
00935 SequenceElement* content = getContent();
00936 double factor = style.sizeFactor();
00937 content->calcSizes(context, tstyle,
00938 context.convertIndexStyleLower(istyle), style );
00939
00940
00941 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) );
00942
00943
00944 setWidth( content->getWidth() );
00945 setHeight( content->getHeight() + distY );
00946
00947 content->setX( 0 );
00948 content->setY( 0 );
00949 setBaseline(content->getBaseline() + content->getY());
00950 }
00951
00952 void UnderlineElement::draw( QPainter& painter, const LuPixelRect& r,
00953 const ContextStyle& context,
00954 ContextStyle::TextStyle tstyle,
00955 ContextStyle::IndexStyle istyle,
00956 StyleAttributes& style,
00957 const LuPixelPoint& parentOrigin )
00958 {
00959 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00960
00961
00962
00963 SequenceElement* content = getContent();
00964 content->draw( painter, r, context, tstyle,
00965 context.convertIndexStyleLower( istyle ), style, myPos );
00966
00967 luPixel x = myPos.x();
00968 luPixel y = myPos.y();
00969
00970
00971
00972
00973 double factor = style.sizeFactor();
00974 painter.setPen( QPen( context.getDefaultColor(),
00975 context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) );
00976
00977 painter.drawLine( context.layoutUnitToPixelX( x ),
00978 context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ),
00979 context.layoutUnitToPixelX( x+content->getWidth() ),
00980 context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ) );
00981 }
00982
00983
00984 QString UnderlineElement::toLatex()
00985 {
00986 return "\\underline{" + getContent()->toLatex() + "}";
00987 }
00988
00989 QString UnderlineElement::formulaString()
00990 {
00991 return getContent()->formulaString();
00992 }
00993
00994 void UnderlineElement::writeMathML( QDomDocument& doc, QDomNode& parent, bool oasisFormat ) const
00995 {
00996 QDomElement de = doc.createElement( oasisFormat ? "math:munder" : "munder" );
00997 SingleContentElement::writeMathML( doc, de, oasisFormat );
00998 QDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" );
00999
01000 op.appendChild( doc.createEntityReference( "UnderBar" ) );
01001 de.appendChild( op );
01002 parent.appendChild( de );
01003 }
01004
01005 KFORMULA_NAMESPACE_END