26 #include "kateviewinternal.h"
27 #include "kateviewinternal.moc"
30 #include "katecodefoldinghelpers.h"
31 #include "kateviewhelpers.h"
32 #include "katehighlight.h"
33 #include "katesupercursor.h"
34 #include "katerenderer.h"
35 #include "katecodecompletion.h"
36 #include "kateconfig.h"
40 #include <tdeapplication.h>
41 #include <tdeglobalsettings.h>
45 #include <tqdragobject.h>
46 #include <tqpopupmenu.h>
47 #include <tqdropsite.h>
48 #include <tqpainter.h>
50 #include <tqclipboard.h>
54 KateViewInternal::KateViewInternal(KateView *view, KateDocument *doc)
55 : TQWidget (view,
"", (WFlags)(WStaticContents | WRepaintNoErase | WResizeNoErase) )
56 , editSessionNumber (0)
57 , editIsRunning (false)
60 , cursor (doc, true, 0, 0, this)
61 , possibleTripleClick (false)
63 , m_startPos(doc, true, 0,0)
64 , m_madeVisible(false)
65 , m_shiftKeyPressed (false)
66 , m_autoCenterLines (false)
67 , m_selChangedByUser (false)
68 , selectAnchor (-1, -1)
69 , m_selectionMode( Default )
70 , m_preserveMaxX(false)
72 , m_usePlainLines(false)
73 , m_updatingView(true)
74 , m_cachedMaxStartPos(-1, -1)
75 , m_dragScrollTimer(this)
76 , m_scrollTimer (this)
77 , m_cursorTimer (this)
78 , m_textHintTimer (this)
79 , m_textHintEnabled(false)
80 , m_textHintMouseX(-1)
81 , m_textHintMouseY(-1)
82 , m_imPreeditStartLine(0)
84 , m_imPreeditLength(0)
85 , m_imPreeditSelStart(0)
90 cursor.setMoveOnInsert (
true);
93 selStartCached.setLine( -1 );
99 m_lineScroll->setTracking (
true);
101 m_lineLayout =
new TQVBoxLayout();
102 m_colLayout =
new TQHBoxLayout();
104 m_colLayout->addWidget(m_lineScroll);
105 m_lineLayout->addLayout(m_colLayout);
108 m_dummy =
new TQWidget(m_view);
109 m_dummy->setFixedHeight(style().scrollBarExtent().width());
111 if (m_view->dynWordWrap())
116 m_lineLayout->addWidget(m_dummy);
119 connect(m_lineScroll, TQ_SIGNAL(prevPage()), TQ_SLOT(scrollPrevPage()));
120 connect(m_lineScroll, TQ_SIGNAL(nextPage()), TQ_SLOT(scrollNextPage()));
122 connect(m_lineScroll, TQ_SIGNAL(prevLine()), TQ_SLOT(scrollPrevLine()));
123 connect(m_lineScroll, TQ_SIGNAL(nextLine()), TQ_SLOT(scrollNextLine()));
125 connect(m_lineScroll, TQ_SIGNAL(sliderMoved(
int)), TQ_SLOT(scrollLines(
int)));
126 connect(m_lineScroll, TQ_SIGNAL(sliderMMBMoved(
int)), TQ_SLOT(scrollLines(
int)));
129 m_lineScroll->installEventFilter(
this);
134 m_columnScroll =
new TQScrollBar(TQt::Horizontal,m_view);
137 if (m_view->dynWordWrap())
138 m_columnScroll->hide();
140 m_columnScroll->show();
142 m_columnScroll->setTracking(
true);
145 connect( m_columnScroll, TQ_SIGNAL( valueChanged (
int) ),
146 this, TQ_SLOT( scrollColumns (
int) ) );
151 leftBorder =
new KateIconBorder(
this, m_view );
154 connect( leftBorder, TQ_SIGNAL(toggleRegionVisibility(
unsigned int)),
155 m_doc->foldingTree(), TQ_SLOT(toggleRegionVisibility(
unsigned int)));
157 connect( doc->foldingTree(), TQ_SIGNAL(regionVisibilityChangedAt(
unsigned int)),
158 this, TQ_SLOT(slotRegionVisibilityChangedAt(
unsigned int)));
159 connect( doc, TQ_SIGNAL(codeFoldingUpdated()),
160 this, TQ_SLOT(slotCodeFoldingChanged()) );
162 displayCursor.setPos(0, 0);
166 setAcceptDrops(
true );
167 setBackgroundMode( NoBackground );
170 installEventFilter(
this);
173 setInputMethodEnabled(
true);
177 m_mouseCursor = TQt::IbeamCursor;
180 setMouseTracking(
true);
182 dragInfo.state = diNone;
185 connect( &m_dragScrollTimer, TQ_SIGNAL( timeout() ),
186 this, TQ_SLOT( doDragScroll() ) );
188 connect( &m_scrollTimer, TQ_SIGNAL( timeout() ),
189 this, TQ_SLOT( scrollTimeout() ) );
191 connect( &m_cursorTimer, TQ_SIGNAL( timeout() ),
192 this, TQ_SLOT( cursorTimeout() ) );
194 connect( &m_textHintTimer, TQ_SIGNAL( timeout() ),
195 this, TQ_SLOT( textHintTimeout() ) );
198 connect( m_view, TQ_SIGNAL( selectionChanged() ),
199 this, TQ_SLOT( viewSelectionChanged() ) );
206 if (TQApplication::reverseLayout()){
207 m_view->m_grid->addMultiCellWidget(leftBorder, 0, 1, 2, 2);
208 m_view->m_grid->addMultiCellWidget(m_columnScroll, 1, 1, 0, 1);
209 m_view->m_grid->addMultiCellLayout(m_lineLayout, 0, 0, 0, 0);
212 m_view->m_grid->addMultiCellLayout(m_lineLayout, 0, 1, 2, 2);
213 m_view->m_grid->addMultiCellWidget(m_columnScroll, 1, 1, 0, 1);
214 m_view->m_grid->addWidget(leftBorder, 0, 0);
220 KateViewInternal::~KateViewInternal ()
224 void KateViewInternal::prepareForDynWrapChange()
227 m_wrapChangeViewLine = displayViewLine(displayCursor,
true);
230 void KateViewInternal::dynWrapChanged()
232 if (m_view->dynWordWrap())
234 m_columnScroll->hide();
239 m_columnScroll->show();
246 if (m_view->dynWordWrap())
250 if (m_wrapChangeViewLine != -1) {
251 KateTextCursor newStart = viewLineOffset(displayCursor, -m_wrapChangeViewLine);
252 makeVisible(newStart, newStart.col(),
true);
260 int viewLines = linesDisplayed() - 1;
263 kdDebug(13030) <<
"WARNING: viewLines wrong!" <<
endl;
268 if (!lineRanges.count() || lineRanges[0].line == -1 || viewLines >= (
int)lineRanges.count()) {
270 return KateTextCursor(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
273 for (
int i = viewLines; i >= 0; i--) {
274 KateLineRange& thisRange = lineRanges[i];
276 if (thisRange.line == -1)
continue;
278 if (thisRange.virtualLine >= (
int)m_doc->numVisLines()) {
280 return KateTextCursor(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
283 return KateTextCursor(thisRange.virtualLine, thisRange.wrap ? thisRange.endCol - 1 : thisRange.endCol);
287 kdDebug(13030) <<
"WARNING: could not find a lineRange at all" <<
endl;
291 uint KateViewInternal::endLine()
const
293 return endPos().line();
296 KateLineRange KateViewInternal::yToKateLineRange(uint y)
const
298 uint range = y / m_view->renderer()->fontHeight();
301 if (range >= lineRanges.size())
302 return lineRanges[lineRanges.size()-1];
304 return lineRanges[range];
307 int KateViewInternal::lineToY(uint viewLine)
const
309 return (viewLine-startLine()) * m_view->renderer()->fontHeight();
312 void KateViewInternal::slotIncFontSizes()
314 m_view->renderer()->increaseFontSizes();
317 void KateViewInternal::slotDecFontSizes()
319 m_view->renderer()->decreaseFontSizes();
325 void KateViewInternal::scrollLines (
int line )
332 void KateViewInternal::scrollViewLines(
int offset)
337 m_lineScroll->blockSignals(
true);
338 m_lineScroll->setValue(startLine());
339 m_lineScroll->blockSignals(
false);
342 void KateViewInternal::scrollNextPage()
344 scrollViewLines(kMax( (
int)linesDisplayed() - 1, 0 ));
347 void KateViewInternal::scrollPrevPage()
349 scrollViewLines(-kMax( (
int)linesDisplayed() - 1, 0 ));
352 void KateViewInternal::scrollPrevLine()
357 void KateViewInternal::scrollNextLine()
364 m_usePlainLines =
true;
366 if (m_cachedMaxStartPos.line() == -1 || changed)
368 KateTextCursor end(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
370 m_cachedMaxStartPos = viewLineOffset(end, -((
int)linesDisplayed() - 1));
373 m_usePlainLines =
false;
375 return m_cachedMaxStartPos;
379 void KateViewInternal::scrollPos(
KateTextCursor& c,
bool force,
bool calledExternally)
381 if (!force && ((!m_view->dynWordWrap() && c.line() == (
int)startLine()) || c == startPos()))
392 if (!force && ((!m_view->dynWordWrap() && c.line() == (
int)startLine()) || c == startPos()))
396 int viewLinesScrolled = 0;
401 bool viewLinesScrolledUsable = !force
402 && (c.line() >= (int)startLine()-(int)linesDisplayed()-1)
403 && (c.line() <= (int)endLine()+(int)linesDisplayed()+1);
405 if (viewLinesScrolledUsable)
406 viewLinesScrolled = displayViewLine(c);
408 m_startPos.setPos(c);
411 m_madeVisible =
false;
413 if (viewLinesScrolledUsable)
415 int lines = linesDisplayed();
416 if ((
int)m_doc->numVisLines() < lines) {
417 KateTextCursor end(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
418 lines = kMin((
int)linesDisplayed(), displayViewLine(end) + 1);
421 Q_ASSERT(lines >= 0);
423 if (!calledExternally && TQABS(viewLinesScrolled) < lines)
425 updateView(
false, viewLinesScrolled);
427 int scrollHeight = -(viewLinesScrolled * (int)m_view->renderer()->fontHeight());
428 int scrollbarWidth = style().scrollBarExtent().width();
433 scroll(0, scrollHeight);
434 update(0, height()+scrollHeight-scrollbarWidth, width(), 2*scrollbarWidth);
436 leftBorder->scroll(0, scrollHeight);
437 leftBorder->update(0, leftBorder->height()+scrollHeight-scrollbarWidth, leftBorder->width(), 2*scrollbarWidth);
445 leftBorder->update();
448 void KateViewInternal::scrollColumns (
int x )
456 int dx = m_startX - x;
459 if (TQABS(dx) < width())
464 m_columnScroll->blockSignals(
true);
465 m_columnScroll->setValue(m_startX);
466 m_columnScroll->blockSignals(
false);
470 void KateViewInternal::updateView(
bool changed,
int viewLinesScrolled)
472 m_updatingView =
true;
474 uint contentLines = m_doc->visibleLines();
476 m_lineScroll->blockSignals(
true);
479 int maxLineScrollRange = maxStart.line();
480 if (m_view->dynWordWrap() && maxStart.col() != 0)
481 maxLineScrollRange++;
482 m_lineScroll->setRange(0, maxLineScrollRange);
484 m_lineScroll->setValue(startPos().line());
485 m_lineScroll->setSteps(1, height() / m_view->renderer()->fontHeight());
486 m_lineScroll->blockSignals(
false);
488 uint oldSize = lineRanges.size ();
489 uint newSize = (height() / m_view->renderer()->fontHeight()) + 1;
490 if (oldSize != newSize) {
491 lineRanges.resize((height() / m_view->renderer()->fontHeight()) + 1);
492 if (newSize > oldSize) {
493 static KateLineRange blank;
494 for (uint i = oldSize; i < newSize; i++) {
495 lineRanges[i] = blank;
500 if (oldSize < lineRanges.size ())
502 for (uint i=oldSize; i < lineRanges.size(); i++)
503 lineRanges[i].dirty =
true;
507 if (viewLinesScrolled != 0) {
509 bool forwards = viewLinesScrolled >= 0 ? true :
false;
510 for (uint z = forwards ? 0 : lineRanges.count() - 1; z < lineRanges.count(); forwards ? z++ : z--) {
511 uint oldZ = z + viewLinesScrolled;
512 if (oldZ < lineRanges.count()) {
513 lineRanges[z] = lineRanges[oldZ];
515 lineRanges[z].dirty =
true;
520 if (m_view->dynWordWrap())
523 realStart.setLine(m_doc->getRealLine(realStart.line()));
525 KateLineRange startRange = range(realStart);
526 uint line = startRange.virtualLine;
527 int realLine = startRange.line;
529 int startCol = startRange.startCol;
530 int startX = startRange.startX;
531 int endX = startRange.startX;
532 int shiftX = startRange.startCol ? startRange.shiftX : 0;
534 int newViewLine = startRange.viewLine;
538 bool alreadyDirty =
false;
540 for (uint z = 0; z < lineRanges.size(); z++)
542 if (oldLine != line) {
543 realLine = (int)m_doc->getRealLine(line);
546 lineRanges[z-1].startsInvisibleBlock = (realLine != lineRanges[z-1].line + 1);
548 text = textLine(realLine);
557 if (line >= contentLines || !text)
559 if (lineRanges[z].line != -1)
560 lineRanges[z].dirty =
true;
562 lineRanges[z].clear();
568 if (lineRanges[z].line != realLine || lineRanges[z].startCol != startCol)
569 alreadyDirty = lineRanges[z].dirty =
true;
571 if (lineRanges[z].dirty || changed || alreadyDirty) {
574 lineRanges[z].virtualLine = line;
575 lineRanges[z].line = realLine;
576 lineRanges[z].startsInvisibleBlock =
false;
580 int endCol = m_view->renderer()->textWidth(text, startCol, width() - shiftX, &wrap, &tempEndX);
586 if (m_view->config()->dynWordWrapAlignIndent() > 0)
590 int pos = text->nextNonSpaceChar(0);
593 shiftX = m_view->renderer()->textWidth(text, pos);
595 if (shiftX > ((
double)width() / 100 * m_view->config()->dynWordWrapAlignIndent()))
600 if ((lineRanges[z].startX != startX) || (lineRanges[z].endX != endX) ||
601 (lineRanges[z].startCol != startCol) || (lineRanges[z].endCol != endCol) ||
602 (lineRanges[z].shiftX != shiftX))
603 lineRanges[z].dirty =
true;
605 lineRanges[z].startCol = startCol;
606 lineRanges[z].endCol = endCol;
607 lineRanges[z].startX = startX;
608 lineRanges[z].endX = endX;
609 lineRanges[z].viewLine = newViewLine;
610 lineRanges[z].wrap =
true;
617 if ((lineRanges[z].startX != startX) || (lineRanges[z].endX != endX) ||
618 (lineRanges[z].startCol != startCol) || (lineRanges[z].endCol != endCol))
619 lineRanges[z].dirty =
true;
621 lineRanges[z].startCol = startCol;
622 lineRanges[z].endCol = endCol;
623 lineRanges[z].startX = startX;
624 lineRanges[z].endX = endX;
625 lineRanges[z].viewLine = newViewLine;
626 lineRanges[z].wrap =
false;
631 lineRanges[z].shiftX = shiftX;
635 if (lineRanges[z].wrap) {
636 startCol = lineRanges[z].endCol;
637 startX = lineRanges[z].endX;
638 endX = lineRanges[z].endX;
642 shiftX = lineRanges[z].shiftX;
652 for(; (z + startLine() < contentLines) && (z < lineRanges.size()); z++)
654 if (lineRanges[z].dirty || lineRanges[z].line != (
int)m_doc->getRealLine(z + startLine())) {
655 lineRanges[z].dirty =
true;
657 lineRanges[z].line = m_doc->getRealLine( z + startLine() );
659 lineRanges[z-1].startsInvisibleBlock = (lineRanges[z].line != lineRanges[z-1].line + 1);
661 lineRanges[z].virtualLine = z + startLine();
662 lineRanges[z].startCol = 0;
663 lineRanges[z].endCol = m_doc->lineLength(lineRanges[z].line);
664 lineRanges[z].startX = 0;
665 lineRanges[z].endX = m_view->renderer()->textWidth( textLine( lineRanges[z].line ), -1 );
666 lineRanges[z].shiftX = 0;
667 lineRanges[z].viewLine = 0;
668 lineRanges[z].wrap =
false;
670 else if (z && lineRanges[z-1].dirty)
672 lineRanges[z-1].startsInvisibleBlock = (lineRanges[z].line != lineRanges[z-1].line + 1);
676 for (; z < lineRanges.size(); z++)
678 if (lineRanges[z].line != -1)
679 lineRanges[z].dirty =
true;
681 lineRanges[z].clear();
684 int max = maxLen(startLine()) - width();
694 m_columnScroll->blockSignals(
true);
697 m_columnScroll->setDisabled (max == 0);
699 m_columnScroll->setRange(0, max);
701 m_columnScroll->setValue(m_startX);
704 m_columnScroll->setSteps(m_view->renderer()->config()->fontMetrics()->width(
'a'), width());
706 m_columnScroll->blockSignals(
false);
709 m_updatingView =
false;
712 paintText(0, 0, width(), height(),
true);
715 void KateViewInternal::paintText (
int x,
int y,
int width,
int height,
bool paintOnlyDirty)
718 int xStart = startX() + x;
719 int xEnd = xStart + width;
720 uint h = m_view->renderer()->fontHeight();
721 uint startz = (y / h);
722 uint endz = startz + 1 + (height / h);
723 uint lineRangesSize = lineRanges.size();
725 static TQPixmap drawBuffer;
727 if (drawBuffer.width() < KateViewInternal::width() || drawBuffer.height() < (int)h)
728 drawBuffer.resize(KateViewInternal::width(), (int)h);
730 if (drawBuffer.isNull())
733 TQPainter paint(
this);
734 TQPainter paintDrawBuffer(&drawBuffer);
737 m_view->renderer()->setCaretStyle(m_view->isOverwriteMode() ? KateRenderer::Replace : KateRenderer::Insert);
738 m_view->renderer()->setShowTabs(m_doc->configFlags() & KateDocument::cfShowTabs);
740 for (uint z=startz; z <= endz; z++)
742 if ( (z >= lineRangesSize) || ((lineRanges[z].line == -1) && (!paintOnlyDirty || lineRanges[z].dirty)) )
744 if (!(z >= lineRangesSize))
745 lineRanges[z].dirty =
false;
747 paint.fillRect( x, z * h, width, h, m_view->renderer()->config()->backgroundColor() );
749 else if (!paintOnlyDirty || lineRanges[z].dirty)
751 lineRanges[z].dirty =
false;
753 m_view->renderer()->paintTextLine(paintDrawBuffer, &lineRanges[z], xStart, xEnd, &cursor, &bm);
755 paint.drawPixmap (x, z * h, drawBuffer, 0, 0, width, h);
764 void KateViewInternal::makeVisible (
const KateTextCursor& c, uint endCol,
bool force,
bool center,
bool calledExternally)
774 scrollPos(scroll, force, calledExternally);
776 else if (center && (c < startPos() || c > endPos()))
778 KateTextCursor scroll = viewLineOffset(c, -
int(linesDisplayed()) / 2);
779 scrollPos(scroll,
false, calledExternally);
781 else if ( c > viewLineOffset(endPos(), -m_minLinesVisible) )
783 KateTextCursor scroll = viewLineOffset(c, -((
int)linesDisplayed() - m_minLinesVisible - 1));
784 scrollPos(scroll,
false, calledExternally);
786 else if ( c < viewLineOffset(startPos(), m_minLinesVisible) )
789 scrollPos(scroll,
false, calledExternally);
795 if (startPos() > max) {
796 scrollPos(max, max.col(), calledExternally);
800 if (!m_view->dynWordWrap() && endCol != (uint)-1)
802 int sX = (int)m_view->renderer()->textWidth (textLine( m_doc->getRealLine( c.line() ) ), c.col() );
809 scrollColumns (sXborder);
810 else if (sX > m_startX + width())
811 scrollColumns (sX - width() + 8);
814 m_madeVisible = !force;
817 void KateViewInternal::slotRegionVisibilityChangedAt(
unsigned int)
819 kdDebug(13030) <<
"slotRegionVisibilityChangedAt()" <<
endl;
820 m_cachedMaxStartPos.setLine(-1);
822 if (startPos() > max)
827 leftBorder->update();
830 void KateViewInternal::slotCodeFoldingChanged()
832 leftBorder->update();
835 void KateViewInternal::slotRegionBeginEndAddedRemoved(
unsigned int)
837 kdDebug(13030) <<
"slotRegionBeginEndAddedRemoved()" <<
endl;
839 leftBorder->update();
842 void KateViewInternal::showEvent ( TQShowEvent *e )
846 TQWidget::showEvent (e);
849 uint KateViewInternal::linesDisplayed()
const
852 int fh = m_view->renderer()->fontHeight();
854 return (h - (h % fh)) / fh;
857 TQPoint KateViewInternal::cursorCoordinates()
859 int viewLine = displayViewLine(displayCursor,
true);
862 return TQPoint(-1, -1);
864 uint y = viewLine * m_view->renderer()->fontHeight();
865 uint x = cXPos - m_startX - lineRanges[viewLine].startX + leftBorder->width() + lineRanges[viewLine].xOffset();
867 return TQPoint(x, y);
870 void KateViewInternal::updateMicroFocusHint()
872 int line = displayViewLine(displayCursor,
true);
876 if (line == -1 || !hasFocus())
886 uint preeditStrLen = renderer->textWidth(textLine(m_imPreeditStartLine), cursor.col()) - renderer->textWidth(textLine(m_imPreeditStartLine), m_imPreeditSelStart);
887 uint x = cXPos - m_startX - lineRanges[line].startX + lineRanges[line].xOffset() - preeditStrLen;
888 uint y = line * renderer->fontHeight();
890 setMicroFocusHint(x, y, 0, renderer->fontHeight());
893 void KateViewInternal::doReturn()
896 m_doc->newLine( c,
this );
901 void KateViewInternal::doDelete()
903 m_doc->del( m_view, cursor );
904 if (m_view->m_codeCompletion->codeCompletionVisible()) {
905 m_view->m_codeCompletion->updateBox();
909 void KateViewInternal::doBackspace()
911 m_doc->backspace( m_view, cursor );
912 if (m_view->m_codeCompletion->codeCompletionVisible()) {
913 m_view->m_codeCompletion->updateBox();
917 void KateViewInternal::doTranspose()
919 m_doc->transpose( cursor );
922 void KateViewInternal::doDeleteWordLeft()
925 m_view->removeSelectedText();
929 void KateViewInternal::doDeleteWordRight()
932 m_view->removeSelectedText();
938 CalculatingCursor(KateViewInternal* vi)
953 CalculatingCursor(KateViewInternal* vi, uint line, uint col)
961 virtual CalculatingCursor& operator+=(
int n ) = 0;
963 virtual CalculatingCursor& operator-=(
int n ) = 0;
965 CalculatingCursor& operator++() {
return operator+=( 1 ); }
967 CalculatingCursor& operator--() {
return operator-=( 1 ); }
970 m_line = kMax( 0, kMin(
int( m_vi->m_doc->numLines() - 1 ), line() ) );
971 if (m_vi->m_view->wrapCursor())
972 m_col = kMax( 0, kMin( m_vi->m_doc->lineLength( line() ), col() ) );
974 m_col = kMax( 0, col() );
978 void toEdge( Bias bias ) {
979 if( bias == left_b ) m_col = 0;
980 else if( bias == right_b ) m_col = m_vi->m_doc->lineLength( line() );
983 bool atEdge()
const {
return atEdge( left_b ) || atEdge( right_b ); }
985 bool atEdge( Bias bias )
const {
987 case left_b:
return col() == 0;
988 case none:
return atEdge();
989 case right_b:
return col() == m_vi->m_doc->lineLength( line() );
990 default: Q_ASSERT(
false);
return false;
996 return line() >= 0 &&
997 uint( line() ) < m_vi->m_doc->numLines() &&
999 (!m_vi->m_view->wrapCursor() || col() <= m_vi->m_doc->lineLength( line() ));
1001 KateViewInternal* m_vi;
1004 class BoundedCursor :
public CalculatingCursor {
1006 BoundedCursor(KateViewInternal* vi)
1007 : CalculatingCursor( vi ) {};
1009 : CalculatingCursor( vi, c ) {};
1010 BoundedCursor(KateViewInternal* vi, uint line, uint col )
1011 : CalculatingCursor( vi, line, col ) {};
1012 virtual CalculatingCursor& operator+=(
int n ) {
1015 if (n > 0 && m_vi->m_view->dynWordWrap()) {
1017 if (m_col > m_vi->m_doc->lineLength(m_line)) {
1018 KateLineRange currentRange = m_vi->range(*
this);
1022 m_vi->m_view->renderer()->textWidth(m_vi->textLine(m_line), currentRange.startCol, m_vi->width() - currentRange.xOffset(), &crap, &endX);
1023 endX += (m_col - currentRange.endCol + 1) * m_vi->m_view->renderer()->spaceWidth();
1026 if (endX >= m_vi->width() - currentRange.xOffset()) {
1028 if ( uint( line() ) < m_vi->m_doc->numLines() - 1 ) {
1035 }
else if (n < 0 && col() < 0 && line() > 0 ) {
1037 m_col = m_vi->m_doc->lineLength( line() );
1040 m_col = kMax( 0, col() );
1042 Q_ASSERT( valid() );
1045 virtual CalculatingCursor& operator-=(
int n ) {
1046 return operator+=( -n );
1050 class WrappingCursor :
public CalculatingCursor {
1052 WrappingCursor(KateViewInternal* vi)
1053 : CalculatingCursor( vi) {};
1055 : CalculatingCursor( vi, c ) {};
1056 WrappingCursor(KateViewInternal* vi, uint line, uint col )
1057 : CalculatingCursor( vi, line, col ) {};
1059 virtual CalculatingCursor& operator+=(
int n ) {
1060 if( n < 0 )
return operator-=( -n );
1061 int len = m_vi->m_doc->lineLength( line() );
1062 if( col() + n <= len ) {
1064 }
else if( uint( line() ) < m_vi->m_doc->numLines() - 1 ) {
1065 n -= len - col() + 1;
1072 Q_ASSERT( valid() );
1075 virtual CalculatingCursor& operator-=(
int n ) {
1076 if( n < 0 )
return operator+=( -n );
1077 if( col() - n >= 0 ) {
1079 }
else if( line() > 0 ) {
1082 m_col = m_vi->m_doc->lineLength( line() );
1087 Q_ASSERT( valid() );
1092 void KateViewInternal::moveChar( Bias bias,
bool sel )
1094 if (bias == Bias::none)
1107 int col = cursor.col();
1108 if (bias == Bias::left_b)
1111 if (tl->getChar(col - 1).isLowSurrogate() && tl->getChar(col - 2).isHighSurrogate())
1119 if (tl->getChar(col).isHighSurrogate() && tl->getChar(col + 1).isLowSurrogate())
1126 if (m_view->wrapCursor())
1128 c = WrappingCursor(
this, cursor ) += offset;
1131 c = BoundedCursor(
this, cursor ) += offset;
1134 updateSelection( c, sel );
1138 void KateViewInternal::cursorLeft(
bool sel )
1140 if ( ! m_view->wrapCursor() && cursor.col() == 0 )
1143 moveChar( left_b, sel );
1144 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1145 m_view->m_codeCompletion->updateBox();
1149 void KateViewInternal::cursorRight(
bool sel )
1151 moveChar( right_b, sel );
1152 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1153 m_view->m_codeCompletion->updateBox();
1157 void KateViewInternal::wordLeft (
bool sel )
1159 WrappingCursor c(
this, cursor );
1169 KateHighlighting* h = m_doc->highlight();
1170 if( !c.atEdge( left_b ) ) {
1172 while( !c.atEdge( left_b ) && m_doc->textLine( c.line() )[ c.col() - 1 ].isSpace() )
1175 if( c.atEdge( left_b ) )
1179 else if( h->isInWord( m_doc->textLine( c.line() )[ c.col() - 1 ] ) )
1181 while( !c.atEdge( left_b ) && h->isInWord( m_doc->textLine( c.line() )[ c.col() - 1 ] ) )
1186 while( !c.atEdge( left_b )
1187 && !h->isInWord( m_doc->textLine( c.line() )[ c.col() - 1 ] )
1190 && !m_doc->textLine( c.line() )[ c.col() - 1 ].isSpace() )
1196 updateSelection( c, sel );
1200 void KateViewInternal::wordRight(
bool sel )
1202 WrappingCursor c(
this, cursor );
1212 KateHighlighting* h = m_doc->highlight();
1213 if( c.atEdge( right_b ) )
1217 else if( h->isInWord( m_doc->textLine( c.line() )[ c.col() ] ) )
1219 while( !c.atEdge( right_b ) && h->isInWord( m_doc->textLine( c.line() )[ c.col() ] ) )
1224 while( !c.atEdge( right_b )
1225 && !h->isInWord( m_doc->textLine( c.line() )[ c.col() ] )
1228 && !m_doc->textLine( c.line() )[ c.col() ].isSpace() )
1234 while( !c.atEdge( right_b ) && m_doc->textLine( c.line() )[ c.col() ].isSpace() )
1237 updateSelection( c, sel );
1241 void KateViewInternal::moveEdge( Bias bias,
bool sel )
1243 BoundedCursor c(
this, cursor );
1245 updateSelection( c, sel );
1249 void KateViewInternal::home(
bool sel )
1251 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1252 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Home, 0, 0);
1253 m_view->m_codeCompletion->handleKey(&e);
1257 if (m_view->dynWordWrap() && currentRange().startCol) {
1259 if (cursor.col() != currentRange().startCol) {
1261 updateSelection( c, sel );
1267 if( !(m_doc->configFlags() & KateDocument::cfSmartHome) ) {
1268 moveEdge( left_b, sel );
1278 int lc = l->firstChar();
1280 if( lc < 0 || c.col() == lc ) {
1286 updateSelection( c, sel );
1287 updateCursor( c,
true );
1290 void KateViewInternal::end(
bool sel )
1292 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1293 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_End, 0, 0);
1294 m_view->m_codeCompletion->handleKey(&e);
1298 KateLineRange range = currentRange();
1300 if (m_view->dynWordWrap() && range.wrap) {
1302 if (cursor.col() < range.endCol - 1) {
1304 updateSelection( c, sel );
1310 if( !(m_doc->configFlags() & KateDocument::cfSmartHome) ) {
1311 moveEdge( right_b, sel );
1325 if (c.col() == m_doc->lineLength(c.line())) {
1326 c.setCol(l->lastChar() + 1);
1327 updateSelection(c, sel);
1328 updateCursor(c,
true);
1330 moveEdge(right_b, sel);
1334 KateLineRange KateViewInternal::range(
int realLine,
const KateLineRange* previous)
1337 if (!m_updatingView && realLine >= lineRanges[0].line && realLine <= lineRanges[lineRanges.count() - 1].line)
1338 for (uint i = 0; i < lineRanges.count(); i++)
1339 if (realLine == lineRanges[i].line)
1340 if (!m_view->dynWordWrap() || (!previous && lineRanges[i].startCol == 0) || (previous && lineRanges[i].startCol == previous->endCol))
1341 return lineRanges[i];
1348 return KateLineRange();
1351 if (!m_view->dynWordWrap()) {
1352 Q_ASSERT(!previous);
1353 ret.line = realLine;
1354 ret.virtualLine = m_doc->getVirtualLine(realLine);
1356 ret.endCol = m_doc->lineLength(realLine);
1358 ret.endX = m_view->renderer()->textWidth(text, -1);
1364 ret.endCol = (int)m_view->renderer()->textWidth(text, previous ? previous->endCol : 0, width() - (previous ? previous->shiftX : 0), &ret.wrap, &ret.endX);
1366 Q_ASSERT(ret.endCol > ret.startCol);
1368 ret.line = realLine;
1371 ret.virtualLine = previous->virtualLine;
1372 ret.startCol = previous->endCol;
1373 ret.startX = previous->endX;
1374 ret.endX += previous->endX;
1375 ret.shiftX = previous->shiftX;
1376 ret.viewLine = previous->viewLine + 1;
1380 if (m_view->config()->dynWordWrapAlignIndent() > 0) {
1381 int pos = text->nextNonSpaceChar(0);
1384 ret.shiftX = m_view->renderer()->textWidth(text, pos);
1386 if (ret.shiftX > ((
double)width() / 100 * m_view->config()->dynWordWrapAlignIndent()))
1390 ret.virtualLine = m_doc->getVirtualLine(realLine);
1399 KateLineRange KateViewInternal::currentRange()
1403 return range(cursor);
1406 KateLineRange KateViewInternal::previousRange()
1408 uint currentViewLine = viewLine(cursor);
1410 if (currentViewLine)
1411 return range(cursor.line(), currentViewLine - 1);
1413 return range(m_doc->getRealLine(displayCursor.line() - 1), -1);
1416 KateLineRange KateViewInternal::nextRange()
1418 uint currentViewLine = viewLine(cursor) + 1;
1420 if (currentViewLine >= viewLineCount(cursor.line())) {
1421 currentViewLine = 0;
1422 return range(cursor.line() + 1, currentViewLine);
1424 return range(cursor.line(), currentViewLine);
1428 KateLineRange KateViewInternal::range(
const KateTextCursor& realCursor)
1432 KateLineRange thisRange;
1436 thisRange = range(realCursor.line(), first ? 0L : &thisRange);
1438 }
while (thisRange.wrap && !(realCursor.col() >= thisRange.startCol && realCursor.col() < thisRange.endCol) && thisRange.startCol != thisRange.endCol);
1443 KateLineRange KateViewInternal::range(uint realLine,
int viewLine)
1447 KateLineRange thisRange;
1451 thisRange = range(realLine, first ? 0L : &thisRange);
1453 }
while (thisRange.wrap && viewLine != thisRange.viewLine && thisRange.startCol != thisRange.endCol);
1455 if (viewLine != -1 && viewLine != thisRange.viewLine)
1456 kdDebug(13030) <<
"WARNING: viewLine " << viewLine <<
" of line " << realLine <<
" does not exist." <<
endl;
1466 uint KateViewInternal::viewLine(
const KateTextCursor& realCursor)
1468 if (!m_view->dynWordWrap())
return 0;
1470 if (realCursor.col() == 0)
return 0;
1472 KateLineRange thisRange;
1476 thisRange = range(realCursor.line(), first ? 0L : &thisRange);
1478 }
while (thisRange.wrap && !(realCursor.col() >= thisRange.startCol && realCursor.col() < thisRange.endCol) && thisRange.startCol != thisRange.endCol);
1480 return thisRange.viewLine;
1483 int KateViewInternal::displayViewLine(
const KateTextCursor& virtualCursor,
bool limitToVisible)
1487 int limit = linesDisplayed();
1490 if (!m_view->dynWordWrap()) {
1491 int ret = virtualCursor.line() - startLine();
1492 if (limitToVisible && (ret < 0 || ret > limit))
1498 if (work == virtualCursor) {
1502 int ret = -(int)viewLine(work);
1503 bool forwards = (work < virtualCursor) ?
true :
false;
1507 while (work.line() != virtualCursor.line()) {
1508 ret += viewLineCount(m_doc->getRealLine(work.line()));
1509 work.setLine(work.line() + 1);
1510 if (limitToVisible && ret > limit)
1514 while (work.line() != virtualCursor.line()) {
1515 work.setLine(work.line() - 1);
1516 ret -= viewLineCount(m_doc->getRealLine(work.line()));
1517 if (limitToVisible && ret < 0)
1524 realCursor.setLine(m_doc->getRealLine(realCursor.line()));
1525 if (realCursor.col() == -1) realCursor.setCol(m_doc->lineLength(realCursor.line()));
1526 ret += viewLine(realCursor);
1528 if (limitToVisible && (ret < 0 || ret > limit))
1534 uint KateViewInternal::lastViewLine(uint realLine)
1536 if (!m_view->dynWordWrap())
return 0;
1538 KateLineRange thisRange;
1542 thisRange = range(realLine, first ? 0L : &thisRange);
1544 }
while (thisRange.wrap && thisRange.startCol != thisRange.endCol);
1546 return thisRange.viewLine;
1549 uint KateViewInternal::viewLineCount(uint realLine)
1551 return lastViewLine(realLine) + 1;
1563 if (!m_view->dynWordWrap()) {
1564 KateTextCursor ret(kMin((
int)m_doc->visibleLines() - 1, virtualCursor.line() + offset), 0);
1570 int realLine = m_doc->getRealLine(ret.line());
1571 ret.setCol(m_doc->lineLength(realLine) - 1);
1573 if (m_currentMaxX > cXPos)
1574 cXPos = m_currentMaxX;
1576 if (m_view->wrapCursor())
1577 cXPos = kMin(cXPos, (
int)m_view->renderer()->textWidth(textLine(realLine), m_doc->lineLength(realLine)));
1579 m_view->renderer()->textWidth(ret, cXPos);
1586 realCursor.setLine(m_doc->getRealLine(virtualCursor.line()));
1588 uint cursorViewLine = viewLine(realCursor);
1590 int currentOffset = 0;
1591 int virtualLine = 0;
1593 bool forwards = (offset > 0) ?
true :
false;
1596 currentOffset = lastViewLine(realCursor.line()) - cursorViewLine;
1597 if (offset <= currentOffset) {
1599 KateLineRange thisRange = range(realCursor.line(), cursorViewLine + offset);
1600 Q_ASSERT(thisRange.virtualLine == virtualCursor.line());
1604 virtualLine = virtualCursor.line() + 1;
1608 currentOffset = cursorViewLine;
1609 if (offset <= currentOffset) {
1611 KateLineRange thisRange = range(realCursor.line(), cursorViewLine - offset);
1612 Q_ASSERT(thisRange.virtualLine == virtualCursor.line());
1616 virtualLine = virtualCursor.line() - 1;
1621 while (virtualLine >= 0 && virtualLine < (
int)m_doc->visibleLines())
1623 KateLineRange thisRange;
1625 int realLine = m_doc->getRealLine(virtualLine);
1628 thisRange = range(realLine, first ? 0L : &thisRange);
1631 if (offset == currentOffset) {
1634 int requiredViewLine = lastViewLine(realLine) - thisRange.viewLine;
1635 if (requiredViewLine != thisRange.viewLine) {
1636 thisRange = range(realLine, requiredViewLine);
1644 ret.setCol(thisRange.endCol - 1);
1645 KateTextCursor realCursorTemp(m_doc->getRealLine(virtualCursor.line()), virtualCursor.col());
1646 int visibleX = m_view->renderer()->textWidth(realCursorTemp) - range(realCursorTemp).startX;
1647 int xOffset = thisRange.startX;
1649 if (m_currentMaxX > visibleX)
1650 visibleX = m_currentMaxX;
1652 cXPos = xOffset + visibleX;
1654 cXPos = kMin(cXPos, lineMaxCursorX(thisRange));
1656 m_view->renderer()->textWidth(ret, cXPos);
1664 }
while (thisRange.wrap);
1675 return KateTextCursor(m_doc->visibleLines() - 1, m_doc->lineLength(m_doc->visibleLines() - 1));
1680 int KateViewInternal::lineMaxCursorX(
const KateLineRange& range)
1682 if (!m_view->wrapCursor() && !range.wrap)
1685 int maxX = range.endX;
1687 if (maxX && range.wrap) {
1688 TQChar lastCharInLine = textLine(range.line)->getChar(range.endCol - 1);
1690 if (lastCharInLine == TQChar(
'\t')) {
1692 int lastTabSize = 0;
1693 for(
int i = range.startCol; i < range.endCol; i++) {
1694 if (textLine(range.line)->getChar(i) == TQChar(
'\t')) {
1695 lastTabSize = m_view->tabWidth() - (lineSize % m_view->tabWidth());
1696 lineSize += lastTabSize;
1701 maxX -= lastTabSize * m_view->renderer()->spaceWidth();
1703 maxX -= m_view->renderer()->config()->fontMetrics()->width(lastCharInLine);
1710 int KateViewInternal::lineMaxCol(
const KateLineRange& range)
1712 int maxCol = range.endCol;
1714 if (maxCol && range.wrap)
1720 void KateViewInternal::cursorUp(
bool sel)
1722 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1723 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Up, 0, 0);
1724 m_view->m_codeCompletion->handleKey(&e);
1728 if (displayCursor.line() == 0 && (!m_view->dynWordWrap() || viewLine(cursor) == 0))
1731 int newLine = cursor.line(), newCol = 0, xOffset = 0, startCol = 0;
1732 m_preserveMaxX =
true;
1734 if (m_view->dynWordWrap()) {
1736 KateLineRange thisRange = currentRange();
1738 KateLineRange pRange = previousRange();
1741 Q_ASSERT((cursor.line() == thisRange.line) &&
1742 (cursor.col() >= thisRange.startCol) &&
1743 (!thisRange.wrap || cursor.col() < thisRange.endCol));
1746 int visibleX = m_view->renderer()->textWidth(cursor) - thisRange.startX;
1747 int currentLineVisibleX = visibleX;
1750 visibleX += thisRange.xOffset();
1751 visibleX -= pRange.xOffset();
1754 visibleX = kMax(0, visibleX);
1756 startCol = pRange.startCol;
1757 xOffset = pRange.startX;
1758 newLine = pRange.line;
1762 if (thisRange.xOffset() && !pRange.xOffset() && currentLineVisibleX == 0)
1763 visibleX = m_currentMaxX;
1764 else if (visibleX < m_currentMaxX - pRange.xOffset())
1765 visibleX = m_currentMaxX - pRange.xOffset();
1767 cXPos = xOffset + visibleX;
1769 cXPos = kMin(cXPos, lineMaxCursorX(pRange));
1771 newCol = kMin((
int)m_view->renderer()->textPos(newLine, visibleX, startCol), lineMaxCol(pRange));
1774 newLine = m_doc->getRealLine(displayCursor.line() - 1);
1776 if ((m_view->wrapCursor()) && m_currentMaxX > cXPos)
1777 cXPos = m_currentMaxX;
1781 m_view->renderer()->textWidth(c, cXPos);
1783 updateSelection( c, sel );
1787 void KateViewInternal::cursorDown(
bool sel)
1789 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1790 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Down, 0, 0);
1791 m_view->m_codeCompletion->handleKey(&e);
1795 if ((displayCursor.line() >= (
int)m_doc->numVisLines() - 1) && (!m_view->dynWordWrap() || viewLine(cursor) == lastViewLine(cursor.line())))
1798 int newLine = cursor.line(), newCol = 0, xOffset = 0, startCol = 0;
1799 m_preserveMaxX =
true;
1801 if (m_view->dynWordWrap()) {
1803 KateLineRange thisRange = currentRange();
1805 KateLineRange nRange = nextRange();
1808 Q_ASSERT((cursor.line() == thisRange.line) &&
1809 (cursor.col() >= thisRange.startCol) &&
1810 (!thisRange.wrap || cursor.col() < thisRange.endCol));
1813 int visibleX = m_view->renderer()->textWidth(cursor) - thisRange.startX;
1814 int currentLineVisibleX = visibleX;
1817 visibleX += thisRange.xOffset();
1818 visibleX -= nRange.xOffset();
1821 visibleX = kMax(0, visibleX);
1823 if (!thisRange.wrap) {
1824 newLine = m_doc->getRealLine(displayCursor.line() + 1);
1826 startCol = thisRange.endCol;
1827 xOffset = thisRange.endX;
1832 if (thisRange.xOffset() && !nRange.xOffset() && currentLineVisibleX == 0)
1833 visibleX = m_currentMaxX;
1834 else if (visibleX < m_currentMaxX - nRange.xOffset())
1835 visibleX = m_currentMaxX - nRange.xOffset();
1837 cXPos = xOffset + visibleX;
1839 cXPos = kMin(cXPos, lineMaxCursorX(nRange));
1841 newCol = kMin((
int)m_view->renderer()->textPos(newLine, visibleX, startCol), lineMaxCol(nRange));
1844 newLine = m_doc->getRealLine(displayCursor.line() + 1);
1846 if ((m_view->wrapCursor()) && m_currentMaxX > cXPos)
1847 cXPos = m_currentMaxX;
1851 m_view->renderer()->textWidth(c, cXPos);
1853 updateSelection(c, sel);
1857 void KateViewInternal::cursorToMatchingBracket(
bool sel )
1861 if( !m_doc->findMatchingBracket( start, end ) )
1868 end.setCol(
end.col() + 1);
1870 updateSelection( end, sel );
1871 updateCursor( end );
1874 void KateViewInternal::topOfView(
bool sel )
1876 KateTextCursor c = viewLineOffset(startPos(), m_minLinesVisible);
1877 updateSelection( c, sel );
1881 void KateViewInternal::bottomOfView(
bool sel )
1885 updateSelection( c, sel );
1890 void KateViewInternal::scrollLines(
int lines,
bool sel )
1895 c.setLine(m_doc->getRealLine(c.line()));
1897 updateSelection( c, sel );
1902 void KateViewInternal::scrollUp()
1908 void KateViewInternal::scrollDown()
1914 void KateViewInternal::setAutoCenterLines(
int viewLines,
bool updateView)
1916 m_autoCenterLines = viewLines;
1917 m_minLinesVisible = kMin(
int((linesDisplayed() - 1)/2), m_autoCenterLines);
1919 KateViewInternal::updateView();
1922 void KateViewInternal::pageUp(
bool sel )
1924 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1925 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_PageUp, 0, 0);
1926 m_view->m_codeCompletion->handleKey(&e);
1931 int viewLine = displayViewLine(displayCursor);
1932 bool atTop = (startPos().line() == 0 && startPos().col() == 0);
1935 int lineadj = 2 * m_minLinesVisible;
1936 int cursorStart = (linesDisplayed() - 1) - viewLine;
1937 if (cursorStart < m_minLinesVisible)
1938 lineadj -= m_minLinesVisible - cursorStart;
1940 int linesToScroll = -kMax( ((
int)linesDisplayed() - 1) - lineadj, 0 );
1941 m_preserveMaxX =
true;
1943 if (!m_doc->pageUpDownMovesCursor () && !atTop) {
1944 int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
1946 KateTextCursor newStartPos = viewLineOffset(startPos(), linesToScroll - 1);
1947 scrollPos(newStartPos);
1950 KateTextCursor newPos = viewLineOffset(newStartPos, viewLine,
true);
1951 newPos.setLine(m_doc->getRealLine(newPos.line()));
1953 KateLineRange newLine = range(newPos);
1955 if (m_currentMaxX - newLine.xOffset() > xPos)
1956 xPos = m_currentMaxX - newLine.xOffset();
1958 cXPos = kMin(newLine.startX + xPos, lineMaxCursorX(newLine));
1960 m_view->renderer()->textWidth( newPos, cXPos );
1962 m_preserveMaxX =
true;
1963 updateSelection( newPos, sel );
1964 updateCursor(newPos);
1967 scrollLines( linesToScroll, sel );
1971 void KateViewInternal::pageDown(
bool sel )
1973 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1974 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_PageDown, 0, 0);
1975 m_view->m_codeCompletion->handleKey(&e);
1980 int viewLine = displayViewLine(displayCursor);
1981 bool atEnd = startPos() >= m_cachedMaxStartPos;
1984 int lineadj = 2 * m_minLinesVisible;
1985 int cursorStart = m_minLinesVisible - viewLine;
1986 if (cursorStart > 0)
1987 lineadj -= cursorStart;
1989 int linesToScroll = kMax( ((
int)linesDisplayed() - 1) - lineadj, 0 );
1990 m_preserveMaxX =
true;
1992 if (!m_doc->pageUpDownMovesCursor () && !atEnd) {
1993 int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
1995 KateTextCursor newStartPos = viewLineOffset(startPos(), linesToScroll + 1);
1996 scrollPos(newStartPos);
1999 KateTextCursor newPos = viewLineOffset(newStartPos, viewLine,
true);
2000 newPos.setLine(m_doc->getRealLine(newPos.line()));
2002 KateLineRange newLine = range(newPos);
2004 if (m_currentMaxX - newLine.xOffset() > xPos)
2005 xPos = m_currentMaxX - newLine.xOffset();
2007 cXPos = kMin(newLine.startX + xPos, lineMaxCursorX(newLine));
2009 m_view->renderer()->textWidth( newPos, cXPos );
2011 m_preserveMaxX =
true;
2012 updateSelection( newPos, sel );
2013 updateCursor(newPos);
2016 scrollLines( linesToScroll, sel );
2020 int KateViewInternal::maxLen(uint startLine)
2024 int displayLines = (m_view->height() / m_view->renderer()->fontHeight()) + 1;
2028 for (
int z = 0; z < displayLines; z++) {
2029 int virtualLine = startLine + z;
2031 if (virtualLine < 0 || virtualLine >= (
int)m_doc->visibleLines())
2034 KateLineRange thisRange = range((
int)m_doc->getRealLine(virtualLine));
2036 maxLen = kMax(maxLen, thisRange.endX);
2042 void KateViewInternal::top(
bool sel )
2045 m_view->renderer()->textWidth( c, cXPos );
2046 updateSelection( c, sel );
2050 void KateViewInternal::bottom(
bool sel )
2053 m_view->renderer()->textWidth( c, cXPos );
2054 updateSelection( c, sel );
2058 void KateViewInternal::top_home(
bool sel )
2060 if (m_view->m_codeCompletion->codeCompletionVisible()) {
2061 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Home, 0, 0);
2062 m_view->m_codeCompletion->handleKey(&e);
2066 updateSelection( c, sel );
2070 void KateViewInternal::bottom_end(
bool sel )
2072 if (m_view->m_codeCompletion->codeCompletionVisible()) {
2073 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_End, 0, 0);
2074 m_view->m_codeCompletion->handleKey(&e);
2077 KateTextCursor c( m_doc->lastLine(), m_doc->lineLength( m_doc->lastLine() ) );
2078 updateSelection( c, sel );
2082 void KateViewInternal::updateSelection(
const KateTextCursor& _newCursor,
bool keepSel )
2087 if ( !m_view->hasSelection() || (selectAnchor.line() == -1)
2088 || (m_view->config()->persistentSelection()
2089 && ((cursor < m_view->selectStart) || (cursor > m_view->selectEnd))) )
2091 selectAnchor = cursor;
2092 m_view->setSelection( cursor, newCursor );
2096 bool doSelect =
true;
2097 switch (m_selectionMode)
2108 if ( selStartCached.line() == -1 )
2109 selStartCached = selEndCached;
2112 if ( newCursor > selEndCached )
2114 selectAnchor = selStartCached;
2118 c = newCursor.col();
2119 if ( c > 0 && m_doc->highlight()->isInWord( l->getChar( c-1 ) ) ) {
2120 for (; c < l->length(); c++ )
2121 if ( !m_doc->highlight()->isInWord( l->getChar( c ) ) )
2125 newCursor.setCol( c );
2127 else if ( newCursor < selStartCached )
2129 selectAnchor = selEndCached;
2133 c = newCursor.col();
2134 if ( c > 0 && c < m_doc->textLine( newCursor.line() ).length()
2135 && m_doc->highlight()->isInWord( l->getChar( c ) )
2136 && m_doc->highlight()->isInWord( l->getChar( c-1 ) ) ) {
2137 for ( c -= 2; c >= 0; c-- )
2138 if ( !m_doc->highlight()->isInWord( l->getChar( c ) ) )
2140 newCursor.setCol( c+1 );
2150 if ( newCursor.line() > selStartCached.line() )
2152 if ( newCursor.line()+1 >= m_doc->numLines() )
2153 newCursor.setCol( m_doc->textLine( newCursor.line() ).length() );
2155 newCursor.setPos( newCursor.line() + 1, 0 );
2157 selectAnchor = selStartCached;
2158 selectAnchor.setCol( 0 );
2160 else if ( newCursor.line() < selStartCached.line() )
2162 newCursor.setCol( 0 );
2164 selectAnchor = selEndCached;
2165 if ( selectAnchor.col() > 0 )
2167 if ( selectAnchor.line()+1 >= m_doc->numLines() )
2168 selectAnchor.setCol( m_doc->textLine( selectAnchor.line() ).length() );
2170 selectAnchor.setPos( selectAnchor.line() + 1, 0 );
2178 if ( selStartCached.line() < 0 )
2181 if ( newCursor > selEndCached )
2182 selectAnchor = selStartCached;
2183 else if ( newCursor < selStartCached )
2184 selectAnchor = selEndCached;
2191 if ( selectAnchor.line() < 0 )
2197 m_view->setSelection( selectAnchor, newCursor);
2198 else if ( selStartCached.line() >= 0 )
2199 m_view->setSelection( selStartCached, selEndCached );
2202 m_selChangedByUser =
true;
2204 else if ( !m_view->config()->persistentSelection() )
2206 m_view->clearSelection();
2207 selStartCached.setLine( -1 );
2208 selectAnchor.setLine( -1 );
2212 void KateViewInternal::updateCursor(
const KateTextCursor& newCursor,
bool force,
bool center,
bool calledExternally )
2214 if ( !force && (cursor == newCursor) )
2216 if ( !m_madeVisible && m_view == m_doc->activeView() )
2219 m_doc->foldingTree()->ensureVisible( newCursor.line() );
2221 makeVisible ( displayCursor, displayCursor.col(),
false, center, calledExternally );
2228 m_doc->foldingTree()->ensureVisible( newCursor.line() );
2232 cursor.setPos (newCursor);
2233 displayCursor.setPos (m_doc->getVirtualLine(cursor.line()), cursor.col());
2235 cXPos = m_view->renderer()->textWidth( cursor );
2236 if (m_view == m_doc->activeView())
2237 makeVisible ( displayCursor, displayCursor.col(),
false, center, calledExternally );
2239 updateBracketMarks();
2242 tagLine(oldDisplayCursor);
2243 tagLine(displayCursor);
2245 updateMicroFocusHint();
2247 if (m_cursorTimer.isActive ())
2249 if ( TDEApplication::cursorFlashTime() > 0 )
2250 m_cursorTimer.start( TDEApplication::cursorFlashTime() / 2 );
2251 m_view->renderer()->setDrawCaret(
true);
2256 m_preserveMaxX =
false;
2258 if (m_view->dynWordWrap())
2259 m_currentMaxX = m_view->renderer()->textWidth(displayCursor) - currentRange().startX + currentRange().xOffset();
2261 m_currentMaxX = cXPos;
2266 paintText(0, 0, width(), height(),
true);
2268 emit m_view->cursorPositionChanged();
2271 void KateViewInternal::updateBracketMarks()
2273 if ( bm.isValid() ) {
2274 KateTextCursor bmStart(m_doc->getVirtualLine(bm.start().line()), bm.start().col());
2275 KateTextCursor bmEnd(m_doc->getVirtualLine(bm.end().line()), bm.end().col());
2277 if( bm.getMinIndent() != 0 )
2280 if( bmStart > bmEnd )
2282 tagLines(bmEnd, bmStart);
2286 tagLines(bmStart, bmEnd);
2297 int maxLines = linesDisplayed () * 3;
2298 m_doc->newBracketMark( cursor, bm, maxLines );
2300 if ( bm.isValid() ) {
2301 KateTextCursor bmStart(m_doc->getVirtualLine(bm.start().line()), bm.start().col());
2302 KateTextCursor bmEnd(m_doc->getVirtualLine(bm.end().line()), bm.end().col());
2304 if( bm.getMinIndent() != 0 )
2307 if( bmStart > bmEnd )
2309 tagLines(bmEnd, bmStart);
2313 tagLines(bmStart, bmEnd);
2324 bool KateViewInternal::tagLine(
const KateTextCursor& virtualCursor)
2326 int viewLine = displayViewLine(virtualCursor,
true);
2327 if (viewLine >= 0 && viewLine < (
int)lineRanges.count()) {
2328 lineRanges[viewLine].dirty =
true;
2329 leftBorder->update (0, lineToY(viewLine), leftBorder->width(), m_view->renderer()->fontHeight());
2335 bool KateViewInternal::tagLines(
int start,
int end,
bool realLines )
2345 start.setLine(m_doc->getVirtualLine( start.line() ));
2346 end.setLine(m_doc->getVirtualLine(
end.line() ));
2349 if (
end.line() < (
int)startLine())
2354 if (start.line() > (
int)endLine())
2364 for (uint z = 0; z < lineRanges.size(); z++)
2366 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)))) {
2367 ret = lineRanges[z].dirty =
true;
2372 if (!m_view->dynWordWrap())
2374 int y = lineToY( start.line() );
2376 int h = (
end.line() - start.line() + 2) * m_view->renderer()->fontHeight();
2377 if (
end.line() == (int)m_doc->numVisLines() - 1)
2380 leftBorder->update (0, y, leftBorder->width(), h);
2386 for (uint z = 0; z < lineRanges.size(); z++)
2388 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))))
2391 leftBorder->update (0, z * m_view->renderer()->fontHeight(), leftBorder->width(), leftBorder->height());
2406 void KateViewInternal::tagAll()
2409 for (uint z = 0; z < lineRanges.size(); z++)
2411 lineRanges[z].dirty =
true;
2414 leftBorder->updateFont();
2415 leftBorder->update ();
2418 void KateViewInternal::paintCursor()
2420 if (tagLine(displayCursor))
2421 paintText (0,0,width(), height(),
true);
2425 void KateViewInternal::placeCursor(
const TQPoint& p,
bool keepSelection,
bool updateSelection )
2427 KateLineRange thisRange = yToKateLineRange(p.y());
2429 if (thisRange.line == -1) {
2430 for (
int i = (p.y() / m_view->renderer()->fontHeight()); i >= 0; i--) {
2431 thisRange = lineRanges[i];
2432 if (thisRange.line != -1)
2435 Q_ASSERT(thisRange.line != -1);
2438 int realLine = thisRange.line;
2439 int visibleLine = thisRange.virtualLine;
2440 uint startCol = thisRange.startCol;
2442 visibleLine = kMax( 0, kMin( visibleLine,
int(m_doc->numVisLines()) - 1 ) );
2446 int x = kMin(kMax(-m_startX, p.x() - thisRange.xOffset()), lineMaxCursorX(thisRange) - thisRange.startX);
2448 m_view->renderer()->textWidth( c, startX() + x, startCol);
2450 if (updateSelection)
2451 KateViewInternal::updateSelection( c, keepSelection );
2457 bool KateViewInternal::isTargetSelected(
const TQPoint& p )
2459 KateLineRange thisRange = yToKateLineRange(p.y());
2465 int col = m_view->renderer()->textPos( l, startX() + p.x() - thisRange.xOffset(), thisRange.startCol,
false );
2467 return m_view->lineColSelected( thisRange.line, col );
2472 bool KateViewInternal::eventFilter( TQObject *obj, TQEvent *e )
2474 if (obj == m_lineScroll)
2477 if (e->type() == TQEvent::Wheel && m_lineScroll->minValue() != m_lineScroll->maxValue())
2479 wheelEvent((TQWheelEvent*)e);
2484 return TQWidget::eventFilter( obj, e );
2489 case TQEvent::KeyPress:
2491 TQKeyEvent *k = (TQKeyEvent *)e;
2493 if (m_view->m_codeCompletion->codeCompletionVisible ())
2497 if( k->key() == Key_Escape )
2498 m_view->m_codeCompletion->abortCompletion();
2501 if ((k->key() == TQt::Key_Escape) && !m_view->config()->persistentSelection() )
2503 m_view->clearSelection();
2506 else if ( !((k->state() & ControlButton) || (k->state() & AltButton)) )
2509 return k->isAccepted();
2514 case TQEvent::DragMove:
2516 TQPoint currentPoint = ((TQDragMoveEvent*) e)->pos();
2518 TQRect doNotScrollRegion( scrollMargin, scrollMargin,
2519 width() - scrollMargin * 2,
2520 height() - scrollMargin * 2 );
2522 if ( !doNotScrollRegion.contains( currentPoint ) )
2526 ( (TQDragMoveEvent*)e )->accept( TQRect(0,0,0,0) );
2529 dragMoveEvent((TQDragMoveEvent*)e);
2532 case TQEvent::DragLeave:
2537 case TQEvent::WindowBlocked:
2540 m_doc->m_isasking = -1;
2547 return TQWidget::eventFilter( obj, e );
2550 void KateViewInternal::keyPressEvent( TQKeyEvent* e )
2554 bool codeComp = m_view->m_codeCompletion->codeCompletionVisible ();
2560 if( e->key() == Key_Enter || e->key() == Key_Return ||
2561 (key == SHIFT + TQt::Key_Return) || (key == SHIFT + TQt::Key_Enter)) {
2562 m_view->m_codeCompletion->doComplete();
2568 if( !m_doc->isReadWrite() )
2574 if ((key == TQt::Key_Return) || (key == TQt::Key_Enter))
2576 m_view->keyReturn();
2581 if ((key == SHIFT + TQt::Key_Return) || (key == SHIFT + TQt::Key_Enter))
2583 uint ln = cursor.line();
2584 int col = cursor.col();
2586 int pos = line->firstChar();
2587 if (pos > cursor.col()) pos = cursor.col();
2589 while ((
int)line->length() > pos &&
2590 !line->getChar(pos).isLetterOrNumber() &&
2591 pos < cursor.col()) ++pos;
2593 pos = line->length();
2596 m_doc->insertText( cursor.line(), line->length(),
"\n" + line->string(0, pos)
2597 + line->string().right( line->length() - cursor.col() ) );
2598 cursor.setPos(ln + 1, pos);
2599 if (col <
int(line->length()))
2600 m_doc->editRemoveText(ln, col, line->length() - col);
2602 updateCursor(cursor,
true);
2609 if (key == TQt::Key_Backspace || key == SHIFT + TQt::Key_Backspace)
2611 m_view->backspace();
2615 m_view->m_codeCompletion->updateBox ();
2620 if (key == TQt::Key_Tab || key == SHIFT+TQt::Key_Backtab || key == TQt::Key_Backtab)
2622 if (m_doc->invokeTabInterceptor(key)) {
2626 if (m_doc->configFlags() & KateDocumentConfig::cfTabIndents)
2628 if( key == TQt::Key_Tab )
2630 if (m_view->hasSelection() || (m_doc->configFlags() & KateDocumentConfig::cfTabIndentsMode))
2631 m_doc->indent( m_view, cursor.line(), 1 );
2632 else if (m_doc->configFlags() & KateDocumentConfig::cfTabInsertsTab)
2633 m_doc->typeChars ( m_view, TQString (
"\t") );
2635 m_doc->insertIndentChars ( m_view );
2640 m_view->m_codeCompletion->updateBox ();
2645 if (key == SHIFT+TQt::Key_Backtab || key == TQt::Key_Backtab)
2647 m_doc->indent( m_view, cursor.line(), -1 );
2651 m_view->m_codeCompletion->updateBox ();
2657 if ( !(e->state() & ControlButton) && !(e->state() & AltButton)
2658 && m_doc->typeChars ( m_view, e->text() ) )
2663 m_view->m_codeCompletion->updateBox ();
2671 void KateViewInternal::keyReleaseEvent( TQKeyEvent* e )
2676 m_shiftKeyPressed =
true;
2679 if (m_shiftKeyPressed)
2681 m_shiftKeyPressed =
false;
2683 if (m_selChangedByUser)
2685 TQApplication::clipboard()->setSelectionMode(
true );
2687 TQApplication::clipboard()->setSelectionMode(
false );
2689 m_selChangedByUser =
false;
2698 void KateViewInternal::contextMenuEvent ( TQContextMenuEvent * e )
2702 TQPoint p = e->pos();
2704 if ( m_view->m_doc->browserView() )
2706 m_view->contextMenuEvent( e );
2710 if ( e->reason() == TQContextMenuEvent::Keyboard )
2712 makeVisible( cursor, 0 );
2713 p = cursorCoordinates();
2715 else if ( ! m_view->hasSelection() || m_view->config()->persistentSelection() )
2716 placeCursor( e->pos() );
2719 if (m_view->popup()) {
2720 m_view->popup()->popup( mapToGlobal( p ) );
2725 void KateViewInternal::mousePressEvent( TQMouseEvent* e )
2727 switch (e->button())
2729 case TQt::LeftButton:
2730 m_selChangedByUser =
false;
2732 if (possibleTripleClick)
2734 possibleTripleClick =
false;
2736 m_selectionMode = Line;
2738 if ( e->state() & TQt::ShiftButton )
2740 updateSelection( cursor,
true );
2744 m_view->selectLine( cursor );
2747 TQApplication::clipboard()->setSelectionMode(
true );
2749 TQApplication::clipboard()->setSelectionMode(
false );
2753 if ( selectAnchor.line() > m_view->selectStart.line() )
2756 if ( selectAnchor == m_view->selectEnd && selectAnchor.col() == 0 )
2760 selEndCached = m_view->selectEnd;
2765 selStartCached = m_view->selectStart;
2766 if ( m_view->selectEnd.line() > m_view->selectStart.line() )
2767 selEndCached =
KateTextCursor( m_view->selectStart.line()+1, 0 );
2769 selEndCached = m_view->selectEnd;
2774 if ( m_view->selectStart < selectAnchor
2775 && selectAnchor.line() != m_view->selectStart.line() )
2776 updateCursor( m_view->selectStart );
2778 updateCursor( m_view->selectEnd );
2783 else if (m_selectionMode == Default)
2785 m_selectionMode = Mouse;
2788 if ( e->state() & TQt::ShiftButton )
2790 if (selectAnchor.line() < 0)
2791 selectAnchor = cursor;
2795 selStartCached.setLine( -1 );
2798 if( !( e->state() & TQt::ShiftButton ) && isTargetSelected( e->pos() ) )
2800 dragInfo.state = diPending;
2801 dragInfo.start = e->pos();
2805 dragInfo.state = diNone;
2807 if ( e->state() & TQt::ShiftButton )
2809 placeCursor( e->pos(),
true,
false );
2810 if ( selStartCached.line() >= 0 )
2812 if ( cursor > selEndCached )
2814 m_view->setSelection( selStartCached, cursor );
2815 selectAnchor = selStartCached;
2817 else if ( cursor < selStartCached )
2819 m_view->setSelection( cursor, selEndCached );
2820 selectAnchor = selEndCached;
2824 m_view->setSelection( selStartCached, cursor );
2829 m_view->setSelection( selectAnchor, cursor );
2834 placeCursor( e->pos() );
2840 m_scrollTimer.start (50);
2852 void KateViewInternal::mouseDoubleClickEvent(TQMouseEvent *e)
2854 switch (e->button())
2856 case TQt::LeftButton:
2857 m_selectionMode = Word;
2859 if ( e->state() & TQt::ShiftButton )
2868 ce = selectAnchor.col();
2869 if ( ce > 0 && m_doc->highlight()->isInWord( l->getChar( ce ) ) ) {
2870 for (; ce < l->length(); ce++ )
2871 if ( !m_doc->highlight()->isInWord( l->getChar( ce ) ) )
2875 cs = selectAnchor.col() - 1;
2876 if ( cs < m_doc->textLine( selectAnchor.line() ).length()
2877 && m_doc->highlight()->isInWord( l->getChar( cs ) ) ) {
2878 for ( cs--; cs >= 0; cs-- )
2879 if ( !m_doc->highlight()->isInWord( l->getChar( cs ) ) )
2891 selStartCached = selectAnchor;
2892 selEndCached = selectAnchor;
2895 placeCursor( e->pos(),
true );
2906 m_view->clearSelection(
false,
false );
2907 placeCursor( e->pos() );
2908 m_view->selectWord( cursor );
2909 if (m_view->hasSelection())
2911 selectAnchor = selStartCached = m_view->selectStart;
2912 selEndCached = m_view->selectEnd;
2918 m_selectionMode = Default;
2923 if (m_view->hasSelection())
2925 TQApplication::clipboard()->setSelectionMode(
true );
2927 TQApplication::clipboard()->setSelectionMode(
false );
2931 if (m_view->selectStart < selStartCached)
2932 updateCursor( m_view->selectStart );
2934 updateCursor( m_view->selectEnd );
2937 possibleTripleClick =
true;
2938 TQTimer::singleShot ( TQApplication::doubleClickInterval(),
this, TQ_SLOT(tripleClickTimeout()) );
2943 m_scrollTimer.start (50);
2954 void KateViewInternal::tripleClickTimeout()
2956 possibleTripleClick =
false;
2959 void KateViewInternal::mouseReleaseEvent( TQMouseEvent* e )
2961 switch (e->button())
2963 case TQt::LeftButton:
2964 m_selectionMode = Default;
2967 if (m_selChangedByUser)
2969 TQApplication::clipboard()->setSelectionMode(
true );
2971 TQApplication::clipboard()->setSelectionMode(
false );
2974 if ( m_view->selectStart < selectAnchor )
2975 updateCursor( m_view->selectStart );
2977 updateCursor( m_view->selectEnd );
2979 m_selChangedByUser =
false;
2982 if (dragInfo.state == diPending)
2983 placeCursor( e->pos(), e->state() & ShiftButton );
2984 else if (dragInfo.state == diNone)
2985 m_scrollTimer.stop ();
2987 dragInfo.state = diNone;
2992 case TQt::MidButton:
2993 placeCursor( e->pos() );
2995 if( m_doc->isReadWrite() )
2997 TQApplication::clipboard()->setSelectionMode(
true );
2999 TQApplication::clipboard()->setSelectionMode(
false );
3011 void KateViewInternal::mouseMoveEvent( TQMouseEvent* e )
3013 if( e->state() & TQt::LeftButton )
3015 if (dragInfo.state == diPending)
3019 TQPoint p( e->pos() - dragInfo.start );
3027 else if (dragInfo.state == diDragging)
3039 int d = m_view->renderer()->fontHeight();
3044 if (mouseX > width())
3053 if (mouseY > height())
3059 placeCursor( TQPoint( mouseX, mouseY ),
true );
3064 if (isTargetSelected( e->pos() ) ) {
3067 if (m_mouseCursor != ArrowCursor) {
3069 m_mouseCursor = TQt::ArrowCursor;
3073 if (m_mouseCursor != IbeamCursor) {
3075 m_mouseCursor = TQt::IbeamCursor;
3079 if (m_textHintEnabled)
3081 m_textHintTimer.start(m_textHintTimeout);
3082 m_textHintMouseX=e->x();
3083 m_textHintMouseY=e->y();
3088 void KateViewInternal::paintEvent(TQPaintEvent *e)
3090 paintText(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
3093 void KateViewInternal::resizeEvent(TQResizeEvent* e)
3095 bool expandedHorizontally = width() > e->oldSize().width();
3096 bool expandedVertically = height() > e->oldSize().height();
3097 bool heightChanged = height() != e->oldSize().height();
3099 m_madeVisible =
false;
3101 if (heightChanged) {
3102 setAutoCenterLines(m_autoCenterLines,
false);
3103 m_cachedMaxStartPos.setPos(-1, -1);
3106 if (m_view->dynWordWrap()) {
3107 bool dirtied =
false;
3109 for (uint i = 0; i < lineRanges.count(); i++) {
3112 if (lineRanges[i].wrap ||
3113 (!expandedHorizontally && (lineRanges[i].endX - lineRanges[i].startX) > width())) {
3114 dirtied = lineRanges[i].dirty =
true;
3119 if (dirtied || heightChanged) {
3121 leftBorder->update();
3124 if (width() < e->oldSize().width()) {
3125 if (!m_view->wrapCursor()) {
3127 if (cursor.col() > m_doc->lineLength(cursor.line())) {
3128 KateLineRange thisRange = currentRange();
3130 KateTextCursor newCursor(cursor.line(), thisRange.endCol + ((width() - thisRange.xOffset() - (thisRange.endX - thisRange.startX)) / m_view->renderer()->spaceWidth()) - 1);
3131 updateCursor(newCursor);
3139 if (expandedHorizontally && startX() > 0)
3140 scrollColumns(startX() - (width() - e->oldSize().width()));
3143 if (expandedVertically) {
3145 if (startPos() > max)
3150 void KateViewInternal::scrollTimeout ()
3152 if (scrollX || scrollY)
3154 scrollLines (startPos().line() + (scrollY / (
int)m_view->renderer()->fontHeight()));
3155 placeCursor( TQPoint( mouseX, mouseY ),
true );
3159 void KateViewInternal::cursorTimeout ()
3161 m_view->renderer()->setDrawCaret(!m_view->renderer()->drawCaret());
3165 void KateViewInternal::textHintTimeout ()
3167 m_textHintTimer.stop ();
3169 KateLineRange thisRange = yToKateLineRange(m_textHintMouseY);
3171 if (thisRange.line == -1)
return;
3173 if (m_textHintMouseX> (lineMaxCursorX(thisRange) - thisRange.startX))
return;
3175 int realLine = thisRange.line;
3176 int startCol = thisRange.startCol;
3179 m_view->renderer()->textWidth( c, startX() + m_textHintMouseX, startCol);
3183 emit m_view->needTextHint(c.line(), c.col(), tmp);
3185 if (!tmp.isEmpty())
kdDebug(13030)<<
"Hint text: "<<tmp<<
endl;
3188 void KateViewInternal::focusInEvent (TQFocusEvent *)
3190 if (TDEApplication::cursorFlashTime() > 0)
3191 m_cursorTimer.start ( TDEApplication::cursorFlashTime() / 2 );
3193 if (m_textHintEnabled)
3194 m_textHintTimer.start( m_textHintTimeout );
3198 m_doc->setActiveView( m_view );
3200 emit m_view->gotFocus( m_view );
3203 void KateViewInternal::focusOutEvent (TQFocusEvent *)
3205 if( m_view->renderer() && ! m_view->m_codeCompletion->codeCompletionVisible() )
3207 m_cursorTimer.stop();
3209 m_view->renderer()->setDrawCaret(
true);
3211 emit m_view->lostFocus( m_view );
3214 m_textHintTimer.stop();
3217 void KateViewInternal::doDrag()
3219 dragInfo.state = diDragging;
3220 dragInfo.dragObject =
new TQTextDrag(m_view->selection(),
this);
3221 dragInfo.dragObject->drag();
3224 void KateViewInternal::dragEnterEvent( TQDragEnterEvent* event )
3226 event->accept( (TQTextDrag::canDecode(event) && m_doc->isReadWrite()) ||
3227 KURLDrag::canDecode(event) );
3230 void KateViewInternal::dragMoveEvent( TQDragMoveEvent* event )
3233 placeCursor(
event->pos(),
true,
false );
3237 event->acceptAction();
3240 void KateViewInternal::dropEvent( TQDropEvent* event )
3242 if ( KURLDrag::canDecode(event) ) {
3244 emit dropEventPass(event);
3246 }
else if ( TQTextDrag::canDecode(event) && m_doc->isReadWrite() ) {
3250 if (!TQTextDrag::decode(event, text))
3255 if (
event->source() &&
event->source()->inherits(
"KateViewInternal"))
3256 priv = m_doc->ownedView( ((KateViewInternal*)(
event->source()))->m_view );
3259 bool selected = isTargetSelected(
event->pos() );
3261 if( priv && selected ) {
3268 m_doc->editStart ();
3271 if (
event->action() != TQDropEvent::Copy )
3272 m_view->removeSelectedText();
3274 m_doc->insertText( cursor.line(), cursor.col(), text );
3278 placeCursor(
event->pos() );
3280 event->acceptAction();
3285 dragInfo.state = diNone;
3291 void KateViewInternal::clear()
3293 cursor.setPos(0, 0);
3294 displayCursor.setPos(0, 0);
3297 void KateViewInternal::wheelEvent(TQWheelEvent* e)
3299 if (e->state() & ControlButton)
3312 if (m_lineScroll->minValue() != m_lineScroll->maxValue() && e->orientation() != TQt::Horizontal)
3315 if ( e->state() & ShiftButton )
3324 scrollViewLines(-((e->delta() / 120) * TQApplication::wheelScrollLines()));
3327 leftBorder->update();
3329 }
else if (columnScrollingPossible()) {
3330 TQWheelEvent
copy = *e;
3331 TQApplication::sendEvent(m_columnScroll, ©);
3339 void KateViewInternal::startDragScroll()
3341 if ( !m_dragScrollTimer.isActive() ) {
3342 m_dragScrollTimer.start( scrollTime );
3346 void KateViewInternal::stopDragScroll()
3348 m_dragScrollTimer.stop();
3352 void KateViewInternal::doDragScroll()
3354 TQPoint p = this->mapFromGlobal( TQCursor::pos() );
3357 if ( p.y() < scrollMargin ) {
3358 dy = p.y() - scrollMargin;
3359 }
else if ( p.y() > height() - scrollMargin ) {
3360 dy = scrollMargin - (height() - p.y());
3363 if ( p.x() < scrollMargin ) {
3364 dx = p.x() - scrollMargin;
3365 }
else if ( p.x() > width() - scrollMargin ) {
3366 dx = scrollMargin - (width() - p.x());
3372 scrollLines(startPos().line() + dy);
3374 if (columnScrollingPossible () && dx)
3375 scrollColumns(kMin (m_startX + dx, m_columnScroll->maxValue()));
3381 void KateViewInternal::enableTextHints(
int timeout)
3383 m_textHintTimeout=timeout;
3384 m_textHintEnabled=
true;
3385 m_textHintTimer.start(timeout);
3388 void KateViewInternal::disableTextHints()
3390 m_textHintEnabled=
false;
3391 m_textHintTimer.stop ();
3394 bool KateViewInternal::columnScrollingPossible ()
3396 return !m_view->dynWordWrap() && m_columnScroll->isEnabled() && (m_columnScroll->maxValue() > 0);
3400 void KateViewInternal::editStart()
3402 editSessionNumber++;
3404 if (editSessionNumber > 1)
3407 editIsRunning =
true;
3408 editOldCursor = cursor;
3411 void KateViewInternal::editEnd(
int editTagLineStart,
int editTagLineEnd,
bool tagFrom)
3413 if (editSessionNumber == 0)
3416 editSessionNumber--;
3418 if (editSessionNumber > 0)
3421 if (tagFrom && (editTagLineStart <=
int(m_doc->getRealLine(startLine()))))
3424 tagLines (editTagLineStart, tagFrom ? m_doc->lastLine() : editTagLineEnd,
true);
3426 if (editOldCursor == cursor)
3427 updateBracketMarks();
3429 if (m_imPreeditLength <= 0)
3432 if ((editOldCursor != cursor) && (m_imPreeditLength <= 0))
3434 m_madeVisible =
false;
3435 updateCursor ( cursor,
true );
3437 else if ( m_view == m_doc->activeView() )
3439 makeVisible(displayCursor, displayCursor.col());
3442 editIsRunning =
false;
3445 void KateViewInternal::editSetCursor (
const KateTextCursor &cursor)
3447 if (this->cursor != cursor)
3449 this->cursor.setPos (cursor);
3454 void KateViewInternal::viewSelectionChanged ()
3456 if (!m_view->hasSelection())
3458 selectAnchor.setPos (-1, -1);
3459 selStartCached.setPos (-1, -1);
3464 void KateViewInternal::imStartEvent( TQIMEvent *e )
3466 if ( m_doc->m_bReadOnly ) {
3471 if ( m_view->hasSelection() )
3472 m_view->removeSelectedText();
3474 m_imPreeditStartLine = cursor.line();
3475 m_imPreeditStart = cursor.col();
3476 m_imPreeditLength = 0;
3477 m_imPreeditSelStart = m_imPreeditStart;
3479 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
true );
3482 void KateViewInternal::imComposeEvent( TQIMEvent *e )
3484 if ( m_doc->m_bReadOnly ) {
3490 if ( m_imPreeditLength > 0 ) {
3491 cursor.setPos( m_imPreeditStartLine, m_imPreeditStart );
3492 m_doc->removeText( m_imPreeditStartLine, m_imPreeditStart,
3493 m_imPreeditStartLine, m_imPreeditStart + m_imPreeditLength );
3496 m_imPreeditLength = e->text().length();
3497 m_imPreeditSelStart = m_imPreeditStart + e->cursorPos();
3500 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, m_imPreeditStart + m_imPreeditLength,
3501 m_imPreeditSelStart, m_imPreeditSelStart + e->selectionLength(),
3505 m_doc->insertText( m_imPreeditStartLine, m_imPreeditStart, e->text() );
3509 cursor.setPos( m_imPreeditStartLine, m_imPreeditSelStart );
3510 updateCursor( cursor,
true );
3515 void KateViewInternal::imEndEvent( TQIMEvent *e )
3517 if ( m_doc->m_bReadOnly ) {
3522 if ( m_imPreeditLength > 0 ) {
3523 cursor.setPos( m_imPreeditStartLine, m_imPreeditStart );
3524 m_doc->removeText( m_imPreeditStartLine, m_imPreeditStart,
3525 m_imPreeditStartLine, m_imPreeditStart + m_imPreeditLength );
3528 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
false );
3530 if ( e->text().length() > 0 ) {
3531 m_doc->insertText( cursor.line(), cursor.col(), e->text() );
3533 if ( !m_cursorTimer.isActive() && TDEApplication::cursorFlashTime() > 0 )
3534 m_cursorTimer.start ( TDEApplication::cursorFlashTime() / 2 );
3537 updateCursor( cursor,
true );
3540 m_imPreeditStart = 0;
3541 m_imPreeditLength = 0;
3542 m_imPreeditSelStart = 0;