00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022 #include <math.h>
00023
00024 #include <qpainter.h>
00025 #include <qpaintdevice.h>
00026 #include <qvaluestack.h>
00027
00028 #include <kcommand.h>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031
00032
00033
00034 #include "MatrixDialog.h"
00035 #include "bracketelement.h"
00036 #include "creationstrategy.h"
00037 #include "elementtype.h"
00038 #include "elementvisitor.h"
00039 #include "formulacursor.h"
00040 #include "formulaelement.h"
00041 #include "fractionelement.h"
00042 #include "indexelement.h"
00043 #include "kformulacommand.h"
00044 #include "kformulacontainer.h"
00045 #include "kformuladocument.h"
00046 #include "matrixelement.h"
00047 #include "rootelement.h"
00048 #include "sequenceelement.h"
00049 #include "sequenceparser.h"
00050 #include "spaceelement.h"
00051 #include "symbolelement.h"
00052 #include "symboltable.h"
00053 #include "textelement.h"
00054 #include "numberelement.h"
00055 #include "identifierelement.h"
00056 #include "operatorelement.h"
00057
00058 #include <assert.h>
00059
00060 KFORMULA_NAMESPACE_BEGIN
00061
00062
00063 ElementCreationStrategy* SequenceElement::creationStrategy = 0;
00064
00065 void SequenceElement::setCreationStrategy( ElementCreationStrategy* strategy )
00066 {
00067 creationStrategy = strategy;
00068 }
00069
00070 void SequenceElement::setStyle( StyleElement *st )
00071 {
00072 style = st;
00073 }
00074
00075 SequenceElement::SequenceElement(BasicElement* parent)
00076 : BasicElement(parent), parseTree(0), textSequence(true),singlePipe(true), style(0)
00077 {
00078 assert( creationStrategy != 0 );
00079 children.setAutoDelete(true);
00080 }
00081
00082
00083 SequenceElement::~SequenceElement()
00084 {
00085 delete parseTree;
00086 }
00087
00088 SequenceElement::SequenceElement( const SequenceElement& other )
00089 : BasicElement( other )
00090 {
00091 children.setAutoDelete(true);
00092 uint count = other.children.count();
00093 for (uint i = 0; i < count; i++) {
00094 BasicElement* child = children.at(i)->clone();
00095 child->setParent( this );
00096 children.append( child );
00097 }
00098 }
00099
00100
00101 bool SequenceElement::accept( ElementVisitor* visitor )
00102 {
00103 return visitor->visit( this );
00104 }
00105
00106
00107 bool SequenceElement::readOnly( const FormulaCursor* ) const
00108 {
00109 return getParent()->readOnly( this );
00110 }
00111
00112
00116 BasicElement* SequenceElement::goToPos( FormulaCursor* cursor, bool& handled,
00117 const LuPixelPoint& point, const LuPixelPoint& parentOrigin )
00118 {
00119 BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin);
00120 if (e != 0) {
00121 LuPixelPoint myPos(parentOrigin.x() + getX(),
00122 parentOrigin.y() + getY());
00123
00124 uint count = children.count();
00125 for (uint i = 0; i < count; i++) {
00126 BasicElement* child = children.at(i);
00127 e = child->goToPos(cursor, handled, point, myPos);
00128 if (e != 0) {
00129 if (!handled) {
00130 handled = true;
00131 if ((point.x() - myPos.x()) < (e->getX() + e->getWidth()*2/3)) {
00132 cursor->setTo(this, children.find(e));
00133 }
00134 else {
00135 cursor->setTo(this, children.find(e)+1);
00136 }
00137 }
00138 return e;
00139 }
00140 }
00141
00142 luPixel dx = point.x() - myPos.x();
00143
00144
00145 for (uint i = 0; i < count; i++) {
00146 BasicElement* child = children.at(i);
00147 if (dx < child->getX()) {
00148 cursor->setTo( this, i );
00149 handled = true;
00150 return children.at( i );
00151 }
00152 }
00153
00154 cursor->setTo(this, countChildren());
00155 handled = true;
00156 return this;
00157 }
00158 return 0;
00159 }
00160
00161
00162 bool SequenceElement::isEmpty()
00163 {
00164 uint count = children.count();
00165 for (uint i = 0; i < count; i++) {
00166 BasicElement* child = children.at(i);
00167 if (!child->isInvisible()) {
00168 return false;
00169 }
00170 }
00171 return true;
00172 }
00173
00174
00179 void SequenceElement::calcSizes( const ContextStyle& context,
00180 ContextStyle::TextStyle tstyle,
00181 ContextStyle::IndexStyle istyle,
00182 StyleAttributes& style )
00183 {
00184 double factor = style.sizeFactor();
00185 if (!isEmpty()) {
00186 luPixel width = 0;
00187 luPixel toBaseline = 0;
00188 luPixel fromBaseline = 0;
00189
00190 width += context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) );
00191
00192
00193 QPtrListIterator<BasicElement> it( children );
00194 for ( ; it.current(); ++it ) {
00195 BasicElement* child = it.current();
00196
00197 if ( !child->isInvisible() ) {
00198 child->calcSizes( context, tstyle, istyle, style );
00199 child->setX( width );
00200 width += child->getWidth();
00201
00202 luPixel childBaseline = child->getBaseline();
00203 if ( childBaseline > -1 ) {
00204 toBaseline = QMAX( toBaseline, childBaseline );
00205 fromBaseline = QMAX( fromBaseline,
00206 child->getHeight() - childBaseline );
00207 }
00208 else {
00209 luPixel bl = child->getHeight()/2 + context.axisHeight( tstyle, factor );
00210 toBaseline = QMAX( toBaseline, bl );
00211 fromBaseline = QMAX( fromBaseline, child->getHeight() - bl );
00212 }
00213 }
00214 else {
00215 child->setX( width );
00216 }
00217 }
00218
00219 width += context.ptToPixelX( getSpaceAfter( context, tstyle, factor ) );
00220
00221 setWidth(width);
00222 setHeight(toBaseline+fromBaseline);
00223 setBaseline(toBaseline);
00224
00225 setChildrenPositions();
00226 }
00227 else {
00228 luPixel w = context.getEmptyRectWidth( factor );
00229 luPixel h = context.getEmptyRectHeight( factor );
00230 setWidth( w );
00231 setHeight( h );
00232 setBaseline( h );
00233
00234 }
00235 }
00236
00237
00238 void SequenceElement::setChildrenPositions()
00239 {
00240 QPtrListIterator<BasicElement> it( children );
00241 for ( ; it.current(); ++it ) {
00242 BasicElement* child = it.current();
00243 child->setY(getBaseline() - child->getBaseline());
00244 }
00245 }
00246
00247
00253 void SequenceElement::draw( QPainter& painter, const LuPixelRect& r,
00254 const ContextStyle& context,
00255 ContextStyle::TextStyle tstyle,
00256 ContextStyle::IndexStyle istyle,
00257 StyleAttributes& style,
00258 const LuPixelPoint& parentOrigin )
00259 {
00260 LuPixelPoint myPos( parentOrigin.x() + getX(), parentOrigin.y() + getY() );
00261
00262
00263
00264
00265
00266 if (!isEmpty()) {
00267 QPtrListIterator<BasicElement> it( children );
00268 for (int i = 0 ; it.current(); i++) {
00269 BasicElement* child = it.current();
00270 if (!child->isInvisible()) {
00271 child->draw(painter, r, context, tstyle, istyle, style, myPos);
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 }
00285
00286 ++it;
00287
00288 }
00289 }
00290 else {
00291 drawEmptyRect( painter, context, style.sizeFactor(), myPos );
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 }
00307
00308
00309 void SequenceElement::dispatchFontCommand( FontCommand* cmd )
00310 {
00311 QPtrListIterator<BasicElement> it( children );
00312 for ( ; it.current(); ++it ) {
00313 BasicElement* child = it.current();
00314 child->dispatchFontCommand( cmd );
00315 }
00316 }
00317
00318
00319 void SequenceElement::drawEmptyRect( QPainter& painter, const ContextStyle& context,
00320 double factor, const LuPixelPoint& upperLeft )
00321 {
00322 if ( context.edit() ) {
00323 painter.setBrush(Qt::NoBrush);
00324 painter.setPen( QPen( context.getEmptyColor(),
00325 context.layoutUnitToPixelX( context.getLineWidth( factor ) ) ) );
00326 painter.drawRect( context.layoutUnitToPixelX( upperLeft.x() ),
00327 context.layoutUnitToPixelY( upperLeft.y() ),
00328 context.layoutUnitToPixelX( getWidth() ),
00329 context.layoutUnitToPixelY( getHeight() ) );
00330 }
00331 }
00332
00333 void SequenceElement::calcCursorSize( const ContextStyle& context,
00334 FormulaCursor* cursor, bool smallCursor )
00335 {
00336 LuPixelPoint point = widgetPos();
00337 uint pos = cursor->getPos();
00338
00339 luPixel posX = getChildPosition( context, pos );
00340 luPixel height = getHeight();
00341
00342 luPixel unitX = context.ptToLayoutUnitPixX( 1 );
00343 luPixel unitY = context.ptToLayoutUnitPixY( 1 );
00344
00345
00346
00347 if ( cursor->isSelection() ) {
00348 uint mark = cursor->getMark();
00349 luPixel markX = getChildPosition( context, mark );
00350 luPixel x = QMIN(posX, markX);
00351 luPixel width = abs(posX - markX);
00352
00353 if ( smallCursor ) {
00354 cursor->cursorSize.setRect( point.x()+x, point.y(), width, height );
00355 }
00356 else {
00357 cursor->cursorSize.setRect( point.x()+x, point.y() - 2*unitY,
00358 width + unitX, height + 4*unitY );
00359 }
00360 }
00361 else {
00362 if ( smallCursor ) {
00363 cursor->cursorSize.setRect( point.x()+posX, point.y(),
00364 unitX, height );
00365 }
00366 else {
00367 cursor->cursorSize.setRect( point.x(), point.y() - 2*unitY,
00368 getWidth() + unitX, height + 4*unitY );
00369 }
00370 }
00371
00372 cursor->cursorPoint.setX( point.x()+posX );
00373 cursor->cursorPoint.setY( point.y()+getHeight()/2 );
00374 }
00375
00376
00380 void SequenceElement::drawCursor( QPainter& painter, const ContextStyle& context,
00381 StyleAttributes& style, FormulaCursor* cursor,
00382 bool smallCursor, bool activeCursor )
00383 {
00384 painter.setRasterOp( Qt::XorROP );
00385 if ( cursor->isSelection() ) {
00386 const LuPixelRect& r = cursor->cursorSize;
00387 painter.fillRect( context.layoutUnitToPixelX( r.x() ),
00388 context.layoutUnitToPixelY( r.y() ),
00389 context.layoutUnitToPixelX( r.width() ),
00390 context.layoutUnitToPixelY( r.height() ),
00391 Qt::white );
00392 }
00393 painter.setPen( QPen( Qt::white,
00394 context.layoutUnitToPixelX( context.getLineWidth( style.sizeFactor() )/2 ) ) );
00395 const LuPixelPoint& point = cursor->getCursorPoint();
00396 const LuPixelRect& size = cursor->getCursorSize();
00397 if ( activeCursor )
00398 {
00399 int offset = 0;
00400 if ( cursor->isSelection() && cursor->getPos() > cursor->getMark() )
00401 offset = -1;
00402 painter.drawLine( context.layoutUnitToPixelX( point.x() ) + offset,
00403 context.layoutUnitToPixelY( size.top() ),
00404 context.layoutUnitToPixelX( point.x() ) + offset,
00405 context.layoutUnitToPixelY( size.bottom() )-1 );
00406 painter.drawLine( context.layoutUnitToPixelX( point.x() ) + offset + 1,
00407 context.layoutUnitToPixelY( size.top() ),
00408 context.layoutUnitToPixelX( point.x() ) + offset + 1,
00409 context.layoutUnitToPixelY( size.bottom() )-1 );
00410 }
00411 if ( !smallCursor && !cursor->isSelection() )
00412 painter.drawLine( context.layoutUnitToPixelX( size.left() ),
00413 context.layoutUnitToPixelY( size.bottom() )-1,
00414 context.layoutUnitToPixelX( size.right() )-1,
00415 context.layoutUnitToPixelY( size.bottom() )-1 );
00416
00417 painter.setRasterOp( Qt::CopyROP );
00418 }
00419
00420
00421 luPixel SequenceElement::getChildPosition( const ContextStyle& context, uint child )
00422 {
00423 if (child < children.count()) {
00424 return children.at(child)->getX();
00425 }
00426 else {
00427 if (children.count() > 0) {
00428 return children.at(child-1)->getX() + children.at(child-1)->getWidth();
00429 }
00430 else {
00431 return context.ptToLayoutUnitPixX( 2 );
00432 }
00433 }
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00450 void SequenceElement::moveLeft(FormulaCursor* cursor, BasicElement* from)
00451 {
00452
00453 if (from == getParent()) {
00454 cursor->setTo(this, children.count());
00455 if ( cursor->isSelectionMode() ) {
00456 cursor->setMark( children.count() );
00457 }
00458 from->entered( this );
00459 }
00460
00461
00462 else if (from == this) {
00463 if (cursor->getPos() > 0) {
00464 cursor->setTo(this, cursor->getPos()-1);
00465
00466
00467 if (children.at(cursor->getPos())->isInvisible()) {
00468 moveLeft(cursor, this);
00469 }
00470 }
00471 else {
00472
00473 if (getParent() != 0) {
00474 getParent()->moveLeft(cursor, this);
00475 }
00476 else {
00477 formula()->moveOutLeft( cursor );
00478 }
00479 }
00480 }
00481
00482
00483
00484 else {
00485 int fromPos = children.find(from);
00486 if ( fromPos > 0 ) {
00487 children.at( fromPos - 1)->moveLeft( cursor, this );
00488 }
00489
00490
00491 if (from->isInvisible()) {
00492 moveLeft(cursor, this);
00493 }
00494 formula()->tell( "" );
00495 }
00496 }
00497
00503 void SequenceElement::moveRight(FormulaCursor* cursor, BasicElement* from)
00504 {
00505
00506 if (from == getParent()) {
00507 cursor->setTo(this, 0);
00508 from->entered( this );
00509 }
00510
00511
00512 else if (from == this) {
00513 uint pos = cursor->getPos();
00514 if (pos < children.count()) {
00515 cursor->setTo(this, pos+1);
00516
00517
00518 if (children.at(pos)->isInvisible()) {
00519 moveRight(cursor, this);
00520 }
00521 }
00522 else {
00523
00524 if (getParent() != 0) {
00525 getParent()->moveRight(cursor, this);
00526 }
00527 else {
00528 formula()->moveOutRight( cursor );
00529 }
00530 }
00531 }
00532
00533
00534
00535 else {
00536 int fromPos = children.find(from);
00537 if ( fromPos < children.count() - 1 ) {
00538 children.at( fromPos + 1 )->moveDown( cursor, this );
00539 }
00540 else {
00541 cursor->setTo(this, fromPos+1);
00542 }
00543 if (cursor->isSelectionMode()) {
00544 cursor->setMark(fromPos);
00545 }
00546
00547
00548 if (from->isInvisible()) {
00549 moveRight(cursor, this);
00550 }
00551 formula()->tell( "" );
00552 }
00553 }
00554
00555
00556 void SequenceElement::moveWordLeft(FormulaCursor* cursor)
00557 {
00558 uint pos = cursor->getPos();
00559 if (pos > 0) {
00560 ElementType* type = children.at(pos-1)->getElementType();
00561 if (type != 0) {
00562 cursor->setTo(this, type->start());
00563 }
00564 }
00565 else {
00566 moveLeft(cursor, this);
00567 }
00568 }
00569
00570
00571 void SequenceElement::moveWordRight(FormulaCursor* cursor)
00572 {
00573 uint pos = cursor->getPos();
00574 if (pos < children.count()) {
00575 ElementType* type = children.at(pos)->getElementType();
00576 if (type != 0) {
00577 cursor->setTo(this, type->end());
00578 }
00579 }
00580 else {
00581 moveRight(cursor, this);
00582 }
00583 }
00584
00585
00591 void SequenceElement::moveUp(FormulaCursor* cursor, BasicElement* from)
00592 {
00593 if (from == getParent()) {
00594 moveRight(cursor, this);
00595 }
00596 else if ( from == this ) {
00597 if ( getParent() != 0 ) {
00598 uint pos = cursor->getPos();
00599 if ( pos < (children.count() - 1) / 2 ) {
00600 getParent()->moveLeft( cursor, this );
00601 }
00602 else {
00603 getParent()->moveRight( cursor, this );
00604 }
00605 }
00606 else {
00607 formula()->moveOutAbove( cursor );
00608 }
00609 }
00610 else {
00611 if (getParent() != 0) {
00612 getParent()->moveUp(cursor, this);
00613 }
00614 else {
00615 formula()->moveOutAbove( cursor );
00616 }
00617 }
00618 }
00619
00625 void SequenceElement::moveDown(FormulaCursor* cursor, BasicElement* from)
00626 {
00627 if (from == getParent()) {
00628 cursor->setTo(this, 0);
00629 from->entered( this );
00630 }
00631 else if (from == this) {
00632 uint pos = cursor->getPos();
00633 if (pos < children.count()) {
00634 children.at(pos)->moveDown(cursor, this);
00635 }
00636 }
00637 else {
00638 if (getParent() != 0) {
00639 getParent()->moveDown(cursor, this);
00640 }
00641 else {
00642 cursor->setTo( this, children.count() );
00643 from->entered( this );
00644
00645 }
00646 }
00647 }
00648
00653 void SequenceElement::moveHome(FormulaCursor* cursor)
00654 {
00655 if (cursor->isSelectionMode()) {
00656 BasicElement* element = cursor->getElement();
00657 if (element != this) {
00658 while (element->getParent() != this) {
00659 element = element->getParent();
00660 }
00661 cursor->setMark(children.find(element)+1);
00662 }
00663 }
00664 cursor->setTo(this, 0);
00665 }
00666
00671 void SequenceElement::moveEnd(FormulaCursor* cursor)
00672 {
00673 if (cursor->isSelectionMode()) {
00674 BasicElement* element = cursor->getElement();
00675 if (element != this) {
00676 while (element->getParent() != this) {
00677 element = element->getParent();
00678 if (element == 0) {
00679 cursor->setMark(children.count());
00680 break;
00681 }
00682 }
00683 if (element != 0) {
00684 cursor->setMark(children.find(element));
00685 }
00686 }
00687 }
00688 cursor->setTo(this, children.count());
00689 }
00690
00695 void SequenceElement::goInside(FormulaCursor* cursor)
00696 {
00697 cursor->setSelection(false);
00698 cursor->setTo(this, 0);
00699 }
00700
00705 void SequenceElement::goInsideLast(FormulaCursor* cursor)
00706 {
00707 cursor->setSelection(false);
00708 cursor->setTo(this, children.count());
00709 }
00710
00711
00712
00713
00724 bool SequenceElement::insert( uint index, BasicElement *child )
00725 {
00726 return children.insert( index, child );
00727 }
00728
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00759 void SequenceElement::insert(FormulaCursor* cursor,
00760 QPtrList<BasicElement>& newChildren,
00761 Direction direction)
00762 {
00763 int pos = cursor->getPos();
00764 uint count = newChildren.count();
00765 for (uint i = 0; i < count; i++) {
00766 BasicElement* child = newChildren.take(0);
00767 child->setParent(this);
00768 children.insert(pos+i, child);
00769 }
00770 if (direction == beforeCursor) {
00771 cursor->setTo(this, pos+count, pos);
00772 }
00773 else {
00774 cursor->setTo(this, pos, pos+count);
00775 }
00776
00777 formula()->changed();
00778 parse();
00779 }
00780
00781
00788 void SequenceElement::remove(FormulaCursor* cursor,
00789 QPtrList<BasicElement>& removedChildren,
00790 Direction direction)
00791 {
00792 if (cursor->isSelection()) {
00793 int from = cursor->getSelectionStart();
00794 int to = cursor->getSelectionEnd();
00795 for (int i = from; i < to; i++) {
00796 removeChild(removedChildren, from);
00797 }
00798 cursor->setTo(this, from);
00799 cursor->setSelection(false);
00800 }
00801 else {
00802 if (direction == beforeCursor) {
00803 int pos = cursor->getPos() - 1;
00804 if (pos >= 0) {
00805 while (pos >= 0) {
00806 BasicElement* child = children.at(pos);
00807 formula()->elementRemoval(child);
00808 children.take(pos);
00809 removedChildren.prepend(child);
00810 if (!child->isInvisible()) {
00811 break;
00812 }
00813 pos--;
00814 }
00815 cursor->setTo(this, pos);
00816 formula()->changed();
00817 }
00818 }
00819 else {
00820 uint pos = cursor->getPos();
00821 if (pos < children.count()) {
00822 while (pos < children.count()) {
00823 BasicElement* child = children.at(pos);
00824 formula()->elementRemoval(child);
00825 children.take(pos);
00826 removedChildren.append(child);
00827 if (!child->isInvisible()) {
00828 break;
00829 }
00830 }
00831
00832
00833
00834 cursor->setTo(this, pos);
00835 formula()->changed();
00836 }
00837 }
00838 }
00839 parse();
00840 }
00841
00842
00846 void SequenceElement::removeChild(QPtrList<BasicElement>& removedChildren, int pos)
00847 {
00848 BasicElement* child = children.at(pos);
00849 formula()->elementRemoval(child);
00850 children.take(pos);
00851 removedChildren.append(child);
00852
00853 formula()->changed();
00854 }
00855
00856
00861 void SequenceElement::normalize(FormulaCursor* cursor, Direction)
00862 {
00863 cursor->setSelection(false);
00864 }
00865
00866
00871 BasicElement* SequenceElement::getChild( FormulaCursor* cursor, Direction direction )
00872 {
00873 if ( direction == beforeCursor ) {
00874 if ( cursor->getPos() > 0 ) {
00875 return children.at( cursor->getPos() - 1 );
00876 }
00877 }
00878 else {
00879 if ( cursor->getPos() < qRound( children.count() ) ) {
00880 return children.at( cursor->getPos() );
00881 }
00882 }
00883 return 0;
00884 }
00885
00886
00891 void SequenceElement::selectChild(FormulaCursor* cursor, BasicElement* child)
00892 {
00893 int pos = children.find(child);
00894 if (pos > -1) {
00895 cursor->setTo(this, pos+1, pos);
00896 }
00897 }
00898
00899 void SequenceElement::childWillVanish(FormulaCursor* cursor, BasicElement* child)
00900 {
00901 int childPos = children.find(child);
00902 if (childPos > -1) {
00903 int pos = cursor->getPos();
00904 if (pos > childPos) {
00905 pos--;
00906 }
00907 int mark = cursor->getMark();
00908 if (mark > childPos) {
00909 mark--;
00910 }
00911 cursor->setTo(this, pos, mark);
00912 }
00913 }
00914
00915
00919 void SequenceElement::selectAllChildren(FormulaCursor* cursor)
00920 {
00921 cursor->setTo(this, children.count(), 0);
00922 }
00923
00924 bool SequenceElement::onlyTextSelected( FormulaCursor* cursor )
00925 {
00926 if ( cursor->isSelection() ) {
00927 uint from = QMIN( cursor->getPos(), cursor->getMark() );
00928 uint to = QMAX( cursor->getPos(), cursor->getMark() );
00929 for ( uint i = from; i < to; i++ ) {
00930 BasicElement* element = getChild( i );
00931 if ( element->getCharacter() == QChar::null ) {
00932 return false;
00933 }
00934 }
00935 }
00936 return true;
00937 }
00938
00939
00940 KCommand* SequenceElement::buildCommand( Container* container, Request* request )
00941 {
00942 FormulaCursor* cursor = container->activeCursor();
00943 if ( cursor->isReadOnly() ) {
00944 formula()->tell( i18n( "write protection" ) );
00945 return 0;
00946 }
00947
00948 switch ( *request ) {
00949 case req_addText: {
00950 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container );
00951 TextRequest* tr = static_cast<TextRequest*>( request );
00952 IdentifierElement* id = creationStrategy->createIdentifierElement();
00953 command->addToken( id );
00954 for ( uint i = 0; i < tr->text().length(); i++ ) {
00955 TextElement* text = creationStrategy->createTextElement( tr->text()[i] );
00956 command->addContent( id, text );
00957 }
00958 return command;
00959 }
00960 case req_addTextChar: {
00961 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container );
00962 TextCharRequest* tr = static_cast<TextCharRequest*>( request );
00963 IdentifierElement* id = creationStrategy->createIdentifierElement();
00964 TextElement* text = creationStrategy->createTextElement( tr->ch() );
00965 command->addToken( id );
00966 command->addContent( id, text );
00967 return command;
00968 }
00969
00970 case req_addOperator: {
00971 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Operator"), container );
00972 OperatorRequest* opr = static_cast<OperatorRequest*>( request );
00973 OperatorElement* op = creationStrategy->createOperatorElement();
00974 TextElement* text = creationStrategy->createTextElement( opr->ch() );
00975 command->addToken( op );
00976 command->addContent( op, text );
00977 return command;
00978 }
00979
00980 case req_addNumber: {
00981 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Number"), container );
00982 NumberRequest* nr = static_cast<NumberRequest*>( request );
00983 NumberElement* num = creationStrategy->createNumberElement();
00984 num->setParent( this );
00985 TextElement* text = creationStrategy->createTextElement( nr->ch() );
00986 text->setParent( num );
00987 command->addToken( num );
00988 command->addContent( num, text );
00989 return command;
00990 }
00991
00992 case req_addEmptyBox: {
00993 EmptyElement* element = creationStrategy->createEmptyElement();
00994 if ( element != 0 ) {
00995 KFCReplace* command = new KFCReplace( i18n("Add Empty Box"), container );
00996 command->addElement( element );
00997 return command;
00998 }
00999 break;
01000 }
01001 case req_addNameSequence:
01002 if ( onlyTextSelected( container->activeCursor() ) ) {
01003 NameSequence* nameSequence = creationStrategy->createNameSequence();
01004 if ( nameSequence != 0 ) {
01005 KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Name" ), container );
01006 command->setElement( nameSequence );
01007 return command;
01008 }
01009 }
01010 break;
01011 case req_addBracket: {
01012 BracketRequest* br = static_cast<BracketRequest*>( request );
01013 BracketElement* bracketElement =
01014 creationStrategy->createBracketElement( br->left(), br->right() );
01015 if ( bracketElement != 0 ) {
01016 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Bracket"), container);
01017 command->setElement( bracketElement );
01018 return command;
01019 }
01020 break;
01021 }
01022 case req_addOverline: {
01023 OverlineElement* overline = creationStrategy->createOverlineElement();
01024 if ( overline != 0 ) {
01025 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Overline"), container);
01026 command->setElement( overline );
01027 return command;
01028 }
01029 break;
01030 }
01031 case req_addUnderline: {
01032 UnderlineElement* underline = creationStrategy->createUnderlineElement();
01033 if ( underline != 0 ) {
01034 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Underline"), container);
01035 command->setElement( underline );
01036 return command;
01037 }
01038 break;
01039 }
01040 case req_addMultiline: {
01041 MultilineElement* multiline = creationStrategy->createMultilineElement();
01042 if ( multiline != 0 ) {
01043 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Multiline"), container);
01044 command->setElement( multiline );
01045 return command;
01046 }
01047 break;
01048 }
01049 case req_addSpace: {
01050 SpaceRequest* sr = static_cast<SpaceRequest*>( request );
01051 SpaceElement* element = creationStrategy->createSpaceElement( sr->space() );
01052 if ( element != 0 ) {
01053 KFCReplace* command = new KFCReplace( i18n("Add Space"), container );
01054 command->addElement( element );
01055 return command;
01056 }
01057 break;
01058 }
01059 case req_addFraction: {
01060 FractionElement* fraction = creationStrategy->createFractionElement();
01061 if ( fraction != 0 ) {
01062 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Fraction"), container);
01063 command->setElement( fraction );
01064 return command;
01065 }
01066 break;
01067 }
01068 case req_addRoot: {
01069 RootElement* root = creationStrategy->createRootElement();
01070 if ( root != 0 ) {
01071 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Root"), container);
01072 command->setElement( root );
01073 return command;
01074 }
01075 break;
01076 }
01077 case req_addSymbol: {
01078 SymbolRequest* sr = static_cast<SymbolRequest*>( request );
01079 SymbolElement* symbol = creationStrategy->createSymbolElement( sr->type() );
01080 if ( symbol != 0 ) {
01081 KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Symbol" ), container );
01082 command->setElement( symbol );
01083 return command;
01084 }
01085 break;
01086 }
01087 case req_addOneByTwoMatrix: {
01088 FractionElement* element = creationStrategy->createFractionElement();
01089 if ( element != 0 ) {
01090 KFCAddReplacing* command = new KFCAddReplacing( i18n("Add 1x2 Matrix"), container );
01091 element->showLine(false);
01092 command->setElement(element);
01093 return command;
01094 }
01095 }
01096 case req_addMatrix: {
01097 MatrixRequest* mr = static_cast<MatrixRequest*>( request );
01098 uint rows = mr->rows(), cols = mr->columns();
01099 if ( ( rows == 0 ) || ( cols == 0 ) ) {
01100 MatrixDialog* dialog = new MatrixDialog( 0 );
01101 if ( dialog->exec() ) {
01102 rows = dialog->h;
01103 cols = dialog->w;
01104 }
01105 delete dialog;
01106 }
01107
01108 if ( ( rows != 0 ) && ( cols != 0 ) ) {
01109 KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Matrix" ), container );
01110 command->setElement( creationStrategy->createMatrixElement( rows, cols ) );
01111 return command;
01112 }
01113 else
01114 return 0L;
01115 }
01116 case req_addIndex: {
01117 if ( cursor->getPos() > 0 && !cursor->isSelection() ) {
01118 IndexElement* element =
01119 dynamic_cast<IndexElement*>( children.at( cursor->getPos()-1 ) );
01120 if ( element != 0 ) {
01121 element->goInside( cursor );
01122 return element->buildCommand( container, request );
01123 }
01124 }
01125 IndexElement* element = creationStrategy->createIndexElement();
01126 if ( element != 0 ) {
01127 if ( !cursor->isSelection() ) {
01128 cursor->moveLeft( SelectMovement | WordMovement );
01129 }
01130 IndexRequest* ir = static_cast<IndexRequest*>( request );
01131 KFCAddIndex* command = new KFCAddIndex( container, element,
01132 element->getIndex( ir->index() ) );
01133 return command;
01134 }
01135 break;
01136 }
01137 case req_removeEnclosing: {
01138 if ( !cursor->isSelection() ) {
01139 DirectedRemove* dr = static_cast<DirectedRemove*>( request );
01140 KFCRemoveEnclosing* command = new KFCRemoveEnclosing( container, dr->direction() );
01141 return command;
01142 }
01143 }
01144 case req_remove: {
01145 SequenceElement* sequence = cursor->normal();
01146 if ( sequence &&
01147 ( sequence == sequence->formula() ) &&
01148 ( sequence->countChildren() == 0 ) ) {
01149 sequence->formula()->removeFormula( cursor );
01150 return 0;
01151 }
01152 else {
01153 DirectedRemove* dr = static_cast<DirectedRemove*>( request );
01154
01155
01156 if ( !cursor->isSelection() ) {
01157 if ( countChildren() > 0 ) {
01158 if ( ( cursor->getPos() == 0 ) && ( dr->direction() == beforeCursor ) ) {
01159 return 0;
01160 }
01161 if ( ( cursor->getPos() == countChildren() ) && ( dr->direction() == afterCursor ) ) {
01162 return 0;
01163 }
01164 }
01165 else if ( getParent() == 0 ) {
01166 return 0;
01167 }
01168 }
01169
01170 KFCRemove* command = new KFCRemove( container, dr->direction() );
01171 return command;
01172 }
01173 }
01174 case req_compactExpression: {
01175 cursor->moveEnd();
01176 cursor->moveRight();
01177 formula()->cursorHasMoved( cursor );
01178 break;
01179 }
01180 case req_makeGreek: {
01181 TextElement* element = cursor->getActiveTextElement();
01182 if ((element != 0) && !element->isSymbol()) {
01183 cursor->selectActiveElement();
01184 const SymbolTable& table = container->document()->getSymbolTable();
01185 if (table.greekLetters().find(element->getCharacter()) != -1) {
01186 KFCReplace* command = new KFCReplace( i18n( "Change Char to Symbol" ), container );
01187 TextElement* symbol = creationStrategy->createTextElement( table.unicodeFromSymbolFont( element->getCharacter() ), true );
01188 command->addElement( symbol );
01189 return command;
01190 }
01191 cursor->setSelection( false );
01192 }
01193 break;
01194 }
01195 case req_paste:
01196 case req_copy:
01197 case req_cut:
01198 break;
01199 case req_formatBold:
01200 case req_formatItalic: {
01201 if ( cursor->isSelection() ) {
01202 CharStyleRequest* csr = static_cast<CharStyleRequest*>( request );
01203 CharStyle cs = normalChar;
01204 if ( csr->bold() ) cs = static_cast<CharStyle>( cs | boldChar );
01205 if ( csr->italic() ) cs = static_cast<CharStyle>( cs | italicChar );
01206 CharStyleCommand* cmd = new CharStyleCommand( cs, i18n( "Change Char Style" ), container );
01207 int end = cursor->getSelectionEnd();
01208 for ( int i = cursor->getSelectionStart(); i<end; ++i ) {
01209 cmd->addElement( children.at( i ) );
01210 }
01211 return cmd;
01212 }
01213 break;
01214 }
01215 case req_formatFamily: {
01216 if ( cursor->isSelection() ) {
01217 CharFamilyRequest* cfr = static_cast<CharFamilyRequest*>( request );
01218 CharFamily cf = cfr->charFamily();
01219 CharFamilyCommand* cmd = new CharFamilyCommand( cf, i18n( "Change Char Family" ), container );
01220 int end = cursor->getSelectionEnd();
01221 for ( int i = cursor->getSelectionStart(); i<end; ++i ) {
01222 cmd->addElement( children.at( i ) );
01223 }
01224 return cmd;
01225 }
01226 break;
01227 }
01228 default:
01229 break;
01230 }
01231 return 0;
01232 }
01233
01234
01235 KCommand* SequenceElement::input( Container* container, QKeyEvent* event )
01236 {
01237 QChar ch = event->text().at( 0 );
01238 if ( ch.isPrint() ) {
01239 return input( container, ch );
01240 }
01241 else {
01242 int action = event->key();
01243 int state = event->state();
01244 MoveFlag flag = movementFlag(state);
01245
01246 switch ( action ) {
01247 case Qt::Key_BackSpace: {
01248 DirectedRemove r( req_remove, beforeCursor );
01249 return buildCommand( container, &r );
01250 }
01251 case Qt::Key_Delete: {
01252 DirectedRemove r( req_remove, afterCursor );
01253 return buildCommand( container, &r );
01254 }
01255 case Qt::Key_Left: {
01256 FormulaCursor* cursor = container->activeCursor();
01257 cursor->moveLeft( flag );
01258 formula()->cursorHasMoved( cursor );
01259 break;
01260 }
01261 case Qt::Key_Right: {
01262 FormulaCursor* cursor = container->activeCursor();
01263 cursor->moveRight( flag );
01264 formula()->cursorHasMoved( cursor );
01265 break;
01266 }
01267 case Qt::Key_Up: {
01268 FormulaCursor* cursor = container->activeCursor();
01269 cursor->moveUp( flag );
01270 formula()->cursorHasMoved( cursor );
01271 break;
01272 }
01273 case Qt::Key_Down: {
01274 FormulaCursor* cursor = container->activeCursor();
01275 cursor->moveDown( flag );
01276 formula()->cursorHasMoved( cursor );
01277 break;
01278 }
01279 case Qt::Key_Home: {
01280 FormulaCursor* cursor = container->activeCursor();
01281 cursor->moveHome( flag );
01282 formula()->cursorHasMoved( cursor );
01283 break;
01284 }
01285 case Qt::Key_End: {
01286 FormulaCursor* cursor = container->activeCursor();
01287 cursor->moveEnd( flag );
01288 formula()->cursorHasMoved( cursor );
01289 break;
01290 }
01291 default:
01292 if ( state & Qt::ControlButton ) {
01293 switch ( event->key() ) {
01294 case Qt::Key_AsciiCircum: {
01295 IndexRequest r( upperLeftPos );
01296 return buildCommand( container, &r );
01297 }
01298 case Qt::Key_Underscore: {
01299 IndexRequest r( lowerLeftPos );
01300 return buildCommand( container, &r );
01301 }
01302 default:
01303 break;
01304 }
01305 }
01306 }
01307 }
01308 return 0;
01309 }
01310
01311
01312 KCommand* SequenceElement::input( Container* container, QChar ch )
01313 {
01314 int unicode = ch.unicode();
01315 switch (unicode) {
01316 case '(': {
01317 BracketRequest r( container->document()->leftBracketChar(),
01318 container->document()->rightBracketChar() );
01319 singlePipe = true;
01320 return buildCommand( container, &r );
01321 }
01322 case '[': {
01323 BracketRequest r( LeftSquareBracket, RightSquareBracket );
01324 singlePipe = true;
01325 return buildCommand( container, &r );
01326 }
01327 case '{': {
01328 BracketRequest r( LeftCurlyBracket, RightCurlyBracket );
01329 singlePipe = true;
01330 return buildCommand( container, &r );
01331 }
01332 case '|': {
01333 if (!singlePipe) {
01334
01335 DirectedRemove rDelete( req_remove, beforeCursor );
01336 KCommand* command = buildCommand( container, &rDelete );
01337 command->execute();
01338
01339 BracketRequest rBracket( LeftLineBracket , RightLineBracket);
01340 singlePipe = true;
01341 return buildCommand( container, &rBracket );
01342 }
01343 else {
01344 TextCharRequest r(ch);
01345
01346
01347 singlePipe = false;
01348
01349 return buildCommand( container, &r );
01350 }
01351 }
01352 case '^': {
01353 IndexRequest r( upperRightPos );
01354 singlePipe = true;
01355 return buildCommand( container, &r );
01356 }
01357 case '_': {
01358 IndexRequest r( lowerRightPos );
01359 singlePipe = true;
01360 return buildCommand( container, &r );
01361 }
01362
01363
01364
01365
01366
01367
01368 case '}': {
01369 Request r( req_addEmptyBox );
01370 singlePipe = true;
01371 return buildCommand( container, &r );
01372 }
01373 case ']':
01374 case ')':
01375 singlePipe = true;
01376 break;
01377 case '\\': {
01378 Request r( req_addNameSequence );
01379 singlePipe = true;
01380 return buildCommand( container, &r );
01381 }
01382 default: {
01383 singlePipe = true;
01384 if ( ch.isPunct() || ch.isSymbol() ) {
01385 OperatorRequest r( ch );
01386 return buildCommand( container, &r );
01387 }
01388 if ( ch.isNumber() ) {
01389 NumberRequest r( ch );
01390 return buildCommand( container, &r );
01391 }
01392 TextCharRequest r( ch );
01393 return buildCommand( container, &r );
01394 }
01395 }
01396 return 0;
01397 }
01398
01402 void SequenceElement::getChildrenDom( QDomDocument& doc, QDomElement elem,
01403 uint from, uint to)
01404 {
01405 for (uint i = from; i < to; i++) {
01406 QDomElement tmpEleDom=children.at(i)->getElementDom(doc);
01407 elem.appendChild(tmpEleDom);
01408 }
01409 }
01410
01414 void SequenceElement::getChildrenMathMLDom( QDomDocument& doc, QDomNode& parent,
01415 uint from, uint to)
01416 {
01417 for ( uint i = from; i < to; i++ ) {
01418 children.at( i )->writeMathML( doc, parent, false );
01419 }
01420 }
01421
01422
01428 bool SequenceElement::buildChildrenFromDom(QPtrList<BasicElement>& list, QDomNode n)
01429 {
01430 while (!n.isNull()) {
01431 if (n.isElement()) {
01432 QDomElement e = n.toElement();
01433 BasicElement* child = 0;
01434 QString tag = e.tagName().upper();
01435
01436 child = createElement(tag, e);
01437 if (child != 0) {
01438 child->setParent(this);
01439 if (child->buildFromDom(e)) {
01440 list.append(child);
01441 }
01442 else {
01443 delete child;
01444 return false;
01445 }
01446 }
01447 else {
01448 return false;
01449 }
01450 }
01451 n = n.nextSibling();
01452 }
01453 parse();
01454 return true;
01455 }
01456
01457
01458 BasicElement* SequenceElement::createElement( QString type, const QDomElement& element )
01459 {
01460 return creationStrategy->createElement( type, element );
01461 }
01462
01466 void SequenceElement::writeDom(QDomElement element)
01467 {
01468 BasicElement::writeDom(element);
01469
01470 uint count = children.count();
01471 QDomDocument doc = element.ownerDocument();
01472 getChildrenDom(doc, element, 0, count);
01473 }
01474
01479 bool SequenceElement::readAttributesFromDom(QDomElement element)
01480 {
01481 if (!BasicElement::readAttributesFromDom(element)) {
01482 return false;
01483 }
01484 return true;
01485 }
01486
01492 bool SequenceElement::readContentFromDom(QDomNode& node)
01493 {
01494 if (!BasicElement::readContentFromDom(node)) {
01495 return false;
01496 }
01497
01498 return buildChildrenFromDom(children, node);
01499 }
01500
01501
01502 void SequenceElement::parse()
01503 {
01504 delete parseTree;
01505
01506 textSequence = true;
01507 for (BasicElement* element = children.first();
01508 element != 0;
01509 element = children.next()) {
01510
01511
01512
01513 element->setElementType(0);
01514
01515 if (element->getCharacter().isNull()) {
01516 textSequence = false;
01517 }
01518 }
01519
01520 const SymbolTable& symbols = formula()->getSymbolTable();
01521 SequenceParser parser(symbols);
01522 parseTree = parser.parse(children);
01523
01524
01525
01526 BasicElement* p = getParent();
01527 if ( p != 0 ) {
01528 SequenceElement* seq = dynamic_cast<SequenceElement*>( p->getParent() );
01529 if ( seq != 0 ) {
01530 seq->parse();
01531 }
01532 }
01533
01534
01535 }
01536
01537
01538 bool SequenceElement::isFirstOfToken( BasicElement* child )
01539 {
01540 return ( child->getElementType() != 0 ) && isChildNumber( child->getElementType()->start(), child );
01541 }
01542
01543
01544 QString SequenceElement::toLatex()
01545 {
01546 QString content;
01547 uint count = children.count();
01548 for ( uint i = 0; i < count; i++ ) {
01549 BasicElement* child = children.at( i );
01550
01551
01552
01553 content += child->toLatex();
01554 }
01555 return content;
01556 }
01557
01558
01559 QString SequenceElement::formulaString()
01560 {
01561 QString content;
01562 uint count = children.count();
01563 for ( uint i = 0; i < count; i++ ) {
01564 BasicElement* child = children.at( i );
01565
01566
01567
01568 content += child->formulaString();
01569 }
01570 return content;
01571 }
01572
01573
01574 void SequenceElement::writeMathMLContent( QDomDocument& doc, QDomElement& element, bool oasisFormat ) const
01575 {
01576 for ( QPtrListIterator<BasicElement> it( children ); it.current(); ++it ) {
01577 it.current()->writeMathML( doc, element, oasisFormat );
01578 }
01579 }
01580
01581
01582 const BasicElement* SequenceElement::getChild( uint i ) const
01583 {
01584 QPtrListIterator<BasicElement> it( children );
01585 it += i;
01586 return it.current();
01587 }
01588
01589
01590 int SequenceElement::childPos( const BasicElement* child ) const
01591 {
01592 QPtrListIterator<BasicElement> it( children );
01593 uint count = it.count();
01594 for ( uint i=0; i<count; ++i, ++it ) {
01595 if ( it.current() == child ) {
01596 return i;
01597 }
01598 }
01599 return -1;
01600 }
01601
01602
01603 NameSequence::NameSequence( BasicElement* parent )
01604 : SequenceElement( parent )
01605 {
01606 }
01607
01608
01609 bool NameSequence::accept( ElementVisitor* visitor )
01610 {
01611 return visitor->visit( this );
01612 }
01613
01614
01615 void NameSequence::calcCursorSize( const ContextStyle& context,
01616 FormulaCursor* cursor, bool smallCursor )
01617 {
01618 inherited::calcCursorSize( context, cursor, smallCursor );
01619 LuPixelPoint point = widgetPos();
01620 luPixel unitX = context.ptToLayoutUnitPixX( 1 );
01621 luPixel unitY = context.ptToLayoutUnitPixY( 1 );
01622 cursor->addCursorSize( LuPixelRect( point.x()-unitX, point.y()-unitY,
01623 getWidth()+2*unitX, getHeight()+2*unitY ) );
01624 }
01625
01626 void NameSequence::drawCursor( QPainter& painter, const ContextStyle& context,
01627 StyleAttributes& style, FormulaCursor* cursor,
01628 bool smallCursor, bool activeCursor )
01629 {
01630 LuPixelPoint point = widgetPos();
01631 painter.setPen( QPen( context.getEmptyColor(),
01632 context.layoutUnitToPixelX( context.getLineWidth( style.sizeFactor() )/2 ) ) );
01633 luPixel unitX = context.ptToLayoutUnitPixX( 1 );
01634 luPixel unitY = context.ptToLayoutUnitPixY( 1 );
01635 painter.drawRect( context.layoutUnitToPixelX( point.x()-unitX ),
01636 context.layoutUnitToPixelY( point.y()-unitY ),
01637 context.layoutUnitToPixelX( getWidth()+2*unitX ),
01638 context.layoutUnitToPixelY( getHeight()+2*unitY ) );
01639
01640 inherited::drawCursor( painter, context, style, cursor, smallCursor, activeCursor );
01641 }
01642
01643 void NameSequence::moveWordLeft( FormulaCursor* cursor )
01644 {
01645 uint pos = cursor->getPos();
01646 if ( pos > 0 ) {
01647 cursor->setTo( this, 0 );
01648 }
01649 else {
01650 moveLeft( cursor, this );
01651 }
01652 }
01653
01654 void NameSequence::moveWordRight( FormulaCursor* cursor )
01655 {
01656 int pos = cursor->getPos();
01657 if ( pos < countChildren() ) {
01658 cursor->setTo( this, countChildren() );
01659 }
01660 else {
01661 moveRight( cursor, this );
01662 }
01663 }
01664
01665
01666 KCommand* NameSequence::compactExpressionCmd( Container* container )
01667 {
01668 BasicElement* element = replaceElement( container->document()->getSymbolTable() );
01669 if ( element != 0 ) {
01670 getParent()->selectChild( container->activeCursor(), this );
01671
01672 KFCReplace* command = new KFCReplace( i18n( "Add Element" ), container );
01673 command->addElement( element );
01674 return command;
01675 }
01676 return 0;
01677 }
01678
01679 KCommand* NameSequence::buildCommand( Container* container, Request* request )
01680 {
01681 switch ( *request ) {
01682 case req_compactExpression:
01683 return compactExpressionCmd( container );
01684 case req_addSpace:
01685 case req_addIndex:
01686 case req_addMatrix:
01687 case req_addOneByTwoMatrix:
01688 case req_addSymbol:
01689 case req_addRoot:
01690 case req_addFraction:
01691 case req_addBracket:
01692 case req_addNameSequence:
01693 return 0;
01694 default:
01695 break;
01696 }
01697 return inherited::buildCommand( container, request );
01698 }
01699
01700
01701 KCommand* NameSequence::input( Container* container, QChar ch )
01702 {
01703 int unicode = ch.unicode();
01704 switch (unicode) {
01705 case '(':
01706 case '[':
01707 case '|':
01708 case '^':
01709 case '_':
01710 case '}':
01711 case ']':
01712 case ')':
01713 case '\\': {
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725 break;
01726 }
01727 case '{':
01728 case ' ': {
01729 Request r( req_compactExpression );
01730 return buildCommand( container, &r );
01731 }
01732 default: {
01733 TextCharRequest r( ch );
01734 return buildCommand( container, &r );
01735 }
01736 }
01737 return 0;
01738 }
01739
01740 void NameSequence::setElementType( ElementType* t )
01741 {
01742 inherited::setElementType( t );
01743 parse();
01744 }
01745
01746 BasicElement* NameSequence::replaceElement( const SymbolTable& table )
01747 {
01748 QString name = buildName();
01749 QChar ch = table.unicode( name );
01750 if ( !ch.isNull() ) {
01751 return new TextElement( ch, true );
01752 }
01753 else {
01754 ch = table.unicode( i18n( name.latin1() ) );
01755 if ( !ch.isNull() ) {
01756 return new TextElement( ch, true );
01757 }
01758 }
01759
01760 if ( name == "!" ) return new SpaceElement( NEGTHIN );
01761 if ( name == "," ) return new SpaceElement( THIN );
01762 if ( name == ">" ) return new SpaceElement( MEDIUM );
01763 if ( name == ";" ) return new SpaceElement( THICK );
01764 if ( name == "quad" ) return new SpaceElement( QUAD );
01765
01766 if ( name == "frac" ) return new FractionElement();
01767 if ( name == "atop" ) {
01768 FractionElement* frac = new FractionElement();
01769 frac->showLine( false );
01770 return frac;
01771 }
01772 if ( name == "sqrt" ) return new RootElement();
01773
01774 return 0;
01775 }
01776
01777 BasicElement* NameSequence::createElement( QString type )
01778 {
01779 if ( type == "TEXT" ) return new TextElement();
01780 return 0;
01781 }
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792 QString NameSequence::buildName()
01793 {
01794 QString name;
01795 for ( uint i = 0; i < countChildren(); i++ ) {
01796 name += getChild( i )->getCharacter();
01797 }
01798 return name;
01799 }
01800
01801 bool NameSequence::isValidSelection( FormulaCursor* cursor )
01802 {
01803 SequenceElement* sequence = cursor->normal();
01804 if ( sequence == 0 ) {
01805 return false;
01806 }
01807 return sequence->onlyTextSelected( cursor );
01808 }
01809
01810 int SequenceElement::buildChildrenFromMathMLDom(QPtrList<BasicElement>& list, QDomNode n)
01811 {
01812 while (!n.isNull()) {
01813 int nodeNumber = 1;
01814 if (n.isElement()) {
01815 QDomElement e = n.toElement();
01816 BasicElement* child = 0;
01817 QString tag = e.tagName().lower();
01818
01819 kdDebug( DEBUGID ) << "Sequence Tag: " << tag << endl;
01820 if ( tag == "semantics" ) {
01821 QDomNode node = e.firstChild();
01822 while( ! node.isElement() ) {
01823 node = node.nextSibling();
01824 if ( node.isNull() ) {
01825 return -1;
01826 }
01827 }
01828 e = node.toElement();
01829 tag = e.tagName().lower();
01830 }
01831 child = creationStrategy->createElement(tag, e);
01832 if (child != 0) {
01833 child->setParent(this);
01834 if (style != 0) {
01835 child->setStyle(style);
01836 }
01837 nodeNumber = child->buildFromMathMLDom( e );
01838 if ( nodeNumber != -1 ) {
01839 list.append(child);
01840 }
01841 else {
01842 delete child;
01843 return -1;
01844 }
01845 }
01846 else {
01847 kdWarning() << "Unsupported MathML element: " << tag << endl;
01848 }
01849 }
01850 for (int i = 0; i < nodeNumber; i++ ) {
01851 if ( n.isNull() ) {
01852 return -1;
01853 }
01854 n = n.nextSibling();
01855 }
01856 }
01857
01858
01859
01860
01861
01862
01863
01864 if ( list.count() > 1 ) {
01865 if ( list.getFirst()->getElementName() == "mo" ) {
01866 static_cast<OperatorElement*>( list.getFirst() )->setForm( PrefixForm );
01867 }
01868 if ( list.getLast()->getElementName() == "mo" ) {
01869 static_cast<OperatorElement*>( list.getLast() )->setForm( PostfixForm );
01870 }
01871 for ( uint i = 1; i < list.count() - 1; i++ ) {
01872 if ( list.at( i )->getElementName() == "mo" ) {
01873 static_cast<OperatorElement*>( list.at( i ) )->setForm( InfixForm );
01874 }
01875 }
01876 }
01877 else if ( list.count() == 1 ) {
01878 if ( list.getFirst()->getElementName() == "mo" ) {
01879 static_cast<OperatorElement*>( list.getFirst() )->setForm( InfixForm );
01880 }
01881 }
01882 parse();
01883 return 1;
01884 }
01885
01888 int SequenceElement::readContentFromMathMLDom(QDomNode& node)
01889 {
01890 if ( BasicElement::readContentFromMathMLDom(node) == -1 ) {
01891 return -1;
01892 }
01893
01894 return buildChildrenFromMathMLDom(children, node);
01895 }
01896
01897 int SequenceElement::buildMathMLChild( QDomNode node )
01898 {
01899 int nodeCounter = 1;
01900 while ( ! node.isElement() ) {
01901 node = node.nextSibling();
01902 nodeCounter++;
01903 if ( node.isNull() ) {
01904 return -1;
01905 }
01906 }
01907 QDomElement e = node.toElement();
01908 BasicElement* child = 0;
01909 QString tag = e.tagName().lower();
01910
01911 child = creationStrategy->createElement(tag, e);
01912 if (child != 0) {
01913 child->setParent(this);
01914 if (style != 0) {
01915 child->setStyle(style);
01916 }
01917 if (child->buildFromMathMLDom(e) != -1) {
01918 children.append(child);
01919 }
01920 else {
01921 delete child;
01922 return -1;
01923 }
01924 }
01925 else {
01926 return -1;
01927 }
01928 parse();
01929 return nodeCounter;
01930 }
01931
01932
01933
01934 KFORMULA_NAMESPACE_END