00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "katesupercursor.h"
00020
#include "katesupercursor.moc"
00021
00022
#include "katedocument.h"
00023
00024
#include <kdebug.h>
00025
00026
#include <qobjectlist.h>
00027
00028 KateSuperCursor::KateSuperCursor(KateDocument* doc,
bool privateC,
const KateTextCursor& cursor,
QObject* parent,
const char* name)
00029 :
QObject(parent, name)
00030 ,
KateDocCursor(cursor.line(), cursor.col(), doc)
00031 , Kate::Cursor ()
00032 , m_doc (doc)
00033 {
00034 m_moveOnInsert =
false;
00035 m_lineRemoved =
false;
00036 m_privateCursor = privateC;
00037
00038 m_doc->addSuperCursor (
this, privateC);
00039 }
00040
00041 KateSuperCursor::KateSuperCursor(KateDocument* doc,
bool privateC,
int lineNum,
int col,
QObject* parent,
const char* name)
00042 :
QObject(parent, name)
00043 ,
KateDocCursor(lineNum, col, doc)
00044 , Kate::Cursor ()
00045 , m_doc (doc)
00046 {
00047 m_moveOnInsert =
false;
00048 m_lineRemoved =
false;
00049 m_privateCursor = privateC;
00050
00051 m_doc->addSuperCursor (
this, privateC);
00052 }
00053
00054 KateSuperCursor::~KateSuperCursor ()
00055 {
00056 m_doc->removeSuperCursor (
this, m_privateCursor);
00057 }
00058
00059
void KateSuperCursor::position(uint *pline, uint *pcol)
const
00060
{
00061 KateDocCursor::position(pline, pcol);
00062 }
00063
00064
bool KateSuperCursor::setPosition(uint line, uint col)
00065 {
00066
if (line == uint(-2) && col == uint(-2)) {
delete this;
return true; }
00067
return KateDocCursor::setPosition(line, col);
00068 }
00069
00070
bool KateSuperCursor::insertText(
const QString& s)
00071 {
00072
return KateDocCursor::insertText(s);
00073 }
00074
00075
bool KateSuperCursor::removeText(uint nbChar)
00076 {
00077
return KateDocCursor::removeText(nbChar);
00078 }
00079
00080
QChar KateSuperCursor::currentChar()
const
00081
{
00082
return KateDocCursor::currentChar();
00083 }
00084
00085 bool KateSuperCursor::atStartOfLine()
const
00086
{
00087
return col() == 0;
00088 }
00089
00090 bool KateSuperCursor::atEndOfLine()
const
00091
{
00092
return col() >= (
int)m_doc->kateTextLine(line())->length();
00093 }
00094
00095 bool KateSuperCursor::moveOnInsert()
const
00096
{
00097
return m_moveOnInsert;
00098 }
00099
00100 void KateSuperCursor::setMoveOnInsert(
bool moveOnInsert)
00101 {
00102 m_moveOnInsert = moveOnInsert;
00103 }
00104
00105
void KateSuperCursor::setLine(
int lineNum)
00106 {
00107
int tempLine = line(), tempcol = col();
00108 KateDocCursor::setLine(lineNum);
00109
00110
if (tempLine != line() || tempcol != col())
00111 emit
positionDirectlyChanged();
00112 }
00113
00114
void KateSuperCursor::setCol(
int colNum)
00115 {
00116 KateDocCursor::setCol(colNum);
00117 }
00118
00119
void KateSuperCursor::setPos(
const KateTextCursor& pos)
00120 {
00121 KateDocCursor::setPos(pos);
00122 }
00123
00124
void KateSuperCursor::setPos(
int lineNum,
int colNum)
00125 {
00126 KateDocCursor::setPos(lineNum, colNum);
00127 }
00128
00129
void KateSuperCursor::editTextInserted(uint line, uint col, uint len)
00130 {
00131
if (m_line == int(line))
00132 {
00133
if ((m_col > int(col)) || (m_moveOnInsert && (m_col == int(col))))
00134 {
00135
bool insertedAt = m_col == int(col);
00136
00137 m_col += len;
00138
00139
if (insertedAt)
00140 emit
charInsertedAt();
00141
00142 emit
positionChanged();
00143
return;
00144 }
00145 }
00146
00147 emit
positionUnChanged();
00148 }
00149
00150
void KateSuperCursor::editTextRemoved(uint line, uint col, uint len)
00151 {
00152
if (m_line == int(line))
00153 {
00154
if (m_col > int(col))
00155 {
00156
if (m_col > int(col + len))
00157 {
00158 m_col -= len;
00159 }
00160
else
00161 {
00162
bool prevCharDeleted = m_col == int(col + len);
00163
00164 m_col = col;
00165
00166
if (prevCharDeleted)
00167 emit
charDeletedBefore();
00168
else
00169 emit
positionDeleted();
00170 }
00171
00172 emit
positionChanged();
00173
return;
00174
00175 }
00176
else if (m_col == int(col))
00177 {
00178 emit
charDeletedAfter();
00179 }
00180 }
00181
00182 emit
positionUnChanged();
00183 }
00184
00185
void KateSuperCursor::editLineWrapped(uint line, uint col,
bool newLine)
00186 {
00187
if (newLine && (m_line > int(line)))
00188 {
00189 m_line++;
00190
00191 emit
positionChanged();
00192
return;
00193 }
00194
else if ( (m_line == int(line)) && (m_col > int(col)) || (m_moveOnInsert && (m_col == int(col))) )
00195 {
00196 m_line++;
00197 m_col -= col;
00198
00199 emit
positionChanged();
00200
return;
00201 }
00202
00203 emit
positionUnChanged();
00204 }
00205
00206
void KateSuperCursor::editLineUnWrapped(uint line, uint col,
bool removeLine, uint length)
00207 {
00208
if (removeLine && (m_line > int(line+1)))
00209 {
00210 m_line--;
00211
00212 emit
positionChanged();
00213
return;
00214 }
00215
else if ( (m_line == int(line+1)) && (removeLine || (m_col < int(length))) )
00216 {
00217 m_line = line;
00218 m_col += col;
00219
00220 emit
positionChanged();
00221
return;
00222 }
00223
else if ( (m_line == int(line+1)) && (m_col >= int(length)) )
00224 {
00225 m_col -= length;
00226
00227 emit
positionChanged();
00228
return;
00229 }
00230
00231 emit
positionUnChanged();
00232 }
00233
00234
void KateSuperCursor::editLineInserted (uint line)
00235 {
00236
if (m_line >= int(line))
00237 {
00238 m_line++;
00239
00240 emit
positionChanged();
00241
return;
00242 }
00243
00244 emit
positionUnChanged();
00245 }
00246
00247
void KateSuperCursor::editLineRemoved(uint line)
00248 {
00249
if (m_line > int(line))
00250 {
00251 m_line--;
00252
00253 emit
positionChanged();
00254
return;
00255 }
00256
else if (m_line == int(line))
00257 {
00258 m_line = (line <= m_doc->lastLine()) ? line : (line - 1);
00259 m_col = 0;
00260
00261 emit
positionDeleted();
00262
00263 emit
positionChanged();
00264
return;
00265 }
00266
00267 emit
positionUnChanged();
00268 }
00269
00270 KateSuperCursor::operator QString()
00271 {
00272
return QString(
"[%1,%1]").arg(line()).arg(col());
00273 }
00274
00275 KateSuperRange::KateSuperRange(
KateSuperCursor* start,
KateSuperCursor* end,
QObject* parent,
const char* name)
00276 :
QObject(parent, name)
00277 , m_start(start)
00278 , m_end(end)
00279 , m_evaluate(false)
00280 , m_startChanged(false)
00281 , m_endChanged(false)
00282 , m_deleteCursors(false)
00283 , m_allowZeroLength(false)
00284 {
00285 init();
00286 }
00287
00288 KateSuperRange::KateSuperRange(KateDocument* doc,
const KateRange& range,
QObject* parent,
const char* name)
00289 :
QObject(parent, name)
00290 , m_start(new
KateSuperCursor(doc, true, range.start()))
00291 , m_end(new
KateSuperCursor(doc, true, range.end()))
00292 , m_evaluate(false)
00293 , m_startChanged(false)
00294 , m_endChanged(false)
00295 , m_deleteCursors(true)
00296 , m_allowZeroLength(false)
00297 {
00298 init();
00299 }
00300
00301
KateSuperRange::KateSuperRange(KateDocument* doc,
const KateTextCursor& start,
const KateTextCursor& end,
QObject* parent,
const char* name)
00302 :
QObject(parent,
name)
00303 , m_start(new
KateSuperCursor(doc, true, start))
00304 , m_end(new
KateSuperCursor(doc, true,
end))
00305 , m_evaluate(false)
00306 , m_startChanged(false)
00307 , m_endChanged(false)
00308 , m_deleteCursors(true)
00309 , m_allowZeroLength(false)
00310 {
00311 init();
00312 }
00313
00314
void KateSuperRange::init()
00315 {
00316 Q_ASSERT(
isValid());
00317
if (!
isValid())
00318
kdDebug(13020) <<
superStart() <<
" " <<
superEnd() <<
endl;
00319
00320
insertChild(m_start);
00321
insertChild(m_end);
00322
00323
setBehaviour(DoNotExpand);
00324
00325
00326
connect(m_start, SIGNAL(positionDirectlyChanged()), SIGNAL(
contentsChanged()));
00327
connect(m_end, SIGNAL(positionDirectlyChanged()), SIGNAL(
contentsChanged()));
00328
00329
connect(m_start, SIGNAL(
positionChanged()), SLOT(slotEvaluateChanged()));
00330
connect(m_end, SIGNAL(
positionChanged()), SLOT(slotEvaluateChanged()));
00331
connect(m_start, SIGNAL(
positionUnChanged()), SLOT(slotEvaluateUnChanged()));
00332
connect(m_end, SIGNAL(
positionUnChanged()), SLOT(slotEvaluateUnChanged()));
00333
connect(m_start, SIGNAL(positionDeleted()), SIGNAL(
boundaryDeleted()));
00334
connect(m_end, SIGNAL(positionDeleted()), SIGNAL(
boundaryDeleted()));
00335 }
00336
00337 KateSuperRange::~KateSuperRange()
00338 {
00339
if (m_deleteCursors)
00340 {
00341
00342
00343
delete m_start;
00344
delete m_end;
00345 }
00346 }
00347
00348
KateTextCursor& KateSuperRange::start()
00349 {
00350
return *m_start;
00351 }
00352
00353
const KateTextCursor& KateSuperRange::start()
const
00354
{
00355
return *m_start;
00356 }
00357
00358
KateTextCursor& KateSuperRange::end()
00359 {
00360
return *m_end;
00361 }
00362
00363
const KateTextCursor& KateSuperRange::end()
const
00364
{
00365
return *m_end;
00366 }
00367
00368 KateSuperCursor&
KateSuperRange::superStart()
00369 {
00370
return *m_start;
00371 }
00372
00373
const KateSuperCursor&
KateSuperRange::superStart()
const
00374
{
00375
return *m_start;
00376 }
00377
00378 KateSuperCursor&
KateSuperRange::superEnd()
00379 {
00380
return *m_end;
00381 }
00382
00383
const KateSuperCursor&
KateSuperRange::superEnd()
const
00384
{
00385
return *m_end;
00386 }
00387
00388 int KateSuperRange::behaviour()
const
00389
{
00390
return (m_start->
moveOnInsert() ?
DoNotExpand :
ExpandLeft) | (m_end->
moveOnInsert() ?
ExpandRight :
DoNotExpand);
00391 }
00392
00393 void KateSuperRange::setBehaviour(
int behaviour)
00394 {
00395 m_start->
setMoveOnInsert(behaviour &
ExpandLeft);
00396 m_end->
setMoveOnInsert(!(behaviour &
ExpandRight));
00397 }
00398
00399 bool KateSuperRange::isValid()
const
00400
{
00401
return superStart() <=
superEnd();
00402 }
00403
00404 bool KateSuperRange::owns(
const KateTextCursor& cursor)
const
00405
{
00406
if (!
includes(cursor))
return false;
00407
00408
if (
children())
00409
for (QObjectListIt it(*
children()); *it; ++it)
00410
if ((*it)->inherits(
"KateSuperRange"))
00411
if (static_cast<KateSuperRange*>(*it)->owns(cursor))
00412
return false;
00413
00414
return true;
00415 }
00416
00417 bool KateSuperRange::includes(
const KateTextCursor& cursor)
const
00418
{
00419
return isValid() && cursor >=
superStart() && cursor <
superEnd();
00420 }
00421
00422 bool KateSuperRange::includes(uint lineNum)
const
00423
{
00424
return isValid() && (
int)lineNum >=
superStart().
line() && (
int)lineNum <=
superEnd().
line();
00425 }
00426
00427 bool KateSuperRange::includesWholeLine(uint lineNum)
const
00428
{
00429
return isValid() && ((
int)lineNum >
superStart().
line() || ((
int)lineNum ==
superStart().
line() &&
superStart().
atStartOfLine())) && ((
int)lineNum <
superEnd().
line() || ((
int)lineNum ==
superEnd().
line() &&
superEnd().
atEndOfLine()));
00430 }
00431
00432 bool KateSuperRange::boundaryAt(
const KateTextCursor& cursor)
const
00433
{
00434
return isValid() && (cursor ==
superStart() || cursor ==
superEnd());
00435 }
00436
00437 bool KateSuperRange::boundaryOn(uint lineNum)
const
00438
{
00439
return isValid() && (
superStart().
line() == (
int)lineNum ||
superEnd().
line() == (
int)lineNum);
00440 }
00441
00442
void KateSuperRange::slotEvaluateChanged()
00443 {
00444
if (
sender() == static_cast<QObject*>(m_start)) {
00445
if (m_evaluate) {
00446
if (!m_endChanged) {
00447
00448 evaluateEliminated();
00449
00450 }
else {
00451
00452 evaluatePositionChanged();
00453 m_endChanged =
false;
00454 }
00455
00456 }
else {
00457 m_startChanged =
true;
00458 }
00459
00460 }
else {
00461
if (m_evaluate) {
00462
if (!m_startChanged) {
00463
00464 evaluateEliminated();
00465
00466 }
else {
00467
00468 evaluatePositionChanged();
00469 m_startChanged =
false;
00470 }
00471
00472 }
else {
00473 m_endChanged =
true;
00474 }
00475 }
00476
00477 m_evaluate = !m_evaluate;
00478 }
00479
00480
void KateSuperRange::slotEvaluateUnChanged()
00481 {
00482
if (
sender() == static_cast<QObject*>(m_start)) {
00483
if (m_evaluate) {
00484
if (m_endChanged) {
00485
00486 evaluateEliminated();
00487 m_endChanged =
false;
00488
00489 }
else {
00490
00491 emit
positionUnChanged();
00492 }
00493 }
00494
00495 }
else {
00496
if (m_evaluate) {
00497
if (m_startChanged) {
00498
00499 evaluateEliminated();
00500 m_startChanged =
false;
00501
00502 }
else {
00503
00504 emit
positionUnChanged();
00505 }
00506 }
00507 }
00508
00509 m_evaluate = !m_evaluate;
00510 }
00511
00512
void KateSuperRange::slotTagRange()
00513 {
00514 emit
tagRange(
this);
00515 }
00516
00517
void KateSuperRange::evaluateEliminated()
00518 {
00519
if (
superStart() ==
superEnd()) {
00520
if (!m_allowZeroLength) emit
eliminated();
00521 }
00522
else
00523 emit
contentsChanged();
00524 }
00525
00526
void KateSuperRange::evaluatePositionChanged()
00527 {
00528
if (
superStart() ==
superEnd())
00529 emit
eliminated();
00530
else
00531 emit
positionChanged();
00532 }
00533
00534
int KateSuperCursorList::compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2)
00535 {
00536
if (*(static_cast<KateSuperCursor*>(item1)) == *(static_cast<KateSuperCursor*>(item2)))
00537
return 0;
00538
00539
return *(static_cast<KateSuperCursor*>(item1)) < *(static_cast<KateSuperCursor*>(item2)) ? -1 : 1;
00540 }
00541
00542 KateSuperRangeList::KateSuperRangeList(
bool autoManage,
QObject* parent,
const char* name)
00543 :
QObject(parent,
name)
00544 , m_autoManage(autoManage)
00545 , m_connect(true)
00546 , m_trackingBoundaries(false)
00547 {
00548 setAutoManage(autoManage);
00549 }
00550
00551 KateSuperRangeList::KateSuperRangeList(
const QPtrList<KateSuperRange>& rangeList,
QObject* parent,
const char* name)
00552 :
QObject(parent,
name)
00553 , m_autoManage(false)
00554 , m_connect(false)
00555 , m_trackingBoundaries(false)
00556 {
00557 appendList(rangeList);
00558 }
00559
00560
void KateSuperRangeList::appendList(
const QPtrList<KateSuperRange>& rangeList)
00561 {
00562
for (
QPtrListIterator<KateSuperRange> it = rangeList; *it; ++it)
00563 append(*it);
00564 }
00565
00566
void KateSuperRangeList::clear()
00567 {
00568
for (
KateSuperRange* range = first(); range; range =
next())
00569 emit rangeEliminated(range);
00570
00571
QPtrList<KateSuperRange>::clear();
00572 }
00573
00574
void KateSuperRangeList::connectAll()
00575 {
00576
if (!m_connect) {
00577 m_connect =
true;
00578
for (
KateSuperRange* range = first(); range; range =
next()) {
00579
connect(range, SIGNAL(
destroyed(
QObject*)), SLOT(slotDeleted(
QObject*)));
00580
connect(range, SIGNAL(
eliminated()), SLOT(slotEliminated()));
00581 }
00582 }
00583 }
00584
00585
bool KateSuperRangeList::autoManage()
const
00586
{
00587
return m_autoManage;
00588 }
00589
00590
void KateSuperRangeList::setAutoManage(
bool autoManage)
00591 {
00592 m_autoManage = autoManage;
00593 setAutoDelete(m_autoManage);
00594 }
00595
00596
QPtrList<KateSuperRange> KateSuperRangeList::rangesIncluding(
const KateTextCursor& cursor)
00597 {
00598 sort();
00599
00600
QPtrList<KateSuperRange> ret;
00601
00602
for (
KateSuperRange* r = first(); r; r =
next())
00603
if (r->
includes(cursor))
00604 ret.
append(r);
00605
00606
return ret;
00607 }
00608
00609
QPtrList<KateSuperRange> KateSuperRangeList::rangesIncluding(uint line)
00610 {
00611 sort();
00612
00613
QPtrList<KateSuperRange> ret;
00614
00615
for (
KateSuperRange* r = first(); r; r =
next())
00616
if (r->
includes(line))
00617 ret.
append(r);
00618
00619
return ret;
00620 }
00621
00622
bool KateSuperRangeList::rangesInclude(
const KateTextCursor& cursor)
00623 {
00624
for (
KateSuperRange* r = first(); r; r =
next())
00625
if (r->
includes(cursor))
00626
return true;
00627
00628
return false;
00629 }
00630
00631
void KateSuperRangeList::slotEliminated()
00632 {
00633
if (
sender()) {
00634
KateSuperRange* range = static_cast<KateSuperRange*>(const_cast<QObject*>(
sender()));
00635 emit rangeEliminated(range);
00636
00637
if (m_trackingBoundaries) {
00638 m_columnBoundaries.removeRef(range->
m_start);
00639 m_columnBoundaries.removeRef(range->
m_end);
00640 }
00641
00642
if (m_autoManage)
00643 removeRef(range);
00644
00645
if (!count())
00646 emit listEmpty();
00647 }
00648 }
00649
00650
void KateSuperRangeList::slotDeleted(
QObject* range)
00651 {
00652
00653
KateSuperRange* r = static_cast<KateSuperRange*>(range);
00654
00655
if (m_trackingBoundaries) {
00656 m_columnBoundaries.removeRef(r->
m_start);
00657 m_columnBoundaries.removeRef(r->
m_end);
00658 }
00659
00660
int index = findRef(r);
00661
if (index != -1)
00662 take(index);
00663
00664
00665
if (!count())
00666 emit listEmpty();
00667 }
00668
00669
KateSuperCursor* KateSuperRangeList::firstBoundary(
const KateTextCursor* start)
00670 {
00671
if (!m_trackingBoundaries) {
00672 m_trackingBoundaries =
true;
00673
00674
for (
KateSuperRange* r = first(); r; r =
next()) {
00675 m_columnBoundaries.
append(&(r->
superStart()));
00676 m_columnBoundaries.append(&(r->
superEnd()));
00677 }
00678 }
00679
00680 m_columnBoundaries.sort();
00681
00682
if (start)
00683
00684
for (
KateSuperCursor* c = m_columnBoundaries.first(); c; c = m_columnBoundaries.next())
00685
if (*start <= *c)
00686
break;
00687
00688
return m_columnBoundaries.current();
00689 }
00690
00691
KateSuperCursor* KateSuperRangeList::nextBoundary()
00692 {
00693
KateSuperCursor* current = m_columnBoundaries.current();
00694
00695
00696
if (current)
00697
while (m_columnBoundaries.next())
00698
if (*(m_columnBoundaries.current()) != *current)
00699
break;
00700
00701
return m_columnBoundaries.current();
00702 }
00703
00704
KateSuperCursor* KateSuperRangeList::currentBoundary()
00705 {
00706
return m_columnBoundaries.current();
00707 }
00708
00709
int KateSuperRangeList::compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2)
00710 {
00711
if (static_cast<KateSuperRange*>(item1)->superStart() == static_cast<KateSuperRange*>(item2)->superStart()) {
00712
if (static_cast<KateSuperRange*>(item1)->superEnd() == static_cast<KateSuperRange*>(item2)->superEnd()) {
00713
return 0;
00714 }
else {
00715
return static_cast<KateSuperRange*>(item1)->superEnd() < static_cast<KateSuperRange*>(item2)->superEnd() ? -1 : 1;
00716 }
00717 }
00718
00719
return static_cast<KateSuperRange*>(item1)->superStart() < static_cast<KateSuperRange*>(item2)->superStart() ? -1 : 1;
00720 }
00721
00722
QPtrCollection::Item KateSuperRangeList::newItem(QPtrCollection::Item d)
00723 {
00724
if (m_connect) {
00725
connect(static_cast<KateSuperRange*>(d), SIGNAL(
destroyed(
QObject*)), SLOT(slotDeleted(
QObject*)));
00726
connect(static_cast<KateSuperRange*>(d), SIGNAL(
eliminated()), SLOT(slotEliminated()));
00727
connect(static_cast<KateSuperRange*>(d), SIGNAL(
tagRange(
KateSuperRange*)), SIGNAL(
tagRange(
KateSuperRange*)));
00728
00729
00730 static_cast<KateSuperRange*>(d)->slotTagRange();
00731 }
00732
00733
if (m_trackingBoundaries) {
00734 m_columnBoundaries.append(&(static_cast<KateSuperRange*>(d)->
superStart()));
00735 m_columnBoundaries.append(&(static_cast<KateSuperRange*>(d)->
superEnd()));
00736 }
00737
00738
return QPtrList<KateSuperRange>::newItem(d);
00739 }
00740
00741