00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "kateviewinternal.h"
00027
#include "kateviewinternal.moc"
00028
00029
#include "kateview.h"
00030
#include "katedocument.h"
00031
#include "katecodefoldinghelpers.h"
00032
#include "kateviewhelpers.h"
00033
#include "katehighlight.h"
00034
#include "katesupercursor.h"
00035
#include "katerenderer.h"
00036
#include "katecodecompletion.h"
00037
#include "kateconfig.h"
00038
00039
#include <kcursor.h>
00040
#include <kdebug.h>
00041
#include <kapplication.h>
00042
#include <kglobalsettings.h>
00043
#include <kurldrag.h>
00044
00045
#include <qstyle.h>
00046
#include <qdragobject.h>
00047
#include <qpopupmenu.h>
00048
#include <qdropsite.h>
00049
#include <qpainter.h>
00050
#include <qlayout.h>
00051
#include <qclipboard.h>
00052
#include <qpixmap.h>
00053
00054 KateViewInternal::KateViewInternal(KateView *view, KateDocument *doc)
00055 :
QWidget (view, "",
Qt::WStaticContents |
Qt::WRepaintNoErase |
Qt::WResizeNoErase )
00056 , editSessionNumber (0)
00057 , editIsRunning (false)
00058 , m_view (view)
00059 , m_doc (doc)
00060 , cursor (doc, true, 0, 0, this)
00061 , possibleTripleClick (false)
00062 , m_dummy (0)
00063 , m_startPos(0,0)
00064 , m_oldStartPos(0,0)
00065 , m_madeVisible(false)
00066 , m_shiftKeyPressed (false)
00067 , m_autoCenterLines (false)
00068 , m_columnScrollDisplayed(false)
00069 , m_selChangedByUser (false)
00070 , selectAnchor (-1, -1)
00071 , m_preserveMaxX(false)
00072 , m_currentMaxX(0)
00073 , m_usePlainLines(false)
00074 , m_updatingView(true)
00075 , m_cachedMaxStartPos(-1, -1)
00076 , m_dragScrollTimer(this)
00077 , m_scrollTimer (this)
00078 , m_cursorTimer (this)
00079 , m_textHintTimer (this)
00080 , m_suppressColumnScrollBar(false)
00081 , m_textHintEnabled(false)
00082 , m_textHintMouseX(-1)
00083 , m_textHintMouseY(-1)
00084 , m_imPreeditStartLine(0)
00085 , m_imPreeditStart(0)
00086 , m_imPreeditLength(0)
00087 {
00088 setMinimumSize (0,0);
00089
00090
00091 cursor.setMoveOnInsert (
true);
00092
00093
00094
00095
00096 m_lineScroll =
new KateScrollBar(QScrollBar::Vertical, m_view);
00097 m_lineScroll->show();
00098 m_lineScroll->setTracking (
true);
00099
00100 m_lineLayout =
new QVBoxLayout();
00101 m_colLayout =
new QHBoxLayout();
00102
00103 m_colLayout->addWidget(m_lineScroll);
00104 m_lineLayout->addLayout(m_colLayout);
00105
00106
if (!m_view->dynWordWrap())
00107 {
00108
00109 m_dummy =
new QWidget(m_view);
00110 m_dummy->setFixedHeight(style().scrollBarExtent().width());
00111 m_dummy->show();
00112 m_lineLayout->addWidget(m_dummy);
00113 }
00114
00115
00116 connect(m_lineScroll, SIGNAL(prevPage()), SLOT(scrollPrevPage()));
00117 connect(m_lineScroll, SIGNAL(nextPage()), SLOT(scrollNextPage()));
00118
00119 connect(m_lineScroll, SIGNAL(prevLine()), SLOT(scrollPrevLine()));
00120 connect(m_lineScroll, SIGNAL(nextLine()), SLOT(scrollNextLine()));
00121
00122 connect(m_lineScroll, SIGNAL(sliderMoved(
int)), SLOT(scrollLines(
int)));
00123 connect(m_lineScroll, SIGNAL(sliderMMBMoved(
int)), SLOT(scrollLines(
int)));
00124
00125
00126 m_lineScroll->installEventFilter(
this);
00127
00128
00129
00130
00131 m_columnScroll =
new QScrollBar(QScrollBar::Horizontal,m_view);
00132 m_columnScroll->hide();
00133 m_columnScroll->setTracking(
true);
00134 m_startX = 0;
00135 m_oldStartX = 0;
00136
00137 connect( m_columnScroll, SIGNAL( valueChanged (
int) ),
00138
this, SLOT( scrollColumns (
int) ) );
00139
00140
00141
00142
00143 leftBorder =
new KateIconBorder(
this, m_view );
00144 leftBorder->show ();
00145
00146 connect( leftBorder, SIGNAL(toggleRegionVisibility(
unsigned int)),
00147 m_doc->foldingTree(), SLOT(toggleRegionVisibility(
unsigned int)));
00148
00149 connect( doc->foldingTree(), SIGNAL(regionVisibilityChangedAt(
unsigned int)),
00150
this, SLOT(slotRegionVisibilityChangedAt(
unsigned int)));
00151 connect( doc, SIGNAL(codeFoldingUpdated()),
00152
this, SLOT(slotCodeFoldingChanged()) );
00153
00154 displayCursor.setPos(0, 0);
00155 cursor.setPos(0, 0);
00156 cXPos = 0;
00157
00158 setAcceptDrops(
true );
00159 setBackgroundMode( NoBackground );
00160
00161
00162 installEventFilter(
this);
00163
00164
00165 setInputMethodEnabled(
true);
00166
00167
00168 setCursor( KCursor::ibeamCursor() );
00169
00170 dragInfo.state = diNone;
00171
00172
00173 connect( &m_dragScrollTimer, SIGNAL( timeout() ),
00174
this, SLOT( doDragScroll() ) );
00175
00176 connect( &m_scrollTimer, SIGNAL( timeout() ),
00177
this, SLOT( scrollTimeout() ) );
00178
00179 connect( &m_cursorTimer, SIGNAL( timeout() ),
00180
this, SLOT( cursorTimeout() ) );
00181
00182 connect( &m_textHintTimer, SIGNAL( timeout() ),
00183
this, SLOT( textHintTimeout() ) );
00184
00185
00186 connect( m_doc, SIGNAL( selectionChanged() ),
00187
this, SLOT( docSelectionChanged() ) );
00188
00189
00190
00191
00192
00193
00194
if (QApplication::reverseLayout()){
00195 m_view->m_grid->addMultiCellWidget(leftBorder, 0, 1, 2, 2);
00196 m_view->m_grid->addMultiCellWidget(m_columnScroll, 1, 1, 0, 1);
00197 m_view->m_grid->addMultiCellLayout(m_lineLayout, 0, 0, 0, 0);
00198 }
00199
else{
00200 m_view->m_grid->addMultiCellLayout(m_lineLayout, 0, 1, 2, 2);
00201 m_view->m_grid->addMultiCellWidget(m_columnScroll, 1, 1, 0, 1);
00202 m_view->m_grid->addWidget(leftBorder, 0, 0);
00203 }
00204
00205 updateView ();
00206 }
00207
00208 KateViewInternal::~KateViewInternal ()
00209 {
00210 }
00211
00212
void KateViewInternal::prepareForDynWrapChange()
00213 {
00214
00215 m_wrapChangeViewLine = displayViewLine(displayCursor,
true);
00216 }
00217
00218
void KateViewInternal::dynWrapChanged()
00219 {
00220
if (m_view->dynWordWrap())
00221 {
00222
delete m_dummy;
00223 m_dummy = 0;
00224 m_columnScroll->hide();
00225 m_columnScrollDisplayed =
false;
00226
00227 }
00228
else
00229 {
00230
00231 m_dummy =
new QWidget(m_view);
00232 m_dummy->setFixedSize( style().scrollBarExtent().width(),
00233 style().scrollBarExtent().width() );
00234 m_dummy->show();
00235 m_lineLayout->addWidget(m_dummy);
00236 }
00237
00238 tagAll();
00239 updateView();
00240
00241
if (m_view->dynWordWrap())
00242 scrollColumns(0);
00243
00244
00245
if (m_wrapChangeViewLine != -1) {
00246
KateTextCursor newStart = viewLineOffset(displayCursor, -m_wrapChangeViewLine);
00247
00248
00249
if (!m_view->dynWordWrap() && scrollbarVisible(newStart.
line())) {
00250
int lines = linesDisplayed() - 1;
00251
00252
if (m_view->height() != height())
00253 lines++;
00254
00255
if (newStart.
line() + lines == displayCursor.line())
00256 newStart = viewLineOffset(displayCursor, 1 - m_wrapChangeViewLine);
00257 }
00258
00259 makeVisible(newStart, newStart.
col(),
true);
00260
00261 }
else {
00262 update();
00263 }
00264 }
00265
00266
KateTextCursor KateViewInternal::endPos()
const
00267
{
00268
int viewLines = linesDisplayed() - 1;
00269
00270
if (viewLines < 0) {
00271
kdDebug(13030) <<
"WARNING: viewLines wrong!" <<
endl;
00272 viewLines = 0;
00273 }
00274
00275
00276
if (!lineRanges.count() || lineRanges[0].line == -1 || viewLines >= (
int)lineRanges.count()) {
00277
00278
return KateTextCursor(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
00279 }
00280
00281
for (
int i = viewLines; i >= 0; i--) {
00282 LineRange& thisRange = lineRanges[i];
00283
00284
if (thisRange.line == -1)
continue;
00285
00286
if (thisRange.virtualLine >= (
int)m_doc->numVisLines()) {
00287
00288
return KateTextCursor(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
00289 }
00290
00291
return KateTextCursor(thisRange.virtualLine, thisRange.wrap ? thisRange.endCol - 1 : thisRange.endCol);
00292 }
00293
00294 Q_ASSERT(
false);
00295
kdDebug(13030) <<
"WARNING: could not find a lineRange at all" <<
endl;
00296
return KateTextCursor(-1, -1);
00297 }
00298
00299 uint KateViewInternal::endLine()
const
00300
{
00301
return endPos().line();
00302 }
00303
00304 LineRange KateViewInternal::yToLineRange(uint y)
const
00305
{
00306
return lineRanges[y / m_view->renderer()->fontHeight()];
00307 }
00308
00309
int KateViewInternal::lineToY(uint viewLine)
const
00310
{
00311
return (viewLine-startLine()) * m_view->renderer()->fontHeight();
00312 }
00313
00314
void KateViewInternal::slotIncFontSizes()
00315 {
00316 m_view->renderer()->increaseFontSizes();
00317 }
00318
00319
void KateViewInternal::slotDecFontSizes()
00320 {
00321 m_view->renderer()->decreaseFontSizes();
00322 }
00323
00327
void KateViewInternal::scrollLines (
int line )
00328 {
00329
KateTextCursor newPos(line, 0);
00330 scrollPos(newPos);
00331 }
00332
00333
00334
void KateViewInternal::scrollViewLines(
int offset)
00335 {
00336
KateTextCursor c = viewLineOffset(startPos(), offset);
00337 scrollPos(c);
00338
00339 m_lineScroll->blockSignals(
true);
00340 m_lineScroll->setValue(startLine());
00341 m_lineScroll->blockSignals(
false);
00342 }
00343
00344
void KateViewInternal::scrollNextPage()
00345 {
00346 scrollViewLines(QMAX( linesDisplayed() - 1, 0 ));
00347 }
00348
00349
void KateViewInternal::scrollPrevPage()
00350 {
00351 scrollViewLines(-QMAX( linesDisplayed() - 1, 0 ));
00352 }
00353
00354
void KateViewInternal::scrollPrevLine()
00355 {
00356 scrollViewLines(-1);
00357 }
00358
00359
void KateViewInternal::scrollNextLine()
00360 {
00361 scrollViewLines(1);
00362 }
00363
00364
KateTextCursor KateViewInternal::maxStartPos(
bool changed)
00365 {
00366 m_usePlainLines =
true;
00367
00368
if (m_cachedMaxStartPos.line() == -1 || changed)
00369 {
00370
KateTextCursor end(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
00371
00372 m_cachedMaxStartPos = viewLineOffset(end, -(linesDisplayed() - 1));
00373 }
00374
00375
00376
if (!m_view->dynWordWrap() && m_columnScroll->isHidden() && scrollbarVisible(m_cachedMaxStartPos.line()))
00377 {
00378
KateTextCursor end(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
00379
00380
return viewLineOffset(end, -linesDisplayed());
00381 }
00382
00383 m_usePlainLines =
false;
00384
00385
return m_cachedMaxStartPos;
00386 }
00387
00388
00389
void KateViewInternal::scrollPos(
KateTextCursor& c,
bool force,
bool calledExternally)
00390 {
00391
if (!force && ((!m_view->dynWordWrap() && c.
line() == (
int)startLine()) || c == startPos()))
00392
return;
00393
00394
if (c.
line() < 0)
00395 c.
setLine(0);
00396
00397
KateTextCursor limit = maxStartPos();
00398
if (c > limit) {
00399 c = limit;
00400
00401
00402
00403
if (m_view->dynWordWrap())
00404 m_suppressColumnScrollBar =
true;
00405
00406
00407
if (!force && ((!m_view->dynWordWrap() && c.
line() == (
int)startLine()) || c == startPos()))
00408
return;
00409 }
00410
00411
int viewLinesScrolled = displayViewLine(c);
00412
00413 m_oldStartPos = m_startPos;
00414 m_startPos = c;
00415
00416
00417 m_madeVisible =
false;
00418
00419
if (!force) {
00420
int lines = linesDisplayed();
00421
if ((
int)m_doc->numVisLines() < lines) {
00422
KateTextCursor end(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
00423 lines = QMIN((
int)linesDisplayed(), displayViewLine(end) + 1);
00424 }
00425
00426 Q_ASSERT(lines >= 0);
00427
00428
if (!calledExternally && QABS(viewLinesScrolled) < lines)
00429 {
00430 updateView(
false, viewLinesScrolled);
00431
00432
int scrollHeight = -(viewLinesScrolled * m_view->renderer()->fontHeight());
00433
int scrollbarWidth = style().scrollBarExtent().width();
00434
00435
00436
00437
00438 scroll(0, scrollHeight);
00439 update(0, height()+scrollHeight-scrollbarWidth, width(), 2*scrollbarWidth);
00440
00441 leftBorder->scroll(0, scrollHeight);
00442 leftBorder->update(0, leftBorder->height()+scrollHeight-scrollbarWidth, leftBorder->width(), 2*scrollbarWidth);
00443
00444
return;
00445 }
00446 }
00447
00448 updateView();
00449 update();
00450 leftBorder->update();
00451 }
00452
00453
void KateViewInternal::scrollColumns (
int x )
00454 {
00455
if (x == m_startX)
00456
return;
00457
00458
if (x < 0)
00459 x = 0;
00460
00461
int dx = m_startX - x;
00462 m_oldStartX = m_startX;
00463 m_startX = x;
00464
00465
if (QABS(dx) < width())
00466 scroll(dx, 0);
00467
else
00468 update();
00469
00470 m_columnScroll->blockSignals(
true);
00471 m_columnScroll->setValue(m_startX);
00472 m_columnScroll->blockSignals(
false);
00473 }
00474
00475
00476
void KateViewInternal::updateView(
bool changed,
int viewLinesScrolled)
00477 {
00478 m_updatingView =
true;
00479
00480 uint contentLines = m_doc->visibleLines();
00481
00482 m_lineScroll->blockSignals(
true);
00483
00484
KateTextCursor maxStart = maxStartPos(changed);
00485
int maxLineScrollRange = maxStart.
line();
00486
if (m_view->dynWordWrap() && maxStart.
col() != 0)
00487 maxLineScrollRange++;
00488 m_lineScroll->setRange(0, maxLineScrollRange);
00489
00490
if (m_view->dynWordWrap() && m_suppressColumnScrollBar) {
00491 m_suppressColumnScrollBar =
false;
00492 m_lineScroll->setValue(maxStart.
line());
00493 }
else {
00494 m_lineScroll->setValue(startPos().line());
00495 }
00496 m_lineScroll->setSteps(1, height() / m_view->renderer()->fontHeight());
00497 m_lineScroll->blockSignals(
false);
00498
00499 uint oldSize = lineRanges.size ();
00500 uint newSize = (height() / m_view->renderer()->fontHeight()) + 1;
00501
if (oldSize != newSize) {
00502 lineRanges.resize((height() / m_view->renderer()->fontHeight()) + 1);
00503
if (newSize > oldSize) {
00504
static LineRange blank;
00505
for (uint i = oldSize; i < newSize; i++) {
00506 lineRanges[i] = blank;
00507 }
00508 }
00509 }
00510
00511
if (oldSize < lineRanges.size ())
00512 {
00513
for (uint i=oldSize; i < lineRanges.size(); i++)
00514 lineRanges[i].dirty =
true;
00515 }
00516
00517
00518
if (viewLinesScrolled != 0) {
00519
00520
bool forwards = viewLinesScrolled >= 0 ?
true :
false;
00521
for (uint z = forwards ? 0 : lineRanges.count() - 1; z < lineRanges.count(); forwards ? z++ : z--) {
00522 uint oldZ = z + viewLinesScrolled;
00523
if (oldZ < lineRanges.count()) {
00524 lineRanges[z] = lineRanges[oldZ];
00525 }
else {
00526 lineRanges[z].dirty =
true;
00527 }
00528 }
00529 }
00530
00531
if (m_view->dynWordWrap())
00532 {
00533
KateTextCursor realStart = startPos();
00534 realStart.
setLine(m_doc->getRealLine(realStart.
line()));
00535
00536 LineRange startRange = range(realStart);
00537 uint line = startRange.virtualLine;
00538
int realLine = startRange.line;
00539 uint oldLine = line;
00540
int startCol = startRange.startCol;
00541
int startX = startRange.startX;
00542
int endX = startRange.startX;
00543
int shiftX = startRange.startCol ? startRange.shiftX : 0;
00544
bool wrap =
false;
00545
int newViewLine = startRange.viewLine;
00546
00547 TextLine::Ptr
text = textLine(realLine);
00548
00549
bool alreadyDirty =
false;
00550
00551
for (uint z = 0; z < lineRanges.size(); z++)
00552 {
00553
if (oldLine != line) {
00554 realLine = (
int)m_doc->getRealLine(line);
00555
00556
if (z)
00557 lineRanges[z-1].startsInvisibleBlock = (realLine != lineRanges[z-1].line + 1);
00558
00559 text = textLine(realLine);
00560 startCol = 0;
00561 startX = 0;
00562 endX = 0;
00563 shiftX = 0;
00564 newViewLine = 0;
00565 oldLine = line;
00566 }
00567
00568
if (line >= contentLines || !text)
00569 {
00570
if (lineRanges[z].line != -1)
00571 lineRanges[z].dirty =
true;
00572
00573 lineRanges[z].clear();
00574
00575 line++;
00576 }
00577
else
00578 {
00579
if (lineRanges[z].line != realLine || lineRanges[z].startCol != startCol)
00580 alreadyDirty = lineRanges[z].dirty =
true;
00581
00582
if (lineRanges[z].dirty || changed || alreadyDirty) {
00583 alreadyDirty =
true;
00584
00585 lineRanges[z].virtualLine = line;
00586 lineRanges[z].line = realLine;
00587 lineRanges[z].startsInvisibleBlock =
false;
00588
00589
int tempEndX = 0;
00590
00591
int endCol = m_view->renderer()->textWidth(text, startCol, width() - shiftX, &wrap, &tempEndX);
00592
00593 endX += tempEndX;
00594
00595
if (wrap)
00596 {
00597
if (m_view->config()->dynWordWrapAlignIndent() > 0)
00598 {
00599
if (startX == 0)
00600 {
00601
int pos = text->nextNonSpaceChar(0);
00602
00603
if (pos > 0)
00604 shiftX = m_view->renderer()->textWidth(text, pos);
00605
00606
if (shiftX > ((
double)width() / 100 * m_view->config()->dynWordWrapAlignIndent()))
00607 shiftX = 0;
00608 }
00609 }
00610
00611
if ((lineRanges[z].startX != startX) || (lineRanges[z].endX != endX) ||
00612 (lineRanges[z].startCol != startCol) || (lineRanges[z].endCol != endCol) ||
00613 (lineRanges[z].shiftX != shiftX))
00614 lineRanges[z].dirty =
true;
00615
00616 lineRanges[z].startCol = startCol;
00617 lineRanges[z].endCol = endCol;
00618 lineRanges[z].startX = startX;
00619 lineRanges[z].endX = endX;
00620 lineRanges[z].viewLine = newViewLine;
00621 lineRanges[z].wrap =
true;
00622
00623 startCol = endCol;
00624 startX = endX;
00625 }
00626
else
00627 {
00628
if ((lineRanges[z].startX != startX) || (lineRanges[z].endX != endX) ||
00629 (lineRanges[z].startCol != startCol) || (lineRanges[z].endCol != endCol))
00630 lineRanges[z].dirty =
true;
00631
00632 lineRanges[z].startCol = startCol;
00633 lineRanges[z].endCol = endCol;
00634 lineRanges[z].startX = startX;
00635 lineRanges[z].endX = endX;
00636 lineRanges[z].viewLine = newViewLine;
00637 lineRanges[z].wrap =
false;
00638
00639 line++;
00640 }
00641
00642 lineRanges[z].shiftX = shiftX;
00643
00644 }
else {
00645
00646
if (lineRanges[z].wrap) {
00647 startCol = lineRanges[z].endCol;
00648 startX = lineRanges[z].endX;
00649 endX = lineRanges[z].endX;
00650 }
else {
00651 line++;
00652 }
00653 shiftX = lineRanges[z].shiftX;
00654 }
00655 }
00656 newViewLine++;
00657 }
00658 }
00659
else
00660 {
00661 uint z = 0;
00662
00663
for(; (z + startLine() < contentLines) && (z < lineRanges.size()); z++)
00664 {
00665
if (lineRanges[z].dirty || lineRanges[z].line != (
int)m_doc->getRealLine(z + startLine())) {
00666 lineRanges[z].dirty =
true;
00667
00668 lineRanges[z].line = m_doc->getRealLine( z + startLine() );
00669
if (z)
00670 lineRanges[z-1].startsInvisibleBlock = (lineRanges[z].line != lineRanges[z-1].line + 1);
00671
00672 lineRanges[z].virtualLine = z + startLine();
00673 lineRanges[z].startCol = 0;
00674 lineRanges[z].endCol = m_doc->lineLength(lineRanges[z].line);
00675 lineRanges[z].startX = 0;
00676 lineRanges[z].endX = m_view->renderer()->textWidth( textLine( lineRanges[z].line ), -1 );
00677 lineRanges[z].shiftX = 0;
00678 lineRanges[z].viewLine = 0;
00679 lineRanges[z].wrap =
false;
00680 }
00681
else if (z && lineRanges[z-1].dirty)
00682 {
00683 lineRanges[z-1].startsInvisibleBlock = (lineRanges[z].line != lineRanges[z-1].line + 1);
00684 }
00685 }
00686
00687
for (; z < lineRanges.size(); z++)
00688 {
00689
if (lineRanges[z].line != -1)
00690 lineRanges[z].dirty =
true;
00691
00692 lineRanges[z].clear();
00693 }
00694
00695
if (scrollbarVisible(startLine()))
00696 {
00697 m_columnScroll->blockSignals(
true);
00698
00699
int max = maxLen(startLine()) - width();
00700
if (max < 0)
00701 max = 0;
00702
00703 m_columnScroll->setRange(0, max);
00704
00705 m_columnScroll->setValue(m_startX);
00706
00707
00708 m_columnScroll->setSteps(m_view->renderer()->config()->fontMetrics()->width(
'a'), width());
00709
00710 m_columnScroll->blockSignals(
false);
00711
00712
if (!m_columnScroll->isVisible () && !m_suppressColumnScrollBar)
00713 {
00714 m_columnScroll->show();
00715 m_columnScrollDisplayed =
true;
00716 }
00717 }
00718
else if (m_columnScroll->isVisible () && !m_suppressColumnScrollBar && (startX() == 0))
00719 {
00720 m_columnScroll->hide();
00721 m_columnScrollDisplayed =
false;
00722 }
00723 }
00724
00725 m_updatingView =
false;
00726
00727
if (changed)
00728 paintText(0, 0, width(), height(),
true);
00729 }
00730
00731
void KateViewInternal::paintText (
int x,
int y,
int width,
int height,
bool paintOnlyDirty)
00732 {
00733
00734
int xStart = startX() + x;
00735
int xEnd = xStart + width;
00736 uint h = m_view->renderer()->fontHeight();
00737 uint startz = (y / h);
00738 uint endz = startz + 1 + (height / h);
00739 uint lineRangesSize = lineRanges.size();
00740
00741
static QPixmap drawBuffer;
00742
00743
if (drawBuffer.width() < KateViewInternal::width() || drawBuffer.height() < (
int)h)
00744 drawBuffer.resize(KateViewInternal::width(), (
int)h);
00745
00746
if (drawBuffer.isNull())
00747
return;
00748
00749
QPainter paint(
this);
00750
QPainter paintDrawBuffer(&drawBuffer);
00751
00752
00753 m_view->renderer()->setCaretStyle(m_view->isOverwriteMode() ? KateRenderer::Replace : KateRenderer::Insert);
00754 m_view->renderer()->setShowTabs(m_doc->configFlags() & KateDocument::cfShowTabs);
00755
00756
for (uint z=startz; z <= endz; z++)
00757 {
00758
if ( (z >= lineRangesSize) || ((lineRanges[z].line == -1) && (!paintOnlyDirty || lineRanges[z].dirty)) )
00759 {
00760
if (!(z >= lineRangesSize))
00761 lineRanges[z].dirty =
false;
00762
00763 paint.fillRect( x, z * h, width, h, *m_view->renderer()->config()->backgroundColor() );
00764 }
00765
else if (!paintOnlyDirty || lineRanges[z].dirty)
00766 {
00767 lineRanges[z].dirty =
false;
00768
00769 m_view->renderer()->paintTextLine(paintDrawBuffer, &lineRanges[z], xStart, xEnd, &cursor, &bm);
00770
00771 paint.drawPixmap (x, z * h, drawBuffer, 0, 0, width, h);
00772 }
00773 }
00774 }
00775
00780
void KateViewInternal::makeVisible (
const KateTextCursor& c, uint endCol,
bool force,
bool center,
bool calledExternally)
00781 {
00782
00783
00784
00785
00786
00787
if ( force )
00788 {
00789
KateTextCursor scroll = c;
00790 scrollPos(scroll, force, calledExternally);
00791 }
00792
else if (center && (c < startPos() || c > endPos()))
00793 {
00794
KateTextCursor scroll = viewLineOffset(c, -
int(linesDisplayed()) / 2);
00795 scrollPos(scroll,
false, calledExternally);
00796 }
00797
else if ( c > viewLineOffset(endPos(), -m_minLinesVisible) )
00798 {
00799
KateTextCursor scroll = viewLineOffset(c, -(linesDisplayed() - m_minLinesVisible - 1));
00800
00801
if (!m_view->dynWordWrap() && m_columnScroll->isHidden())
00802
if (scrollbarVisible(scroll.
line()))
00803 scroll.
setLine(scroll.
line() + 1);
00804
00805 scrollPos(scroll,
false, calledExternally);
00806 }
00807
else if ( c < viewLineOffset(startPos(), m_minLinesVisible) )
00808 {
00809
KateTextCursor scroll = viewLineOffset(c, -m_minLinesVisible);
00810 scrollPos(scroll,
false, calledExternally);
00811 }
00812
else
00813 {
00814
00815
KateTextCursor max = maxStartPos();
00816
if (startPos() > max) {
00817 scrollPos(max, max.
col(), calledExternally);
00818 }
00819 }
00820
00821
if (!m_view->dynWordWrap() && endCol != (uint)-1)
00822 {
00823
int sX = (
int)m_view->renderer()->textWidth (textLine( m_doc->getRealLine( c.
line() ) ), c.
col() );
00824
00825
int sXborder = sX-8;
00826
if (sXborder < 0)
00827 sXborder = 0;
00828
00829
if (sX < m_startX)
00830 scrollColumns (sXborder);
00831
else if (sX > m_startX + width())
00832 scrollColumns (sX - width() + 8);
00833 }
00834
00835 m_madeVisible = !force;
00836 }
00837
00838
void KateViewInternal::slotRegionVisibilityChangedAt(
unsigned int)
00839 {
00840
kdDebug(13030) <<
"slotRegionVisibilityChangedAt()" <<
endl;
00841 m_cachedMaxStartPos.setLine(-1);
00842
KateTextCursor max = maxStartPos();
00843
if (startPos() > max)
00844 scrollPos(max);
00845
00846 updateView();
00847 update();
00848 leftBorder->update();
00849 }
00850
00851
void KateViewInternal::slotCodeFoldingChanged()
00852 {
00853 leftBorder->update();
00854 }
00855
00856
void KateViewInternal::slotRegionBeginEndAddedRemoved(
unsigned int)
00857 {
00858
kdDebug(13030) <<
"slotRegionBeginEndAddedRemoved()" <<
endl;
00859
00860 leftBorder->update();
00861 }
00862
00863
void KateViewInternal::showEvent (
QShowEvent *e )
00864 {
00865 updateView ();
00866
00867 QWidget::showEvent (e);
00868 }
00869
00870 uint KateViewInternal::linesDisplayed()
const
00871
{
00872
int h = height();
00873
int fh = m_view->renderer()->fontHeight();
00874
00875
return (h - (h % fh)) / fh;
00876 }
00877
00878
QPoint KateViewInternal::cursorCoordinates()
00879 {
00880
int viewLine = displayViewLine(displayCursor,
true);
00881
00882
if (viewLine == -1)
00883
return QPoint(-1, -1);
00884
00885 uint y = viewLine * m_view->renderer()->fontHeight();
00886 uint x = cXPos - m_startX - lineRanges[viewLine].startX + leftBorder->width() + lineRanges[viewLine].xOffset();
00887
00888
return QPoint(x, y);
00889 }
00890
00891
void KateViewInternal::doReturn()
00892 {
00893
KateTextCursor c = cursor;
00894 m_doc->newLine( c,
this );
00895 updateCursor( c );
00896 updateView();
00897 }
00898
00899
void KateViewInternal::doDelete()
00900 {
00901 m_doc->del( cursor );
00902 }
00903
00904
void KateViewInternal::doBackspace()
00905 {
00906 m_doc->backspace( cursor );
00907 }
00908
00909
void KateViewInternal::doPaste()
00910 {
00911 m_doc->paste( m_view );
00912 }
00913
00914
void KateViewInternal::doTranspose()
00915 {
00916 m_doc->transpose( cursor );
00917 }
00918
00919
void KateViewInternal::doDeleteWordLeft()
00920 {
00921 wordLeft(
true );
00922 m_doc->removeSelectedText();
00923 update();
00924 }
00925
00926
void KateViewInternal::doDeleteWordRight()
00927 {
00928 wordRight(
true );
00929 m_doc->removeSelectedText();
00930 update();
00931 }
00932
00933
class CalculatingCursor :
public KateTextCursor {
00934
public:
00935 CalculatingCursor(KateViewInternal* vi)
00936 :
KateTextCursor()
00937 , m_vi(vi)
00938 {
00939 Q_ASSERT(valid());
00940 }
00941
00942 CalculatingCursor(KateViewInternal* vi,
const KateTextCursor& c)
00943 :
KateTextCursor(c)
00944 , m_vi(vi)
00945 {
00946 Q_ASSERT(valid());
00947 }
00948
00949
00950 CalculatingCursor(KateViewInternal* vi, uint line, uint col)
00951 :
KateTextCursor(line, col)
00952 , m_vi(vi)
00953 {
00954 makeValid();
00955 }
00956
00957
00958
virtual CalculatingCursor& operator+=(
int n ) = 0;
00959
00960
virtual CalculatingCursor& operator-=(
int n ) = 0;
00961
00962 CalculatingCursor& operator++() {
return operator+=( 1 ); }
00963
00964 CalculatingCursor& operator--() {
return operator-=( 1 ); }
00965
00966
void makeValid() {
00967 m_line = QMAX( 0, QMIN(
int( m_vi->m_doc->numLines() - 1 ), line() ) );
00968
if (m_vi->m_doc->wrapCursor())
00969 m_col = QMAX( 0, QMIN( m_vi->m_doc->lineLength( line() ), col() ) );
00970
else
00971 m_col = QMAX( 0, col() );
00972 Q_ASSERT( valid() );
00973 }
00974
00975
void toEdge( Bias bias ) {
00976
if( bias == left ) m_col = 0;
00977
else if( bias == right ) m_col = m_vi->m_doc->lineLength( line() );
00978 }
00979
00980
bool atEdge()
const {
return atEdge( left ) || atEdge( right ); }
00981
00982
bool atEdge( Bias bias )
const {
00983
switch( bias ) {
00984
case left:
return col() == 0;
00985
case none:
return atEdge();
00986
case right:
return col() == m_vi->m_doc->lineLength( line() );
00987
default: Q_ASSERT(
false);
return false;
00988 }
00989 }
00990
00991
protected:
00992
bool valid()
const {
00993
return line() >= 0 &&
00994 uint( line() ) < m_vi->m_doc->numLines() &&
00995 col() >= 0 &&
00996 (!m_vi->m_doc->wrapCursor() || col() <= m_vi->m_doc->lineLength( line() ));
00997 }
00998 KateViewInternal* m_vi;
00999 };
01000
01001
class BoundedCursor :
public CalculatingCursor {
01002
public:
01003 BoundedCursor(KateViewInternal* vi)
01004 : CalculatingCursor( vi ) {};
01005 BoundedCursor(KateViewInternal* vi,
const KateTextCursor& c )
01006 : CalculatingCursor( vi, c ) {};
01007 BoundedCursor(KateViewInternal* vi, uint line, uint col )
01008 : CalculatingCursor( vi, line, col ) {};
01009
virtual CalculatingCursor& operator+=(
int n ) {
01010 m_col += n;
01011
01012
if (n > 0 && m_vi->m_view->dynWordWrap()) {
01013
01014
if (m_col > m_vi->m_doc->lineLength(m_line)) {
01015 LineRange currentRange = m_vi->range(*
this);
01016
01017
int endX;
01018
bool crap;
01019 m_vi->m_view->renderer()->textWidth(m_vi->textLine(m_line), currentRange.startCol, m_vi->width() - currentRange.xOffset(), &crap, &endX);
01020 endX += (m_col - currentRange.endCol + 1) * m_vi->m_view->renderer()->spaceWidth();
01021
01022
01023
if (endX >= m_vi->width() - currentRange.xOffset()) {
01024 m_col -= n;
01025
if ( uint( line() ) < m_vi->m_doc->numLines() - 1 ) {
01026 m_line++;
01027 m_col = 0;
01028 }
01029 }
01030 }
01031
01032 }
else if (n < 0 && col() < 0 && line() > 0 ) {
01033 m_line--;
01034 m_col = m_vi->m_doc->lineLength( line() );
01035 }
01036
01037 m_col = QMAX( 0, col() );
01038
01039 Q_ASSERT( valid() );
01040
return *
this;
01041 }
01042
virtual CalculatingCursor& operator-=(
int n ) {
01043
return operator+=( -n );
01044 }
01045 };
01046
01047
class WrappingCursor :
public CalculatingCursor {
01048
public:
01049 WrappingCursor(KateViewInternal* vi)
01050 : CalculatingCursor( vi) {};
01051 WrappingCursor(KateViewInternal* vi,
const KateTextCursor& c )
01052 : CalculatingCursor( vi, c ) {};
01053 WrappingCursor(KateViewInternal* vi, uint line, uint col )
01054 : CalculatingCursor( vi, line, col ) {};
01055
01056
virtual CalculatingCursor& operator+=(
int n ) {
01057
if( n < 0 )
return operator-=( -n );
01058
int len = m_vi->m_doc->lineLength( line() );
01059
if( col() + n <= len ) {
01060 m_col += n;
01061 }
else if( uint( line() ) < m_vi->m_doc->numLines() - 1 ) {
01062 n -= len - col() + 1;
01063 m_col = 0;
01064 m_line++;
01065 operator+=( n );
01066 }
else {
01067 m_col = len;
01068 }
01069 Q_ASSERT( valid() );
01070
return *
this;
01071 }
01072
virtual CalculatingCursor& operator-=(
int n ) {
01073
if( n < 0 )
return operator+=( -n );
01074
if( col() - n >= 0 ) {
01075 m_col -= n;
01076 }
else if( line() > 0 ) {
01077 n -= col() + 1;
01078 m_line--;
01079 m_col = m_vi->m_doc->lineLength( line() );
01080 operator-=( n );
01081 }
else {
01082 m_col = 0;
01083 }
01084 Q_ASSERT( valid() );
01085
return *
this;
01086 }
01087 };
01088
01089
void KateViewInternal::moveChar( Bias bias,
bool sel )
01090 {
01091
KateTextCursor c;
01092
if ( m_doc->wrapCursor() ) {
01093 c = WrappingCursor(
this, cursor ) += bias;
01094 }
else {
01095 c = BoundedCursor(
this, cursor ) += bias;
01096 }
01097 updateSelection( c, sel );
01098 updateCursor( c );
01099 }
01100
01101
void KateViewInternal::cursorLeft(
bool sel ) { moveChar( left, sel ); }
01102
void KateViewInternal::cursorRight(
bool sel ) { moveChar( right, sel ); }
01103
01104
void KateViewInternal::moveWord( Bias bias,
bool sel )
01105 {
01106
01107
01108 WrappingCursor c(
this, cursor );
01109
if( !c.atEdge( bias ) ) {
01110 Highlight* h = m_doc->highlight();
01111
01112
bool moved =
false;
01113
while( !c.atEdge( bias ) && !h->isInWord( m_doc->textLine( c.line() )[ c.col() - (bias == left ? 1 : 0) ] ) )
01114 {
01115 c += bias;
01116 moved =
true;
01117 }
01118
01119
if ( bias != right || !moved )
01120 {
01121
while( !c.atEdge( bias ) && h->isInWord( m_doc->textLine( c.line() )[ c.col() - (bias == left ? 1 : 0) ] ) )
01122 c += bias;
01123
if ( bias == right )
01124 {
01125
while ( !c.atEdge( bias ) && m_doc->textLine( c.line() )[ c.col() ].isSpace() )
01126 c+= bias;
01127 }
01128 }
01129
01130 }
else {
01131 c += bias;
01132 }
01133 updateSelection( c, sel );
01134 updateCursor( c );
01135 }
01136
01137
void KateViewInternal::wordLeft (
bool sel ) { moveWord( left, sel ); }
01138
void KateViewInternal::wordRight(
bool sel ) { moveWord( right, sel ); }
01139
01140
void KateViewInternal::moveEdge( Bias bias,
bool sel )
01141 {
01142 BoundedCursor c(
this, cursor );
01143 c.toEdge( bias );
01144 updateSelection( c, sel );
01145 updateCursor( c );
01146 }
01147
01148
void KateViewInternal::home(
bool sel )
01149 {
01150
if (m_view->dynWordWrap() && currentRange().startCol) {
01151
01152
if (cursor.col() != currentRange().startCol) {
01153
KateTextCursor c(cursor.line(), currentRange().startCol);
01154 updateSelection( c, sel );
01155 updateCursor( c );
01156
return;
01157 }
01158 }
01159
01160
if( !(m_doc->configFlags() & KateDocument::cfSmartHome) ) {
01161 moveEdge( left, sel );
01162
return;
01163 }
01164
01165
KateTextCursor c = cursor;
01166
int lc = textLine( c.
line() )->firstChar();
01167
01168
if( lc < 0 || c.
col() == lc ) {
01169 c.
setCol(0);
01170 }
else {
01171 c.
setCol(lc);
01172 }
01173
01174 updateSelection( c, sel );
01175 updateCursor( c );
01176 }
01177
01178
void KateViewInternal::end(
bool sel )
01179 {
01180
if (m_view->dynWordWrap() && currentRange().wrap) {
01181
01182
if (cursor.col() < currentRange().endCol - 1) {
01183
KateTextCursor c(cursor.line(), currentRange().endCol - 1);
01184 updateSelection( c, sel );
01185 updateCursor( c );
01186
return;
01187 }
01188 }
01189
01190 moveEdge( right, sel );
01191 }
01192
01193 LineRange KateViewInternal::range(
int realLine,
const LineRange* previous)
01194 {
01195
01196
if (!m_updatingView && realLine >= lineRanges[0].line && realLine <= lineRanges[lineRanges.count() - 1].line)
01197
for (uint i = 0; i < lineRanges.count(); i++)
01198
if (realLine == lineRanges[i].line)
01199
if (!m_view->dynWordWrap() || (!previous && lineRanges[i].startCol == 0) || (previous && lineRanges[i].startCol == previous->endCol))
01200
return lineRanges[i];
01201
01202
01203 LineRange ret;
01204
01205 TextLine::Ptr text = textLine(realLine);
01206
if (!text) {
01207
return LineRange();
01208 }
01209
01210
if (!m_view->dynWordWrap()) {
01211 Q_ASSERT(!previous);
01212 ret.line = realLine;
01213 ret.virtualLine = m_doc->getVirtualLine(realLine);
01214 ret.startCol = 0;
01215 ret.endCol = m_doc->lineLength(realLine);
01216 ret.startX = 0;
01217 ret.endX = m_view->renderer()->textWidth(text, -1);
01218 ret.viewLine = 0;
01219 ret.wrap =
false;
01220
return ret;
01221 }
01222
01223 ret.endCol = (
int)m_view->renderer()->textWidth(text, previous ? previous->endCol : 0, width() - (previous ? previous->shiftX : 0), &ret.wrap, &ret.endX);
01224
01225 Q_ASSERT(ret.endCol > ret.startCol);
01226
01227 ret.line = realLine;
01228
01229
if (previous) {
01230 ret.virtualLine = previous->virtualLine;
01231 ret.startCol = previous->endCol;
01232 ret.startX = previous->endX;
01233 ret.endX += previous->endX;
01234 ret.shiftX = previous->shiftX;
01235 ret.viewLine = previous->viewLine + 1;
01236
01237 }
else {
01238
01239
if (m_view->config()->dynWordWrapAlignIndent() > 0) {
01240
int pos = text->nextNonSpaceChar(0);
01241
01242
if (pos > 0)
01243 ret.shiftX = m_view->renderer()->textWidth(text, pos);
01244
01245
if (ret.shiftX > ((
double)width() / 100 * m_view->config()->dynWordWrapAlignIndent()))
01246 ret.shiftX = 0;
01247 }
01248
01249 ret.virtualLine = m_doc->getVirtualLine(realLine);
01250 ret.startCol = 0;
01251 ret.startX = 0;
01252 ret.viewLine = 0;
01253 }
01254
01255
return ret;
01256 }
01257
01258 LineRange KateViewInternal::currentRange()
01259 {
01260
01261
01262
return range(cursor);
01263 }
01264
01265 LineRange KateViewInternal::previousRange()
01266 {
01267 uint currentViewLine = viewLine(cursor);
01268
01269
if (currentViewLine)
01270
return range(cursor.line(), currentViewLine - 1);
01271
else
01272
return range(m_doc->getRealLine(displayCursor.line() - 1), -1);
01273 }
01274
01275 LineRange KateViewInternal::nextRange()
01276 {
01277 uint currentViewLine = viewLine(cursor) + 1;
01278
01279
if (currentViewLine >= viewLineCount(cursor.line())) {
01280 currentViewLine = 0;
01281
return range(cursor.line() + 1, currentViewLine);
01282 }
else {
01283
return range(cursor.line(), currentViewLine);
01284 }
01285 }
01286
01287 LineRange KateViewInternal::range(
const KateTextCursor& realCursor)
01288 {
01289
01290
01291 LineRange thisRange;
01292
bool first =
true;
01293
01294
do {
01295 thisRange = range(realCursor.
line(), first ? 0L : &thisRange);
01296 first =
false;
01297 }
while (thisRange.wrap && !(realCursor.
col() >= thisRange.startCol && realCursor.
col() < thisRange.endCol) && thisRange.startCol != thisRange.endCol);
01298
01299
return thisRange;
01300 }
01301
01302 LineRange KateViewInternal::range(uint realLine,
int viewLine)
01303 {
01304
01305
01306 LineRange thisRange;
01307
bool first =
true;
01308
01309
do {
01310 thisRange = range(realLine, first ? 0L : &thisRange);
01311 first =
false;
01312 }
while (thisRange.wrap && viewLine != thisRange.viewLine && thisRange.startCol != thisRange.endCol);
01313
01314
if (viewLine != -1 && viewLine != thisRange.viewLine)
01315
kdDebug(13030) <<
"WARNING: viewLine " << viewLine <<
" of line " << realLine <<
" does not exist." <<
endl;
01316
01317
return thisRange;
01318 }
01319
01325 uint KateViewInternal::viewLine(
const KateTextCursor& realCursor)
01326 {
01327
if (!m_view->dynWordWrap())
return 0;
01328
01329
if (realCursor.
col() == 0)
return 0;
01330
01331 LineRange thisRange;
01332
bool first =
true;
01333
01334
do {
01335 thisRange = range(realCursor.
line(), first ? 0L : &thisRange);
01336 first =
false;
01337 }
while (thisRange.wrap && !(realCursor.
col() >= thisRange.startCol && realCursor.
col() < thisRange.endCol) && thisRange.startCol != thisRange.endCol);
01338
01339
return thisRange.viewLine;
01340 }
01341
01342
int KateViewInternal::displayViewLine(
const KateTextCursor& virtualCursor,
bool limitToVisible)
01343 {
01344
KateTextCursor work = startPos();
01345
01346
int limit = linesDisplayed();
01347
01348
01349
if (!m_view->dynWordWrap()) {
01350
int ret = virtualCursor.
line() - startLine();
01351
if (limitToVisible && (ret < 0 || ret > limit))
01352
return -1;
01353
else
01354
return ret;
01355 }
01356
01357
if (work == virtualCursor) {
01358
return 0;
01359 }
01360
01361
int ret = -viewLine(work);
01362
bool forwards = (work < virtualCursor) ?
true :
false;
01363
01364
01365
if (forwards) {
01366
while (work.
line() != virtualCursor.
line()) {
01367 ret += viewLineCount(m_doc->getRealLine(work.
line()));
01368 work.
setLine(work.
line() + 1);
01369
if (limitToVisible && ret > limit)
01370
return -1;
01371 }
01372 }
else {
01373
while (work.
line() != virtualCursor.
line()) {
01374 work.
setLine(work.
line() - 1);
01375 ret -= viewLineCount(m_doc->getRealLine(work.
line()));
01376
if (limitToVisible && ret < 0)
01377
return -1;
01378 }
01379 }
01380
01381
01382
KateTextCursor realCursor = virtualCursor;
01383 realCursor.
setLine(m_doc->getRealLine(realCursor.
line()));
01384
if (realCursor.
col() == -1) realCursor.
setCol(m_doc->lineLength(realCursor.
line()));
01385 ret += viewLine(realCursor);
01386
01387
if (limitToVisible && (ret < 0 || ret > limit))
01388
return -1;
01389
01390
return ret;
01391 }
01392
01393 uint KateViewInternal::lastViewLine(uint realLine)
01394 {
01395
if (!m_view->dynWordWrap())
return 0;
01396
01397 LineRange thisRange;
01398
bool first =
true;
01399
01400
do {
01401 thisRange = range(realLine, first ? 0L : &thisRange);
01402 first =
false;
01403 }
while (thisRange.wrap && thisRange.startCol != thisRange.endCol);
01404
01405
return thisRange.viewLine;
01406 }
01407
01408 uint KateViewInternal::viewLineCount(uint realLine)
01409 {
01410
return lastViewLine(realLine) + 1;
01411 }
01412
01413
01414
01415
01416
01417
01418
01419
01420
KateTextCursor KateViewInternal::viewLineOffset(
const KateTextCursor& virtualCursor,
int offset,
bool keepX)
01421 {
01422
if (!m_view->dynWordWrap()) {
01423
KateTextCursor ret(QMIN((
int)m_doc->visibleLines() - 1, virtualCursor.
line() + offset), 0);
01424
01425
if (ret.
line() < 0)
01426 ret.
setLine(0);
01427
01428
if (keepX) {
01429
int realLine = m_doc->getRealLine(ret.
line());
01430 ret.
setCol(m_doc->lineLength(realLine) - 1);
01431
01432
if (m_currentMaxX > cXPos)
01433 cXPos = m_currentMaxX;
01434
01435
if (m_doc->wrapCursor())
01436 cXPos = QMIN(cXPos, (
int)m_view->renderer()->textWidth(textLine(realLine), m_doc->lineLength(realLine)));
01437
01438 m_view->renderer()->textWidth(ret, cXPos);
01439 }
01440
01441
return ret;
01442 }
01443
01444
KateTextCursor realCursor = virtualCursor;
01445 realCursor.
setLine(m_doc->getRealLine(virtualCursor.
line()));
01446
01447 uint cursorViewLine = viewLine(realCursor);
01448
01449
int currentOffset = 0;
01450
int virtualLine = 0;
01451
01452
bool forwards = (offset > 0) ?
true :
false;
01453
01454
if (forwards) {
01455 currentOffset = lastViewLine(realCursor.
line()) - cursorViewLine;
01456
if (offset <= currentOffset) {
01457
01458 LineRange thisRange = range(realCursor.
line(), cursorViewLine + offset);
01459 Q_ASSERT(thisRange.virtualLine == virtualCursor.
line());
01460
return KateTextCursor(virtualCursor.
line(), thisRange.startCol);
01461 }
01462
01463 virtualLine = virtualCursor.
line() + 1;
01464
01465 }
else {
01466 offset = -offset;
01467 currentOffset = cursorViewLine;
01468
if (offset <= currentOffset) {
01469
01470 LineRange thisRange = range(realCursor.
line(), cursorViewLine - offset);
01471 Q_ASSERT(thisRange.virtualLine == virtualCursor.
line());
01472
return KateTextCursor(virtualCursor.
line(), thisRange.startCol);
01473 }
01474
01475 virtualLine = virtualCursor.
line() - 1;
01476 }
01477
01478 currentOffset++;
01479
01480
while (virtualLine >= 0 && virtualLine < (
int)m_doc->visibleLines())
01481 {
01482 LineRange thisRange;
01483
bool first =
true;
01484
int realLine = m_doc->getRealLine(virtualLine);
01485
01486
do {
01487 thisRange = range(realLine, first ? 0L : &thisRange);
01488 first =
false;
01489
01490
if (offset == currentOffset) {
01491
if (!forwards) {
01492
01493
int requiredViewLine = lastViewLine(realLine) - thisRange.viewLine;
01494
if (requiredViewLine != thisRange.viewLine) {
01495 thisRange = range(realLine, requiredViewLine);
01496 }
01497 }
01498
01499
KateTextCursor ret(virtualLine, thisRange.startCol);
01500
01501
01502
if (keepX) {
01503 ret.
setCol(thisRange.endCol - 1);
01504
KateTextCursor realCursorTemp(m_doc->getRealLine(virtualCursor.
line()), virtualCursor.
col());
01505
int visibleX = m_view->renderer()->textWidth(realCursorTemp) - range(realCursorTemp).startX;
01506
int xOffset = thisRange.startX;
01507
01508
if (m_currentMaxX > visibleX)
01509 visibleX = m_currentMaxX;
01510
01511 cXPos = xOffset + visibleX;
01512
01513 cXPos = QMIN(cXPos, lineMaxCursorX(thisRange));
01514
01515 m_view->renderer()->textWidth(ret, cXPos);
01516 }
01517
01518
return ret;
01519 }
01520
01521 currentOffset++;
01522
01523 }
while (thisRange.wrap);
01524
01525
if (forwards)
01526 virtualLine++;
01527
else
01528 virtualLine--;
01529 }
01530
01531
01532
01533
if (forwards)
01534
return KateTextCursor(m_doc->visibleLines() - 1, m_doc->lineLength(m_doc->visibleLines() - 1));
01535
else
01536
return KateTextCursor(0, 0);
01537 }
01538
01539
int KateViewInternal::lineMaxCursorX(
const LineRange& range)
01540 {
01541
if (!m_doc->wrapCursor() && !range.wrap)
01542
return INT_MAX;
01543
01544
int maxX = range.endX;
01545
01546
if (maxX && range.wrap) {
01547
QChar lastCharInLine = textLine(range.line)->getChar(range.endCol - 1);
01548 maxX -= m_view->renderer()->config()->fontMetrics()->width(lastCharInLine);
01549 }
01550
01551
return maxX;
01552 }
01553
01554
int KateViewInternal::lineMaxCol(
const LineRange& range)
01555 {
01556
int maxCol = range.endCol;
01557
01558
if (maxCol && range.wrap)
01559 maxCol--;
01560
01561
return maxCol;
01562 }
01563
01564
void KateViewInternal::cursorUp(
bool sel)
01565 {
01566
if (displayCursor.line() == 0 && (!m_view->dynWordWrap() || viewLine(cursor) == 0))
01567
return;
01568
01569
int newLine = cursor.line(), newCol = 0, xOffset = 0, startCol = 0;
01570 m_preserveMaxX =
true;
01571
01572
if (m_view->dynWordWrap()) {
01573
01574 LineRange thisRange = currentRange();
01575
01576 LineRange pRange = previousRange();
01577
01578
01579 Q_ASSERT((cursor.line() == thisRange.line) &&
01580 (cursor.col() >= thisRange.startCol) &&
01581 (!thisRange.wrap || cursor.col() < thisRange.endCol));
01582
01583
01584
int visibleX = m_view->renderer()->textWidth(cursor) - thisRange.startX;
01585
int currentLineVisibleX = visibleX;
01586
01587
01588 visibleX += thisRange.xOffset();
01589 visibleX -= pRange.xOffset();
01590
01591
01592 visibleX = QMAX(0, visibleX);
01593
01594 startCol = pRange.startCol;
01595 xOffset = pRange.startX;
01596 newLine = pRange.line;
01597
01598
01599
01600
if (thisRange.xOffset() && !pRange.xOffset() && currentLineVisibleX == 0)
01601 visibleX = m_currentMaxX;
01602
else if (visibleX < m_currentMaxX - pRange.xOffset())
01603 visibleX = m_currentMaxX - pRange.xOffset();
01604
01605 cXPos = xOffset + visibleX;
01606
01607 cXPos = QMIN(cXPos, lineMaxCursorX(pRange));
01608
01609 newCol = QMIN((
int)m_view->renderer()->textPos(newLine, visibleX, startCol), lineMaxCol(pRange));
01610
01611 }
else {
01612 newLine = m_doc->getRealLine(displayCursor.line() - 1);
01613
01614
if ((m_doc->wrapCursor()) && m_currentMaxX > cXPos)
01615 cXPos = m_currentMaxX;
01616 }
01617
01618
KateTextCursor c(newLine, newCol);
01619 m_view->renderer()->textWidth(c, cXPos);
01620
01621 updateSelection( c, sel );
01622 updateCursor( c );
01623 }
01624
01625
void KateViewInternal::cursorDown(
bool sel)
01626 {
01627
if ((displayCursor.line() >= (
int)m_doc->numVisLines() - 1) && (!m_view->dynWordWrap() || viewLine(cursor) == lastViewLine(cursor.line())))
01628
return;
01629
01630
int newLine = cursor.line(), newCol = 0, xOffset = 0, startCol = 0;
01631 m_preserveMaxX =
true;
01632
01633
if (m_view->dynWordWrap()) {
01634
01635 LineRange thisRange = currentRange();
01636
01637 LineRange nRange = nextRange();
01638
01639
01640 Q_ASSERT((cursor.line() == thisRange.line) &&
01641 (cursor.col() >= thisRange.startCol) &&
01642 (!thisRange.wrap || cursor.col() < thisRange.endCol));
01643
01644
01645
int visibleX = m_view->renderer()->textWidth(cursor) - thisRange.startX;
01646
int currentLineVisibleX = visibleX;
01647
01648
01649 visibleX += thisRange.xOffset();
01650 visibleX -= nRange.xOffset();
01651
01652
01653 visibleX = QMAX(0, visibleX);
01654
01655
if (!thisRange.wrap) {
01656 newLine = m_doc->getRealLine(displayCursor.line() + 1);
01657 }
else {
01658 startCol = thisRange.endCol;
01659 xOffset = thisRange.endX;
01660 }
01661
01662
01663
01664
if (thisRange.xOffset() && !nRange.xOffset() && currentLineVisibleX == 0)
01665 visibleX = m_currentMaxX;
01666
else if (visibleX < m_currentMaxX - nRange.xOffset())
01667 visibleX = m_currentMaxX - nRange.xOffset();
01668
01669 cXPos = xOffset + visibleX;
01670
01671 cXPos = QMIN(cXPos, lineMaxCursorX(nRange));
01672
01673 newCol = QMIN((
int)m_view->renderer()->textPos(newLine, visibleX, startCol), lineMaxCol(nRange));
01674
01675 }
else {
01676 newLine = m_doc->getRealLine(displayCursor.line() + 1);
01677
01678
if ((m_doc->wrapCursor()) && m_currentMaxX > cXPos)
01679 cXPos = m_currentMaxX;
01680 }
01681
01682
KateTextCursor c(newLine, newCol);
01683 m_view->renderer()->textWidth(c, cXPos);
01684
01685 updateSelection(c, sel);
01686 updateCursor(c);
01687 }
01688
01689
void KateViewInternal::cursorToMatchingBracket(
bool sel )
01690 {
01691
KateTextCursor start( cursor ),
end;
01692
01693
if( !m_doc->findMatchingBracket( start, end ) )
01694
return;
01695
01696
01697
01698
01699
if(
end > start )
01700
end.setCol(
end.col() + 1);
01701
01702 updateSelection( end, sel );
01703 updateCursor( end );
01704 }
01705
01706
void KateViewInternal::topOfView(
bool sel )
01707 {
01708
KateTextCursor c = viewLineOffset(startPos(), m_minLinesVisible);
01709 updateSelection( c, sel );
01710 updateCursor( c );
01711 }
01712
01713
void KateViewInternal::bottomOfView(
bool sel )
01714 {
01715
01716
KateTextCursor c = viewLineOffset(endPos(), -m_minLinesVisible);
01717 updateSelection( c, sel );
01718 updateCursor( c );
01719 }
01720
01721
01722
void KateViewInternal::scrollLines(
int lines,
bool sel )
01723 {
01724
KateTextCursor c = viewLineOffset(displayCursor, lines,
true);
01725
01726
01727 c.
setLine(m_doc->getRealLine(c.
line()));
01728
01729 updateSelection( c, sel );
01730 updateCursor( c );
01731 }
01732
01733
01734
void KateViewInternal::scrollUp()
01735 {
01736
KateTextCursor newPos = viewLineOffset(m_startPos, -1);
01737 scrollPos(newPos);
01738 }
01739
01740
void KateViewInternal::scrollDown()
01741 {
01742
KateTextCursor newPos = viewLineOffset(m_startPos, 1);
01743 scrollPos(newPos);
01744 }
01745
01746
void KateViewInternal::setAutoCenterLines(
int viewLines,
bool updateView)
01747 {
01748 m_autoCenterLines = viewLines;
01749 m_minLinesVisible = QMIN(
int((linesDisplayed() - 1)/2), m_autoCenterLines);
01750
if (updateView)
01751 KateViewInternal::updateView();
01752 }
01753
01754
void KateViewInternal::pageUp(
bool sel )
01755 {
01756
01757
int viewLine = displayViewLine(displayCursor);
01758
bool atTop = (startPos().
line() == 0 && startPos().col() == 0);
01759
01760
01761
int lineadj = 2 * m_minLinesVisible;
01762
int cursorStart = (linesDisplayed() - 1) - viewLine;
01763
if (cursorStart < m_minLinesVisible)
01764 lineadj -= m_minLinesVisible - cursorStart;
01765
01766
int linesToScroll = -QMAX( (linesDisplayed() - 1) - lineadj, 0 );
01767 m_preserveMaxX =
true;
01768
01769
01770
if (!m_view->dynWordWrap()) {
01771
if (scrollbarVisible(startLine() + linesToScroll + viewLine)) {
01772
if (!m_columnScrollDisplayed) {
01773 linesToScroll++;
01774 }
01775 }
else {
01776
if (m_columnScrollDisplayed) {
01777 linesToScroll--;
01778 }
01779 }
01780 }
01781
01782
if (!m_doc->pageUpDownMovesCursor () && !atTop) {
01783
int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
01784
01785
KateTextCursor newStartPos = viewLineOffset(startPos(), linesToScroll - 1);
01786 scrollPos(newStartPos);
01787
01788
01789
KateTextCursor newPos = viewLineOffset(newStartPos, viewLine,
true);
01790 newPos.
setLine(m_doc->getRealLine(newPos.
line()));
01791
01792 LineRange newLine = range(newPos);
01793
01794
if (m_currentMaxX - newLine.xOffset() > xPos)
01795 xPos = m_currentMaxX - newLine.xOffset();
01796
01797 cXPos = QMIN(newLine.startX + xPos, lineMaxCursorX(newLine));
01798
01799 m_view->renderer()->textWidth( newPos, cXPos );
01800
01801 m_preserveMaxX =
true;
01802 updateSelection( newPos, sel );
01803 updateCursor(newPos);
01804
01805 }
else {
01806 scrollLines( linesToScroll, sel );
01807 }
01808 }
01809
01810
void KateViewInternal::pageDown(
bool sel )
01811 {
01812
01813
int viewLine = displayViewLine(displayCursor);
01814
bool atEnd = startPos() >= m_cachedMaxStartPos;
01815
01816
01817
int lineadj = 2 * m_minLinesVisible;
01818
int cursorStart = m_minLinesVisible - viewLine;
01819
if (cursorStart > 0)
01820 lineadj -= cursorStart;
01821
01822
int linesToScroll = QMAX( (linesDisplayed() - 1) - lineadj, 0 );
01823 m_preserveMaxX =
true;
01824
01825
01826
if (!m_view->dynWordWrap()) {
01827
if (scrollbarVisible(startLine() + linesToScroll + viewLine - (linesDisplayed() - 1))) {
01828
if (!m_columnScrollDisplayed) {
01829 linesToScroll--;
01830 }
01831 }
else {
01832
if (m_columnScrollDisplayed) {
01833 linesToScroll--;
01834 }
01835 }
01836 }
01837
01838
if (!m_doc->pageUpDownMovesCursor () && !atEnd) {
01839
int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
01840
01841
KateTextCursor newStartPos = viewLineOffset(startPos(), linesToScroll + 1);
01842 scrollPos(newStartPos);
01843
01844
01845
KateTextCursor newPos = viewLineOffset(newStartPos, viewLine,
true);
01846 newPos.
setLine(m_doc->getRealLine(newPos.
line()));
01847
01848 LineRange newLine = range(newPos);
01849
01850
if (m_currentMaxX - newLine.xOffset() > xPos)
01851 xPos = m_currentMaxX - newLine.xOffset();
01852
01853 cXPos = QMIN(newLine.startX + xPos, lineMaxCursorX(newLine));
01854
01855 m_view->renderer()->textWidth( newPos, cXPos );
01856
01857 m_preserveMaxX =
true;
01858 updateSelection( newPos, sel );
01859 updateCursor(newPos);
01860
01861 }
else {
01862 scrollLines( linesToScroll, sel );
01863 }
01864 }
01865
01866
bool KateViewInternal::scrollbarVisible(uint startLine)
01867 {
01868
return maxLen(startLine) > width() - 8;
01869 }
01870
01871
int KateViewInternal::maxLen(uint startLine)
01872 {
01873 Q_ASSERT(!m_view->dynWordWrap());
01874
01875
int displayLines = (m_view->height() / m_view->renderer()->fontHeight()) + 1;
01876
01877
int maxLen = 0;
01878
01879
for (
int z = 0; z < displayLines; z++) {
01880
int virtualLine = startLine + z;
01881
01882
if (virtualLine < 0 || virtualLine >= (
int)m_doc->visibleLines())
01883
break;
01884
01885 LineRange thisRange = range((
int)m_doc->getRealLine(virtualLine));
01886
01887 maxLen = QMAX(maxLen, thisRange.endX);
01888 }
01889
01890
return maxLen;
01891 }
01892
01893
void KateViewInternal::top(
bool sel )
01894 {
01895
KateTextCursor c( 0, cursor.col() );
01896 m_view->renderer()->textWidth( c, cXPos );
01897 updateSelection( c, sel );
01898 updateCursor( c );
01899 }
01900
01901
void KateViewInternal::bottom(
bool sel )
01902 {
01903
KateTextCursor c( m_doc->lastLine(), cursor.col() );
01904 m_view->renderer()->textWidth( c, cXPos );
01905 updateSelection( c, sel );
01906 updateCursor( c );
01907 }
01908
01909
void KateViewInternal::top_home(
bool sel )
01910 {
01911
KateTextCursor c( 0, 0 );
01912 updateSelection( c, sel );
01913 updateCursor( c );
01914 }
01915
01916
void KateViewInternal::bottom_end(
bool sel )
01917 {
01918
KateTextCursor c( m_doc->lastLine(), m_doc->lineLength( m_doc->lastLine() ) );
01919 updateSelection( c, sel );
01920 updateCursor( c );
01921 }
01922
01923
void KateViewInternal::updateSelection(
const KateTextCursor& newCursor,
bool keepSel )
01924 {
01925
if( keepSel )
01926 {
01927
if ( !m_doc->hasSelection() || (selectAnchor.line() == -1)
01928 || ((m_doc->configFlags() & KateDocument::cfPersistent)
01929 && ((cursor < m_doc->selectStart) || (cursor > m_doc->selectEnd))) )
01930 {
01931 selectAnchor = cursor;
01932 m_doc->setSelection( cursor, newCursor );
01933 }
01934
else
01935 m_doc->setSelection( selectAnchor, newCursor);
01936
01937 m_selChangedByUser =
true;
01938 }
01939
else if ( !(m_doc->configFlags() & KateDocument::cfPersistent) )
01940 m_doc->clearSelection();
01941 }
01942
01943
void KateViewInternal::updateCursor(
const KateTextCursor& newCursor,
bool force,
bool center,
bool calledExternally )
01944 {
01945 TextLine::Ptr l = textLine( newCursor.
line() );
01946
01947
if ( !force && (cursor == newCursor) )
01948 {
01949
if ( !m_madeVisible )
01950 {
01951
01952
if ( l && ! l->isVisible() )
01953 m_doc->foldingTree()->ensureVisible( newCursor.
line() );
01954
01955 makeVisible ( displayCursor, displayCursor.col(),
false, center, calledExternally );
01956 }
01957
01958
return;
01959 }
01960
01961
01962
if ( l && ! l->isVisible() )
01963 m_doc->foldingTree()->ensureVisible( newCursor.
line() );
01964
01965
KateTextCursor oldDisplayCursor = displayCursor;
01966
01967 cursor.setPos (newCursor);
01968 displayCursor.
setPos (m_doc->getVirtualLine(cursor.line()), cursor.col());
01969
01970 cXPos = m_view->renderer()->textWidth( cursor );
01971 makeVisible ( displayCursor, displayCursor.
col(),
false, center, calledExternally );
01972
01973 updateBracketMarks();
01974
01975
01976 tagLine(oldDisplayCursor);
01977 tagLine(displayCursor);
01978
01979
QPoint cursorP = cursorCoordinates();
01980 setMicroFocusHint( cursorP.x(), cursorP.y(), 0, m_view->renderer()->fontHeight() );
01981
01982
if (m_cursorTimer.isActive ())
01983 {
01984 m_cursorTimer.start( KApplication::cursorFlashTime() / 2 );
01985 m_view->renderer()->setDrawCaret(
true);
01986 }
01987
01988
01989
if (m_preserveMaxX)
01990 m_preserveMaxX =
false;
01991
else
01992
if (m_view->dynWordWrap())
01993 m_currentMaxX = m_view->renderer()->textWidth(displayCursor) - currentRange().startX + currentRange().xOffset();
01994
else
01995 m_currentMaxX = cXPos;
01996
01997
01998
01999
02000 paintText(0, 0, width(), height(),
true);
02001
02002 emit m_view->cursorPositionChanged();
02003 }
02004
02005
void KateViewInternal::updateBracketMarks()
02006 {
02007
if ( bm.isValid() ) {
02008
KateTextCursor bmStart(m_doc->getVirtualLine(bm.start().line()), bm.start().col());
02009
KateTextCursor bmEnd(m_doc->getVirtualLine(bm.end().line()), bm.end().col());
02010 tagLine(bmStart);
02011 tagLine(bmEnd);
02012 }
02013
02014 m_doc->newBracketMark( cursor, bm );
02015
02016
if ( bm.isValid() ) {
02017
KateTextCursor bmStart(m_doc->getVirtualLine(bm.start().line()), bm.start().col());
02018
KateTextCursor bmEnd(m_doc->getVirtualLine(bm.end().line()), bm.end().col());
02019 tagLine(bmStart);
02020 tagLine(bmEnd);
02021 }
02022 }
02023
02024
bool KateViewInternal::tagLine(
const KateTextCursor& virtualCursor)
02025 {
02026
int viewLine = displayViewLine(virtualCursor,
true);
02027
if (viewLine >= 0 && viewLine < (
int)lineRanges.count()) {
02028 lineRanges[viewLine].dirty =
true;
02029 leftBorder->update (0, lineToY(viewLine), leftBorder->width(), m_view->renderer()->fontHeight());
02030
return true;
02031 }
02032
return false;
02033 }
02034
02035
bool KateViewInternal::tagLines(
int start,
int end,
bool realLines )
02036 {
02037
return tagLines(
KateTextCursor(start, 0),
KateTextCursor(end, -1), realLines);
02038 }
02039
02040
bool KateViewInternal::tagLines(
KateTextCursor start,
KateTextCursor end,
bool realCursors)
02041 {
02042
if (realCursors)
02043 {
02044
02045 start.
setLine(m_doc->getVirtualLine( start.
line() ));
02046
end.setLine(m_doc->getVirtualLine(
end.line() ));
02047 }
02048
02049
if (
end.line() < (
int)startLine())
02050 {
02051
02052
return false;
02053 }
02054
if (start.
line() > (
int)endLine())
02055 {
02056
02057
return false;
02058 }
02059
02060
02061
02062
bool ret =
false;
02063
02064
for (uint z = 0; z < lineRanges.size(); z++)
02065 {
02066
if ((lineRanges[z].virtualLine > start.
line() || (lineRanges[z].virtualLine == start.
line() && lineRanges[z].endCol >= start.
col() && start.
col() != -1)) && (lineRanges[z].virtualLine <
end.line() || (lineRanges[z].virtualLine ==
end.line() && (lineRanges[z].startCol <=
end.col() ||
end.col() == -1)))) {
02067 ret = lineRanges[z].dirty =
true;
02068
02069 }
02070 }
02071
02072
if (!m_view->dynWordWrap())
02073 {
02074
int y = lineToY( start.
line() );
02075
02076
int h = (
end.line() - start.
line() + 2) * m_view->renderer()->fontHeight();
02077
if (
end.line() == (
int)m_doc->numVisLines() - 1)
02078 h = height();
02079
02080 leftBorder->update (0, y, leftBorder->width(), h);
02081 }
02082
else
02083 {
02084
02085
02086
for (uint z = 0; z < lineRanges.size(); z++)
02087 {
02088
if ((lineRanges[z].virtualLine > start.
line() || (lineRanges[z].virtualLine == start.
line() && lineRanges[z].endCol >= start.
col() && start.
col() != -1)) && (lineRanges[z].virtualLine <
end.line() || (lineRanges[z].virtualLine ==
end.line() && (lineRanges[z].startCol <=
end.col() ||
end.col() == -1))))
02089 {
02090
02091 leftBorder->update (0, z * m_view->renderer()->fontHeight(), leftBorder->width(), leftBorder->height());
02092
break;
02093 }
02094
02095
02096
02097
02098
02099
02100 }
02101 }
02102
02103
return ret;
02104 }
02105
02106
void KateViewInternal::tagAll()
02107 {
02108
02109
for (uint z = 0; z < lineRanges.size(); z++)
02110 {
02111 lineRanges[z].dirty =
true;
02112 }
02113
02114 leftBorder->updateFont();
02115 leftBorder->update ();
02116 }
02117
02118
void KateViewInternal::paintCursor()
02119 {
02120
if (tagLine(displayCursor))
02121 paintText (0,0,width(), height(),
true);
02122 }
02123
02124
02125
void KateViewInternal::placeCursor(
const QPoint& p,
bool keepSelection,
bool updateSelection )
02126 {
02127 LineRange thisRange = yToLineRange(p.y());
02128
02129
if (thisRange.line == -1) {
02130
for (
int i = (p.y() / m_view->renderer()->fontHeight()); i >= 0; i--) {
02131 thisRange = lineRanges[i];
02132
if (thisRange.line != -1)
02133
break;
02134 }
02135 Q_ASSERT(thisRange.line != -1);
02136 }
02137
02138
int realLine = thisRange.line;
02139
int visibleLine = thisRange.virtualLine;
02140 uint startCol = thisRange.startCol;
02141
02142 visibleLine = QMAX( 0, QMIN( visibleLine,
int(m_doc->numVisLines()) - 1 ) );
02143
02144
KateTextCursor c(realLine, 0);
02145
02146
int x = QMIN(QMAX(0, p.x() - thisRange.xOffset()), lineMaxCursorX(thisRange) - thisRange.startX);
02147
02148 m_view->renderer()->textWidth( c, startX() + x, startCol);
02149
02150
if (updateSelection)
02151 KateViewInternal::updateSelection( c, keepSelection );
02152 updateCursor( c );
02153 }
02154
02155
02156
bool KateViewInternal::isTargetSelected(
const QPoint& p )
02157 {
02158 LineRange thisRange = yToLineRange(p.y());
02159
02160 TextLine::Ptr l = textLine( thisRange.line );
02161
if( !l )
02162
return false;
02163
02164
int col = m_view->renderer()->textPos( l, p.x() - thisRange.xOffset(), thisRange.startCol );
02165
02166
return m_doc->lineColSelected( thisRange.line, col );
02167 }
02168
02169
02170
02171
02172
02173
bool KateViewInternal::eventFilter(
QObject *obj,
QEvent *e )
02174 {
02175
if (obj == m_lineScroll)
02176 {
02177
02178
if (e->type() == QEvent::Wheel && m_lineScroll->minValue() != m_lineScroll->maxValue())
02179 {
02180 wheelEvent((
QWheelEvent*)e);
02181
return true;
02182 }
02183
02184
02185
return QWidget::eventFilter( obj, e );
02186 }
02187
02188
switch( e->type() )
02189 {
02190
case QEvent::KeyPress:
02191 {
02192
QKeyEvent *k = (
QKeyEvent *)e;
02193
02194
if ((k->key() == Qt::Key_Escape) && !(m_doc->configFlags() & KateDocument::cfPersistent) )
02195 {
02196 m_doc->clearSelection();
02197
return true;
02198 }
02199
else if ( !((k->state() & ControlButton) || (k->state() & AltButton)) )
02200 {
02201 keyPressEvent( k );
02202
return k->isAccepted();
02203 }
02204
02205 }
break;
02206
02207
case QEvent::DragMove:
02208 {
02209
QPoint currentPoint = ((
QDragMoveEvent*) e)->pos();
02210
02211
QRect doNotScrollRegion( scrollMargin, scrollMargin,
02212 width() - scrollMargin * 2,
02213 height() - scrollMargin * 2 );
02214
02215
if ( !doNotScrollRegion.contains( currentPoint ) )
02216 {
02217 startDragScroll();
02218
02219 ( (
QDragMoveEvent*)e )->accept(
QRect(0,0,0,0) );
02220 }
02221
02222 dragMoveEvent((
QDragMoveEvent*)e);
02223 }
break;
02224
02225
case QEvent::DragLeave:
02226 stopDragScroll();
02227
break;
02228
02229
default:
02230
break;
02231 }
02232
02233
return QWidget::eventFilter( obj, e );
02234 }
02235
02236
void KateViewInternal::keyPressEvent(
QKeyEvent* e )
02237 {
02238
KKey key(e);
02239
02240
if (
key == Qt::Key_Left)
02241 {
02242 m_view->cursorLeft();
02243 e->accept();
02244
return;
02245 }
02246
02247
if (
key == Qt::Key_Right)
02248 {
02249 m_view->cursorRight();
02250 e->accept();
02251
return;
02252 }
02253
02254
if (
key == Qt::Key_Down)
02255 {
02256 m_view->down();
02257 e->accept();
02258
return;
02259 }
02260
02261
if (
key == Qt::Key_Up)
02262 {
02263 m_view->up();
02264 e->accept();
02265
return;
02266 }
02267
02268
if( !m_doc->isReadWrite() )
02269 {
02270 e->ignore();
02271
return;
02272 }
02273
02274
if ((
key == Qt::Key_Return) || (
key == Qt::Key_Enter) ||
02275 (
key == SHIFT + Qt::Key_Return) || (
key == SHIFT + Qt::Key_Enter))
02276 {
02277 m_view->keyReturn();
02278 e->accept();
02279
return;
02280 }
02281
02282
if (
key == Qt::Key_Backspace ||
key == SHIFT + Qt::Key_Backspace)
02283 {
02284 m_view->backspace();
02285 e->accept();
02286
return;
02287 }
02288
02289
if (
key == Qt::Key_Delete)
02290 {
02291 m_view->keyDelete();
02292 e->accept();
02293
return;
02294 }
02295
02296
if( (
key == Qt::Key_Tab ||
key == SHIFT+Qt::Key_Backtab ||
key == Qt::Key_Backtab)
02297 && (m_doc->configFlags() & KateDocumentConfig::cfTabIndents) )
02298 {
02299
if(
key == Qt::Key_Tab )
02300 {
02301
if (m_doc->hasSelection() || (m_doc->configFlags() & KateDocumentConfig::cfTabIndentsMode))
02302 m_doc->indent( m_view, cursor.line(), 1 );
02303
else if (m_doc->configFlags() & KateDocumentConfig::cfTabInsertsTab)
02304 m_doc->typeChars ( m_view,
QString (
"\t") );
02305
else
02306 m_doc->insertIndentChars ( m_view );
02307
02308 e->accept();
02309
return;
02310 }
02311
02312
if (
key == SHIFT+Qt::Key_Backtab ||
key == Qt::Key_Backtab)
02313 {
02314 m_doc->indent( m_view, cursor.line(), -1 );
02315 e->accept();
02316
return;
02317 }
02318 }
02319
02320
if ( !(e->state() & ControlButton) && !(e->state() & AltButton)
02321 && m_doc->typeChars ( m_view, e->text() ) )
02322 {
02323 e->accept();
02324
return;
02325 }
02326
02327 e->ignore();
02328 }
02329
02330
void KateViewInternal::keyReleaseEvent(
QKeyEvent* e )
02331 {
02332
KKey key(e);
02333
02334
if (
key == SHIFT)
02335 m_shiftKeyPressed =
true;
02336
else
02337 {
02338
if (m_shiftKeyPressed)
02339 {
02340 m_shiftKeyPressed =
false;
02341
02342
if (m_selChangedByUser)
02343 {
02344 QApplication::clipboard()->setSelectionMode(
true );
02345 m_doc->copy();
02346 QApplication::clipboard()->setSelectionMode(
false );
02347
02348 m_selChangedByUser =
false;
02349 }
02350 }
02351 }
02352
02353 e->ignore();
02354
return;
02355 }
02356
02357
void KateViewInternal::mousePressEvent(
QMouseEvent* e )
02358 {
02359
switch (e->button())
02360 {
02361
case LeftButton:
02362 m_selChangedByUser =
false;
02363
02364
if (possibleTripleClick)
02365 {
02366 possibleTripleClick =
false;
02367
02368 m_doc->selectLine( cursor );
02369 QApplication::clipboard()->setSelectionMode(
true );
02370 m_doc->copy();
02371 QApplication::clipboard()->setSelectionMode(
false );
02372
02373 cursor.setCol(0);
02374 updateCursor( cursor );
02375
return;
02376 }
02377
02378
if( isTargetSelected( e->pos() ) )
02379 {
02380 dragInfo.state = diPending;
02381 dragInfo.start = e->pos();
02382 }
02383
else
02384 {
02385 dragInfo.state = diNone;
02386
02387 placeCursor( e->pos(), e->state() & ShiftButton );
02388 scrollX = 0;
02389 scrollY = 0;
02390
02391 m_scrollTimer.start (50);
02392 }
02393
02394 e->accept ();
02395
break;
02396
02397
case RightButton:
02398
if ( !isTargetSelected( e->pos() ) )
02399 placeCursor( e->pos() );
02400
02401
02402
if (m_view->popup())
02403 m_view->popup()->popup( mapToGlobal( e->pos() ) );
02404
02405 e->accept ();
02406
break;
02407
02408
default:
02409 e->ignore ();
02410
break;
02411 }
02412 }
02413
02414
void KateViewInternal::mouseDoubleClickEvent(
QMouseEvent *e)
02415 {
02416
switch (e->button())
02417 {
02418
case LeftButton:
02419 m_doc->selectWord( cursor );
02420
02421
02422
if (m_doc->hasSelection())
02423 {
02424 QApplication::clipboard()->setSelectionMode(
true );
02425 m_doc->copy();
02426 QApplication::clipboard()->setSelectionMode(
false );
02427
02428 cursor.setPos(m_doc->selectEnd);
02429 updateCursor( cursor );
02430 }
02431
02432 possibleTripleClick =
true;
02433 QTimer::singleShot ( QApplication::doubleClickInterval(),
this, SLOT(tripleClickTimeout()) );
02434
02435 e->accept ();
02436
break;
02437
02438
default:
02439 e->ignore ();
02440
break;
02441 }
02442 }
02443
02444
void KateViewInternal::tripleClickTimeout()
02445 {
02446 possibleTripleClick =
false;
02447 }
02448
02449
void KateViewInternal::mouseReleaseEvent(
QMouseEvent* e )
02450 {
02451
switch (e->button())
02452 {
02453
case LeftButton:
02454
if (m_selChangedByUser)
02455 {
02456 QApplication::clipboard()->setSelectionMode(
true );
02457 m_doc->copy();
02458 QApplication::clipboard()->setSelectionMode(
false );
02459
02460 m_selChangedByUser =
false;
02461 }
02462
02463
if (dragInfo.state == diPending)
02464 placeCursor( e->pos() );
02465
else if (dragInfo.state == diNone)
02466 m_scrollTimer.stop ();
02467
02468 dragInfo.state = diNone;
02469
02470 e->accept ();
02471
break;
02472
02473
case MidButton:
02474 placeCursor( e->pos() );
02475
02476
if( m_doc->isReadWrite() )
02477 {
02478 QApplication::clipboard()->setSelectionMode(
true );
02479 doPaste();
02480 QApplication::clipboard()->setSelectionMode(
false );
02481 }
02482
02483 e->accept ();
02484
break;
02485
02486
default:
02487 e->ignore ();
02488
break;
02489 }
02490 }
02491
02492
void KateViewInternal::mouseMoveEvent(
QMouseEvent* e )
02493 {
02494
if( e->state() & LeftButton )
02495 {
02496
if (dragInfo.state == diPending)
02497 {
02498
02499
02500
QPoint p( e->pos() - dragInfo.start );
02501
02502
02503
if( p.manhattanLength() >
KGlobalSettings::dndEventDelay() )
02504 doDrag();
02505
02506
return;
02507 }
02508
02509 mouseX = e->x();
02510 mouseY = e->y();
02511
02512 scrollX = 0;
02513 scrollY = 0;
02514
int d = m_view->renderer()->fontHeight();
02515
02516
if (mouseX < 0)
02517 scrollX = -d;
02518
02519
if (mouseX > width())
02520 scrollX = d;
02521
02522
if (mouseY < 0)
02523 {
02524 mouseY = 0;
02525 scrollY = -d;
02526 }
02527
02528
if (mouseY > height())
02529 {
02530 mouseY = height();
02531 scrollY = d;
02532 }
02533
02534 placeCursor(
QPoint( mouseX, mouseY ),
true );
02535 }
02536
else
02537 {
02538
if (m_textHintEnabled)
02539 {
02540 m_textHintTimer.start(m_textHintTimeout);
02541 m_textHintMouseX=e->x();
02542 m_textHintMouseY=e->y();
02543 }
02544 }
02545 }
02546
02547
void KateViewInternal::paintEvent(
QPaintEvent *e)
02548 {
02549 paintText(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
02550 }
02551
02552
void KateViewInternal::resizeEvent(
QResizeEvent* e)
02553 {
02554
bool expandedHorizontally = width() > e->oldSize().width();
02555
bool expandedVertically = height() > e->oldSize().height();
02556
bool heightChanged = height() != e->oldSize().height();
02557
02558 m_madeVisible =
false;
02559
02560
if (heightChanged) {
02561 setAutoCenterLines(m_autoCenterLines,
false);
02562 m_cachedMaxStartPos.setPos(-1, -1);
02563 }
02564
02565
if (m_view->dynWordWrap()) {
02566
bool dirtied =
false;
02567
02568
for (uint i = 0; i < lineRanges.count(); i++) {
02569
02570
02571
if (lineRanges[i].wrap ||
02572 (!expandedHorizontally && (lineRanges[i].endX - lineRanges[i].startX) > width())) {
02573 dirtied = lineRanges[i].dirty =
true;
02574
break;
02575 }
02576 }
02577
02578
if (dirtied || heightChanged) {
02579 updateView(
true);
02580 leftBorder->update();
02581 }
02582
02583
if (width() < e->oldSize().width()) {
02584
if (!m_doc->wrapCursor()) {
02585
02586
if (cursor.col() > m_doc->lineLength(cursor.line())) {
02587 LineRange thisRange = currentRange();
02588
02589
KateTextCursor newCursor(cursor.line(), thisRange.endCol + ((width() - thisRange.xOffset() - (thisRange.endX - thisRange.startX)) / m_view->renderer()->spaceWidth()) - 1);
02590 updateCursor(newCursor);
02591 }
02592 }
02593 }
02594
02595 }
else {
02596 updateView();
02597
02598
if (expandedHorizontally && startX() > 0)
02599 scrollColumns(startX() - (width() - e->oldSize().width()));
02600 }
02601
02602
if (expandedVertically) {
02603
KateTextCursor max = maxStartPos();
02604
if (startPos() > max)
02605 scrollPos(max);
02606 }
02607 }
02608
02609
void KateViewInternal::scrollTimeout ()
02610 {
02611
if (scrollX || scrollY)
02612 {
02613 scrollLines (startPos().line() + (scrollY / (
int)m_view->renderer()->fontHeight()));
02614 placeCursor(
QPoint( mouseX, mouseY ),
true );
02615 }
02616 }
02617
02618
void KateViewInternal::cursorTimeout ()
02619 {
02620 m_view->renderer()->setDrawCaret(!m_view->renderer()->drawCaret());
02621 paintCursor();
02622 }
02623
02624
void KateViewInternal::textHintTimeout ()
02625 {
02626 m_textHintTimer.stop ();
02627
02628 LineRange thisRange = yToLineRange(m_textHintMouseY);
02629
02630
if (thisRange.line == -1)
return;
02631
02632
if (m_textHintMouseX> (lineMaxCursorX(thisRange) - thisRange.startX))
return;
02633
02634
int realLine = thisRange.line;
02635
int startCol = thisRange.startCol;
02636
02637
KateTextCursor c(realLine, 0);
02638 m_view->renderer()->textWidth( c, startX() + m_textHintMouseX, startCol);
02639
02640
QString tmp;
02641
02642 emit m_view->needTextHint(c.
line(), c.
col(), tmp);
02643
02644
if (!tmp.isEmpty())
kdDebug(13030)<<
"Hint text: "<<tmp<<
endl;
02645 }
02646
02647
void KateViewInternal::focusInEvent (
QFocusEvent *)
02648 {
02649 m_cursorTimer.start ( KApplication::cursorFlashTime() / 2 );
02650
02651
if (m_textHintEnabled)
02652 m_textHintTimer.start( m_textHintTimeout );
02653
02654 paintCursor();
02655
02656 m_doc->m_activeView = m_view;
02657
02658 emit m_view->gotFocus( m_view );
02659 }
02660
02661
void KateViewInternal::focusOutEvent (
QFocusEvent *)
02662 {
02663
if( ! m_view->m_codeCompletion->codeCompletionVisible() )
02664 {
02665 m_cursorTimer.stop();
02666
02667 m_view->renderer()->setDrawCaret(
true);
02668 paintCursor();
02669 emit m_view->lostFocus( m_view );
02670 }
02671
02672 m_textHintTimer.stop();
02673 }
02674
02675
void KateViewInternal::doDrag()
02676 {
02677 dragInfo.state = diDragging;
02678 dragInfo.dragObject =
new QTextDrag(m_doc->selection(),
this);
02679 dragInfo.dragObject->drag();
02680 }
02681
02682
void KateViewInternal::dragEnterEvent(
QDragEnterEvent* event )
02683 {
02684
event->accept( (QTextDrag::canDecode(event) && m_doc->isReadWrite()) ||
02685 KURLDrag::canDecode(event) );
02686 }
02687
02688
void KateViewInternal::dragMoveEvent(
QDragMoveEvent* event )
02689 {
02690
02691 placeCursor(
event->pos(),
true,
false );
02692
02693
02694
event->acceptAction();
02695 }
02696
02697
void KateViewInternal::dropEvent(
QDropEvent* event )
02698 {
02699
if ( KURLDrag::canDecode(event) ) {
02700
02701 emit dropEventPass(event);
02702
02703 }
else if ( QTextDrag::canDecode(event) && m_doc->isReadWrite() ) {
02704
02705
QString text;
02706
02707
if (!QTextDrag::decode(event, text))
02708
return;
02709
02710
02711
bool priv =
false;
02712
if (
event->source() &&
event->source()->inherits(
"KateViewInternal"))
02713 priv = m_doc->ownedView( ((KateViewInternal*)(
event->source()))->m_view );
02714
02715
02716
bool selected = isTargetSelected(
event->pos() );
02717
02718
if( priv && selected ) {
02719
02720
02721
return;
02722 }
02723
02724
02725
if (
event->action() != QDropEvent::Copy )
02726 m_doc->removeSelectedText();
02727 m_doc->insertText( cursor.line(), cursor.col(), text );
02728 placeCursor(
event->pos() );
02729
event->acceptAction();
02730 updateView();
02731 }
02732
02733 dragInfo.state = diNone;
02734
02735 stopDragScroll();
02736 }
02737
02738
void KateViewInternal::imStartEvent(
QIMEvent *e )
02739 {
02740
if ( m_doc->m_bReadOnly ) {
02741 e->ignore();
02742
return;
02743 }
02744
02745
if ( m_doc->hasSelection() )
02746 m_doc->removeSelectedText();
02747
02748 m_imPreeditStartLine = cursor.line();
02749 m_imPreeditStart = cursor.col();
02750 m_imPreeditLength = 0;
02751
02752 m_doc->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
true );
02753 }
02754
02755
void KateViewInternal::imComposeEvent(
QIMEvent *e )
02756 {
02757
if ( m_doc->m_bReadOnly ) {
02758 e->ignore();
02759
return;
02760 }
02761
02762
if ( m_imPreeditLength > 0 ) {
02763 m_doc->removeText( cursor.line(), m_imPreeditStart,
02764 cursor.line(), m_imPreeditStart + m_imPreeditLength );
02765 }
02766
02767 m_doc->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, m_imPreeditStart + e->text().length(),
02768 m_imPreeditStart + e->cursorPos(), m_imPreeditStart + e->cursorPos() + e->selectionLength(),
02769
true );
02770
02771 m_doc->insertText( cursor.line(), cursor.col(), e->text() );
02772
02773 updateView(
true );
02774 updateCursor( cursor,
true );
02775 m_imPreeditLength = e->text().length();
02776 }
02777
02778
void KateViewInternal::imEndEvent(
QIMEvent *e )
02779 {
02780
if ( m_doc->m_bReadOnly ) {
02781 e->ignore();
02782
return;
02783 }
02784
02785
if ( m_imPreeditLength > 0 ) {
02786 m_doc->removeText( cursor.line(), m_imPreeditStart,
02787 cursor.line(), m_imPreeditStart + m_imPreeditLength );
02788 }
02789
02790 m_doc->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
false );
02791
02792
if ( e->text().length() > 0 ) {
02793 m_doc->insertText( cursor.line(), cursor.col(), e->text() );
02794
02795
if ( !m_cursorTimer.isActive() )
02796 m_cursorTimer.start ( KApplication::cursorFlashTime() / 2 );
02797
02798 updateView(
true );
02799 updateCursor( cursor,
true );
02800
02801 }
02802
02803 m_imPreeditStart = 0;
02804 m_imPreeditLength = 0;
02805 }
02806
02807
02808
02809
02810
02811
void KateViewInternal::clear()
02812 {
02813 cursor.setPos(0, 0);
02814 displayCursor.
setPos(0, 0);
02815 }
02816
02817
void KateViewInternal::wheelEvent(
QWheelEvent* e)
02818 {
02819
if (m_lineScroll->minValue() != m_lineScroll->maxValue() && e->orientation() != Qt::Horizontal) {
02820
02821
if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) {
02822
if (e->delta() > 0)
02823 scrollPrevPage();
02824
else
02825 scrollNextPage();
02826 }
else {
02827 scrollViewLines(-((e->delta() / 120) * QApplication::wheelScrollLines()));
02828
02829 update();
02830 leftBorder->update();
02831 }
02832
02833 }
else if (!m_columnScroll->isHidden()) {
02834
QWheelEvent copy = *e;
02835 QApplication::sendEvent(m_columnScroll, ©);
02836
02837 }
else {
02838 e->ignore();
02839 }
02840 }
02841
02842
void KateViewInternal::startDragScroll()
02843 {
02844
if ( !m_dragScrollTimer.isActive() ) {
02845 m_suppressColumnScrollBar =
true;
02846 m_dragScrollTimer.start( scrollTime );
02847 }
02848 }
02849
02850
void KateViewInternal::stopDragScroll()
02851 {
02852 m_suppressColumnScrollBar =
false;
02853 m_dragScrollTimer.stop();
02854 updateView();
02855 }
02856
02857
void KateViewInternal::doDragScroll()
02858 {
02859
QPoint p = this->mapFromGlobal( QCursor::pos() );
02860
02861
int dx = 0, dy = 0;
02862
if ( p.y() < scrollMargin ) {
02863 dy = p.y() - scrollMargin;
02864 }
else if ( p.y() > height() - scrollMargin ) {
02865 dy = scrollMargin - (height() - p.y());
02866 }
02867
if ( p.x() < scrollMargin ) {
02868 dx = p.x() - scrollMargin;
02869 }
else if ( p.x() > width() - scrollMargin ) {
02870 dx = scrollMargin - (width() - p.x());
02871 }
02872 dy /= 4;
02873
02874
if (dy)
02875 scrollLines(startPos().line() + dy);
02876
if (dx)
02877 scrollColumns(m_startX + dx);
02878
if (!dy && !dx)
02879 stopDragScroll();
02880 }
02881
02882
void KateViewInternal::enableTextHints(
int timeout)
02883 {
02884 m_textHintTimeout=timeout;
02885 m_textHintEnabled=
true;
02886 m_textHintTimer.start(timeout);
02887 }
02888
02889
void KateViewInternal::disableTextHints()
02890 {
02891 m_textHintEnabled=
false;
02892 m_textHintTimer.stop ();
02893 }
02894
02895
02896
void KateViewInternal::editStart()
02897 {
02898 editSessionNumber++;
02899
02900
if (editSessionNumber > 1)
02901
return;
02902
02903 editIsRunning =
true;
02904 editOldCursor = cursor;
02905 }
02906
02907
void KateViewInternal::editEnd(
int editTagLineStart,
int editTagLineEnd,
bool tagFrom)
02908 {
02909
if (editSessionNumber == 0)
02910
return;
02911
02912 editSessionNumber--;
02913
02914
if (editSessionNumber > 0)
02915
return;
02916
02917
if (tagFrom && (editTagLineStart <= int(m_doc->getRealLine(startLine()))))
02918 tagAll();
02919
else
02920 tagLines (editTagLineStart, tagFrom ? m_doc->lastLine() : editTagLineEnd, true);
02921
02922
if (editOldCursor == cursor)
02923 updateBracketMarks();
02924
02925
if (m_imPreeditLength <= 0)
02926 updateView(
true);
02927
02928
if ((editOldCursor != cursor) && (m_imPreeditLength <= 0))
02929 {
02930 m_madeVisible =
false;
02931 updateCursor ( cursor,
true );
02932 }
02933
else if ( m_view->isActive() )
02934 {
02935 makeVisible(displayCursor, displayCursor.
col());
02936 }
02937
02938 editIsRunning =
false;
02939 }
02940
02941
void KateViewInternal::editSetCursor (
const KateTextCursor &cursor)
02942 {
02943
if (this->cursor != cursor)
02944 {
02945 this->cursor.
setPos (cursor);
02946 }
02947 }
02948
02949
02950
void KateViewInternal::docSelectionChanged ()
02951 {
02952
if (!m_doc->hasSelection())
02953 selectAnchor.setPos (-1, -1);
02954 }
02955
02956
02957 KateScrollBar::KateScrollBar (Orientation orientation, QWidget* parent,
const char* name)
02958 : QScrollBar (orientation, parent,
name)
02959 , m_middleMouseDown (false)
02960 {
02961 connect(
this, SIGNAL(valueChanged(
int)), SLOT(sliderMaybeMoved(
int)));
02962 }
02963
02964
void KateScrollBar::mousePressEvent(
QMouseEvent* e)
02965 {
02966
if (e->button() == MidButton)
02967 m_middleMouseDown =
true;
02968
02969 QScrollBar::mousePressEvent(e);
02970 }
02971
02972
void KateScrollBar::mouseReleaseEvent(
QMouseEvent* e)
02973 {
02974 QScrollBar::mouseReleaseEvent(e);
02975
02976 m_middleMouseDown =
false;
02977 }
02978
02979
void KateScrollBar::sliderMaybeMoved(
int value)
02980 {
02981
if (m_middleMouseDown)
02982 emit sliderMMBMoved(value);
02983 }
02984
02985 TextLine::Ptr KateViewInternal::textLine(
int realLine )
02986 {
02987
if (m_usePlainLines)
02988
return m_doc->plainKateTextLine(realLine);
02989
else
02990
return m_doc->kateTextLine(realLine);
02991 }
02992
02993
02994
02995