00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <qpainter.h>
00022
00023
#include <kdebug.h>
00024
#include <assert.h>
00025
00026
#include "formulacursor.h"
00027
#include "formulaelement.h"
00028
#include "indexelement.h"
00029
#include "matrixelement.h"
00030
#include "rootelement.h"
00031
#include "sequenceelement.h"
00032
#include "symbolelement.h"
00033
#include "textelement.h"
00034
00035 KFORMULA_NAMESPACE_BEGIN
00036
00037 FormulaCursor::FormulaCursor(
FormulaElement* element)
00038 : selectionFlag(false), linearMovement(false),
00039 hasChangedFlag(true), readOnly(false)
00040 {
00041
00042 element->
goInside(
this );
00043 }
00044
00045 void FormulaCursor::setTo(
BasicElement* element,
int cursor,
int mark)
00046 {
00047 hasChangedFlag =
true;
00048 current = element;
00049 cursorPos = cursor;
00050
if ((mark == -1) && selectionFlag) {
00051
return;
00052 }
00053
if (mark != -1) {
00054
setSelection(
true);
00055 }
00056 markPos = mark;
00057 }
00058
00059
00060
void FormulaCursor::setPos(
int pos)
00061 {
00062 hasChangedFlag =
true;
00063 cursorPos = pos;
00064 }
00065
00066
void FormulaCursor::setMark(
int mark)
00067 {
00068 hasChangedFlag =
true;
00069 markPos = mark;
00070 }
00071
00072 void FormulaCursor::calcCursorSize(
const ContextStyle& context,
bool smallCursor )
00073 {
00074
00075
SequenceElement* sequence = dynamic_cast<SequenceElement*>(current);
00076
00077
if (sequence != 0) {
00078 sequence->
calcCursorSize( context,
this, smallCursor );
00079 }
00080 }
00081
00082 void FormulaCursor::draw(
QPainter& painter,
const ContextStyle& context,
bool smallCursor )
00083 {
00084
00085
00086
00087
00088
SequenceElement* sequence = dynamic_cast<SequenceElement*>(current);
00089
00090
if (sequence != 0) {
00091 sequence->
drawCursor( painter, context,
this, smallCursor );
00092 }
00093 }
00094
00095
00096
void FormulaCursor::handleSelectState(
int flag)
00097 {
00098
if (flag & SelectMovement) {
00099
if (!
isSelection()) {
00100 setMark(getPos());
00101 setSelection(
true);
00102 }
00103 }
00104
else {
00105
setSelection(
false);
00106 }
00107 }
00108
00109
void FormulaCursor::moveLeft(
int flag)
00110 {
00111
BasicElement* element =
getElement();
00112 handleSelectState(flag);
00113
if (flag & WordMovement) {
00114
SequenceElement* sequence = dynamic_cast<SequenceElement*>(current);
00115
if (sequence != 0) {
00116 sequence->
moveWordLeft(
this);
00117 }
00118
else {
00119 element->
moveHome(
this);
00120 }
00121 }
00122
else {
00123 element->
moveLeft(
this, element);
00124 }
00125 }
00126
00127
void FormulaCursor::moveRight(
int flag)
00128 {
00129
BasicElement* element =
getElement();
00130 handleSelectState(flag);
00131
if (flag & WordMovement) {
00132
SequenceElement* sequence = dynamic_cast<SequenceElement*>(current);
00133
if (sequence != 0) {
00134 sequence->
moveWordRight(
this);
00135 }
00136
else {
00137 element->
moveEnd(
this);
00138 }
00139 }
00140
else {
00141 element->
moveRight(
this, element);
00142 }
00143 }
00144
00145
void FormulaCursor::moveUp(
int flag)
00146 {
00147
BasicElement* element =
getElement();
00148 handleSelectState(flag);
00149 element->
moveUp(
this, element);
00150 }
00151
00152
void FormulaCursor::moveDown(
int flag)
00153 {
00154
BasicElement* element =
getElement();
00155 handleSelectState(flag);
00156 element->
moveDown(
this, element);
00157 }
00158
00159
void FormulaCursor::moveHome(
int flag)
00160 {
00161
BasicElement* element =
getElement();
00162 handleSelectState(flag);
00163
if (flag & WordMovement) {
00164 element->
formula()->
moveHome(
this);
00165 }
00166
else {
00167 element->
moveHome(
this);
00168 }
00169 }
00170
00171
void FormulaCursor::moveEnd(
int flag)
00172 {
00173
BasicElement* element =
getElement();
00174 handleSelectState(flag);
00175
if (flag & WordMovement) {
00176 element->
formula()->
moveEnd(
this);
00177 }
00178
else {
00179 element->
moveEnd(
this);
00180 }
00181 }
00182
00183 bool FormulaCursor::isHome()
const
00184
{
00185
return (
getElement() ==
getElement()->
formula() ) && ( getPos() == 0 );
00186 }
00187
00188 bool FormulaCursor::isEnd()
const
00189
{
00190
return (
getElement() ==
getElement()->
formula() ) &&
00191 ( getPos() ==
normal()->
countChildren() );
00192 }
00193
00194
void FormulaCursor::mousePress(
const LuPixelPoint& pos,
int flag )
00195 {
00196
FormulaElement* formula =
getElement()->
formula();
00197 formula->
goToPos(
this, pos );
00198
if (flag & SelectMovement) {
00199 setSelection(
true);
00200
if (getMark() == -1) {
00201 setMark(getPos());
00202 }
00203 }
00204
else {
00205
setSelection(
false);
00206 setMark(getPos());
00207 }
00208 }
00209
00210
void FormulaCursor::mouseMove(
const LuPixelPoint& point,
int )
00211 {
00212
setSelection(
true);
00213
BasicElement* element =
getElement();
00214
int mark = getMark();
00215
00216
FormulaElement* formula =
getElement()->
formula();
00217 formula->
goToPos(
this, point );
00218
BasicElement* newElement =
getElement();
00219
int pos = getPos();
00220
00221
BasicElement* posChild = 0;
00222
BasicElement* markChild = 0;
00223
while (element != newElement) {
00224 posChild = newElement;
00225 newElement = newElement->
getParent();
00226
if (newElement == 0) {
00227 posChild = 0;
00228 newElement =
getElement();
00229 markChild = element;
00230 element = element->
getParent();
00231 }
00232 }
00233
00234
if (dynamic_cast<SequenceElement*>(element) == 0) {
00235 element = element->
getParent();
00236 element->
selectChild(
this, newElement);
00237 }
00238
else {
00239
if (posChild != 0) {
00240 element->
selectChild(
this, posChild);
00241 pos = getPos();
00242 }
00243
if (markChild != 0) {
00244 element->
selectChild(
this, markChild);
00245 mark = getMark();
00246 }
00247
if (pos == mark) {
00248
if ((posChild == 0) && (markChild != 0)) {
00249 mark++;
00250 }
00251
else if ((posChild != 0) && (markChild == 0)) {
00252 mark--;
00253 }
00254 }
00255
else if (pos < mark) {
00256
if (posChild != 0) {
00257 pos--;
00258 }
00259 }
00260
setTo(element, pos, mark);
00261 }
00262 }
00263
00264
void FormulaCursor::mouseRelease(
const LuPixelPoint&,
int )
00265 {
00266
00267 }
00268
00269
00273 void FormulaCursor::goInsideElement(
BasicElement* element)
00274 {
00275 element->
goInside(
this);
00276 }
00277
00278
00285 void FormulaCursor::normalize(Direction direction)
00286 {
00287
BasicElement* element =
getElement();
00288 element->
normalize(
this, direction);
00289 }
00290
00291
00296 void FormulaCursor::insert(
BasicElement* child, Direction direction)
00297 {
00298
QPtrList<BasicElement> list;
00299 list.append(child);
00300
insert(list, direction);
00301 }
00302
00303 void FormulaCursor::insert(
QPtrList<BasicElement>& children,
00304 Direction direction)
00305 {
00306 assert( !
isReadOnly() );
00307
BasicElement* element =
getElement();
00308 element->
insert(
this, children, direction);
00309 }
00310
00311
00317 void FormulaCursor::remove(
QPtrList<BasicElement>& children,
00318 Direction direction)
00319 {
00320 assert( !
isReadOnly() );
00321
SequenceElement* sequence =
normal();
00322
if (sequence != 0) {
00323
00324
00325
00326
if (sequence->
countChildren() == 0) {
00327
BasicElement* parent = sequence->
getParent();
00328
if (parent != 0) {
00329 parent->
selectChild(
this, sequence);
00330 parent->
remove(
this, children, direction);
00331
return;
00332 }
00333 }
00334
else {
00335 sequence->
remove(
this, children, direction);
00336 }
00337 }
00338 }
00339
00340
00345 void FormulaCursor::replaceSelectionWith(
BasicElement* element,
00346 Direction direction)
00347 {
00348 assert( !
isReadOnly() );
00349
QPtrList<BasicElement> list;
00350
00351
00352
00353
00354
00355
if (
isSelection()) {
00356
getElement()->
remove(
this, list, direction);
00357 }
00358
00359
insert(element, direction);
00360
SequenceElement* mainChild = element->
getMainChild();
00361
if (mainChild != 0) {
00362 mainChild->
goInside(
this);
00363
insert(list);
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 element->
selectChild(
this, mainChild);
00374 }
00375 }
00376
00377
00382 BasicElement*
FormulaCursor::replaceByMainChildContent(Direction direction)
00383 {
00384 assert( !
isReadOnly() );
00385
QPtrList<BasicElement> childrenList;
00386
QPtrList<BasicElement> list;
00387
BasicElement* element =
getElement();
00388
SequenceElement* mainChild = element->
getMainChild();
00389
if ((mainChild != 0) && (mainChild->
countChildren() > 0)) {
00390 mainChild->
selectAllChildren(
this);
00391
remove(childrenList);
00392 }
00393 element->
getParent()->
moveRight(
this, element);
00394
setSelection(
false);
00395
remove(list);
00396
insert(childrenList, direction);
00397
if (list.count() > 0) {
00398
return list.take(0);
00399 }
00400
return 0;
00401 }
00402
00403
00411 BasicElement*
FormulaCursor::removeEnclosingElement(Direction direction)
00412 {
00413 assert( !
isReadOnly() );
00414
BasicElement* parent =
getElement()->
getParent();
00415
if (parent != 0) {
00416
if (
getElement() == parent->
getMainChild()) {
00417 parent->
selectChild(
this,
getElement());
00418
return replaceByMainChildContent(direction);
00419 }
00420 }
00421
return 0;
00422 }
00423
00424
00429 bool FormulaCursor::elementIsSenseless()
00430 {
00431
BasicElement* element =
getElement();
00432
return element->
isSenseless();
00433 }
00434
00435
00443
BasicElement* FormulaCursor::getActiveChild(Direction direction)
00444 {
00445
return getElement()->
getChild(
this, direction);
00446 }
00447
00448
BasicElement* FormulaCursor::getSelectedChild()
00449 {
00450
if (
isSelection()) {
00451
if ((getSelectionEnd() - getSelectionStart()) > 1) {
00452
return 0;
00453 }
00454
return getActiveChild((getPos() > getMark()) ?
00455 beforeCursor :
00456 afterCursor);
00457 }
00458
else {
00459
return getActiveChild(beforeCursor);
00460 }
00461 }
00462
00463
00464 void FormulaCursor::selectActiveElement()
00465 {
00466
if ( !
isSelection() && getPos() > 0 ) {
00467
setSelection(
true );
00468 setMark( getPos() - 1 );
00469 }
00470 }
00471
00472
00477
bool FormulaCursor::pointsAfterMainChild(
BasicElement* element)
00478 {
00479
if (element != 0) {
00480
SequenceElement* mainChild = element->
getMainChild();
00481
return (
getElement() == mainChild) &&
00482 ((mainChild->
countChildren() == getPos()) || (0 == getPos()));
00483 }
00484
return false;
00485 }
00486
00487
00492 IndexElement*
FormulaCursor::getActiveIndexElement()
00493 {
00494
IndexElement* element = dynamic_cast<IndexElement*>(getSelectedChild());
00495
00496
if ((element == 0) && !
isSelection()) {
00497 element = dynamic_cast<IndexElement*>(
getElement()->
getParent());
00498
if (!pointsAfterMainChild(element)) {
00499
return 0;
00500 }
00501 }
00502
return element;
00503 }
00504
00505
00510 RootElement*
FormulaCursor::getActiveRootElement()
00511 {
00512
RootElement* element = dynamic_cast<RootElement*>(getSelectedChild());
00513
00514
if ((element == 0) && !
isSelection()) {
00515 element = dynamic_cast<RootElement*>(
getElement()->
getParent());
00516
if (!pointsAfterMainChild(element)) {
00517
return 0;
00518 }
00519 }
00520
return element;
00521 }
00522
00523
00528 SymbolElement*
FormulaCursor::getActiveSymbolElement()
00529 {
00530
SymbolElement* element = dynamic_cast<SymbolElement*>(getSelectedChild());
00531
00532
if ((element == 0) && !
isSelection()) {
00533 element = dynamic_cast<SymbolElement*>(
getElement()->
getParent());
00534
if (!pointsAfterMainChild(element)) {
00535
return 0;
00536 }
00537 }
00538
return element;
00539 }
00540
00545 NameSequence*
FormulaCursor::getActiveNameSequence()
00546 {
00547
NameSequence* element = dynamic_cast<NameSequence*>( getSelectedChild() );
00548
00549
if ( ( element == 0 ) && !
isSelection() ) {
00550 element = dynamic_cast<NameSequence*>(
getElement() );
00551
if ( !pointsAfterMainChild( element ) ) {
00552
return 0;
00553 }
00554 }
00555
return element;
00556 }
00557
00561 TextElement*
FormulaCursor::getActiveTextElement()
00562 {
00563
return dynamic_cast<TextElement*>(getSelectedChild());
00564 }
00565
00566
00567 MatrixElement*
FormulaCursor::getActiveMatrixElement()
00568 {
00569
MatrixElement* element = dynamic_cast<MatrixElement*>(getSelectedChild());
00570
00571
if ( ( element != 0 ) && !
isSelection() ) {
00572
normal()->
selectChild(
this, element );
00573 }
00574
00575
00576
00577
00578
00579
00580
return element;
00581 }
00582
00586 void FormulaCursor::elementWillVanish(
BasicElement* element)
00587 {
00588
BasicElement* child =
getElement();
00589
if (child == element->
getParent()) {
00590 child->
childWillVanish(
this, element);
00591
return;
00592 }
00593
while (child != 0) {
00594
if (child == element) {
00595
00596
00597 child->
getParent()->
moveLeft(
this, child);
00598
setSelection(
false);
00599 hasChangedFlag =
true;
00600
return;
00601 }
00602 child = child->
getParent();
00603 }
00604 }
00605
00606
00610 void FormulaCursor::formulaLoaded(
FormulaElement* rootElement)
00611 {
00612
00613
00614 rootElement->
goInside(
this );
00615 setMark(-1);
00616
setSelection(
false);
00617 }
00618
00619
00620 bool FormulaCursor::isReadOnly()
const
00621
{
00622
if ( readOnly ) {
00623
return true;
00624 }
00625
const SequenceElement* sequence =
normal();
00626
if ( sequence != 0 ) {
00627
bool ro = sequence->
readOnly(
this );
00628
00629
return ro;
00630 }
00631
return false;
00632 }
00633
00634
00638 void FormulaCursor::copy(
QDomDocument doc )
00639 {
00640
if (
isSelection()) {
00641
SequenceElement* sequence =
normal();
00642
if (sequence != 0) {
00643
QDomElement root = doc.documentElement();
00644
QDomElement de = sequence->
formula()->
emptyFormulaElement( doc );
00645 root.appendChild( de );
00646
00647 sequence->
getChildrenDom(doc, de, getSelectionStart(), getSelectionEnd());
00648 }
00649
else {
00650
00651 qFatal(
"A not normalized cursor is selecting.");
00652 }
00653 }
00654 }
00655
00660 bool FormulaCursor::buildElementsFromDom(
QDomElement root,
QPtrList<BasicElement>& list )
00661 {
00662 assert( !
isReadOnly() );
00663
SequenceElement* sequence =
normal();
00664
if (sequence != 0) {
00665
QDomElement e = root.firstChild().toElement();
00666
if (sequence->
buildChildrenFromDom(list, e.firstChild())) {
00667
return true;
00668 }
00669 }
00670
return false;
00671 }
00672
00673
00678 FormulaCursor::CursorData*
FormulaCursor::getCursorData()
00679 {
00680
return new CursorData(current, cursorPos, markPos,
00681 selectionFlag, linearMovement, readOnly);
00682 }
00683
00684
00685
00686
FormulaCursor& FormulaCursor::operator= (
const FormulaCursor& other)
00687 {
00688 current = other.
current;
00689 cursorPos = other.
cursorPos;
00690 markPos = other.
markPos;
00691 selectionFlag = other.
selectionFlag;
00692 linearMovement = other.
linearMovement;
00693 readOnly = other.
readOnly;
00694 hasChangedFlag =
true;
00695
return *
this;
00696 }
00697
00698
00703 void FormulaCursor::setCursorData(
FormulaCursor::CursorData* data)
00704 {
00705 current = data->
current;
00706 cursorPos = data->
cursorPos;
00707 markPos = data->
markPos;
00708 selectionFlag = data->
selectionFlag;
00709 linearMovement = data->
linearMovement;
00710 readOnly = data->
readOnly;
00711 hasChangedFlag =
true;
00712 }
00713
00714
00718 SequenceElement*
FormulaCursor::normal()
00719 {
00720
return dynamic_cast<SequenceElement*>(current);
00721 }
00722
00723
const SequenceElement*
FormulaCursor::normal()
const
00724
{
00725
return dynamic_cast<SequenceElement*>(current);
00726 }
00727
00728 KFORMULA_NAMESPACE_END