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 if ( content->buildMathMLChild( node ) == -1 ) {
00201 kdWarning( DEBUGID) << "Empty content in SingleContentElement\n";
00202 return -1;
00203 }
00204
00205 return 1;
00206 }
00207
00208 void SingleContentElement::writeMathMLContent( QDomDocument& doc, QDomElement& element, bool oasisFormat ) const
00209 {
00210 content->writeMathML( doc, element, oasisFormat );
00211 }
00212
00213
00214
00215 BracketElement::BracketElement(SymbolType l, SymbolType r, BasicElement* parent)
00216 : SingleContentElement(parent),
00217 left( 0 ), right( 0 ),
00218 leftType( l ), rightType( r ),
00219 m_operator( false ), m_customLeft( false ), m_customRight( false )
00220 {
00221 }
00222
00223
00224 BracketElement::~BracketElement()
00225 {
00226 delete left;
00227 delete right;
00228 }
00229
00230
00231 BracketElement::BracketElement( const BracketElement& other )
00232 : SingleContentElement( other ),
00233 left( 0 ), right( 0 ),
00234 leftType( other.leftType ), rightType( other.rightType ),
00235 m_operator( other.m_operator ),
00236 m_customLeft( other.m_customLeft ), m_customRight( other.m_customRight )
00237 {
00238 }
00239
00240
00241 bool BracketElement::accept( ElementVisitor* visitor )
00242 {
00243 return visitor->visit( this );
00244 }
00245
00246
00247 void BracketElement::entered( SequenceElement* )
00248 {
00249 formula()->tell( i18n( "Delimited list" ) );
00250 }
00251
00252
00253 BasicElement* BracketElement::goToPos( FormulaCursor* cursor, bool& handled,
00254 const LuPixelPoint& point, const LuPixelPoint& parentOrigin )
00255 {
00256 BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin);
00257 if (e != 0) {
00258 LuPixelPoint myPos(parentOrigin.x() + getX(),
00259 parentOrigin.y() + getY());
00260 e = getContent()->goToPos(cursor, handled, point, myPos);
00261 if (e != 0) {
00262 return e;
00263 }
00264
00265
00266 luPixel dx = point.x() - myPos.x();
00267 luPixel dy = point.y() - myPos.y();
00268
00269 if ((dx > getContent()->getX()+getContent()->getWidth()) ||
00270 (dy > getContent()->getY()+getContent()->getHeight())) {
00271 getContent()->moveEnd(cursor);
00272 handled = true;
00273 return getContent();
00274 }
00275 return this;
00276 }
00277 return 0;
00278 }
00279
00280
00285 void BracketElement::calcSizes( const ContextStyle& context,
00286 ContextStyle::TextStyle tstyle,
00287 ContextStyle::IndexStyle istyle,
00288 StyleAttributes& style )
00289 {
00290 SequenceElement* content = getContent();
00291 content->calcSizes( context, tstyle, istyle, style );
00292
00293
00294 delete left;
00295 delete right;
00296 left = context.fontStyle().createArtwork( leftType );
00297 right = context.fontStyle().createArtwork( rightType );
00298
00299
00300 double factor = style.sizeFactor();
00301 if (content->isTextOnly()) {
00302 left->calcSizes(context, tstyle, factor);
00303 right->calcSizes(context, tstyle, factor);
00304
00305 setBaseline(QMAX(content->getBaseline(),
00306 QMAX(left->getBaseline(), right->getBaseline())));
00307
00308 content->setY(getBaseline() - content->getBaseline());
00309 left ->setY(getBaseline() - left ->getBaseline());
00310 right ->setY(getBaseline() - right ->getBaseline());
00311
00312
00313 setHeight(QMAX(content->getY() + content->getHeight(),
00314 QMAX(left ->getY() + left ->getHeight(),
00315 right->getY() + right->getHeight())));
00316 }
00317 else {
00318
00319 luPixel contentHeight = 2 * QMAX( content->axis( context, tstyle, factor ),
00320 content->getHeight() - content->axis( context, tstyle, factor ) );
00321 left->calcSizes( context, tstyle, factor, contentHeight );
00322 right->calcSizes( context, tstyle, factor, contentHeight );
00323
00324
00325 setHeight(QMAX(contentHeight,
00326 QMAX(left->getHeight(), right->getHeight())));
00327
00328
00329 content->setY(getHeight() / 2 - content->axis( context, tstyle, factor ));
00330 setBaseline(content->getBaseline() + content->getY());
00331
00332 if ( left->isNormalChar() ) {
00333 left->setY(getBaseline() - left->getBaseline());
00334 }
00335 else {
00336 left->setY((getHeight() - left->getHeight())/2);
00337 }
00338 if ( right->isNormalChar() ) {
00339 right->setY(getBaseline() - right->getBaseline());
00340 }
00341 else {
00342 right->setY((getHeight() - right->getHeight())/2);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352 }
00353
00354
00355 setWidth(left->getWidth() + content->getWidth() + right->getWidth());
00356 content->setX(left->getWidth());
00357 right ->setX(left->getWidth()+content->getWidth());
00358 }
00359
00360
00366 void BracketElement::draw( QPainter& painter, const LuPixelRect& r,
00367 const ContextStyle& context,
00368 ContextStyle::TextStyle tstyle,
00369 ContextStyle::IndexStyle istyle,
00370 StyleAttributes& style,
00371 const LuPixelPoint& parentOrigin )
00372 {
00373 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00374
00375
00376
00377 SequenceElement* content = getContent();
00378 content->draw(painter, r, context, tstyle, istyle, style, myPos);
00379
00380 if (content->isTextOnly()) {
00381 left->draw(painter, r, context, tstyle, style, myPos);
00382 right->draw(painter, r, context, tstyle, style, myPos);
00383 }
00384 else {
00385 double factor = style.sizeFactor();
00386 luPixel contentHeight = 2 * QMAX(content->axis( context, tstyle, factor ),
00387 content->getHeight() - content->axis( context, tstyle, factor ));
00388 left->draw(painter, r, context, tstyle, style, contentHeight, myPos);
00389 right->draw(painter, r, context, tstyle, style, contentHeight, myPos);
00390 }
00391
00392
00393 #if 0
00394 painter.setBrush( Qt::NoBrush );
00395 painter.setPen( Qt::red );
00396 painter.drawRect( context.layoutUnitToPixelX( myPos.x()+left->getX() ),
00397 context.layoutUnitToPixelY( myPos.y()+left->getY() ),
00398 context.layoutUnitToPixelX( left->getWidth() ),
00399 context.layoutUnitToPixelY( left->getHeight() ) );
00400 painter.drawRect( context.layoutUnitToPixelX( myPos.x()+right->getX() ),
00401 context.layoutUnitToPixelY( myPos.y()+right->getY() ),
00402 context.layoutUnitToPixelX( right->getWidth() ),
00403 context.layoutUnitToPixelY( right->getHeight() ) );
00404 #endif
00405 }
00406
00407
00411 void BracketElement::writeDom(QDomElement element)
00412 {
00413 SingleContentElement::writeDom(element);
00414 element.setAttribute("LEFT", leftType);
00415 element.setAttribute("RIGHT", rightType);
00416 }
00417
00422 bool BracketElement::readAttributesFromDom(QDomElement element)
00423 {
00424 if (!BasicElement::readAttributesFromDom(element)) {
00425 return false;
00426 }
00427 QString leftStr = element.attribute("LEFT");
00428 if(!leftStr.isNull()) {
00429 leftType = static_cast<SymbolType>(leftStr.toInt());
00430 }
00431 QString rightStr = element.attribute("RIGHT");
00432 if(!rightStr.isNull()) {
00433 rightType = static_cast<SymbolType>(rightStr.toInt());
00434 }
00435 return true;
00436 }
00437
00442 bool BracketElement::readAttributesFromMathMLDom(const QDomElement& element)
00443 {
00444 if ( !BasicElement::readAttributesFromMathMLDom( element ) ) {
00445 return false;
00446 }
00447
00448 if ( element.tagName().lower() == "mo" ) {
00449 m_operator = true;
00450
00451 }
00452 else {
00453 leftType = LeftRoundBracket;
00454 rightType = RightRoundBracket;
00455 QString openStr = element.attribute( "open" ).stripWhiteSpace();
00456 if ( !openStr.isNull() ) {
00457 m_customLeft = true;
00458 if ( openStr == "[" )
00459 leftType = LeftSquareBracket;
00460 else if ( openStr == "]" )
00461 leftType = RightSquareBracket;
00462 else if ( openStr == "{" )
00463 leftType = LeftCurlyBracket;
00464 else if ( openStr == "}" )
00465 leftType = RightCurlyBracket;
00466 else if ( openStr == "<" )
00467 leftType = LeftCornerBracket;
00468 else if ( openStr == ">" )
00469 leftType = RightCornerBracket;
00470 else if ( openStr == "(" )
00471 leftType = LeftRoundBracket;
00472 else if ( openStr == ")" )
00473 leftType = RightRoundBracket;
00474 else if ( openStr == "/" )
00475 leftType = SlashBracket;
00476 else if ( openStr == "\\" )
00477 leftType = BackSlashBracket;
00478 else
00479 leftType = LeftRoundBracket;
00480 }
00481 QString closeStr = element.attribute( "close" ).stripWhiteSpace();
00482 if ( !closeStr.isNull() ) {
00483 m_customRight = true;
00484 if ( closeStr == "[" )
00485 rightType = LeftSquareBracket;
00486 else if ( closeStr == "]" )
00487 rightType = RightSquareBracket;
00488 else if ( closeStr == "{" )
00489 rightType = LeftCurlyBracket;
00490 else if ( closeStr == "}" )
00491 rightType = RightCurlyBracket;
00492 else if ( closeStr == "<" )
00493 rightType = LeftCornerBracket;
00494 else if ( closeStr == ">" )
00495 rightType = RightCornerBracket;
00496 else if ( closeStr == "(" )
00497 rightType = LeftRoundBracket;
00498 else if ( closeStr == ")" )
00499 rightType = RightRoundBracket;
00500 else if ( closeStr == "/" )
00501 rightType = SlashBracket;
00502 else if ( closeStr == "\\" )
00503 rightType = BackSlashBracket;
00504 else
00505 rightType = LeftRoundBracket;
00506 }
00507 m_separators = element.attribute( "separators" ).simplifyWhiteSpace();
00508 }
00509 return true;
00510 }
00511
00517 int BracketElement::readContentFromMathMLDom(QDomNode& node)
00518 {
00519 bool empty = false;
00520 if ( m_operator ) {
00521 node = node.parentNode();
00522 QDomNode open = node;
00523 QDomNode parent = node.parentNode();
00524 if ( ! operatorType( node, true ) )
00525 return -1;
00526 int nodeNum = searchOperator( node );
00527 if ( nodeNum == -1 )
00528 return -1;
00529 if ( nodeNum == 0 ) {
00530 empty = true;
00531 }
00532 if ( nodeNum > 1 ) {
00533 kdWarning() << "NodeNum: " << nodeNum << endl;
00534 QDomDocument doc = node.ownerDocument();
00535 QDomElement de = doc.createElement( "mrow" );
00536 int i = 0;
00537 do {
00538 QDomNode n = node.nextSibling();
00539 de.appendChild( node.toElement() );
00540 node = n;
00541 } while ( ++i < nodeNum );
00542 parent.insertAfter( de, open );
00543 node = de;
00544 kdWarning() << doc.toString() << endl;
00545 }
00546 }
00547 else {
00548
00549
00550 while ( ! node.isNull() && ! node.isElement() )
00551 node = node.nextSibling();
00552 QDomNode next = node.nextSibling();
00553 while ( ! next.isNull() && ! next.isElement() )
00554 next = next.nextSibling();
00555 if ( ! next.isNull()) {
00556 QDomDocument doc = node.ownerDocument();
00557 QDomNode parent = node.parentNode();
00558 QString ns = parent.prefix();
00559 QDomElement de = doc.createElementNS( ns, "mrow" );
00560 uint pos = 0;
00561 while ( ! node.isNull() ) {
00562 QDomNode no = node.nextSibling();
00563 while ( ! no.isNull() && ! no.isElement() )
00564 no = no.nextSibling();
00565 de.appendChild( node.toElement() );
00566 if ( ! no.isNull() && ( m_separators.isNull() || ! m_separators.isEmpty() ) ) {
00567 QDomElement sep = doc.createElementNS( ns, "mo" );
00568 de.appendChild( sep );
00569 if ( m_separators.isNull() ) {
00570 sep.appendChild( doc.createTextNode( "," ) );
00571 }
00572 else {
00573 if ( m_separators.at( pos ).isSpace() ) {
00574 pos++;
00575 }
00576 sep.appendChild( doc.createTextNode( QString ( m_separators.at( pos ) ) ) );
00577 }
00578 if ( pos < m_separators.length() - 1 ) {
00579 pos++;
00580 }
00581 }
00582 node = no;
00583 }
00584 parent.appendChild( de );
00585 node = parent.firstChild();
00586 while ( ! node.isElement() )
00587 node = node.nextSibling();
00588 }
00589 }
00590 if ( ! empty ) {
00591 inherited::readContentFromMathMLDom( node );
00592 }
00593 if ( m_operator ) {
00594 if ( ! operatorType( node, false ) ) {
00595 return -1;
00596 }
00597 if ( empty )
00598 return 2;
00599 return 3;
00600 }
00601 return 1;
00602 }
00603
00604 QString BracketElement::toLatex()
00605 {
00606 QString ls,rs,cs;
00607 cs=getContent()->toLatex();
00608 ls="\\left"+latexString(leftType) + " ";
00609 rs=" \\right"+latexString(rightType);
00610
00611 return ls+cs+rs;
00612 }
00613
00614 QString BracketElement::latexString(char type)
00615 {
00616 switch (type) {
00617 case ']':
00618 return "]";
00619 case '[':
00620 return "[";
00621 case '{':
00622 return "\\{";
00623 case '}':
00624 return "\\}";
00625 case '(':
00626 return "(";
00627 case ')':
00628 return ")";
00629 case '|':
00630 return "|";
00631 case '<':
00632 return "\\langle";
00633 case '>':
00634 return "\\rangle";
00635 case '/':
00636 return "/";
00637 case '\\':
00638 return "\\backslash";
00639 }
00640 return ".";
00641 }
00642
00643 QString BracketElement::formulaString()
00644 {
00645 return "(" + getContent()->formulaString() + ")";
00646 }
00647
00648 bool BracketElement::operatorType( QDomNode& node, bool open )
00649 {
00650 SymbolType* type = open ? &leftType : &rightType;
00651 if ( node.isElement() ) {
00652 QDomElement e = node.toElement();
00653 QString s = e.text();
00654 if ( s.isNull() )
00655 return false;
00656 *type = static_cast<SymbolType>( QString::number( s.at( 0 ).latin1() ).toInt() );
00657 node = node.nextSibling();
00658 }
00659 else if ( node.isEntityReference() ) {
00660 QString name = node.nodeName();
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 if ( name == "LeftAngleBracket" ) {
00674 *type = LeftCornerBracket;
00675 }
00676 else if ( name == "RightAngleBracket" ) {
00677 *type = RightCornerBracket;
00678 }
00679 else {
00680 if ( open ) {
00681 *type = LeftRoundBracket;
00682 }
00683 else
00684 *type = RightRoundBracket;
00685 }
00686 node = node.nextSibling();
00687 }
00688 else {
00689 return false;
00690 }
00691 return true;
00692 }
00693
00694 int BracketElement::searchOperator( const QDomNode& node )
00695 {
00696 QDomNode n = node;
00697 for ( int i = 0; ! n.isNull(); n = n.nextSibling(), i++ ) {
00698 if ( n.isElement() ) {
00699 QDomElement e = n.toElement();
00700 if ( e.tagName().lower() == "mo" ) {
00701
00702 QString form = e.attribute( "form" );
00703 QString f;
00704 if ( ! form.isNull() ) {
00705 f = form.stripWhiteSpace().lower();
00706 }
00707 QString fence = e.attribute( "fence" );
00708 if ( ! fence.isNull() ) {
00709 if ( fence.stripWhiteSpace().lower() == "false" ) {
00710 continue;
00711 }
00712 if ( ! f.isNull() ) {
00713 if ( f == "postfix" ) {
00714 return i;
00715 }
00716 else {
00717 continue;
00718 }
00719 }
00720 }
00721
00722
00723 QDomNode child = e.firstChild();
00724 QString name;
00725 if ( child.isText() )
00726 name = child.toText().data().stripWhiteSpace();
00727 else if ( child.isEntityReference() )
00728 name = child.nodeName();
00729 else
00730 continue;
00731 if ( name == ")"
00732 || name == "]"
00733 || name == "}"
00734 || name == "CloseCurlyDoubleQuote"
00735 || name == "CloseCurlyQuote"
00736 || name == "RightAngleBracket"
00737 || name == "RightCeiling"
00738 || name == "RightDoubleBracket"
00739 || name == "RightFloor" ) {
00740 if ( f.isNull() || f == "postfix" )
00741 return i;
00742 }
00743 if ( name == "("
00744 || name == "["
00745 || name == "{"
00746 || name == "LeftAngleBracket"
00747 || name == "LeftCeiling"
00748 || name == "LeftDoubleBracket"
00749 || name == "LeftFloor"
00750 || name == "OpenCurlyQuote" ) {
00751 if ( ! f.isNull() && f == "postfix" )
00752 return i;
00753 }
00754 }
00755 }
00756 }
00757 return -1;
00758 }
00759
00760
00761 void BracketElement::writeMathMLAttributes( QDomElement& element ) const
00762 {
00763 if ( left->getType() != LeftRoundBracket ||
00764 right->getType() != RightRoundBracket )
00765 {
00766 element.setAttribute( "open", QString( QChar( leftType ) ) );
00767 element.setAttribute( "close", QString( QChar( rightType ) ) );
00768 }
00769 if ( ! m_separators.isNull() ) {
00770 element.setAttribute( "separators", m_separators );
00771 }
00772 }
00773
00774 OverlineElement::OverlineElement( BasicElement* parent )
00775 : SingleContentElement( parent )
00776 {
00777 }
00778
00779 OverlineElement::~OverlineElement()
00780 {
00781 }
00782
00783 OverlineElement::OverlineElement( const OverlineElement& other )
00784 : SingleContentElement( other )
00785 {
00786 }
00787
00788
00789 bool OverlineElement::accept( ElementVisitor* visitor )
00790 {
00791 return visitor->visit( this );
00792 }
00793
00794
00795 void OverlineElement::entered( SequenceElement* )
00796 {
00797 formula()->tell( i18n( "Overline" ) );
00798 }
00799
00800
00801 void OverlineElement::calcSizes( const ContextStyle& context,
00802 ContextStyle::TextStyle tstyle,
00803 ContextStyle::IndexStyle istyle,
00804 StyleAttributes& style )
00805 {
00806 SequenceElement* content = getContent();
00807 content->calcSizes(context, tstyle,
00808 context.convertIndexStyleLower(istyle), style );
00809
00810
00811 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, style.sizeFactor() ) );
00812
00813
00814 setWidth( content->getWidth() );
00815 setHeight( content->getHeight() + distY );
00816
00817 content->setX( 0 );
00818 content->setY( distY );
00819 setBaseline(content->getBaseline() + content->getY());
00820 }
00821
00822 void OverlineElement::draw( QPainter& painter, const LuPixelRect& r,
00823 const ContextStyle& context,
00824 ContextStyle::TextStyle tstyle,
00825 ContextStyle::IndexStyle istyle,
00826 StyleAttributes& style,
00827 const LuPixelPoint& parentOrigin )
00828 {
00829 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00830
00831
00832
00833 SequenceElement* content = getContent();
00834 content->draw( painter, r, context, tstyle,
00835 context.convertIndexStyleLower( istyle ), style, myPos );
00836
00837 luPixel x = myPos.x();
00838 luPixel y = myPos.y();
00839
00840 double factor = style.sizeFactor();
00841 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) );
00842
00843
00844 painter.setPen( QPen( context.getDefaultColor(),
00845 context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) );
00846
00847 painter.drawLine( context.layoutUnitToPixelX( x ),
00848 context.layoutUnitToPixelY( y+distY/3 ),
00849 context.layoutUnitToPixelX( x+content->getWidth() ),
00850 context.layoutUnitToPixelY( y+distY/3 ) );
00851 }
00852
00853
00854 QString OverlineElement::toLatex()
00855 {
00856 return "\\overline{" + getContent()->toLatex() + "}";
00857 }
00858
00859 QString OverlineElement::formulaString()
00860 {
00861 return getContent()->formulaString();
00862 }
00863
00864 void OverlineElement::writeMathML( QDomDocument& doc, QDomNode& parent, bool oasisFormat ) const
00865 {
00866 QDomElement de = doc.createElement( oasisFormat ? "math:mover" : "mover" );
00867 SingleContentElement::writeMathML( doc, de, oasisFormat );
00868 QDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" );
00869
00870 op.appendChild( doc.createEntityReference( "OverBar" ) );
00871 de.appendChild( op );
00872 parent.appendChild( de );
00873 }
00874
00875
00876 UnderlineElement::UnderlineElement( BasicElement* parent )
00877 : SingleContentElement( parent )
00878 {
00879 }
00880
00881 UnderlineElement::~UnderlineElement()
00882 {
00883 }
00884
00885
00886 UnderlineElement::UnderlineElement( const UnderlineElement& other )
00887 : SingleContentElement( other )
00888 {
00889 }
00890
00891
00892 bool UnderlineElement::accept( ElementVisitor* visitor )
00893 {
00894 return visitor->visit( this );
00895 }
00896
00897
00898 void UnderlineElement::entered( SequenceElement* )
00899 {
00900 formula()->tell( i18n( "Underline" ) );
00901 }
00902
00903
00904 void UnderlineElement::calcSizes( const ContextStyle& context,
00905 ContextStyle::TextStyle tstyle,
00906 ContextStyle::IndexStyle istyle,
00907 StyleAttributes& style )
00908 {
00909 SequenceElement* content = getContent();
00910 double factor = style.sizeFactor();
00911 content->calcSizes(context, tstyle,
00912 context.convertIndexStyleLower(istyle), style );
00913
00914
00915 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) );
00916
00917
00918 setWidth( content->getWidth() );
00919 setHeight( content->getHeight() + distY );
00920
00921 content->setX( 0 );
00922 content->setY( 0 );
00923 setBaseline(content->getBaseline() + content->getY());
00924 }
00925
00926 void UnderlineElement::draw( QPainter& painter, const LuPixelRect& r,
00927 const ContextStyle& context,
00928 ContextStyle::TextStyle tstyle,
00929 ContextStyle::IndexStyle istyle,
00930 StyleAttributes& style,
00931 const LuPixelPoint& parentOrigin )
00932 {
00933 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00934
00935
00936
00937 SequenceElement* content = getContent();
00938 content->draw( painter, r, context, tstyle,
00939 context.convertIndexStyleLower( istyle ), style, myPos );
00940
00941 luPixel x = myPos.x();
00942 luPixel y = myPos.y();
00943
00944
00945
00946
00947 double factor = style.sizeFactor();
00948 painter.setPen( QPen( context.getDefaultColor(),
00949 context.layoutUnitToPixelY( context.getLineWidth( factor ) ) ) );
00950
00951 painter.drawLine( context.layoutUnitToPixelX( x ),
00952 context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ),
00953 context.layoutUnitToPixelX( x+content->getWidth() ),
00954 context.layoutUnitToPixelY( y+getHeight()-context.getLineWidth( factor ) ) );
00955 }
00956
00957
00958 QString UnderlineElement::toLatex()
00959 {
00960 return "\\underline{" + getContent()->toLatex() + "}";
00961 }
00962
00963 QString UnderlineElement::formulaString()
00964 {
00965 return getContent()->formulaString();
00966 }
00967
00968 void UnderlineElement::writeMathML( QDomDocument& doc, QDomNode& parent, bool oasisFormat ) const
00969 {
00970 QDomElement de = doc.createElement( oasisFormat ? "math:munder" : "munder" );
00971 SingleContentElement::writeMathML( doc, de, oasisFormat );
00972 QDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" );
00973
00974 op.appendChild( doc.createEntityReference( "UnderBar" ) );
00975 de.appendChild( op );
00976 parent.appendChild( de );
00977 }
00978
00979 KFORMULA_NAMESPACE_END