00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "katecodefoldinghelpers.h"
00020
#include "katecodefoldinghelpers.moc"
00021
00022
#include "katebuffer.h"
00023
#include "katecursor.h"
00024
#include <kdebug.h>
00025
00026
#include <qstring.h>
00027
00028
#define JW_DEBUG 0
00029
00030
bool KateCodeFoldingTree::trueVal =
true;
00031
00032 KateCodeFoldingNode::KateCodeFoldingNode() :
00033 parentNode(0),
00034 startLineRel(0),
00035 endLineRel(0),
00036 startCol(0),
00037 endCol(0),
00038 startLineValid(false),
00039 endLineValid(false),
00040 type(0),
00041 visible(true),
00042 deleteOpening(false),
00043 deleteEnding(false)
00044 {
00045 }
00046
00047 KateCodeFoldingNode::KateCodeFoldingNode(KateCodeFoldingNode *par,
signed char typ,
unsigned int sLRel):
00048 parentNode(par),
00049 startLineRel(sLRel),
00050 endLineRel(10000),
00051 startCol(0),
00052 endCol(0),
00053 startLineValid(true),
00054 endLineValid(false),
00055 type(typ),
00056 visible(true),
00057 deleteOpening(false),
00058 deleteEnding(false)
00059 {
00060 }
00061
00062 KateCodeFoldingNode::~KateCodeFoldingNode()
00063 {
00064
00065 clearChildren ();
00066 }
00067
00068
bool KateCodeFoldingNode::getBegin(KateCodeFoldingTree *tree,
KateTextCursor* begin) {
00069
if (!startLineValid)
return false;
00070
unsigned int line=startLineRel;
00071
for (KateCodeFoldingNode *n=parentNode;n;n=n->parentNode)
00072 line+=n->startLineRel;
00073
00074 tree->m_buffer->codeFoldingColumnUpdate(line);
00075 begin->
setLine(line);
00076 begin->
setCol(startCol);
00077
00078
return true;
00079 }
00080
00081
bool KateCodeFoldingNode::getEnd(KateCodeFoldingTree *tree,
KateTextCursor *end) {
00082
if (!endLineValid)
return false;
00083
unsigned int line=startLineRel+endLineRel;
00084
for (KateCodeFoldingNode *n=parentNode;n;n=n->parentNode)
00085 line+=n->startLineRel;
00086
00087 tree->m_buffer->codeFoldingColumnUpdate(line);
00088
end->setLine(line);
00089
end->setCol(endCol);
00090
00091
return true;
00092 }
00093
00094
int KateCodeFoldingNode::cmpPos(KateCodeFoldingTree *tree, uint line,uint col) {
00095
KateTextCursor cur(line,col);
00096
KateTextCursor start,
end;
00097
kdDebug(13000)<<
"KateCodeFoldingNode::cmpPos (1)"<<
endl;
00098
bool startValid=getBegin(tree, &start);
00099
kdDebug(13000)<<
"KateCodeFoldingNode::cmpPos (2)"<<
endl;
00100
bool endValid=getEnd(tree, &end);
00101
kdDebug(13000)<<
"KateCodeFoldingNode::cmpPos (3)"<<
endl;
00102
if ((!endValid) && startValid) {
00103
return ((start>cur)?-1:0);
00104 }
00105
if ((!startValid) && endValid) {
00106
return ((cur>
end)?1:0);
00107 }
00108
00109 Q_ASSERT(startValid && endValid);
00110
return ( (cur<start)?(-1):( (cur>
end) ? 1:0));
00111 }
00112
00113
void KateCodeFoldingNode::insertChild (uint index, KateCodeFoldingNode *node)
00114 {
00115 uint s = m_children.size ();
00116
00117
if (index > s)
00118
return;
00119
00120 m_children.resize (++s);
00121
00122
for (uint i=s-1; i > index; --i)
00123 m_children[i] = m_children[i-1];
00124
00125 m_children[index] = node;
00126 }
00127
00128 KateCodeFoldingNode *KateCodeFoldingNode::takeChild (uint index)
00129 {
00130 uint s = m_children.size ();
00131
00132
if (index >= s)
00133
return 0;
00134
00135 KateCodeFoldingNode *n = m_children[index];
00136
00137
for (uint i=index; (i+1) < s; ++i)
00138 m_children[i] = m_children[i+1];
00139
00140 m_children.resize (s-1);
00141
00142
return n;
00143 }
00144
00145
void KateCodeFoldingNode::clearChildren ()
00146 {
00147
for (uint i=0; i < m_children.size(); ++i)
00148
delete m_children[i];
00149
00150 m_children.resize (0);
00151 }
00152
00153 KateCodeFoldingTree::KateCodeFoldingTree(
KateBuffer *buffer):
QObject(buffer), m_buffer (buffer)
00154 {
00155
clear();
00156 }
00157
00158
void KateCodeFoldingTree::fixRoot(
int endLRel)
00159 {
00160 m_root.endLineRel = endLRel;
00161 }
00162
00163
void KateCodeFoldingTree::clear()
00164 {
00165 m_root.clearChildren();
00166
00167
00168 m_root.startLineValid=
true;
00169 m_root.endLineValid=
true;
00170 m_root.endLineRel=1;
00171
00172 hiddenLinesCountCacheValid=
false;
00173 lineMapping.setAutoDelete(
true);
00174 hiddenLines.clear();
00175 lineMapping.clear();
00176 nodesForLine.clear();
00177 markedForDeleting.clear();
00178 dontIgnoreUnchangedLines.clear();
00179 }
00180
00181 KateCodeFoldingTree::~KateCodeFoldingTree()
00182 {
00183 }
00184
00185
bool KateCodeFoldingTree::isTopLevel(
unsigned int line)
00186 {
00187
if (m_root.noChildren())
00188
return true;
00189
00190
00191
for ( uint i=0; i < m_root.childCount(); ++i )
00192 {
00193 KateCodeFoldingNode *node = m_root.child(i);
00194
00195
if ((node->startLineRel<=line) && (line<=node->startLineRel+node->endLineRel))
00196
return false;
00197 }
00198
00199
return true;
00200 }
00201
00202
void KateCodeFoldingTree::getLineInfo(KateLineInfo *info,
unsigned int line)
00203 {
00204
00205
00206 info->topLevel =
true;
00207 info->startsVisibleBlock =
false;
00208 info->startsInVisibleBlock =
false;
00209 info->endsBlock =
false;
00210 info->invalidBlockEnd =
false;
00211
00212
if (m_root.noChildren())
00213
return;
00214
00215
00216
for ( uint i=0; i < m_root.childCount(); ++i )
00217 {
00218 KateCodeFoldingNode *node = m_root.child(i);
00219
00220
if ((node->startLineRel<=line) && (line<=node->startLineRel+node->endLineRel))
00221 {
00222 info->topLevel =
false;
00223 findAllNodesOpenedOrClosedAt(line);
00224
00225
for ( KateCodeFoldingNode *node = nodesForLine.first(); node; node = nodesForLine.next() )
00226 {
00227 uint startLine = getStartLine(node);
00228
00229
00230
00231
if (node->type < 0)
00232 info->invalidBlockEnd=
true;
00233
else
00234 {
00235
if (startLine != line)
00236 info->endsBlock =
true;
00237
else
00238 {
00239
00240
if (node->visible)
00241 info->startsVisibleBlock=
true;
00242
else
00243 info->startsInVisibleBlock=
true;
00244 }
00245 }
00246 }
00247
00248
return;
00249 }
00250 }
00251
00252
return;
00253 }
00254
00255
00256 KateCodeFoldingNode *KateCodeFoldingTree::findNodeForLine(
unsigned int line)
00257 {
00258
if (m_root.noChildren())
00259
return &m_root;
00260
00261
00262
for ( uint i=0; i < m_root.childCount(); ++i )
00263 {
00264 KateCodeFoldingNode *node = m_root.child(i);
00265
00266
if ((node->startLineRel<=line) && (line<=node->startLineRel+node->endLineRel))
00267 {
00268
00269
return findNodeForLineDescending(node,line,0);
00270 }
00271 }
00272
00273
return &m_root;
00274 }
00275
00276
00277 KateCodeFoldingNode *KateCodeFoldingTree::findNodeForLineDescending ( KateCodeFoldingNode *node,
00278
unsigned int line,
unsigned int offset,
bool oneStepOnly )
00279 {
00280
if (node->noChildren())
00281
return node;
00282
00283
00284 offset += node->startLineRel;
00285
00286
for ( uint i=0; i < node->childCount(); ++i )
00287 {
00288 KateCodeFoldingNode *subNode = node->child(i);
00289
00290
if ((subNode->startLineRel+offset<=line) && (line<=subNode->endLineRel+subNode->startLineRel+offset))
00291 {
00292
00293
00294
00295
if (oneStepOnly)
00296
return subNode;
00297
else
00298
return findNodeForLineDescending (subNode,line,offset);
00299 }
00300 }
00301
00302
return node;
00303 }
00304
00305 KateCodeFoldingNode *KateCodeFoldingTree::findNodeForPosition(
unsigned int line,
unsigned int column)
00306 {
00307 KateCodeFoldingNode *node=findNodeForLine(line);
00308
00309
if (node==&m_root)
return &m_root;
00310
00311
kdDebug(13000)<<
"initial cmpPos"<<
endl;
00312
00313 KateCodeFoldingNode *tmp;
00314
int leq=node->cmpPos(
this, line,column);
00315
while (
true) {
00316
switch (leq) {
00317
case 0: {
00318
if (node->noChildren())
00319
return node;
00320
else
00321 {
00322 tmp=node;
00323
for ( uint i=0; i < node->childCount(); ++i )
00324 {
00325 KateCodeFoldingNode *subNode = node->child(i);
00326
kdDebug(13000)<<
"cmdPos(case0):calling"<<
endl;
00327 leq=subNode->cmpPos(
this, line,column);
00328
kdDebug(13000)<<
"cmdPos(case0):returned"<<
endl;
00329
if (leq==0) {
00330 tmp=subNode;
00331
break;
00332 }
else if (leq==-1)
break;
00333 }
00334
if (tmp!=node) node=tmp;
else return node;
00335 }
00336
break;
00337 }
00338
00339
case -1:
00340
case 1: {
00341
if (!(node->parentNode))
return &m_root;
00342
kdDebug(13000)<<
"current node type"<<node->type<<
endl;
00343 node=node->parentNode;
00344
kdDebug(13000)<<
"cmdPos(case-1/1):calling:"<<node<<
endl;
00345 leq=node->cmpPos(
this, line,column);
00346
kdDebug(13000)<<
"cmdPos(case-1/1):returned"<<
endl;
00347
break;
00348 }
00349 }
00350
00351 }
00352 Q_ASSERT(
false);
00353
return &m_root;
00354 }
00355
00356
void KateCodeFoldingTree::debugDump()
00357 {
00358
00359
kdDebug(13000)<<
"The parsed region/block tree for code folding"<<
endl;
00360 dumpNode(&m_root,
"");
00361 }
00362
00363
void KateCodeFoldingTree::dumpNode(KateCodeFoldingNode *node,
const QString &prefix)
00364 {
00365
00366
kdDebug(13000)<<prefix<<
QString(
"Type: %1, startLineValid %2, startLineRel %3, endLineValid %4, endLineRel %5, visible %6").
00367 arg(node->type).arg(node->startLineValid).arg(node->startLineRel).arg(node->endLineValid).
00368 arg(node->endLineRel).arg(node->visible)<<
endl;
00369
00370
00371
if (node->noChildren())
00372
return;
00373
00374 QString newprefix(prefix +
" ");
00375
for ( uint i=0; i < node->childCount(); ++i )
00376 dumpNode (node->child(i),newprefix);
00377 }
00378
00379
00380
00381
00382
void KateCodeFoldingTree::updateLine(
unsigned int line,
00383
QMemArray<uint> *regionChanges,
bool *updated,
bool changed,
bool colsChanged)
00384 {
00385
if ( (!changed) || colsChanged)
00386 {
00387
if (dontIgnoreUnchangedLines.isEmpty())
00388
return;
00389
00390
if (dontIgnoreUnchangedLines[line])
00391 dontIgnoreUnchangedLines.remove(line);
00392
else
00393
return;
00394 }
00395
00396 something_changed =
false;
00397
00398 findAndMarkAllNodesforRemovalOpenedOrClosedAt(line);
00399
00400
if (regionChanges->isEmpty())
00401 {
00402
00403
00404
00405 }
00406
else
00407 {
00408
for (
unsigned int i=0;i<regionChanges->size() / 4;i++)
00409 {
00410
signed char tmp=(*regionChanges)[regionChanges->size()-2-i*2];
00411 uint tmppos=(*regionChanges)[regionChanges->size()-1-i*2];
00412 (*regionChanges)[regionChanges->size()-2-i*2]=(*regionChanges)[i*2];
00413 (*regionChanges)[regionChanges->size()-1-i*2]=(*regionChanges)[i*2+1];
00414 (*regionChanges)[i*2]=tmp;
00415 (*regionChanges)[i*2+1]=tmppos;
00416 }
00417
00418
00419
signed char data= (*regionChanges)[regionChanges->size()-2];
00420 uint charPos=(*regionChanges)[regionChanges->size()-1];
00421 regionChanges->resize (regionChanges->size()-2);
00422
00423
int insertPos=-1;
00424 KateCodeFoldingNode *node = findNodeForLine(line);
00425
00426
if (data<0)
00427 {
00428
00429 {
00430
unsigned int tmpLine=line-getStartLine(node);
00431
00432
for ( uint i=0; i < node->childCount(); ++i )
00433 {
00434
if (node->child(i)->startLineRel >= tmpLine)
00435 {
00436 insertPos=i;
00437
break;
00438 }
00439 }
00440 }
00441 }
00442
else
00443 {
00444
for (; (node->parentNode) && (getStartLine(node->parentNode)==line) && (node->parentNode->type!=0); node=node->parentNode);
00445
00446
if ((getStartLine(node)==line) && (node->type!=0))
00447 {
00448 insertPos=node->parentNode->findChild(node);
00449 node = node->parentNode;
00450 }
00451
else
00452 {
00453
for ( uint i=0; i < node->childCount(); ++i )
00454 {
00455
if (getStartLine(node->child(i))>=line)
00456 {
00457 insertPos=i;
00458
break;
00459 }
00460 }
00461 }
00462 }
00463
00464
do
00465 {
00466
if (data<0)
00467 {
00468
if (correctEndings(data,node,line,charPos,insertPos))
00469 {
00470 insertPos=node->parentNode->findChild(node)+1;
00471 node=node->parentNode;
00472 }
00473
else
00474 {
00475
if (insertPos!=-1) insertPos++;
00476 }
00477 }
00478
else
00479 {
00480
int startLine=getStartLine(node);
00481
if ((insertPos==-1) || (insertPos>=(
int)node->childCount()))
00482 {
00483 KateCodeFoldingNode *newNode =
new KateCodeFoldingNode (node,data,line-startLine);
00484 something_changed =
true;
00485 node->appendChild(newNode);
00486 addOpening(newNode, data, regionChanges, line,charPos);
00487 insertPos = node->findChild(newNode)+1;
00488 }
00489
else
00490 {
00491
if (node->child(insertPos)->startLineRel == line-startLine)
00492 {
00493 addOpening(node->child(insertPos), data, regionChanges, line,charPos);
00494 insertPos++;
00495 }
00496
else
00497 {
00498
00499 KateCodeFoldingNode *newNode =
new KateCodeFoldingNode (node,data,line-startLine);
00500 something_changed =
true;
00501 node->insertChild(insertPos, newNode);
00502 addOpening(newNode, data, regionChanges, line,charPos);
00503 insertPos++;
00504 }
00505 }
00506 }
00507
00508
if (regionChanges->isEmpty())
00509 data = 0;
00510
else
00511 {
00512 data = (*regionChanges)[regionChanges->size()-2];
00513 charPos=(*regionChanges)[regionChanges->size()-1];
00514 regionChanges->resize (regionChanges->size()-2);
00515 }
00516 }
while (data!=0);
00517 }
00518
00519 cleanupUnneededNodes(line);
00520
00521 (*updated) = something_changed;
00522 }
00523
00524
00525
bool KateCodeFoldingTree::removeOpening(KateCodeFoldingNode *node,
unsigned int line)
00526 {
00527
signed char type;
00528
if ((type=node->type) == 0)
00529 {
00530 dontDeleteOpening(node);
00531 dontDeleteEnding(node);
00532
return false;
00533 }
00534
00535
if (!node->visible)
00536 {
00537 toggleRegionVisibility(getStartLine(node));
00538 }
00539
00540 KateCodeFoldingNode *parent = node->parentNode;
00541
int mypos = parent->findChild(node);
00542
00543
if (mypos > -1)
00544 {
00545
00546
for(; node->childCount()>0 ;)
00547 {
00548 KateCodeFoldingNode *tmp;
00549 parent->insertChild(mypos, tmp=node->takeChild(0));
00550 tmp->parentNode = parent;
00551 tmp->startLineRel += node->startLineRel;
00552 mypos++;
00553 }
00554
00555
00556
00557
bool endLineValid = node->endLineValid;
00558
int endLineRel = node->endLineRel;
00559 uint endCol=node->endCol;
00560
00561
00562
delete parent->takeChild(mypos);
00563
00564
if ((type>0) && (endLineValid))
00565 correctEndings(-type, parent, line+endLineRel,endCol, mypos);
00566 }
00567
00568
return true;
00569 }
00570
00571
bool KateCodeFoldingTree::removeEnding(KateCodeFoldingNode *node,
unsigned int )
00572 {
00573 KateCodeFoldingNode *parent = node->parentNode;
00574
00575
if (!parent)
00576
return false;
00577
00578
if (node->type == 0)
00579
return false;
00580
00581
if (node->type < 0)
00582 {
00583
00584
int i = parent->findChild (node);
00585
if (i >= 0)
00586
delete parent->takeChild (i);
00587
00588
return true;
00589 }
00590
00591
int mypos = parent->findChild(node);
00592
int count = parent->childCount();
00593
00594
for (
int i=mypos+1; i<count; i++)
00595 {
00596
if (parent->child(i)->type == -node->type)
00597 {
00598 node->endLineValid =
true;
00599 node->endLineRel = parent->child(i)->startLineRel - node->startLineRel;
00600
00601
delete parent->takeChild(i);
00602
00603 count = i-mypos-1;
00604
if (count > 0)
00605 {
00606
for (
int i=0; i<count; i++)
00607 {
00608 KateCodeFoldingNode *tmp = parent->takeChild(mypos+1);
00609 tmp->startLineRel -= node->startLineRel;
00610 tmp->parentNode = node;
00611 node->appendChild(tmp);
00612 }
00613 }
00614
return false;
00615 }
00616 }
00617
00618
if ( (parent->type == node->type) || (!parent->parentNode))
00619 {
00620
for (
int i=mypos+1; i<(
int)parent->childCount(); i++)
00621 {
00622 KateCodeFoldingNode *tmp = parent->takeChild(mypos+1);
00623 tmp->startLineRel -= node->startLineRel;
00624 tmp->parentNode = node;
00625 node->appendChild(tmp);
00626 }
00627
00628
00629
if (!parent->parentNode)
00630 node->endLineValid=
false;
00631
else
00632 node->endLineValid = parent->endLineValid;
00633
00634 node->endLineRel = parent->endLineRel-node->startLineRel;
00635
00636
if (node->endLineValid)
00637
return removeEnding(parent, getStartLine(parent)+parent->endLineRel);
00638
00639
return false;
00640 }
00641
00642 node->endLineValid =
false;
00643 node->endLineRel = parent->endLineRel - node->startLineRel;
00644
00645
return false;
00646 }
00647
00648
00649
bool KateCodeFoldingTree::correctEndings(
signed char data, KateCodeFoldingNode *node,
unsigned int line,
unsigned int endCol,
int insertPos)
00650 {
00651
00652 uint startLine = getStartLine(node);
00653
if (data != -node->type)
00654 {
00655
#if JW_DEBUG
00656
kdDebug(13000)<<
"data!=-node->type (correctEndings)"<<
endl;
00657
#endif
00658
00659 dontDeleteEnding(node);
00660
if (data == node->type) {
00661 node->endCol=endCol;
00662
return false;
00663 }
00664 KateCodeFoldingNode *newNode =
new KateCodeFoldingNode (node,data,line-startLine);
00665 something_changed =
true;
00666 newNode->startLineValid =
false;
00667 newNode->endLineValid =
true;
00668 newNode->endLineRel = 0;
00669 newNode->endCol=endCol;
00670
00671
if ((insertPos==-1) || (insertPos==(
int)node->childCount()))
00672 node->appendChild(newNode);
00673
else
00674 node->insertChild(insertPos,newNode);
00675
00676
00677
return false;
00678 }
00679
else
00680 {
00681 something_changed =
true;
00682 dontDeleteEnding(node);
00683
00684
00685
if (!node->endLineValid)
00686 {
00687 node->endLineValid =
true;
00688 node->endLineRel = line - startLine;
00689 node->endCol=endCol;
00690
00691
00692 moveSubNodesUp(node);
00693 }
00694
else
00695 {
00696
#if JW_DEBUG
00697
kdDebug(13000)<<
"Closing a node which had already a valid end"<<
endl;
00698
#endif
00699
00700
if (startLine+node->endLineRel == line)
00701 {
00702 node->endCol=endCol;
00703
00704
#if JW_DEBUG
00705
kdDebug(13000)<<
"We won, just skipping (correctEndings)"<<
endl;
00706
#endif
00707
}
00708
else
00709 {
00710
int bakEndLine = node->endLineRel+startLine;
00711 uint bakEndCol = node->endCol;
00712 node->endLineRel = line-startLine;
00713 node->endCol=endCol;
00714
00715
#if JW_DEBUG
00716
kdDebug(13000)<<
"reclosed node had childnodes()"<<
endl;
00717
kdDebug(13000)<<
"It could be, that childnodes() need to be moved up"<<
endl;
00718
#endif
00719
moveSubNodesUp(node);
00720
00721
if (node->parentNode)
00722 {
00723 correctEndings(data,node->parentNode,bakEndLine, bakEndCol,node->parentNode->findChild(node)+1);
00724 }
00725
else
00726 {
00727
00728 }
00729 }
00730 }
00731 }
00732
return true;
00733 }
00734
00735
void KateCodeFoldingTree::moveSubNodesUp(KateCodeFoldingNode *node)
00736 {
00737
int mypos = node->parentNode->findChild(node);
00738
int removepos=-1;
00739
int count = node->childCount();
00740
for (
int i=0; i<count; i++)
00741
if (node->child(i)->startLineRel >= node->endLineRel)
00742 {
00743 removepos=i;
00744
break;
00745 }
00746
#if JW_DEBUG
00747
kdDebug(13000)<<
QString(
"remove pos: %1").arg(removepos)<<
endl;
00748
#endif
00749
if (removepos>-1)
00750 {
00751
#if JW_DEBUG
00752
kdDebug(13000)<<
"Children need to be moved"<<
endl;
00753
#endif
00754
KateCodeFoldingNode *moveNode;
00755
if (mypos == (
int)node->parentNode->childCount()-1)
00756 {
00757
while (removepos<(
int)node->childCount())
00758 {
00759 node->parentNode->appendChild(moveNode=node->takeChild(removepos));
00760 moveNode->parentNode = node->parentNode;
00761 moveNode->startLineRel += node->startLineRel;
00762 }
00763 }
00764
else
00765 {
00766
int insertPos=mypos;
00767
while (removepos < (
int)node->childCount())
00768 {
00769 insertPos++;
00770 node->parentNode->insertChild(insertPos, moveNode=node->takeChild(removepos));
00771 moveNode->parentNode = node->parentNode;
00772 moveNode->startLineRel += node->startLineRel;
00773 }
00774 }
00775 }
00776
00777 }
00778
00779
00780
00781
void KateCodeFoldingTree::addOpening(KateCodeFoldingNode *node,
signed char nType,
QMemArray<uint>* list,
unsigned int line,
unsigned int charPos)
00782 {
00783 uint startLine = getStartLine(node);
00784
if ((startLine==line) && (node->type!=0))
00785 {
00786
#if JW_DEBUG
00787
kdDebug(13000)<<
"startLine equals line"<<
endl;
00788
#endif
00789
if (nType == node->type)
00790 {
00791
#if JW_DEBUG
00792
kdDebug(13000)<<
"Node exists"<<
endl;
00793
#endif
00794
node->deleteOpening =
false;
00795 node->startCol=charPos;
00796 KateCodeFoldingNode *parent = node->parentNode;
00797
00798
if (!node->endLineValid)
00799 {
00800
int current = parent->findChild(node);
00801
int count = parent->childCount()-(current+1);
00802 node->endLineRel = parent->endLineRel - node->startLineRel;
00803
00804
00805
00806
if (parent)
00807
if (parent->type == node->type)
00808 {
00809
if (parent->endLineValid)
00810 {
00811 removeEnding(parent, line);
00812 node->endLineValid =
true;
00813 }
00814 }
00815
00816
00817
00818
if (current != (
int)parent->childCount()-1)
00819 {
00820
00821
#ifdef __GNUC__
00822
#warning "FIXME: why does this seem to work?"
00823
#endif
00824
00825 {
00826
for (
int i=current+1; i<(
int)parent->childCount(); i++)
00827 {
00828
if (parent->child(i)->type == -node->type)
00829 {
00830 count = (i-current-1);
00831 node->endLineValid =
true;
00832 node->endLineRel = getStartLine(parent->child(i))-line;
00833 node->endCol = parent->child(i)->endCol;
00834
delete parent->takeChild(i);
00835
break;
00836 }
00837 }
00838 }
00839
00840
00841
00842
00843
00844
00845
if (count>0)
00846 {
00847
for (
int i=0;i<count;i++)
00848 {
00849 KateCodeFoldingNode *tmp;
00850 node->appendChild(tmp=parent->takeChild(current+1));
00851 tmp->startLineRel -= node->startLineRel;
00852 tmp->parentNode = node;
00853 }
00854 }
00855 }
00856
00857 }
00858
00859 addOpening_further_iterations(node, nType, list, line, 0, startLine,node->startCol);
00860
00861 }
00862 }
00863
else
00864 {
00865 KateCodeFoldingNode *newNode =
new KateCodeFoldingNode (node,nType,line-startLine);
00866 something_changed =
true;
00867
00868
int insert_position=-1;
00869
for (
int i=0; i<(
int)node->childCount(); i++)
00870 {
00871
if (startLine+node->child(i)->startLineRel > line)
00872 {
00873 insert_position=i;
00874
break;
00875 }
00876 }
00877
00878
int current;
00879
if (insert_position==-1)
00880 {
00881 node->appendChild(newNode);
00882 current = node->childCount()-1;
00883 }
00884
else
00885 {
00886 node->insertChild(insert_position, newNode);
00887 current = insert_position;
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
int count = node->childCount() - (current+1);
00898 newNode->endLineRel -= newNode->startLineRel;
00899
if (current != (
int)node->childCount()-1)
00900 {
00901
if (node->type != newNode->type)
00902 {
00903
for (
int i=current+1; i<(
int)node->childCount(); i++)
00904 {
00905
if (node->child(i)->type == -newNode->type)
00906 {
00907 count = node->childCount() - i - 1;
00908 newNode->endLineValid =
true;
00909 newNode->endLineRel = line - getStartLine(node->child(i));
00910
delete node->takeChild(i);
00911
break;
00912 }
00913 }
00914 }
00915
else
00916 {
00917 node->endLineValid =
false;
00918 node->endLineRel = 10000;
00919 }
00920
if (count > 0)
00921 {
00922
for (
int i=0;i<count;i++)
00923 {
00924 KateCodeFoldingNode *tmp;
00925 newNode->appendChild(tmp=node->takeChild(current+1));
00926 tmp->parentNode=newNode;
00927 }
00928 }
00929
00930 }
00931
00932 addOpening(newNode, nType, list, line,charPos);
00933
00934 addOpening_further_iterations(node, node->type, list, line, current, startLine,node->startCol);
00935 }
00936 }
00937
00938
00939
void KateCodeFoldingTree::addOpening_further_iterations(KateCodeFoldingNode *node,
signed char ,
QMemArray<uint>*
00940 list,
unsigned int line,
int current,
unsigned int startLine,
unsigned int charPos)
00941 {
00942
while (!(list->isEmpty()))
00943 {
00944
if (list->isEmpty())
00945
return;
00946
else
00947 {
00948
signed char data = (*list)[list->size()-2];
00949 uint charPos=(*list)[list->size()-1];
00950 list->resize (list->size()-2);
00951
00952
if (data<0)
00953 {
00954
#if JW_DEBUG
00955
kdDebug(13000)<<
"An ending was found"<<
endl;
00956
#endif
00957
00958
if (correctEndings(data,node,line,charPos,-1))
00959
return;
00960
00961
#if 0
00962
if(data == -nType)
00963 {
00964
if (node->endLineValid)
00965 {
00966
if (node->endLineRel+startLine==line)
00967 {
00968
00969 }
00970
else
00971 {
00972 node->endLineRel=line-startLine;
00973 node->endLineValid=
true;
00974 }
00975
return;
00976 }
00977
else
00978 {
00979 node->endLineRel=line-startLine;
00980 node->endLineValid=
true;
00981
00982 }
00983 }
00984
#endif
00985
}
00986
else
00987 {
00988
bool needNew =
true;
00989
if (current < (
int)node->childCount())
00990 {
00991
if (getStartLine(node->child(current)) == line)
00992 needNew=
false;
00993 }
00994
if (needNew)
00995 {
00996 something_changed =
true;
00997 KateCodeFoldingNode *newNode =
new KateCodeFoldingNode(node, data, line-startLine);
00998 node->insertChild(current, newNode);
00999 }
01000
01001 addOpening(node->child(current), data, list, line,charPos);
01002 current++;
01003
01004 }
01005 }
01006 }
01007 }
01008
01009
unsigned int KateCodeFoldingTree::getStartLine(KateCodeFoldingNode *node)
01010 {
01011
unsigned int lineStart=0;
01012
for (KateCodeFoldingNode *iter=node; iter->type != 0; iter=iter->parentNode)
01013 lineStart += iter->startLineRel;
01014
01015
return lineStart;
01016 }
01017
01018
01019
void KateCodeFoldingTree::lineHasBeenRemoved(
unsigned int line)
01020 {
01021 lineMapping.clear();
01022 dontIgnoreUnchangedLines.insert(line, &trueVal);
01023 dontIgnoreUnchangedLines.insert(line-1, &trueVal);
01024 dontIgnoreUnchangedLines.insert(line+1, &trueVal);
01025 hiddenLinesCountCacheValid =
false;
01026
#if JW_DEBUG
01027
kdDebug(13000)<<
QString(
"KateCodeFoldingTree::lineHasBeenRemoved: %1").arg(line)<<
endl;
01028
#endif
01029
01030
01031 findAndMarkAllNodesforRemovalOpenedOrClosedAt(line);
01032 cleanupUnneededNodes(line);
01033
01034 KateCodeFoldingNode *node = findNodeForLine(line);
01035
01036 {
01037
int startLine = getStartLine(node);
01038
if (startLine == (
int)line)
01039 node->startLineRel--;
01040
else
01041 {
01042
if (node->endLineRel == 0)
01043 node->endLineValid =
false;
01044 node->endLineRel--;
01045 }
01046
01047
int count = node->childCount();
01048
for (
int i=0; i<count; i++)
01049 {
01050
if (node->child(i)->startLineRel+startLine >= line)
01051 node->child(i)->startLineRel--;
01052 }
01053 }
01054
01055
if (node->parentNode)
01056 decrementBy1(node->parentNode, node);
01057
01058
for (
QValueList<KateHiddenLineBlock>::Iterator it=hiddenLines.begin(); it!=hiddenLines.end(); ++it)
01059 {
01060
if ((*it).start > line)
01061 (*it).start--;
01062
else if ((*it).start+(*it).length > line)
01063 (*it).length--;
01064 }
01065 }
01066
01067
01068
void KateCodeFoldingTree::decrementBy1(KateCodeFoldingNode *node, KateCodeFoldingNode *after)
01069 {
01070
if (node->endLineRel == 0)
01071 node->endLineValid =
false;
01072 node->endLineRel--;
01073
01074
for (uint i=node->findChild(after)+1; i < node->childCount(); ++i)
01075 node->child(i)->startLineRel--;
01076
01077
if (node->parentNode)
01078 decrementBy1(node->parentNode,node);
01079 }
01080
01081
01082
void KateCodeFoldingTree::lineHasBeenInserted(
unsigned int line)
01083 {
01084 lineMapping.clear();
01085 dontIgnoreUnchangedLines.insert(line, &trueVal);
01086 dontIgnoreUnchangedLines.insert(line-1, &trueVal);
01087 dontIgnoreUnchangedLines.insert(line+1, &trueVal);
01088 hiddenLinesCountCacheValid =
false;
01089
01090
#if JW_DEBUG
01091
kdDebug(13000)<<
QString(
"KateCodeFoldingTree::lineHasBeenInserted: %1").arg(line)<<
endl;
01092
#endif
01093
01094
01095
01096
01097 KateCodeFoldingNode *node = findNodeForLine(line);
01098
01099 {
01100
int startLine=getStartLine(node);
01101
if (node->type < 0)
01102 node->startLineRel++;
01103
else
01104 node->endLineRel++;
01105
01106
for (uint i=0; i < node->childCount(); ++i)
01107 {
01108 KateCodeFoldingNode *iter = node->child(i);
01109
01110
if (iter->startLineRel+startLine >= line)
01111 iter->startLineRel++;
01112 }
01113 }
01114
01115
if (node->parentNode)
01116 incrementBy1(node->parentNode, node);
01117
01118
for (
QValueList<KateHiddenLineBlock>::Iterator it=hiddenLines.begin(); it!=hiddenLines.end(); ++it)
01119 {
01120
if ((*it).start > line)
01121 (*it).start++;
01122
else if ((*it).start+(*it).length > line)
01123 (*it).length++;
01124 }
01125 }
01126
01127
void KateCodeFoldingTree::incrementBy1(KateCodeFoldingNode *node, KateCodeFoldingNode *after)
01128 {
01129 node->endLineRel++;
01130
01131
for (uint i=node->findChild(after)+1; i < node->childCount(); ++i)
01132 node->child(i)->startLineRel++;
01133
01134
if (node->parentNode)
01135 incrementBy1(node->parentNode,node);
01136 }
01137
01138
01139
void KateCodeFoldingTree::findAndMarkAllNodesforRemovalOpenedOrClosedAt(
unsigned int line)
01140 {
01141
#ifdef __GNUC__
01142
#warning "FIXME: make this multiple region changes per line save";
01143
#endif
01144
01145 markedForDeleting.clear();
01146 KateCodeFoldingNode *node = findNodeForLine(line);
01147
if (node->type == 0)
01148
return;
01149
01150 addNodeToRemoveList(node, line);
01151
01152
while (((node->parentNode) && (node->parentNode->type!=0)) && (getStartLine(node->parentNode)==line))
01153 {
01154 node = node->parentNode;
01155 addNodeToRemoveList(node, line);
01156 }
01157
#if JW_DEBUG
01158
kdDebug(13000)<<
" added line to markedForDeleting list"<<
endl;
01159
#endif
01160
}
01161
01162
01163
void KateCodeFoldingTree::addNodeToRemoveList(KateCodeFoldingNode *node,
unsigned int line)
01164 {
01165
bool add=
false;
01166
#ifdef __GNUC__
01167
#warning "FIXME: make this multiple region changes per line save";
01168
#endif
01169
unsigned int startLine=getStartLine(node);
01170
if ((startLine==line) && (node->startLineValid))
01171 {
01172 add=
true;
01173 node->deleteOpening =
true;
01174 }
01175
if ((startLine+node->endLineRel==line) || ((node->endLineValid==
false) && (node->deleteOpening)))
01176 {
01177
int myPos=node->parentNode->findChild(node);
01178
if ((
int)node->parentNode->childCount()>myPos+1)
01179 addNodeToRemoveList(node->parentNode->child(myPos+1),line);
01180 add=
true;
01181 node->deleteEnding =
true;
01182 }
01183
01184
if(add)
01185 markedForDeleting.append(node);
01186
01187 }
01188
01189
01190
void KateCodeFoldingTree::findAllNodesOpenedOrClosedAt(
unsigned int line)
01191 {
01192 nodesForLine.clear();
01193 KateCodeFoldingNode *node = findNodeForLine(line);
01194
if (node->type == 0)
01195
return;
01196
01197
unsigned int startLine = getStartLine(node);
01198
if (startLine == line)
01199 nodesForLine.append(node);
01200
else if ((startLine+node->endLineRel == line))
01201 nodesForLine.append(node);
01202
01203
while (node->parentNode)
01204 {
01205 addNodeToFoundList(node->parentNode, line, node->parentNode->findChild(node));
01206 node = node->parentNode;
01207 }
01208
#if JW_DEBUG
01209
kdDebug(13000)<<
" added line to nodesForLine list"<<
endl;
01210
#endif
01211
}
01212
01213
01214
void KateCodeFoldingTree::addNodeToFoundList(KateCodeFoldingNode *node,
unsigned int line,
int childpos)
01215 {
01216
unsigned int startLine = getStartLine(node);
01217
01218
if ((startLine==line) && (node->type!=0))
01219 nodesForLine.append(node);
01220
else if ((startLine+node->endLineRel==line) && (node->type!=0))
01221 nodesForLine.append(node);
01222
01223
for (
int i=childpos+1; i<(
int)node->childCount(); i++)
01224 {
01225 KateCodeFoldingNode *child = node->child(i);
01226
01227
if (startLine+child->startLineRel == line)
01228 {
01229 nodesForLine.append(child);
01230 addNodeToFoundList(child, line, 0);
01231 }
01232
else
01233
break;
01234 }
01235 }
01236
01237
01238
void KateCodeFoldingTree::cleanupUnneededNodes(
unsigned int line)
01239 {
01240
#if JW_DEBUG
01241
kdDebug(13000)<<
"void KateCodeFoldingTree::cleanupUnneededNodes(unsigned int line)"<<
endl;
01242
#endif
01243
01244
01245
if (markedForDeleting.isEmpty())
01246
return;
01247
01248
for (
int i=0; i<(
int)markedForDeleting.count(); i++)
01249 {
01250 KateCodeFoldingNode *node = markedForDeleting.at(i);
01251
if (node->deleteOpening)
01252
kdDebug(13000)<<
"DELETE OPENING SET"<<
endl;
01253
if (node->deleteEnding)
01254
kdDebug(13000)<<
"DELETE ENDING SET"<<
endl;
01255
01256
if ((node->deleteOpening) && (node->deleteEnding))
01257 {
01258
#if JW_DEBUG
01259
kdDebug(13000)<<
"Deleting complete node"<<
endl;
01260
#endif
01261
if (node->endLineValid)
01262 {
01263
int f = node->parentNode->findChild (node);
01264
01265
if (f >= 0)
01266
delete node->parentNode->takeChild(f);
01267 }
01268
else
01269 {
01270 removeOpening(node, line);
01271
01272 }
01273 something_changed =
true;
01274 }
01275
else
01276 {
01277
if ((node->deleteOpening) && (node->startLineValid))
01278 {
01279
#if JW_DEBUG
01280
kdDebug(13000)<<
"calling removeOpening"<<
endl;
01281
#endif
01282
removeOpening(node, line);
01283 something_changed =
true;
01284 }
01285
else
01286 {
01287 dontDeleteOpening(node);
01288
01289
if ((node->deleteEnding) && (node->endLineValid))
01290 {
01291 dontDeleteEnding(node);
01292 removeEnding(node, line);
01293 something_changed =
true;
01294 }
01295
else
01296 dontDeleteEnding(node);
01297 }
01298 }
01299 }
01300 }
01301
01302
void KateCodeFoldingTree::dontDeleteEnding(KateCodeFoldingNode* node)
01303 {
01304 node->deleteEnding =
false;
01305 }
01306
01307
01308
void KateCodeFoldingTree::dontDeleteOpening(KateCodeFoldingNode* node)
01309 {
01310 node->deleteOpening =
false;
01311 }
01312
01313
01314
void KateCodeFoldingTree::toggleRegionVisibility(
unsigned int line)
01315 {
01316
01317 m_buffer->line (m_buffer->count()-1);
01318
01319 lineMapping.clear();
01320 hiddenLinesCountCacheValid =
false;
01321
kdDebug(13000)<<
QString(
"KateCodeFoldingTree::toggleRegionVisibility() %1").arg(line)<<
endl;
01322
01323 findAllNodesOpenedOrClosedAt(line);
01324
for (
int i=0; i<(
int)nodesForLine.count(); i++)
01325 {
01326 KateCodeFoldingNode *node=nodesForLine.at(i);
01327
if ( (!node->startLineValid) || (getStartLine(node) != line) )
01328 {
01329 nodesForLine.remove(i);
01330 i--;
01331 }
01332 }
01333
01334
if (nodesForLine.isEmpty())
01335
return;
01336
01337 nodesForLine.at(0)->visible = !nodesForLine.at(0)->visible;
01338
01339
if (!nodesForLine.at(0)->visible)
01340 addHiddenLineBlock(nodesForLine.at(0),line);
01341
else
01342 {
01343
for (
QValueList<KateHiddenLineBlock>::Iterator it=hiddenLines.begin(); it!=hiddenLines.end();++it)
01344
if ((*it).start == line+1)
01345 {
01346 hiddenLines.remove(it);
01347
break;
01348 }
01349
01350 updateHiddenSubNodes(nodesForLine.at(0));
01351 }
01352
01353 emit regionVisibilityChangedAt(line);
01354 }
01355
01356
void KateCodeFoldingTree::updateHiddenSubNodes(KateCodeFoldingNode *node)
01357 {
01358
for (uint i=0; i < node->childCount(); ++i)
01359 {
01360 KateCodeFoldingNode *iter = node->child(i);
01361
01362
if (!iter->visible)
01363 addHiddenLineBlock(iter, getStartLine(iter));
01364
else
01365 updateHiddenSubNodes(iter);
01366 }
01367 }
01368
01369
void KateCodeFoldingTree::addHiddenLineBlock(KateCodeFoldingNode *node,
unsigned int line)
01370 {
01371 KateHiddenLineBlock data;
01372 data.start = line+1;
01373 data.length = node->endLineRel-(existsOpeningAtLineAfter(line+node->endLineRel,node)?1:0);
01374
bool inserted =
false;
01375
01376
for (
QValueList<KateHiddenLineBlock>::Iterator it=hiddenLines.begin(); it!=hiddenLines.end(); ++it)
01377 {
01378
if (((*it).start>=data.start) && ((*it).start<=data.start+data.length-1))
01379 {
01380
01381
01382 it=hiddenLines.remove(it);
01383 --it;
01384 }
01385
else
01386 {
01387
if ((*it).start > line)
01388 {
01389 hiddenLines.insert(it, data);
01390 inserted =
true;
01391
01392
break;
01393 }
01394 }
01395 }
01396
01397
if (!inserted)
01398 hiddenLines.append(data);
01399 }
01400
01401
bool KateCodeFoldingTree::existsOpeningAtLineAfter(
unsigned int line, KateCodeFoldingNode *node)
01402 {
01403
for(KateCodeFoldingNode *tmp = node->parentNode; tmp; tmp=tmp->parentNode)
01404 {
01405 KateCodeFoldingNode *tmp2;
01406
unsigned int startLine=getStartLine(tmp);
01407
01408
if ((tmp2 = tmp->child(tmp->findChild(node) + 1))
01409 && ((tmp2->startLineRel + startLine) == line))
01410
return true;
01411
01412
if ((startLine + tmp->endLineRel) > line)
01413
return false;
01414 }
01415
01416
return false;
01417 }
01418
01419
01420
01421
01422
01423
unsigned int KateCodeFoldingTree::getRealLine(
unsigned int virtualLine)
01424 {
01425
01426
if (hiddenLines.isEmpty())
01427
return virtualLine;
01428
01429
01430
01431
unsigned int *real=lineMapping[virtualLine];
01432
if (real)
01433
return (*real);
01434
01435
unsigned int tmp = virtualLine;
01436
for (
QValueList<KateHiddenLineBlock>::ConstIterator it=hiddenLines.begin();it!=hiddenLines.end();++it)
01437 {
01438
if ((*it).start<=virtualLine)
01439 virtualLine += (*it).length;
01440
else
01441
break;
01442 }
01443
01444
01445
01446 lineMapping.insert(tmp,
new unsigned int(virtualLine));
01447
return virtualLine;
01448 }
01449
01450
01451
01452
01453
unsigned int KateCodeFoldingTree::getVirtualLine(
unsigned int realLine)
01454 {
01455
01456
if (hiddenLines.isEmpty())
01457
return realLine;
01458
01459
01460
01461
for (
QValueList<KateHiddenLineBlock>::ConstIterator it=hiddenLines.fromLast(); it!=hiddenLines.end(); --it)
01462 {
01463
if ((*it).start <= realLine)
01464 realLine -= (*it).length;
01465
01466
01467 }
01468
01469
01470
01471
return realLine;
01472 }
01473
01474
01475
01476
01477
unsigned int KateCodeFoldingTree::getHiddenLinesCount(
unsigned int doclen)
01478 {
01479
01480
if (hiddenLines.isEmpty())
01481
return 0;
01482
01483
if (hiddenLinesCountCacheValid)
01484
return hiddenLinesCountCache;
01485
01486 hiddenLinesCountCacheValid =
true;
01487 hiddenLinesCountCache = 0;
01488
01489
for (
QValueList<KateHiddenLineBlock>::ConstIterator it=hiddenLines.begin(); it!=hiddenLines.end(); ++it)
01490 {
01491
if ((*it).start+(*it).length<=doclen)
01492 hiddenLinesCountCache += (*it).length;
01493
else
01494 {
01495 hiddenLinesCountCache += ((*it).length- ((*it).length + (*it).start - doclen));
01496
break;
01497 }
01498 }
01499
01500
return hiddenLinesCountCache;
01501 }
01502
01503
void KateCodeFoldingTree::collapseToplevelNodes()
01504 {
01505
01506 m_buffer->line (m_buffer->count()-1);
01507
01508
if (m_root.noChildren ())
01509
return;
01510
01511
for ( uint i=0; i < m_root.childCount(); ++i )
01512 {
01513 KateCodeFoldingNode *node = m_root.child(i);
01514
01515
if (node->visible && node->startLineValid && node->endLineValid)
01516 {
01517 node->visible=
false;
01518 lineMapping.clear();
01519 hiddenLinesCountCacheValid =
false;
01520 addHiddenLineBlock(node,node->startLineRel);
01521 emit regionVisibilityChangedAt(node->startLineRel);
01522 }
01523 }
01524 }
01525
01526
void KateCodeFoldingTree::expandToplevelNodes(
int numLines)
01527 {
01528
01529 m_buffer->line (m_buffer->count()-1);
01530
01531 KateLineInfo line;
01532
for (
int i = 0; i < numLines; i++) {
01533 getLineInfo(&line, i);
01534
01535
if (line.startsInVisibleBlock)
01536 toggleRegionVisibility(i);
01537 }
01538 }
01539
01540
int KateCodeFoldingTree::collapseOne(
int realLine)
01541 {
01542
01543 m_buffer->line (m_buffer->count()-1);
01544
01545 KateLineInfo line;
01546
int unrelatedBlocks = 0;
01547
for (
int i = realLine; i >= 0; i--) {
01548 getLineInfo(&line, i);
01549
01550
if (line.topLevel && !line.endsBlock)
01551
01552
break;
01553
01554
if (line.endsBlock && ( line.invalidBlockEnd ) && (i != realLine)) {
01555 unrelatedBlocks++;
01556 }
01557
01558
if (line.startsVisibleBlock) {
01559 unrelatedBlocks--;
01560
if (unrelatedBlocks == -1) {
01561 toggleRegionVisibility(i);
01562
return i;
01563 }
01564 }
01565 }
01566
return -1;
01567 }
01568
01569
void KateCodeFoldingTree::expandOne(
int realLine,
int numLines)
01570 {
01571
01572 m_buffer->line (m_buffer->count()-1);
01573
01574 KateLineInfo line;
01575
int blockTrack = 0;
01576
for (
int i = realLine; i >= 0; i--) {
01577 getLineInfo(&line, i);
01578
01579
if (line.topLevel)
01580
01581
break;
01582
01583
if (line.startsInVisibleBlock && i != realLine) {
01584
if (blockTrack == 0)
01585 toggleRegionVisibility(i);
01586
01587 blockTrack--;
01588 }
01589
01590
if (line.endsBlock)
01591 blockTrack++;
01592
01593
if (blockTrack < 0)
01594
01595
break;
01596 }
01597
01598 blockTrack = 0;
01599
for (
int i = realLine; i < numLines; i++) {
01600 getLineInfo(&line, i);
01601
01602
if (line.topLevel)
01603
01604
break;
01605
01606
if (line.startsInVisibleBlock) {
01607
if (blockTrack == 0)
01608 toggleRegionVisibility(i);
01609
01610 blockTrack++;
01611 }
01612
01613
if (line.endsBlock)
01614 blockTrack--;
01615
01616
if (blockTrack < 0)
01617
01618
break;
01619 }
01620 }
01621
01622
void KateCodeFoldingTree::ensureVisible( uint line )
01623 {
01624
01625
bool found=
false;
01626
for (
QValueList<KateHiddenLineBlock>::ConstIterator it=hiddenLines.begin();it!=hiddenLines.end();++it)
01627 {
01628
if ( ((*it).start<=line) && ((*it).start+(*it).length>line) )
01629 {
01630 found=
true;
01631
break;
01632 }
01633 }
01634
01635
01636
if (!found)
return;
01637
01638
kdDebug(13000)<<
"line "<<line<<
" is really hidden ->show block"<<
endl;
01639
01640
01641 KateCodeFoldingNode *n = findNodeForLine( line );
01642
do {
01643
if ( ! n->visible )
01644 toggleRegionVisibility( getStartLine( n ) );
01645 n = n->parentNode;
01646 }
while( n );
01647
01648 }
01649
01650