25#include "elementvisitor.h"
26#include "formulacursor.h"
27#include "formulaelement.h"
28#include "kformulacommand.h"
29#include "sequenceelement.h"
30#include "symbolelement.h"
32KFORMULA_NAMESPACE_BEGIN
36 typedef SequenceElement inherited;
39 SymbolSequenceElement( BasicElement* parent = 0 ) : SequenceElement( parent ) {}
49 virtual KCommand* buildCommand( Container*, Request* );
53KCommand* SymbolSequenceElement::buildCommand(
Container* container, Request* request )
64 ( cursor->getPos() > 0 && cursor->getPos() <
countChildren() ) ) {
67 IndexRequest* ir =
static_cast<IndexRequest*
>( request );
68 if ( ( ir->index() == upperMiddlePos ) || ( ir->index() == lowerMiddlePos ) ) {
69 SymbolElement* element =
static_cast<SymbolElement*
>( getParent() );
70 ElementIndexPtr index = element->
getIndex( ir->index() );
71 if ( !index->hasIndex() ) {
72 KFCAddGenericIndex* command =
new KFCAddGenericIndex( container, index );
76 index->moveToIndex( cursor, afterCursor );
90SymbolElement::SymbolElement(SymbolType type,
BasicElement* parent)
93 content =
new SymbolSequenceElement(
this );
98SymbolElement::~SymbolElement()
108 :
BasicElement( other ), symbol( 0 ), symbolType( other.symbolType )
110 content =
new SymbolSequenceElement( *
dynamic_cast<SymbolSequenceElement*
>( other.content ) );
111 content->setParent(
this );
115 upper->setParent(
this );
122 lower->setParent(
this );
132 return visitor->visit(
this );
137 const LuPixelPoint& point,
const LuPixelPoint& parentOrigin )
141 LuPixelPoint myPos(parentOrigin.x() + getX(),
142 parentOrigin.y() + getY());
144 e = content->
goToPos(cursor, handled, point, myPos);
149 e = lower->
goToPos(cursor, handled, point, myPos);
155 e = upper->
goToPos(cursor, handled, point, myPos);
162 luPixel dx = point.x() - myPos.x();
163 luPixel dy = point.y() - myPos.y();
164 if (dy < symbol->getY()) {
165 if (
hasUpper() && (dx > upper->getX())) {
166 upper->moveLeft(cursor,
this);
171 else if (dy > symbol->getY()+symbol->getHeight()) {
172 if (hasLower() && (dx > lower->getX())) {
173 lower->moveLeft(cursor,
this);
180 if ( ( dx < symbol->getX()+symbol->getWidth() ) &&
181 ( dx > symbol->getX()+symbol->getWidth()/2 ) ) {
182 content->moveRight( cursor,
this );
199 ContextStyle::IndexStyle istyle,
200 StyleAttributes& style )
202 double factor = style.sizeFactor();
203 luPt mySize = context.getAdjustedSize( tstyle, factor );
204 luPixel distX = context.ptToPixelX( context.getThinSpace( tstyle, factor ) );
205 luPixel distY = context.ptToPixelY( context.getThinSpace( tstyle, factor ) );
209 symbol = context.fontStyle().createArtwork( symbolType );
212 symbol->calcSizes(context, tstyle, factor, mySize);
213 content->calcSizes( context, tstyle, istyle, style );
217 luPixel upperWidth = 0;
218 luPixel upperHeight = 0;
220 upper->calcSizes( context, context.convertTextStyleIndex( tstyle ),
221 context.convertIndexStyleUpper( istyle ), style );
222 upperWidth = upper->getWidth();
223 upperHeight = upper->getHeight() + distY;
226 luPixel lowerWidth = 0;
227 luPixel lowerHeight = 0;
229 lower->calcSizes( context, context.convertTextStyleIndex( tstyle ),
230 context.convertIndexStyleLower( istyle ), style );
231 lowerWidth = lower->getWidth();
232 lowerHeight = lower->getHeight() + distY;
236 luPixel xOffset = TQMAX(symbol->getWidth(), TQMAX(upperWidth, lowerWidth));
237 if (context.getCenterSymbol()) {
238 symbol->setX((xOffset - symbol->getWidth()) / 2);
241 symbol->setX(xOffset - symbol->getWidth());
244 content->setX(xOffset +
245 static_cast<luPixel
>( symbol->slant()*symbol->getHeight()/2 ) +
248 setWidth(TQMAX(content->getX() + content->getWidth(),
249 TQMAX(upperWidth, lowerWidth)));
253 luPixel toMidline = TQMAX(content->axis( context, tstyle, factor ),
254 upperHeight + symbol->getHeight()/2);
256 luPixel fromMidline = TQMAX(content->getHeight() - content->axis( context, tstyle, factor ),
257 lowerHeight + symbol->getHeight()/2);
258 setHeight(toMidline + fromMidline);
261 symbol->setY(toMidline - symbol->getHeight()/2);
263 content->setY(toMidline - content->axis( context, tstyle, factor ));
267 static_cast<luPixel
>( symbol->slant()*( symbol->getHeight()+distY ) );
268 if (context.getCenterSymbol()) {
269 upper->setX((xOffset - upperWidth) / 2 + slant );
272 if (upperWidth < symbol->getWidth()) {
273 upper->setX(symbol->getX() +
274 (symbol->getWidth() - upperWidth) / 2 + slant );
277 upper->setX(xOffset - upperWidth);
280 upper->setY(toMidline - upperHeight - symbol->getHeight()/2);
283 luPixel slant =
static_cast<luPixel
>( -symbol->slant()*distY );
284 if (context.getCenterSymbol()) {
285 lower->setX((xOffset - lowerWidth) / 2 + slant);
288 if (lowerWidth < symbol->getWidth()) {
289 lower->setX(symbol->getX() +
290 (symbol->getWidth() - lowerWidth) / 2 + slant );
293 lower->setX(xOffset - lowerWidth);
296 lower->setY(toMidline + symbol->getHeight()/2 + distY);
298 setBaseline(content->getBaseline() + content->getY());
306void SymbolElement::draw( TQPainter& painter,
const LuPixelRect& r,
309 ContextStyle::IndexStyle istyle,
310 StyleAttributes& style,
311 const LuPixelPoint& parentOrigin )
313 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
317 luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() );
318 symbol->draw( painter, r, context, tstyle, style, mySize, myPos );
319 content->draw( painter, r, context, tstyle, istyle, style, myPos );
321 upper->draw( painter, r, context, context.convertTextStyleIndex( tstyle ),
322 context.convertIndexStyleUpper( istyle ), style, myPos );
331 painter.setBrush(TQt::NoBrush);
332 painter.setPen(TQt::red);
338 context.layoutUnitToPixelY( myPos.y()+symbol->getY() ),
340 context.layoutUnitToPixelY( symbol->getHeight() ) );
341 painter.setPen(TQt::green);
343 context.layoutUnitToPixelY( myPos.y()+axis(context, tstyle) ),
345 context.layoutUnitToPixelY( myPos.y()+axis(context, tstyle) ) );
352 content->dispatchFontCommand( cmd );
354 upper->dispatchFontCommand( cmd );
357 lower->dispatchFontCommand( cmd );
377 getParent()->moveLeft(cursor,
this);
380 bool linear = cursor->getLinearMovement();
381 if (from == getParent()) {
382 content->moveLeft(cursor,
this);
384 else if (from == content) {
385 if (linear && hasLower()) {
386 lower->moveLeft(cursor,
this);
389 upper->moveLeft(cursor,
this);
392 getParent()->moveLeft(cursor,
this);
395 else if (from == lower) {
397 upper->moveLeft(cursor,
this);
400 getParent()->moveLeft(cursor,
this);
403 else if (from == upper) {
404 getParent()->moveLeft(cursor,
this);
417 getParent()->moveRight(cursor,
this);
420 bool linear = cursor->getLinearMovement();
421 if (from == getParent()) {
423 upper->moveRight(cursor,
this);
425 else if (linear && hasLower()) {
426 lower->moveRight(cursor,
this);
429 content->moveRight(cursor,
this);
432 else if (from == upper) {
433 if (linear && hasLower()) {
434 lower->moveRight(cursor,
this);
437 content->moveRight(cursor,
this);
440 else if (from == lower) {
441 content->moveRight(cursor,
this);
443 else if (from == content) {
444 getParent()->moveRight(cursor,
this);
457 getParent()->moveUp(cursor,
this);
460 if (from == content) {
462 upper->moveLeft(cursor,
this);
465 getParent()->moveUp(cursor,
this);
468 else if (from == upper) {
469 getParent()->moveUp(cursor,
this);
471 else if ((from == getParent()) || (from == lower)) {
472 content->moveRight(cursor,
this);
485 getParent()->moveDown(cursor,
this);
488 if (from == content) {
490 lower->moveLeft(cursor,
this);
493 getParent()->moveDown(cursor,
this);
496 else if (from == lower) {
497 getParent()->moveDown(cursor,
this);
499 else if ((from == getParent()) || (from == upper)) {
500 content->moveRight(cursor,
this);
531 TQPtrList<BasicElement>& newChildren,
534 SequenceElement* index =
static_cast<SequenceElement*
>(newChildren.take(0));
535 index->setParent(
this);
537 switch (cursor->getPos()) {
549 if (direction == beforeCursor) {
550 index->moveLeft(cursor,
this);
553 index->moveRight(cursor,
this);
571 TQPtrList<BasicElement>& removedChildren,
574 int pos = cursor->getPos();
577 removedChildren.append(upper);
583 removedChildren.append(lower);
589 BasicElement* parent = getParent();
590 parent->selectChild(cursor,
this);
591 parent->remove(cursor, removedChildren, direction);
604 if (direction == beforeCursor) {
605 content->moveLeft(cursor,
this);
608 content->moveRight(cursor,
this);
617 int pos = cursor->getPos();
635 if (child == content) {
636 setToContent(cursor);
638 else if (child == upper) {
641 else if (child == lower) {
648 cursor->
setTo(
this, upperMiddlePos);
653 cursor->
setTo(
this, lowerMiddlePos);
664 cursor->
setTo(
this, contentPos);
668void SymbolElement::moveToUpper(
FormulaCursor* cursor, Direction direction)
671 if (direction == beforeCursor) {
672 upper->moveLeft(cursor,
this);
675 upper->moveRight(cursor,
this);
680void SymbolElement::moveToLower(
FormulaCursor* cursor, Direction direction)
683 if (direction == beforeCursor) {
684 lower->moveLeft(cursor,
this);
687 lower->moveRight(cursor,
this);
695 switch ( position ) {
697 return getLowerIndex();
699 return getUpperIndex();
701 return getUpperIndex();
712 element.setAttribute(
"TYPE", symbolType);
714 TQDomDocument doc = element.ownerDocument();
716 TQDomElement con = doc.createElement(
"CONTENT");
717 con.appendChild(content->getElementDom(doc));
718 element.appendChild(con);
721 TQDomElement ind = doc.createElement(
"LOWER");
722 ind.appendChild(lower->getElementDom(doc));
723 element.appendChild(ind);
726 TQDomElement ind = doc.createElement(
"UPPER");
727 ind.appendChild(upper->getElementDom(doc));
728 element.appendChild(ind);
742 TQString typeStr = element.attribute(
"TYPE");
743 if(!typeStr.isNull()) {
744 symbolType =
static_cast<SymbolType
>(typeStr.toInt());
761 if ( !
buildChild( content, node,
"CONTENT" ) ) {
762 kdWarning( DEBUGID ) <<
"Empty content in SymbolElement." << endl;
765 node = node.nextSibling();
767 bool lowerRead =
false;
768 bool upperRead =
false;
770 while (!node.isNull() && !(upperRead && lowerRead)) {
772 if (!lowerRead && (node.nodeName().upper() ==
"LOWER")) {
773 lowerRead =
buildChild( lower=
new SequenceElement(
this ), node,
"LOWER" );
774 if ( !lowerRead )
return false;
777 if (!upperRead && (node.nodeName().upper() ==
"UPPER")) {
778 upperRead =
buildChild( upper=
new SequenceElement(
this ), node,
"UPPER" );
779 if ( !upperRead )
return false;
782 node = node.nextSibling();
811 sym+=lower->toLatex();
817 sym+=upper->toLatex();
823 sym+=content->toLatex();
829TQString SymbolElement::formulaString()
832 switch ( symbolType ) {
845 sym += content->formulaString();
847 sym +=
", " + lower->formulaString();
850 sym +=
", " + upper->formulaString();
857 TQDomElement de = doc.createElement( oasisFormat ?
"math:mrow" :
"mrow" );
858 TQDomElement mo = doc.createElement( oasisFormat ?
"math:mo" :
"mo" );
864 case EmptyBracket:
break;
865 case LeftLineBracket:
case RightLineBracket:
866 mo.appendChild( doc.createTextNode(
"|" ) );
break;
868 mo.appendChild( doc.createEntityReference(
"int" ) );
break;
870 mo.appendChild( doc.createEntityReference(
"sum" ) );
break;
872 mo.appendChild( doc.createEntityReference(
"prod" ) );
break;
874 mo.appendChild( doc.createTextNode( TQChar( symbolType ) ) );
877 TQDomElement between;
880 between = doc.createElement( oasisFormat ?
"math:msubsup" :
"msubsup" );
881 between.appendChild( mo );
882 lower->writeMathML( doc, between, oasisFormat );
883 upper->writeMathML( doc, between, oasisFormat );
887 between = doc.createElement( oasisFormat ?
"math:msup" :
"msup" );
888 between.appendChild( mo );
889 upper->writeMathML( doc, between, oasisFormat );
891 else if ( hasLower() )
893 between = doc.createElement( oasisFormat ?
"math:msub" :
"msub" );
894 between.appendChild( mo );
895 lower->writeMathML( doc, between, oasisFormat );
900 de.appendChild( between );
901 content->writeMathML( doc, de, oasisFormat );
903 parent.appendChild( de );
906KFORMULA_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 readContentFromDom(TQDomNode &node)
Reads our content from the node.
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.
FormulaCursor * activeCursor()
Contains all the style information for the formela.
TextStyle convertTextStyleIndex(TextStyle tstyle) const
Font-conversions a la TeX.
TextStyle
Textstyles like in TeX.
IndexStyle convertIndexStyleLower(IndexStyle) const
Index-style-conversions a la 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.
The element that contains a number of children.
uint countChildren() const
virtual KCommand * buildCommand(Container *, Request *)
This is called by the container to get a command depending on the current cursor position (this is ho...
A symbol is simply a piece of art.
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 calcSizes(const ContextStyle &cstyle, ContextStyle::TextStyle tstyle, ContextStyle::IndexStyle istyle, StyleAttributes &style)
Calculates our width and height and our children's parentPosition.
ElementIndexPtr getIndex(int position)
Returns the index at the position.
virtual BasicElement * getChild(FormulaCursor *, Direction=beforeCursor)
Returns the child at the cursor.
virtual bool readContentFromDom(TQDomNode &node)
Reads our content from the node.
virtual void selectChild(FormulaCursor *cursor, BasicElement *child)
Sets the cursor to select the child.
virtual void insert(FormulaCursor *, TQPtrList< BasicElement > &, Direction)
Inserts all new children at the cursor position.
virtual bool accept(ElementVisitor *visitor)
Visit this element.
virtual void normalize(FormulaCursor *, Direction)
Moves the cursor to a normal place where new elements might be inserted.
virtual void writeDom(TQDomElement element)
Appends our attributes to the dom element.
virtual TQString toLatex()
virtual bool readAttributesFromDom(TQDomElement element)
Reads our attributes from the element.
bool hasUpper() const
Moves the cursor away from the given child.
virtual void dispatchFontCommand(FontCommand *cmd)
Draws the whole element including its children.
virtual void remove(FormulaCursor *, TQPtrList< BasicElement > &, Direction)
Removes all selected children and returns them.
virtual void writeMathML(TQDomDocument &doc, TQDomNode &parent, bool oasisFormat=false) const
Same as above, just MathML.