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 else {
00490 cursor->setTo(this, fromPos);
00491 }
00492
00493
00494 if (from->isInvisible()) {
00495 moveLeft(cursor, this);
00496 }
00497 formula()->tell( "" );
00498 }
00499 }
00500
00506 void SequenceElement::moveRight(FormulaCursor* cursor, BasicElement* from)
00507 {
00508
00509 if (from == getParent()) {
00510 cursor->setTo(this, 0);
00511 from->entered( this );
00512 }
00513
00514
00515 else if (from == this) {
00516 uint pos = cursor->getPos();
00517 if (pos < children.count()) {
00518 cursor->setTo(this, pos+1);
00519
00520
00521 if (children.at(pos)->isInvisible()) {
00522 moveRight(cursor, this);
00523 }
00524 }
00525 else {
00526
00527 if (getParent() != 0) {
00528 getParent()->moveRight(cursor, this);
00529 }
00530 else {
00531 formula()->moveOutRight( cursor );
00532 }
00533 }
00534 }
00535
00536
00537
00538 else {
00539 int fromPos = children.find(from);
00540 if ( fromPos < children.count() - 1 ) {
00541 children.at( fromPos + 1 )->moveDown( cursor, this );
00542 }
00543 else {
00544 cursor->setTo(this, fromPos+1);
00545 }
00546 if (cursor->isSelectionMode()) {
00547 cursor->setMark(fromPos);
00548 }
00549
00550
00551 if (from->isInvisible()) {
00552 moveRight(cursor, this);
00553 }
00554 formula()->tell( "" );
00555 }
00556 }
00557
00558
00559 void SequenceElement::moveWordLeft(FormulaCursor* cursor)
00560 {
00561 uint pos = cursor->getPos();
00562 if (pos > 0) {
00563 ElementType* type = children.at(pos-1)->getElementType();
00564 if (type != 0) {
00565 cursor->setTo(this, type->start());
00566 }
00567 }
00568 else {
00569 moveLeft(cursor, this);
00570 }
00571 }
00572
00573
00574 void SequenceElement::moveWordRight(FormulaCursor* cursor)
00575 {
00576 uint pos = cursor->getPos();
00577 if (pos < children.count()) {
00578 ElementType* type = children.at(pos)->getElementType();
00579 if (type != 0) {
00580 cursor->setTo(this, type->end());
00581 }
00582 }
00583 else {
00584 moveRight(cursor, this);
00585 }
00586 }
00587
00588
00594 void SequenceElement::moveUp(FormulaCursor* cursor, BasicElement* from)
00595 {
00596 if (from == getParent()) {
00597 moveRight(cursor, this);
00598 }
00599 else if ( from == this ) {
00600 if ( getParent() != 0 ) {
00601 uint pos = cursor->getPos();
00602 if ( pos < (children.count() - 1) / 2 ) {
00603 getParent()->moveLeft( cursor, this );
00604 }
00605 else {
00606 getParent()->moveRight( cursor, this );
00607 }
00608 }
00609 else {
00610 formula()->moveOutAbove( cursor );
00611 }
00612 }
00613 else {
00614 if (getParent() != 0) {
00615 getParent()->moveUp(cursor, this);
00616 }
00617 else {
00618 formula()->moveOutAbove( cursor );
00619 }
00620 }
00621 }
00622
00628 void SequenceElement::moveDown(FormulaCursor* cursor, BasicElement* from)
00629 {
00630 if (from == getParent()) {
00631 cursor->setTo(this, 0);
00632 from->entered( this );
00633 }
00634 else if (from == this) {
00635 uint pos = cursor->getPos();
00636 if (pos < children.count()) {
00637 children.at(pos)->moveDown(cursor, this);
00638 }
00639 }
00640 else {
00641 if (getParent() != 0) {
00642 getParent()->moveDown(cursor, this);
00643 }
00644 else {
00645 cursor->setTo( this, children.count() );
00646 from->entered( this );
00647
00648 }
00649 }
00650 }
00651
00656 void SequenceElement::moveHome(FormulaCursor* cursor)
00657 {
00658 if (cursor->isSelectionMode()) {
00659 BasicElement* element = cursor->getElement();
00660 if (element != this) {
00661 while (element->getParent() != this) {
00662 element = element->getParent();
00663 }
00664 cursor->setMark(children.find(element)+1);
00665 }
00666 }
00667 cursor->setTo(this, 0);
00668 }
00669
00674 void SequenceElement::moveEnd(FormulaCursor* cursor)
00675 {
00676 if (cursor->isSelectionMode()) {
00677 BasicElement* element = cursor->getElement();
00678 if (element != this) {
00679 while (element->getParent() != this) {
00680 element = element->getParent();
00681 if (element == 0) {
00682 cursor->setMark(children.count());
00683 break;
00684 }
00685 }
00686 if (element != 0) {
00687 cursor->setMark(children.find(element));
00688 }
00689 }
00690 }
00691 cursor->setTo(this, children.count());
00692 }
00693
00698 void SequenceElement::goInside(FormulaCursor* cursor)
00699 {
00700 cursor->setSelection(false);
00701 cursor->setTo(this, 0);
00702 }
00703
00708 void SequenceElement::goInsideLast(FormulaCursor* cursor)
00709 {
00710 cursor->setSelection(false);
00711 cursor->setTo(this, children.count());
00712 }
00713
00714
00715
00716
00727 bool SequenceElement::insert( uint index, BasicElement *child )
00728 {
00729 return children.insert( index, child );
00730 }
00731
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00762 void SequenceElement::insert(FormulaCursor* cursor,
00763 QPtrList<BasicElement>& newChildren,
00764 Direction direction)
00765 {
00766 int pos = cursor->getPos();
00767 uint count = newChildren.count();
00768 for (uint i = 0; i < count; i++) {
00769 BasicElement* child = newChildren.take(0);
00770 child->setParent(this);
00771 children.insert(pos+i, child);
00772 }
00773 if (direction == beforeCursor) {
00774 cursor->setTo(this, pos+count, pos);
00775 }
00776 else {
00777 cursor->setTo(this, pos, pos+count);
00778 }
00779
00780 formula()->changed();
00781 parse();
00782 }
00783
00784
00791 void SequenceElement::remove(FormulaCursor* cursor,
00792 QPtrList<BasicElement>& removedChildren,
00793 Direction direction)
00794 {
00795 if (cursor->isSelection()) {
00796 int from = cursor->getSelectionStart();
00797 int to = cursor->getSelectionEnd();
00798 for (int i = from; i < to; i++) {
00799 removeChild(removedChildren, from);
00800 }
00801 cursor->setTo(this, from);
00802 cursor->setSelection(false);
00803 }
00804 else {
00805 if (direction == beforeCursor) {
00806 int pos = cursor->getPos() - 1;
00807 if (pos >= 0) {
00808 while (pos >= 0) {
00809 BasicElement* child = children.at(pos);
00810 formula()->elementRemoval(child);
00811 children.take(pos);
00812 removedChildren.prepend(child);
00813 if (!child->isInvisible()) {
00814 break;
00815 }
00816 pos--;
00817 }
00818 cursor->setTo(this, pos);
00819 formula()->changed();
00820 }
00821 }
00822 else {
00823 uint pos = cursor->getPos();
00824 if (pos < children.count()) {
00825 while (pos < children.count()) {
00826 BasicElement* child = children.at(pos);
00827 formula()->elementRemoval(child);
00828 children.take(pos);
00829 removedChildren.append(child);
00830 if (!child->isInvisible()) {
00831 break;
00832 }
00833 }
00834
00835
00836
00837 cursor->setTo(this, pos);
00838 formula()->changed();
00839 }
00840 }
00841 }
00842 parse();
00843 }
00844
00845
00849 void SequenceElement::removeChild(QPtrList<BasicElement>& removedChildren, int pos)
00850 {
00851 BasicElement* child = children.at(pos);
00852 formula()->elementRemoval(child);
00853 children.take(pos);
00854 removedChildren.append(child);
00855
00856 formula()->changed();
00857 }
00858
00859
00864 void SequenceElement::normalize(FormulaCursor* cursor, Direction)
00865 {
00866 cursor->setSelection(false);
00867 }
00868
00869
00874 BasicElement* SequenceElement::getChild( FormulaCursor* cursor, Direction direction )
00875 {
00876 if ( direction == beforeCursor ) {
00877 if ( cursor->getPos() > 0 ) {
00878 return children.at( cursor->getPos() - 1 );
00879 }
00880 }
00881 else {
00882 if ( cursor->getPos() < qRound( children.count() ) ) {
00883 return children.at( cursor->getPos() );
00884 }
00885 }
00886 return 0;
00887 }
00888
00889
00894 void SequenceElement::selectChild(FormulaCursor* cursor, BasicElement* child)
00895 {
00896 int pos = children.find(child);
00897 if (pos > -1) {
00898 cursor->setTo(this, pos+1, pos);
00899 }
00900 }
00901
00902 void SequenceElement::childWillVanish(FormulaCursor* cursor, BasicElement* child)
00903 {
00904 int childPos = children.find(child);
00905 if (childPos > -1) {
00906 int pos = cursor->getPos();
00907 if (pos > childPos) {
00908 pos--;
00909 }
00910 int mark = cursor->getMark();
00911 if (mark > childPos) {
00912 mark--;
00913 }
00914 cursor->setTo(this, pos, mark);
00915 }
00916 }
00917
00918
00922 void SequenceElement::selectAllChildren(FormulaCursor* cursor)
00923 {
00924 cursor->setTo(this, children.count(), 0);
00925 }
00926
00927 bool SequenceElement::onlyTextSelected( FormulaCursor* cursor )
00928 {
00929 if ( cursor->isSelection() ) {
00930 uint from = QMIN( cursor->getPos(), cursor->getMark() );
00931 uint to = QMAX( cursor->getPos(), cursor->getMark() );
00932 for ( uint i = from; i < to; i++ ) {
00933 BasicElement* element = getChild( i );
00934 if ( element->getCharacter() == QChar::null ) {
00935 return false;
00936 }
00937 }
00938 }
00939 return true;
00940 }
00941
00942
00943 KCommand* SequenceElement::buildCommand( Container* container, Request* request )
00944 {
00945 FormulaCursor* cursor = container->activeCursor();
00946 if ( cursor->isReadOnly() ) {
00947 formula()->tell( i18n( "write protection" ) );
00948 return 0;
00949 }
00950
00951 switch ( *request ) {
00952 case req_addText: {
00953 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container );
00954 TextRequest* tr = static_cast<TextRequest*>( request );
00955 IdentifierElement* id = creationStrategy->createIdentifierElement();
00956 command->addToken( id );
00957 for ( uint i = 0; i < tr->text().length(); i++ ) {
00958 TextElement* text = creationStrategy->createTextElement( tr->text()[i] );
00959 command->addContent( id, text );
00960 }
00961 return command;
00962 }
00963 case req_addTextChar: {
00964 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Text"), container );
00965 TextCharRequest* tr = static_cast<TextCharRequest*>( request );
00966 IdentifierElement* id = creationStrategy->createIdentifierElement();
00967 TextElement* text = creationStrategy->createTextElement( tr->ch() );
00968 command->addToken( id );
00969 command->addContent( id, text );
00970 return command;
00971 }
00972
00973 case req_addOperator: {
00974 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Operator"), container );
00975 OperatorRequest* opr = static_cast<OperatorRequest*>( request );
00976 OperatorElement* op = creationStrategy->createOperatorElement();
00977 TextElement* text = creationStrategy->createTextElement( opr->ch() );
00978 command->addToken( op );
00979 command->addContent( op, text );
00980 return command;
00981 }
00982
00983 case req_addNumber: {
00984 KFCReplaceToken* command = new KFCReplaceToken( i18n("Add Number"), container );
00985 NumberRequest* nr = static_cast<NumberRequest*>( request );
00986 NumberElement* num = creationStrategy->createNumberElement();
00987 num->setParent( this );
00988 TextElement* text = creationStrategy->createTextElement( nr->ch() );
00989 text->setParent( num );
00990 command->addToken( num );
00991 command->addContent( num, text );
00992 return command;
00993 }
00994
00995 case req_addEmptyBox: {
00996 EmptyElement* element = creationStrategy->createEmptyElement();
00997 if ( element != 0 ) {
00998 KFCReplace* command = new KFCReplace( i18n("Add Empty Box"), container );
00999 command->addElement( element );
01000 return command;
01001 }
01002 break;
01003 }
01004 case req_addNameSequence:
01005 if ( onlyTextSelected( container->activeCursor() ) ) {
01006 NameSequence* nameSequence = creationStrategy->createNameSequence();
01007 if ( nameSequence != 0 ) {
01008 KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Name" ), container );
01009 command->setElement( nameSequence );
01010 return command;
01011 }
01012 }
01013 break;
01014 case req_addBracket: {
01015 BracketRequest* br = static_cast<BracketRequest*>( request );
01016 BracketElement* bracketElement =
01017 creationStrategy->createBracketElement( br->left(), br->right() );
01018 if ( bracketElement != 0 ) {
01019 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Bracket"), container);
01020 command->setElement( bracketElement );
01021 return command;
01022 }
01023 break;
01024 }
01025 case req_addOverline: {
01026 OverlineElement* overline = creationStrategy->createOverlineElement();
01027 if ( overline != 0 ) {
01028 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Overline"), container);
01029 command->setElement( overline );
01030 return command;
01031 }
01032 break;
01033 }
01034 case req_addUnderline: {
01035 UnderlineElement* underline = creationStrategy->createUnderlineElement();
01036 if ( underline != 0 ) {
01037 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Underline"), container);
01038 command->setElement( underline );
01039 return command;
01040 }
01041 break;
01042 }
01043 case req_addMultiline: {
01044 MultilineElement* multiline = creationStrategy->createMultilineElement();
01045 if ( multiline != 0 ) {
01046 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Multiline"), container);
01047 command->setElement( multiline );
01048 return command;
01049 }
01050 break;
01051 }
01052 case req_addSpace: {
01053 SpaceRequest* sr = static_cast<SpaceRequest*>( request );
01054 SpaceElement* element = creationStrategy->createSpaceElement( sr->space() );
01055 if ( element != 0 ) {
01056 KFCReplace* command = new KFCReplace( i18n("Add Space"), container );
01057 command->addElement( element );
01058 return command;
01059 }
01060 break;
01061 }
01062 case req_addFraction: {
01063 FractionElement* fraction = creationStrategy->createFractionElement();
01064 if ( fraction != 0 ) {
01065 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Fraction"), container);
01066 command->setElement( fraction );
01067 return command;
01068 }
01069 break;
01070 }
01071 case req_addRoot: {
01072 RootElement* root = creationStrategy->createRootElement();
01073 if ( root != 0 ) {
01074 KFCAddReplacing* command = new KFCAddReplacing(i18n("Add Root"), container);
01075 command->setElement( root );
01076 return command;
01077 }
01078 break;
01079 }
01080 case req_addSymbol: {
01081 SymbolRequest* sr = static_cast<SymbolRequest*>( request );
01082 SymbolElement* symbol = creationStrategy->createSymbolElement( sr->type() );
01083 if ( symbol != 0 ) {
01084 KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Symbol" ), container );
01085 command->setElement( symbol );
01086 return command;
01087 }
01088 break;
01089 }
01090 case req_addOneByTwoMatrix: {
01091 FractionElement* element = creationStrategy->createFractionElement();
01092 if ( element != 0 ) {
01093 KFCAddReplacing* command = new KFCAddReplacing( i18n("Add 1x2 Matrix"), container );
01094 element->showLine(false);
01095 command->setElement(element);
01096 return command;
01097 }
01098 }
01099 case req_addMatrix: {
01100 MatrixRequest* mr = static_cast<MatrixRequest*>( request );
01101 uint rows = mr->rows(), cols = mr->columns();
01102 if ( ( rows == 0 ) || ( cols == 0 ) ) {
01103 MatrixDialog* dialog = new MatrixDialog( 0 );
01104 if ( dialog->exec() ) {
01105 rows = dialog->h;
01106 cols = dialog->w;
01107 }
01108 delete dialog;
01109 }
01110
01111 if ( ( rows != 0 ) && ( cols != 0 ) ) {
01112 KFCAddReplacing* command = new KFCAddReplacing( i18n( "Add Matrix" ), container );
01113 command->setElement( creationStrategy->createMatrixElement( rows, cols ) );
01114 return command;
01115 }
01116 else
01117 return 0L;
01118 }
01119 case req_addIndex: {
01120 if ( cursor->getPos() > 0 && !cursor->isSelection() ) {
01121 IndexElement* element =
01122 dynamic_cast<IndexElement*>( children.at( cursor->getPos()-1 ) );
01123 if ( element != 0 ) {
01124 element->goInside( cursor );
01125 return element->buildCommand( container, request );
01126 }
01127 }
01128 IndexElement* element = creationStrategy->createIndexElement();
01129 if ( element != 0 ) {
01130 if ( !cursor->isSelection() ) {
01131 cursor->moveLeft( SelectMovement | WordMovement );
01132 }
01133 IndexRequest* ir = static_cast<IndexRequest*>( request );
01134 KFCAddIndex* command = new KFCAddIndex( container, element,
01135 element->getIndex( ir->index() ) );
01136 return command;
01137 }
01138 break;
01139 }
01140 case req_removeEnclosing: {
01141 if ( !cursor->isSelection() ) {
01142 DirectedRemove* dr = static_cast<DirectedRemove*>( request );
01143 KFCRemoveEnclosing* command = new KFCRemoveEnclosing( container, dr->direction() );
01144 return command;
01145 }
01146 }
01147 case req_remove: {
01148 SequenceElement* sequence = cursor->normal();
01149 if ( sequence &&
01150 ( sequence == sequence->formula() ) &&
01151 ( sequence->countChildren() == 0 ) ) {
01152 sequence->formula()->removeFormula( cursor );
01153 return 0;
01154 }
01155 else {
01156 DirectedRemove* dr = static_cast<DirectedRemove*>( request );
01157
01158
01159 if ( !cursor->isSelection() ) {
01160 if ( countChildren() > 0 ) {
01161 if ( ( cursor->getPos() == 0 ) && ( dr->direction() == beforeCursor ) ) {
01162 return 0;
01163 }
01164 if ( ( cursor->getPos() == countChildren() ) && ( dr->direction() == afterCursor ) ) {
01165 return 0;
01166 }
01167 }
01168 else if ( getParent() == 0 ) {
01169 return 0;
01170 }
01171 }
01172
01173 KFCRemove* command = new KFCRemove( container, dr->direction() );
01174 return command;
01175 }
01176 }
01177 case req_compactExpression: {
01178 cursor->moveEnd();
01179 cursor->moveRight();
01180 formula()->cursorHasMoved( cursor );
01181 break;
01182 }
01183 case req_makeGreek: {
01184 TextElement* element = cursor->getActiveTextElement();
01185 if ((element != 0) && !element->isSymbol()) {
01186 cursor->selectActiveElement();
01187 const SymbolTable& table = container->document()->getSymbolTable();
01188 if (table.greekLetters().find(element->getCharacter()) != -1) {
01189 KFCReplace* command = new KFCReplace( i18n( "Change Char to Symbol" ), container );
01190 TextElement* symbol = creationStrategy->createTextElement( table.unicodeFromSymbolFont( element->getCharacter() ), true );
01191 command->addElement( symbol );
01192 return command;
01193 }
01194 cursor->setSelection( false );
01195 }
01196 break;
01197 }
01198 case req_paste:
01199 case req_copy:
01200 case req_cut:
01201 break;
01202 case req_formatBold:
01203 case req_formatItalic: {
01204 if ( cursor->isSelection() ) {
01205 CharStyleRequest* csr = static_cast<CharStyleRequest*>( request );
01206 CharStyle cs = normalChar;
01207 if ( csr->bold() ) cs = static_cast<CharStyle>( cs | boldChar );
01208 if ( csr->italic() ) cs = static_cast<CharStyle>( cs | italicChar );
01209 CharStyleCommand* cmd = new CharStyleCommand( cs, i18n( "Change Char Style" ), container );
01210 int end = cursor->getSelectionEnd();
01211 for ( int i = cursor->getSelectionStart(); i<end; ++i ) {
01212 cmd->addElement( children.at( i ) );
01213 }
01214 return cmd;
01215 }
01216 break;
01217 }
01218 case req_formatFamily: {
01219 if ( cursor->isSelection() ) {
01220 CharFamilyRequest* cfr = static_cast<CharFamilyRequest*>( request );
01221 CharFamily cf = cfr->charFamily();
01222 CharFamilyCommand* cmd = new CharFamilyCommand( cf, i18n( "Change Char Family" ), container );
01223 int end = cursor->getSelectionEnd();
01224 for ( int i = cursor->getSelectionStart(); i<end; ++i ) {
01225 cmd->addElement( children.at( i ) );
01226 }
01227 return cmd;
01228 }
01229 break;
01230 }
01231 default:
01232 break;
01233 }
01234 return 0;
01235 }
01236
01237
01238 KCommand* SequenceElement::input( Container* container, QKeyEvent* event )
01239 {
01240 QChar ch = event->text().at( 0 );
01241 if ( ch.isPrint() ) {
01242 return input( container, ch );
01243 }
01244 else {
01245 int action = event->key();
01246 int state = event->state();
01247 MoveFlag flag = movementFlag(state);
01248
01249 switch ( action ) {
01250 case Qt::Key_BackSpace: {
01251 DirectedRemove r( req_remove, beforeCursor );
01252 return buildCommand( container, &r );
01253 }
01254 case Qt::Key_Delete: {
01255 DirectedRemove r( req_remove, afterCursor );
01256 return buildCommand( container, &r );
01257 }
01258 case Qt::Key_Left: {
01259 FormulaCursor* cursor = container->activeCursor();
01260 cursor->moveLeft( flag );
01261 formula()->cursorHasMoved( cursor );
01262 break;
01263 }
01264 case Qt::Key_Right: {
01265 FormulaCursor* cursor = container->activeCursor();
01266 cursor->moveRight( flag );
01267 formula()->cursorHasMoved( cursor );
01268 break;
01269 }
01270 case Qt::Key_Up: {
01271 FormulaCursor* cursor = container->activeCursor();
01272 cursor->moveUp( flag );
01273 formula()->cursorHasMoved( cursor );
01274 break;
01275 }
01276 case Qt::Key_Down: {
01277 FormulaCursor* cursor = container->activeCursor();
01278 cursor->moveDown( flag );
01279 formula()->cursorHasMoved( cursor );
01280 break;
01281 }
01282 case Qt::Key_Home: {
01283 FormulaCursor* cursor = container->activeCursor();
01284 cursor->moveHome( flag );
01285 formula()->cursorHasMoved( cursor );
01286 break;
01287 }
01288 case Qt::Key_End: {
01289 FormulaCursor* cursor = container->activeCursor();
01290 cursor->moveEnd( flag );
01291 formula()->cursorHasMoved( cursor );
01292 break;
01293 }
01294 default:
01295 if ( state & Qt::ControlButton ) {
01296 switch ( event->key() ) {
01297 case Qt::Key_AsciiCircum: {
01298 IndexRequest r( upperLeftPos );
01299 return buildCommand( container, &r );
01300 }
01301 case Qt::Key_Underscore: {
01302 IndexRequest r( lowerLeftPos );
01303 return buildCommand( container, &r );
01304 }
01305 default:
01306 break;
01307 }
01308 }
01309 }
01310 }
01311 return 0;
01312 }
01313
01314
01315 KCommand* SequenceElement::input( Container* container, QChar ch )
01316 {
01317 int unicode = ch.unicode();
01318 switch (unicode) {
01319 case '(': {
01320 BracketRequest r( container->document()->leftBracketChar(),
01321 container->document()->rightBracketChar() );
01322 singlePipe = true;
01323 return buildCommand( container, &r );
01324 }
01325 case '[': {
01326 BracketRequest r( LeftSquareBracket, RightSquareBracket );
01327 singlePipe = true;
01328 return buildCommand( container, &r );
01329 }
01330 case '{': {
01331 BracketRequest r( LeftCurlyBracket, RightCurlyBracket );
01332 singlePipe = true;
01333 return buildCommand( container, &r );
01334 }
01335 case '|': {
01336 if (!singlePipe) {
01337
01338 DirectedRemove rDelete( req_remove, beforeCursor );
01339 KCommand* command = buildCommand( container, &rDelete );
01340 command->execute();
01341
01342 BracketRequest rBracket( LeftLineBracket , RightLineBracket);
01343 singlePipe = true;
01344 return buildCommand( container, &rBracket );
01345 }
01346 else {
01347 TextCharRequest r(ch);
01348
01349
01350 singlePipe = false;
01351
01352 return buildCommand( container, &r );
01353 }
01354 }
01355 case '^': {
01356 IndexRequest r( upperRightPos );
01357 singlePipe = true;
01358 return buildCommand( container, &r );
01359 }
01360 case '_': {
01361 IndexRequest r( lowerRightPos );
01362 singlePipe = true;
01363 return buildCommand( container, &r );
01364 }
01365
01366
01367
01368
01369
01370
01371 case '}': {
01372 Request r( req_addEmptyBox );
01373 singlePipe = true;
01374 return buildCommand( container, &r );
01375 }
01376 case ']':
01377 case ')':
01378 singlePipe = true;
01379 break;
01380 case '\\': {
01381 Request r( req_addNameSequence );
01382 singlePipe = true;
01383 return buildCommand( container, &r );
01384 }
01385 default: {
01386 singlePipe = true;
01387 if ( ch.isPunct() || ch.isSymbol() ) {
01388 OperatorRequest r( ch );
01389 return buildCommand( container, &r );
01390 }
01391 if ( ch.isNumber() ) {
01392 NumberRequest r( ch );
01393 return buildCommand( container, &r );
01394 }
01395 TextCharRequest r( ch );
01396 return buildCommand( container, &r );
01397 }
01398 }
01399 return 0;
01400 }
01401
01405 void SequenceElement::getChildrenDom( QDomDocument& doc, QDomElement elem,
01406 uint from, uint to)
01407 {
01408 for (uint i = from; i < to; i++) {
01409 QDomElement tmpEleDom=children.at(i)->getElementDom(doc);
01410 elem.appendChild(tmpEleDom);
01411 }
01412 }
01413
01417 void SequenceElement::getChildrenMathMLDom( QDomDocument& doc, QDomNode& parent,
01418 uint from, uint to)
01419 {
01420 for ( uint i = from; i < to; i++ ) {
01421 children.at( i )->writeMathML( doc, parent, false );
01422 }
01423 }
01424
01425
01431 bool SequenceElement::buildChildrenFromDom(QPtrList<BasicElement>& list, QDomNode n)
01432 {
01433 while (!n.isNull()) {
01434 if (n.isElement()) {
01435 QDomElement e = n.toElement();
01436 BasicElement* child = 0;
01437 QString tag = e.tagName().upper();
01438
01439 child = createElement(tag, e);
01440 if (child != 0) {
01441 child->setParent(this);
01442 if (child->buildFromDom(e)) {
01443 list.append(child);
01444 }
01445 else {
01446 delete child;
01447 return false;
01448 }
01449 }
01450 else {
01451 return false;
01452 }
01453 }
01454 n = n.nextSibling();
01455 }
01456 parse();
01457 return true;
01458 }
01459
01460
01461 BasicElement* SequenceElement::createElement( QString type, const QDomElement& element )
01462 {
01463 return creationStrategy->createElement( type, element );
01464 }
01465
01469 void SequenceElement::writeDom(QDomElement element)
01470 {
01471 BasicElement::writeDom(element);
01472
01473 uint count = children.count();
01474 QDomDocument doc = element.ownerDocument();
01475 getChildrenDom(doc, element, 0, count);
01476 }
01477
01482 bool SequenceElement::readAttributesFromDom(QDomElement element)
01483 {
01484 if (!BasicElement::readAttributesFromDom(element)) {
01485 return false;
01486 }
01487 return true;
01488 }
01489
01495 bool SequenceElement::readContentFromDom(QDomNode& node)
01496 {
01497 if (!BasicElement::readContentFromDom(node)) {
01498 return false;
01499 }
01500
01501 return buildChildrenFromDom(children, node);
01502 }
01503
01504
01505 void SequenceElement::parse()
01506 {
01507 delete parseTree;
01508
01509 textSequence = true;
01510 for (BasicElement* element = children.first();
01511 element != 0;
01512 element = children.next()) {
01513
01514
01515
01516 element->setElementType(0);
01517
01518 if (element->getCharacter().isNull()) {
01519 textSequence = false;
01520 }
01521 }
01522
01523 const SymbolTable& symbols = formula()->getSymbolTable();
01524 SequenceParser parser(symbols);
01525 parseTree = parser.parse(children);
01526
01527
01528
01529 BasicElement* p = getParent();
01530 if ( p != 0 ) {
01531 SequenceElement* seq = dynamic_cast<SequenceElement*>( p->getParent() );
01532 if ( seq != 0 ) {
01533 seq->parse();
01534 }
01535 }
01536
01537
01538 }
01539
01540
01541 bool SequenceElement::isFirstOfToken( BasicElement* child )
01542 {
01543 return ( child->getElementType() != 0 ) && isChildNumber( child->getElementType()->start(), child );
01544 }
01545
01546
01547 QString SequenceElement::toLatex()
01548 {
01549 QString content;
01550 uint count = children.count();
01551 for ( uint i = 0; i < count; i++ ) {
01552 BasicElement* child = children.at( i );
01553
01554
01555
01556 content += child->toLatex();
01557 }
01558 return content;
01559 }
01560
01561
01562 QString SequenceElement::formulaString()
01563 {
01564 QString content;
01565 uint count = children.count();
01566 for ( uint i = 0; i < count; i++ ) {
01567 BasicElement* child = children.at( i );
01568
01569
01570
01571 content += child->formulaString();
01572 }
01573 return content;
01574 }
01575
01576
01577 void SequenceElement::writeMathMLContent( QDomDocument& doc, QDomElement& element, bool oasisFormat ) const
01578 {
01579 for ( QPtrListIterator<BasicElement> it( children ); it.current(); ++it ) {
01580 it.current()->writeMathML( doc, element, oasisFormat );
01581 }
01582 }
01583
01584
01585 const BasicElement* SequenceElement::getChild( uint i ) const
01586 {
01587 QPtrListIterator<BasicElement> it( children );
01588 it += i;
01589 return it.current();
01590 }
01591
01592
01593 int SequenceElement::childPos( const BasicElement* child ) const
01594 {
01595 QPtrListIterator<BasicElement> it( children );
01596 uint count = it.count();
01597 for ( uint i=0; i<count; ++i, ++it ) {
01598 if ( it.current() == child ) {
01599 return i;
01600 }
01601 }
01602 return -1;
01603 }
01604
01605
01606 NameSequence::NameSequence( BasicElement* parent )
01607 : SequenceElement( parent )
01608 {
01609 }
01610
01611
01612 bool NameSequence::accept( ElementVisitor* visitor )
01613 {
01614 return visitor->visit( this );
01615 }
01616
01617
01618 void NameSequence::calcCursorSize( const ContextStyle& context,
01619 FormulaCursor* cursor, bool smallCursor )
01620 {
01621 inherited::calcCursorSize( context, cursor, smallCursor );
01622 LuPixelPoint point = widgetPos();
01623 luPixel unitX = context.ptToLayoutUnitPixX( 1 );
01624 luPixel unitY = context.ptToLayoutUnitPixY( 1 );
01625 cursor->addCursorSize( LuPixelRect( point.x()-unitX, point.y()-unitY,
01626 getWidth()+2*unitX, getHeight()+2*unitY ) );
01627 }
01628
01629 void NameSequence::drawCursor( QPainter& painter, const ContextStyle& context,
01630 StyleAttributes& style, FormulaCursor* cursor,
01631 bool smallCursor, bool activeCursor )
01632 {
01633 LuPixelPoint point = widgetPos();
01634 painter.setPen( QPen( context.getEmptyColor(),
01635 context.layoutUnitToPixelX( context.getLineWidth( style.sizeFactor() )/2 ) ) );
01636 luPixel unitX = context.ptToLayoutUnitPixX( 1 );
01637 luPixel unitY = context.ptToLayoutUnitPixY( 1 );
01638 painter.drawRect( context.layoutUnitToPixelX( point.x()-unitX ),
01639 context.layoutUnitToPixelY( point.y()-unitY ),
01640 context.layoutUnitToPixelX( getWidth()+2*unitX ),
01641 context.layoutUnitToPixelY( getHeight()+2*unitY ) );
01642
01643 inherited::drawCursor( painter, context, style, cursor, smallCursor, activeCursor );
01644 }
01645
01646 void NameSequence::moveWordLeft( FormulaCursor* cursor )
01647 {
01648 uint pos = cursor->getPos();
01649 if ( pos > 0 ) {
01650 cursor->setTo( this, 0 );
01651 }
01652 else {
01653 moveLeft( cursor, this );
01654 }
01655 }
01656
01657 void NameSequence::moveWordRight( FormulaCursor* cursor )
01658 {
01659 int pos = cursor->getPos();
01660 if ( pos < countChildren() ) {
01661 cursor->setTo( this, countChildren() );
01662 }
01663 else {
01664 moveRight( cursor, this );
01665 }
01666 }
01667
01668
01669 KCommand* NameSequence::compactExpressionCmd( Container* container )
01670 {
01671 BasicElement* element = replaceElement( container->document()->getSymbolTable() );
01672 if ( element != 0 ) {
01673 getParent()->selectChild( container->activeCursor(), this );
01674
01675 KFCReplace* command = new KFCReplace( i18n( "Add Element" ), container );
01676 command->addElement( element );
01677 return command;
01678 }
01679 return 0;
01680 }
01681
01682 KCommand* NameSequence::buildCommand( Container* container, Request* request )
01683 {
01684 switch ( *request ) {
01685 case req_compactExpression:
01686 return compactExpressionCmd( container );
01687 case req_addSpace:
01688 case req_addIndex:
01689 case req_addMatrix:
01690 case req_addOneByTwoMatrix:
01691 case req_addSymbol:
01692 case req_addRoot:
01693 case req_addFraction:
01694 case req_addBracket:
01695 case req_addNameSequence:
01696 return 0;
01697 default:
01698 break;
01699 }
01700 return inherited::buildCommand( container, request );
01701 }
01702
01703
01704 KCommand* NameSequence::input( Container* container, QChar ch )
01705 {
01706 int unicode = ch.unicode();
01707 switch (unicode) {
01708 case '(':
01709 case '[':
01710 case '|':
01711 case '^':
01712 case '_':
01713 case '}':
01714 case ']':
01715 case ')':
01716 case '\\': {
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728 break;
01729 }
01730 case '{':
01731 case ' ': {
01732 Request r( req_compactExpression );
01733 return buildCommand( container, &r );
01734 }
01735 default: {
01736 TextCharRequest r( ch );
01737 return buildCommand( container, &r );
01738 }
01739 }
01740 return 0;
01741 }
01742
01743 void NameSequence::setElementType( ElementType* t )
01744 {
01745 inherited::setElementType( t );
01746 parse();
01747 }
01748
01749 BasicElement* NameSequence::replaceElement( const SymbolTable& table )
01750 {
01751 QString name = buildName();
01752 QChar ch = table.unicode( name );
01753 if ( !ch.isNull() ) {
01754 return new TextElement( ch, true );
01755 }
01756 else {
01757 ch = table.unicode( i18n( name.latin1() ) );
01758 if ( !ch.isNull() ) {
01759 return new TextElement( ch, true );
01760 }
01761 }
01762
01763 if ( name == "!" ) return new SpaceElement( NEGTHIN );
01764 if ( name == "," ) return new SpaceElement( THIN );
01765 if ( name == ">" ) return new SpaceElement( MEDIUM );
01766 if ( name == ";" ) return new SpaceElement( THICK );
01767 if ( name == "quad" ) return new SpaceElement( QUAD );
01768
01769 if ( name == "frac" ) return new FractionElement();
01770 if ( name == "atop" ) {
01771 FractionElement* frac = new FractionElement();
01772 frac->showLine( false );
01773 return frac;
01774 }
01775 if ( name == "sqrt" ) return new RootElement();
01776
01777 return 0;
01778 }
01779
01780 BasicElement* NameSequence::createElement( QString type )
01781 {
01782 if ( type == "TEXT" ) return new TextElement();
01783 return 0;
01784 }
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795 QString NameSequence::buildName()
01796 {
01797 QString name;
01798 for ( uint i = 0; i < countChildren(); i++ ) {
01799 name += getChild( i )->getCharacter();
01800 }
01801 return name;
01802 }
01803
01804 bool NameSequence::isValidSelection( FormulaCursor* cursor )
01805 {
01806 SequenceElement* sequence = cursor->normal();
01807 if ( sequence == 0 ) {
01808 return false;
01809 }
01810 return sequence->onlyTextSelected( cursor );
01811 }
01812
01813 int SequenceElement::buildChildrenFromMathMLDom(QPtrList<BasicElement>& list, QDomNode n)
01814 {
01815 while (!n.isNull()) {
01816 int nodeNumber = 1;
01817 if (n.isElement()) {
01818 QDomElement e = n.toElement();
01819 BasicElement* child = 0;
01820 QString tag = e.tagName().lower();
01821
01822 kdDebug( DEBUGID ) << "Sequence Tag: " << tag << endl;
01823 if ( tag == "semantics" ) {
01824 QDomNode node = e.firstChild();
01825 while( ! node.isElement() ) {
01826 node = node.nextSibling();
01827 if ( node.isNull() ) {
01828 return -1;
01829 }
01830 }
01831 e = node.toElement();
01832 tag = e.tagName().lower();
01833 }
01834 child = creationStrategy->createElement(tag, e);
01835 if (child != 0) {
01836 child->setParent(this);
01837 if (style != 0) {
01838 child->setStyle(style);
01839 }
01840 nodeNumber = child->buildFromMathMLDom( e );
01841 if ( nodeNumber != -1 ) {
01842 list.append(child);
01843 }
01844 else {
01845 delete child;
01846 return -1;
01847 }
01848 }
01849 else {
01850 kdWarning() << "Unsupported MathML element: " << tag << endl;
01851 }
01852 }
01853 for (int i = 0; i < nodeNumber; i++ ) {
01854 if ( n.isNull() ) {
01855 return -1;
01856 }
01857 n = n.nextSibling();
01858 }
01859 }
01860
01861
01862
01863
01864
01865
01866
01867 if ( list.count() > 1 ) {
01868 if ( list.getFirst()->getElementName() == "mo" ) {
01869 static_cast<OperatorElement*>( list.getFirst() )->setForm( PrefixForm );
01870 }
01871 if ( list.getLast()->getElementName() == "mo" ) {
01872 static_cast<OperatorElement*>( list.getLast() )->setForm( PostfixForm );
01873 }
01874 for ( uint i = 1; i < list.count() - 1; i++ ) {
01875 if ( list.at( i )->getElementName() == "mo" ) {
01876 static_cast<OperatorElement*>( list.at( i ) )->setForm( InfixForm );
01877 }
01878 }
01879 }
01880 else if ( list.count() == 1 ) {
01881 if ( list.getFirst()->getElementName() == "mo" ) {
01882 static_cast<OperatorElement*>( list.getFirst() )->setForm( InfixForm );
01883 }
01884 }
01885 parse();
01886 return 1;
01887 }
01888
01891 int SequenceElement::readContentFromMathMLDom(QDomNode& node)
01892 {
01893 if ( BasicElement::readContentFromMathMLDom(node) == -1 ) {
01894 return -1;
01895 }
01896
01897 return buildChildrenFromMathMLDom(children, node);
01898 }
01899
01900 int SequenceElement::buildMathMLChild( QDomNode node )
01901 {
01902 int nodeCounter = 1;
01903 while ( ! node.isElement() ) {
01904 node = node.nextSibling();
01905 nodeCounter++;
01906 if ( node.isNull() ) {
01907 return -1;
01908 }
01909 }
01910 QDomElement e = node.toElement();
01911 BasicElement* child = 0;
01912 QString tag = e.tagName().lower();
01913
01914 child = creationStrategy->createElement(tag, e);
01915 if (child != 0) {
01916 child->setParent(this);
01917 if (style != 0) {
01918 child->setStyle(style);
01919 }
01920 if (child->buildFromMathMLDom(e) != -1) {
01921 children.append(child);
01922 }
01923 else {
01924 delete child;
01925 return -1;
01926 }
01927 }
01928 else {
01929 return -1;
01930 }
01931 parse();
01932 return nodeCounter;
01933 }
01934
01935
01936
01937 KFORMULA_NAMESPACE_END