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 )
1095 if ( m_view->wrapCursor() ) {
1096 c = WrappingCursor(
this, cursor ) += bias;
1098 c = BoundedCursor(
this, cursor ) += bias;
1101 updateSelection( c, sel );
1105 void KateViewInternal::cursorLeft(
bool sel )
1107 if ( ! m_view->wrapCursor() && cursor.col() == 0 )
1110 moveChar( left_b, sel );
1111 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1112 m_view->m_codeCompletion->updateBox();
1116 void KateViewInternal::cursorRight(
bool sel )
1118 moveChar( right_b, sel );
1119 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1120 m_view->m_codeCompletion->updateBox();
1124 void KateViewInternal::wordLeft (
bool sel )
1126 WrappingCursor c(
this, cursor );
1136 KateHighlighting* h = m_doc->highlight();
1137 if( !c.atEdge( left_b ) ) {
1139 while( !c.atEdge( left_b ) && m_doc->textLine( c.line() )[ c.col() - 1 ].isSpace() )
1142 if( c.atEdge( left_b ) )
1146 else if( h->isInWord( m_doc->textLine( c.line() )[ c.col() - 1 ] ) )
1148 while( !c.atEdge( left_b ) && h->isInWord( m_doc->textLine( c.line() )[ c.col() - 1 ] ) )
1153 while( !c.atEdge( left_b )
1154 && !h->isInWord( m_doc->textLine( c.line() )[ c.col() - 1 ] )
1157 && !m_doc->textLine( c.line() )[ c.col() - 1 ].isSpace() )
1163 updateSelection( c, sel );
1167 void KateViewInternal::wordRight(
bool sel )
1169 WrappingCursor c(
this, cursor );
1179 KateHighlighting* h = m_doc->highlight();
1180 if( c.atEdge( right_b ) )
1184 else if( h->isInWord( m_doc->textLine( c.line() )[ c.col() ] ) )
1186 while( !c.atEdge( right_b ) && h->isInWord( m_doc->textLine( c.line() )[ c.col() ] ) )
1191 while( !c.atEdge( right_b )
1192 && !h->isInWord( m_doc->textLine( c.line() )[ c.col() ] )
1195 && !m_doc->textLine( c.line() )[ c.col() ].isSpace() )
1201 while( !c.atEdge( right_b ) && m_doc->textLine( c.line() )[ c.col() ].isSpace() )
1204 updateSelection( c, sel );
1208 void KateViewInternal::moveEdge( Bias bias,
bool sel )
1210 BoundedCursor c(
this, cursor );
1212 updateSelection( c, sel );
1216 void KateViewInternal::home(
bool sel )
1218 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1219 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Home, 0, 0);
1220 m_view->m_codeCompletion->handleKey(&e);
1224 if (m_view->dynWordWrap() && currentRange().startCol) {
1226 if (cursor.col() != currentRange().startCol) {
1228 updateSelection( c, sel );
1234 if( !(m_doc->configFlags() & KateDocument::cfSmartHome) ) {
1235 moveEdge( left_b, sel );
1245 int lc = l->firstChar();
1247 if( lc < 0 || c.col() == lc ) {
1253 updateSelection( c, sel );
1254 updateCursor( c,
true );
1257 void KateViewInternal::end(
bool sel )
1259 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1260 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_End, 0, 0);
1261 m_view->m_codeCompletion->handleKey(&e);
1265 KateLineRange range = currentRange();
1267 if (m_view->dynWordWrap() && range.wrap) {
1269 if (cursor.col() < range.endCol - 1) {
1271 updateSelection( c, sel );
1277 if( !(m_doc->configFlags() & KateDocument::cfSmartHome) ) {
1278 moveEdge( right_b, sel );
1292 if (c.col() == m_doc->lineLength(c.line())) {
1293 c.setCol(l->lastChar() + 1);
1294 updateSelection(c, sel);
1295 updateCursor(c,
true);
1297 moveEdge(right_b, sel);
1301 KateLineRange KateViewInternal::range(
int realLine,
const KateLineRange* previous)
1304 if (!m_updatingView && realLine >= lineRanges[0].line && realLine <= lineRanges[lineRanges.count() - 1].line)
1305 for (uint i = 0; i < lineRanges.count(); i++)
1306 if (realLine == lineRanges[i].line)
1307 if (!m_view->dynWordWrap() || (!previous && lineRanges[i].startCol == 0) || (previous && lineRanges[i].startCol == previous->endCol))
1308 return lineRanges[i];
1315 return KateLineRange();
1318 if (!m_view->dynWordWrap()) {
1319 Q_ASSERT(!previous);
1320 ret.line = realLine;
1321 ret.virtualLine = m_doc->getVirtualLine(realLine);
1323 ret.endCol = m_doc->lineLength(realLine);
1325 ret.endX = m_view->renderer()->textWidth(text, -1);
1331 ret.endCol = (int)m_view->renderer()->textWidth(text, previous ? previous->endCol : 0, width() - (previous ? previous->shiftX : 0), &ret.wrap, &ret.endX);
1333 Q_ASSERT(ret.endCol > ret.startCol);
1335 ret.line = realLine;
1338 ret.virtualLine = previous->virtualLine;
1339 ret.startCol = previous->endCol;
1340 ret.startX = previous->endX;
1341 ret.endX += previous->endX;
1342 ret.shiftX = previous->shiftX;
1343 ret.viewLine = previous->viewLine + 1;
1347 if (m_view->config()->dynWordWrapAlignIndent() > 0) {
1348 int pos = text->nextNonSpaceChar(0);
1351 ret.shiftX = m_view->renderer()->textWidth(text, pos);
1353 if (ret.shiftX > ((
double)width() / 100 * m_view->config()->dynWordWrapAlignIndent()))
1357 ret.virtualLine = m_doc->getVirtualLine(realLine);
1366 KateLineRange KateViewInternal::currentRange()
1370 return range(cursor);
1373 KateLineRange KateViewInternal::previousRange()
1375 uint currentViewLine = viewLine(cursor);
1377 if (currentViewLine)
1378 return range(cursor.line(), currentViewLine - 1);
1380 return range(m_doc->getRealLine(displayCursor.line() - 1), -1);
1383 KateLineRange KateViewInternal::nextRange()
1385 uint currentViewLine = viewLine(cursor) + 1;
1387 if (currentViewLine >= viewLineCount(cursor.line())) {
1388 currentViewLine = 0;
1389 return range(cursor.line() + 1, currentViewLine);
1391 return range(cursor.line(), currentViewLine);
1395 KateLineRange KateViewInternal::range(
const KateTextCursor& realCursor)
1399 KateLineRange thisRange;
1403 thisRange = range(realCursor.line(), first ? 0L : &thisRange);
1405 }
while (thisRange.wrap && !(realCursor.col() >= thisRange.startCol && realCursor.col() < thisRange.endCol) && thisRange.startCol != thisRange.endCol);
1410 KateLineRange KateViewInternal::range(uint realLine,
int viewLine)
1414 KateLineRange thisRange;
1418 thisRange = range(realLine, first ? 0L : &thisRange);
1420 }
while (thisRange.wrap && viewLine != thisRange.viewLine && thisRange.startCol != thisRange.endCol);
1422 if (viewLine != -1 && viewLine != thisRange.viewLine)
1423 kdDebug(13030) <<
"WARNING: viewLine " << viewLine <<
" of line " << realLine <<
" does not exist." <<
endl;
1433 uint KateViewInternal::viewLine(
const KateTextCursor& realCursor)
1435 if (!m_view->dynWordWrap())
return 0;
1437 if (realCursor.col() == 0)
return 0;
1439 KateLineRange thisRange;
1443 thisRange = range(realCursor.line(), first ? 0L : &thisRange);
1445 }
while (thisRange.wrap && !(realCursor.col() >= thisRange.startCol && realCursor.col() < thisRange.endCol) && thisRange.startCol != thisRange.endCol);
1447 return thisRange.viewLine;
1450 int KateViewInternal::displayViewLine(
const KateTextCursor& virtualCursor,
bool limitToVisible)
1454 int limit = linesDisplayed();
1457 if (!m_view->dynWordWrap()) {
1458 int ret = virtualCursor.line() - startLine();
1459 if (limitToVisible && (ret < 0 || ret > limit))
1465 if (work == virtualCursor) {
1469 int ret = -(int)viewLine(work);
1470 bool forwards = (work < virtualCursor) ?
true :
false;
1474 while (work.line() != virtualCursor.line()) {
1475 ret += viewLineCount(m_doc->getRealLine(work.line()));
1476 work.setLine(work.line() + 1);
1477 if (limitToVisible && ret > limit)
1481 while (work.line() != virtualCursor.line()) {
1482 work.setLine(work.line() - 1);
1483 ret -= viewLineCount(m_doc->getRealLine(work.line()));
1484 if (limitToVisible && ret < 0)
1491 realCursor.setLine(m_doc->getRealLine(realCursor.line()));
1492 if (realCursor.col() == -1) realCursor.setCol(m_doc->lineLength(realCursor.line()));
1493 ret += viewLine(realCursor);
1495 if (limitToVisible && (ret < 0 || ret > limit))
1501 uint KateViewInternal::lastViewLine(uint realLine)
1503 if (!m_view->dynWordWrap())
return 0;
1505 KateLineRange thisRange;
1509 thisRange = range(realLine, first ? 0L : &thisRange);
1511 }
while (thisRange.wrap && thisRange.startCol != thisRange.endCol);
1513 return thisRange.viewLine;
1516 uint KateViewInternal::viewLineCount(uint realLine)
1518 return lastViewLine(realLine) + 1;
1530 if (!m_view->dynWordWrap()) {
1531 KateTextCursor ret(kMin((
int)m_doc->visibleLines() - 1, virtualCursor.line() + offset), 0);
1537 int realLine = m_doc->getRealLine(ret.line());
1538 ret.setCol(m_doc->lineLength(realLine) - 1);
1540 if (m_currentMaxX > cXPos)
1541 cXPos = m_currentMaxX;
1543 if (m_view->wrapCursor())
1544 cXPos = kMin(cXPos, (
int)m_view->renderer()->textWidth(textLine(realLine), m_doc->lineLength(realLine)));
1546 m_view->renderer()->textWidth(ret, cXPos);
1553 realCursor.setLine(m_doc->getRealLine(virtualCursor.line()));
1555 uint cursorViewLine = viewLine(realCursor);
1557 int currentOffset = 0;
1558 int virtualLine = 0;
1560 bool forwards = (offset > 0) ?
true :
false;
1563 currentOffset = lastViewLine(realCursor.line()) - cursorViewLine;
1564 if (offset <= currentOffset) {
1566 KateLineRange thisRange = range(realCursor.line(), cursorViewLine + offset);
1567 Q_ASSERT(thisRange.virtualLine == virtualCursor.line());
1571 virtualLine = virtualCursor.line() + 1;
1575 currentOffset = cursorViewLine;
1576 if (offset <= currentOffset) {
1578 KateLineRange thisRange = range(realCursor.line(), cursorViewLine - offset);
1579 Q_ASSERT(thisRange.virtualLine == virtualCursor.line());
1583 virtualLine = virtualCursor.line() - 1;
1588 while (virtualLine >= 0 && virtualLine < (
int)m_doc->visibleLines())
1590 KateLineRange thisRange;
1592 int realLine = m_doc->getRealLine(virtualLine);
1595 thisRange = range(realLine, first ? 0L : &thisRange);
1598 if (offset == currentOffset) {
1601 int requiredViewLine = lastViewLine(realLine) - thisRange.viewLine;
1602 if (requiredViewLine != thisRange.viewLine) {
1603 thisRange = range(realLine, requiredViewLine);
1611 ret.setCol(thisRange.endCol - 1);
1612 KateTextCursor realCursorTemp(m_doc->getRealLine(virtualCursor.line()), virtualCursor.col());
1613 int visibleX = m_view->renderer()->textWidth(realCursorTemp) - range(realCursorTemp).startX;
1614 int xOffset = thisRange.startX;
1616 if (m_currentMaxX > visibleX)
1617 visibleX = m_currentMaxX;
1619 cXPos = xOffset + visibleX;
1621 cXPos = kMin(cXPos, lineMaxCursorX(thisRange));
1623 m_view->renderer()->textWidth(ret, cXPos);
1631 }
while (thisRange.wrap);
1642 return KateTextCursor(m_doc->visibleLines() - 1, m_doc->lineLength(m_doc->visibleLines() - 1));
1647 int KateViewInternal::lineMaxCursorX(
const KateLineRange& range)
1649 if (!m_view->wrapCursor() && !range.wrap)
1652 int maxX = range.endX;
1654 if (maxX && range.wrap) {
1655 TQChar lastCharInLine = textLine(range.line)->getChar(range.endCol - 1);
1657 if (lastCharInLine == TQChar(
'\t')) {
1659 int lastTabSize = 0;
1660 for(
int i = range.startCol; i < range.endCol; i++) {
1661 if (textLine(range.line)->getChar(i) == TQChar(
'\t')) {
1662 lastTabSize = m_view->tabWidth() - (lineSize % m_view->tabWidth());
1663 lineSize += lastTabSize;
1668 maxX -= lastTabSize * m_view->renderer()->spaceWidth();
1670 maxX -= m_view->renderer()->config()->fontMetrics()->width(lastCharInLine);
1677 int KateViewInternal::lineMaxCol(
const KateLineRange& range)
1679 int maxCol = range.endCol;
1681 if (maxCol && range.wrap)
1687 void KateViewInternal::cursorUp(
bool sel)
1689 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1690 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Up, 0, 0);
1691 m_view->m_codeCompletion->handleKey(&e);
1695 if (displayCursor.line() == 0 && (!m_view->dynWordWrap() || viewLine(cursor) == 0))
1698 int newLine = cursor.line(), newCol = 0, xOffset = 0, startCol = 0;
1699 m_preserveMaxX =
true;
1701 if (m_view->dynWordWrap()) {
1703 KateLineRange thisRange = currentRange();
1705 KateLineRange pRange = previousRange();
1708 Q_ASSERT((cursor.line() == thisRange.line) &&
1709 (cursor.col() >= thisRange.startCol) &&
1710 (!thisRange.wrap || cursor.col() < thisRange.endCol));
1713 int visibleX = m_view->renderer()->textWidth(cursor) - thisRange.startX;
1714 int currentLineVisibleX = visibleX;
1717 visibleX += thisRange.xOffset();
1718 visibleX -= pRange.xOffset();
1721 visibleX = kMax(0, visibleX);
1723 startCol = pRange.startCol;
1724 xOffset = pRange.startX;
1725 newLine = pRange.line;
1729 if (thisRange.xOffset() && !pRange.xOffset() && currentLineVisibleX == 0)
1730 visibleX = m_currentMaxX;
1731 else if (visibleX < m_currentMaxX - pRange.xOffset())
1732 visibleX = m_currentMaxX - pRange.xOffset();
1734 cXPos = xOffset + visibleX;
1736 cXPos = kMin(cXPos, lineMaxCursorX(pRange));
1738 newCol = kMin((
int)m_view->renderer()->textPos(newLine, visibleX, startCol), lineMaxCol(pRange));
1741 newLine = m_doc->getRealLine(displayCursor.line() - 1);
1743 if ((m_view->wrapCursor()) && m_currentMaxX > cXPos)
1744 cXPos = m_currentMaxX;
1748 m_view->renderer()->textWidth(c, cXPos);
1750 updateSelection( c, sel );
1754 void KateViewInternal::cursorDown(
bool sel)
1756 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1757 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Down, 0, 0);
1758 m_view->m_codeCompletion->handleKey(&e);
1762 if ((displayCursor.line() >= (
int)m_doc->numVisLines() - 1) && (!m_view->dynWordWrap() || viewLine(cursor) == lastViewLine(cursor.line())))
1765 int newLine = cursor.line(), newCol = 0, xOffset = 0, startCol = 0;
1766 m_preserveMaxX =
true;
1768 if (m_view->dynWordWrap()) {
1770 KateLineRange thisRange = currentRange();
1772 KateLineRange nRange = nextRange();
1775 Q_ASSERT((cursor.line() == thisRange.line) &&
1776 (cursor.col() >= thisRange.startCol) &&
1777 (!thisRange.wrap || cursor.col() < thisRange.endCol));
1780 int visibleX = m_view->renderer()->textWidth(cursor) - thisRange.startX;
1781 int currentLineVisibleX = visibleX;
1784 visibleX += thisRange.xOffset();
1785 visibleX -= nRange.xOffset();
1788 visibleX = kMax(0, visibleX);
1790 if (!thisRange.wrap) {
1791 newLine = m_doc->getRealLine(displayCursor.line() + 1);
1793 startCol = thisRange.endCol;
1794 xOffset = thisRange.endX;
1799 if (thisRange.xOffset() && !nRange.xOffset() && currentLineVisibleX == 0)
1800 visibleX = m_currentMaxX;
1801 else if (visibleX < m_currentMaxX - nRange.xOffset())
1802 visibleX = m_currentMaxX - nRange.xOffset();
1804 cXPos = xOffset + visibleX;
1806 cXPos = kMin(cXPos, lineMaxCursorX(nRange));
1808 newCol = kMin((
int)m_view->renderer()->textPos(newLine, visibleX, startCol), lineMaxCol(nRange));
1811 newLine = m_doc->getRealLine(displayCursor.line() + 1);
1813 if ((m_view->wrapCursor()) && m_currentMaxX > cXPos)
1814 cXPos = m_currentMaxX;
1818 m_view->renderer()->textWidth(c, cXPos);
1820 updateSelection(c, sel);
1824 void KateViewInternal::cursorToMatchingBracket(
bool sel )
1828 if( !m_doc->findMatchingBracket( start, end ) )
1835 end.setCol(
end.col() + 1);
1837 updateSelection( end, sel );
1838 updateCursor( end );
1841 void KateViewInternal::topOfView(
bool sel )
1843 KateTextCursor c = viewLineOffset(startPos(), m_minLinesVisible);
1844 updateSelection( c, sel );
1848 void KateViewInternal::bottomOfView(
bool sel )
1852 updateSelection( c, sel );
1857 void KateViewInternal::scrollLines(
int lines,
bool sel )
1862 c.setLine(m_doc->getRealLine(c.line()));
1864 updateSelection( c, sel );
1869 void KateViewInternal::scrollUp()
1875 void KateViewInternal::scrollDown()
1881 void KateViewInternal::setAutoCenterLines(
int viewLines,
bool updateView)
1883 m_autoCenterLines = viewLines;
1884 m_minLinesVisible = kMin(
int((linesDisplayed() - 1)/2), m_autoCenterLines);
1886 KateViewInternal::updateView();
1889 void KateViewInternal::pageUp(
bool sel )
1891 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1892 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_PageUp, 0, 0);
1893 m_view->m_codeCompletion->handleKey(&e);
1898 int viewLine = displayViewLine(displayCursor);
1899 bool atTop = (startPos().line() == 0 && startPos().col() == 0);
1902 int lineadj = 2 * m_minLinesVisible;
1903 int cursorStart = (linesDisplayed() - 1) - viewLine;
1904 if (cursorStart < m_minLinesVisible)
1905 lineadj -= m_minLinesVisible - cursorStart;
1907 int linesToScroll = -kMax( ((
int)linesDisplayed() - 1) - lineadj, 0 );
1908 m_preserveMaxX =
true;
1910 if (!m_doc->pageUpDownMovesCursor () && !atTop) {
1911 int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
1913 KateTextCursor newStartPos = viewLineOffset(startPos(), linesToScroll - 1);
1914 scrollPos(newStartPos);
1917 KateTextCursor newPos = viewLineOffset(newStartPos, viewLine,
true);
1918 newPos.setLine(m_doc->getRealLine(newPos.line()));
1920 KateLineRange newLine = range(newPos);
1922 if (m_currentMaxX - newLine.xOffset() > xPos)
1923 xPos = m_currentMaxX - newLine.xOffset();
1925 cXPos = kMin(newLine.startX + xPos, lineMaxCursorX(newLine));
1927 m_view->renderer()->textWidth( newPos, cXPos );
1929 m_preserveMaxX =
true;
1930 updateSelection( newPos, sel );
1931 updateCursor(newPos);
1934 scrollLines( linesToScroll, sel );
1938 void KateViewInternal::pageDown(
bool sel )
1940 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1941 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_PageDown, 0, 0);
1942 m_view->m_codeCompletion->handleKey(&e);
1947 int viewLine = displayViewLine(displayCursor);
1948 bool atEnd = startPos() >= m_cachedMaxStartPos;
1951 int lineadj = 2 * m_minLinesVisible;
1952 int cursorStart = m_minLinesVisible - viewLine;
1953 if (cursorStart > 0)
1954 lineadj -= cursorStart;
1956 int linesToScroll = kMax( ((
int)linesDisplayed() - 1) - lineadj, 0 );
1957 m_preserveMaxX =
true;
1959 if (!m_doc->pageUpDownMovesCursor () && !atEnd) {
1960 int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
1962 KateTextCursor newStartPos = viewLineOffset(startPos(), linesToScroll + 1);
1963 scrollPos(newStartPos);
1966 KateTextCursor newPos = viewLineOffset(newStartPos, viewLine,
true);
1967 newPos.setLine(m_doc->getRealLine(newPos.line()));
1969 KateLineRange newLine = range(newPos);
1971 if (m_currentMaxX - newLine.xOffset() > xPos)
1972 xPos = m_currentMaxX - newLine.xOffset();
1974 cXPos = kMin(newLine.startX + xPos, lineMaxCursorX(newLine));
1976 m_view->renderer()->textWidth( newPos, cXPos );
1978 m_preserveMaxX =
true;
1979 updateSelection( newPos, sel );
1980 updateCursor(newPos);
1983 scrollLines( linesToScroll, sel );
1987 int KateViewInternal::maxLen(uint startLine)
1991 int displayLines = (m_view->height() / m_view->renderer()->fontHeight()) + 1;
1995 for (
int z = 0; z < displayLines; z++) {
1996 int virtualLine = startLine + z;
1998 if (virtualLine < 0 || virtualLine >= (
int)m_doc->visibleLines())
2001 KateLineRange thisRange = range((
int)m_doc->getRealLine(virtualLine));
2003 maxLen = kMax(maxLen, thisRange.endX);
2009 void KateViewInternal::top(
bool sel )
2012 m_view->renderer()->textWidth( c, cXPos );
2013 updateSelection( c, sel );
2017 void KateViewInternal::bottom(
bool sel )
2020 m_view->renderer()->textWidth( c, cXPos );
2021 updateSelection( c, sel );
2025 void KateViewInternal::top_home(
bool sel )
2027 if (m_view->m_codeCompletion->codeCompletionVisible()) {
2028 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Home, 0, 0);
2029 m_view->m_codeCompletion->handleKey(&e);
2033 updateSelection( c, sel );
2037 void KateViewInternal::bottom_end(
bool sel )
2039 if (m_view->m_codeCompletion->codeCompletionVisible()) {
2040 TQKeyEvent e(TQEvent::KeyPress, TQt::Key_End, 0, 0);
2041 m_view->m_codeCompletion->handleKey(&e);
2044 KateTextCursor c( m_doc->lastLine(), m_doc->lineLength( m_doc->lastLine() ) );
2045 updateSelection( c, sel );
2049 void KateViewInternal::updateSelection(
const KateTextCursor& _newCursor,
bool keepSel )
2054 if ( !m_view->hasSelection() || (selectAnchor.line() == -1)
2055 || (m_view->config()->persistentSelection()
2056 && ((cursor < m_view->selectStart) || (cursor > m_view->selectEnd))) )
2058 selectAnchor = cursor;
2059 m_view->setSelection( cursor, newCursor );
2063 bool doSelect =
true;
2064 switch (m_selectionMode)
2075 if ( selStartCached.line() == -1 )
2076 selStartCached = selEndCached;
2079 if ( newCursor > selEndCached )
2081 selectAnchor = selStartCached;
2085 c = newCursor.col();
2086 if ( c > 0 && m_doc->highlight()->isInWord( l->getChar( c-1 ) ) ) {
2087 for (; c < l->length(); c++ )
2088 if ( !m_doc->highlight()->isInWord( l->getChar( c ) ) )
2092 newCursor.setCol( c );
2094 else if ( newCursor < selStartCached )
2096 selectAnchor = selEndCached;
2100 c = newCursor.col();
2101 if ( c > 0 && c < m_doc->textLine( newCursor.line() ).length()
2102 && m_doc->highlight()->isInWord( l->getChar( c ) )
2103 && m_doc->highlight()->isInWord( l->getChar( c-1 ) ) ) {
2104 for ( c -= 2; c >= 0; c-- )
2105 if ( !m_doc->highlight()->isInWord( l->getChar( c ) ) )
2107 newCursor.setCol( c+1 );
2117 if ( newCursor.line() > selStartCached.line() )
2119 if ( newCursor.line()+1 >= m_doc->numLines() )
2120 newCursor.setCol( m_doc->textLine( newCursor.line() ).length() );
2122 newCursor.setPos( newCursor.line() + 1, 0 );
2124 selectAnchor = selStartCached;
2125 selectAnchor.setCol( 0 );
2127 else if ( newCursor.line() < selStartCached.line() )
2129 newCursor.setCol( 0 );
2131 selectAnchor = selEndCached;
2132 if ( selectAnchor.col() > 0 )
2134 if ( selectAnchor.line()+1 >= m_doc->numLines() )
2135 selectAnchor.setCol( m_doc->textLine( selectAnchor.line() ).length() );
2137 selectAnchor.setPos( selectAnchor.line() + 1, 0 );
2145 if ( selStartCached.line() < 0 )
2148 if ( newCursor > selEndCached )
2149 selectAnchor = selStartCached;
2150 else if ( newCursor < selStartCached )
2151 selectAnchor = selEndCached;
2158 if ( selectAnchor.line() < 0 )
2164 m_view->setSelection( selectAnchor, newCursor);
2165 else if ( selStartCached.line() >= 0 )
2166 m_view->setSelection( selStartCached, selEndCached );
2169 m_selChangedByUser =
true;
2171 else if ( !m_view->config()->persistentSelection() )
2173 m_view->clearSelection();
2174 selStartCached.setLine( -1 );
2175 selectAnchor.setLine( -1 );
2179 void KateViewInternal::updateCursor(
const KateTextCursor& newCursor,
bool force,
bool center,
bool calledExternally )
2181 if ( !force && (cursor == newCursor) )
2183 if ( !m_madeVisible && m_view == m_doc->activeView() )
2186 m_doc->foldingTree()->ensureVisible( newCursor.line() );
2188 makeVisible ( displayCursor, displayCursor.col(),
false, center, calledExternally );
2195 m_doc->foldingTree()->ensureVisible( newCursor.line() );
2199 cursor.setPos (newCursor);
2200 displayCursor.setPos (m_doc->getVirtualLine(cursor.line()), cursor.col());
2202 cXPos = m_view->renderer()->textWidth( cursor );
2203 if (m_view == m_doc->activeView())
2204 makeVisible ( displayCursor, displayCursor.col(),
false, center, calledExternally );
2206 updateBracketMarks();
2209 tagLine(oldDisplayCursor);
2210 tagLine(displayCursor);
2212 updateMicroFocusHint();
2214 if (m_cursorTimer.isActive ())
2216 if ( TDEApplication::cursorFlashTime() > 0 )
2217 m_cursorTimer.start( TDEApplication::cursorFlashTime() / 2 );
2218 m_view->renderer()->setDrawCaret(
true);
2223 m_preserveMaxX =
false;
2225 if (m_view->dynWordWrap())
2226 m_currentMaxX = m_view->renderer()->textWidth(displayCursor) - currentRange().startX + currentRange().xOffset();
2228 m_currentMaxX = cXPos;
2233 paintText(0, 0, width(), height(),
true);
2235 emit m_view->cursorPositionChanged();
2238 void KateViewInternal::updateBracketMarks()
2240 if ( bm.isValid() ) {
2241 KateTextCursor bmStart(m_doc->getVirtualLine(bm.start().line()), bm.start().col());
2242 KateTextCursor bmEnd(m_doc->getVirtualLine(bm.end().line()), bm.end().col());
2244 if( bm.getMinIndent() != 0 )
2247 if( bmStart > bmEnd )
2249 tagLines(bmEnd, bmStart);
2253 tagLines(bmStart, bmEnd);
2264 int maxLines = linesDisplayed () * 3;
2265 m_doc->newBracketMark( cursor, bm, maxLines );
2267 if ( bm.isValid() ) {
2268 KateTextCursor bmStart(m_doc->getVirtualLine(bm.start().line()), bm.start().col());
2269 KateTextCursor bmEnd(m_doc->getVirtualLine(bm.end().line()), bm.end().col());
2271 if( bm.getMinIndent() != 0 )
2274 if( bmStart > bmEnd )
2276 tagLines(bmEnd, bmStart);
2280 tagLines(bmStart, bmEnd);
2291 bool KateViewInternal::tagLine(
const KateTextCursor& virtualCursor)
2293 int viewLine = displayViewLine(virtualCursor,
true);
2294 if (viewLine >= 0 && viewLine < (
int)lineRanges.count()) {
2295 lineRanges[viewLine].dirty =
true;
2296 leftBorder->update (0, lineToY(viewLine), leftBorder->width(), m_view->renderer()->fontHeight());
2302 bool KateViewInternal::tagLines(
int start,
int end,
bool realLines )
2312 start.setLine(m_doc->getVirtualLine( start.line() ));
2313 end.setLine(m_doc->getVirtualLine(
end.line() ));
2316 if (
end.line() < (
int)startLine())
2321 if (start.line() > (
int)endLine())
2331 for (uint z = 0; z < lineRanges.size(); z++)
2333 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)))) {
2334 ret = lineRanges[z].dirty =
true;
2339 if (!m_view->dynWordWrap())
2341 int y = lineToY( start.line() );
2343 int h = (
end.line() - start.line() + 2) * m_view->renderer()->fontHeight();
2344 if (
end.line() == (int)m_doc->numVisLines() - 1)
2347 leftBorder->update (0, y, leftBorder->width(), h);
2353 for (uint z = 0; z < lineRanges.size(); z++)
2355 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))))
2358 leftBorder->update (0, z * m_view->renderer()->fontHeight(), leftBorder->width(), leftBorder->height());
2373 void KateViewInternal::tagAll()
2376 for (uint z = 0; z < lineRanges.size(); z++)
2378 lineRanges[z].dirty =
true;
2381 leftBorder->updateFont();
2382 leftBorder->update ();
2385 void KateViewInternal::paintCursor()
2387 if (tagLine(displayCursor))
2388 paintText (0,0,width(), height(),
true);
2392 void KateViewInternal::placeCursor(
const TQPoint& p,
bool keepSelection,
bool updateSelection )
2394 KateLineRange thisRange = yToKateLineRange(p.y());
2396 if (thisRange.line == -1) {
2397 for (
int i = (p.y() / m_view->renderer()->fontHeight()); i >= 0; i--) {
2398 thisRange = lineRanges[i];
2399 if (thisRange.line != -1)
2402 Q_ASSERT(thisRange.line != -1);
2405 int realLine = thisRange.line;
2406 int visibleLine = thisRange.virtualLine;
2407 uint startCol = thisRange.startCol;
2409 visibleLine = kMax( 0, kMin( visibleLine,
int(m_doc->numVisLines()) - 1 ) );
2413 int x = kMin(kMax(-m_startX, p.x() - thisRange.xOffset()), lineMaxCursorX(thisRange) - thisRange.startX);
2415 m_view->renderer()->textWidth( c, startX() + x, startCol);
2417 if (updateSelection)
2418 KateViewInternal::updateSelection( c, keepSelection );
2424 bool KateViewInternal::isTargetSelected(
const TQPoint& p )
2426 KateLineRange thisRange = yToKateLineRange(p.y());
2432 int col = m_view->renderer()->textPos( l, startX() + p.x() - thisRange.xOffset(), thisRange.startCol,
false );
2434 return m_view->lineColSelected( thisRange.line, col );
2439 bool KateViewInternal::eventFilter( TQObject *obj, TQEvent *e )
2441 if (obj == m_lineScroll)
2444 if (e->type() == TQEvent::Wheel && m_lineScroll->minValue() != m_lineScroll->maxValue())
2446 wheelEvent((TQWheelEvent*)e);
2451 return TQWidget::eventFilter( obj, e );
2456 case TQEvent::KeyPress:
2458 TQKeyEvent *k = (TQKeyEvent *)e;
2460 if (m_view->m_codeCompletion->codeCompletionVisible ())
2464 if( k->key() == Key_Escape )
2465 m_view->m_codeCompletion->abortCompletion();
2468 if ((k->key() == TQt::Key_Escape) && !m_view->config()->persistentSelection() )
2470 m_view->clearSelection();
2473 else if ( !((k->state() & ControlButton) || (k->state() & AltButton)) )
2476 return k->isAccepted();
2481 case TQEvent::DragMove:
2483 TQPoint currentPoint = ((TQDragMoveEvent*) e)->pos();
2485 TQRect doNotScrollRegion( scrollMargin, scrollMargin,
2486 width() - scrollMargin * 2,
2487 height() - scrollMargin * 2 );
2489 if ( !doNotScrollRegion.contains( currentPoint ) )
2493 ( (TQDragMoveEvent*)e )->accept( TQRect(0,0,0,0) );
2496 dragMoveEvent((TQDragMoveEvent*)e);
2499 case TQEvent::DragLeave:
2504 case TQEvent::WindowBlocked:
2507 m_doc->m_isasking = -1;
2514 return TQWidget::eventFilter( obj, e );
2517 void KateViewInternal::keyPressEvent( TQKeyEvent* e )
2521 bool codeComp = m_view->m_codeCompletion->codeCompletionVisible ();
2527 if( e->key() == Key_Enter || e->key() == Key_Return ||
2528 (key == SHIFT + TQt::Key_Return) || (key == SHIFT + TQt::Key_Enter)) {
2529 m_view->m_codeCompletion->doComplete();
2535 if( !m_doc->isReadWrite() )
2541 if ((key == TQt::Key_Return) || (key == TQt::Key_Enter))
2543 m_view->keyReturn();
2548 if ((key == SHIFT + TQt::Key_Return) || (key == SHIFT + TQt::Key_Enter))
2550 uint ln = cursor.line();
2551 int col = cursor.col();
2553 int pos = line->firstChar();
2554 if (pos > cursor.col()) pos = cursor.col();
2556 while ((
int)line->length() > pos &&
2557 !line->getChar(pos).isLetterOrNumber() &&
2558 pos < cursor.col()) ++pos;
2560 pos = line->length();
2563 m_doc->insertText( cursor.line(), line->length(),
"\n" + line->string(0, pos)
2564 + line->string().right( line->length() - cursor.col() ) );
2565 cursor.setPos(ln + 1, pos);
2566 if (col <
int(line->length()))
2567 m_doc->editRemoveText(ln, col, line->length() - col);
2569 updateCursor(cursor,
true);
2576 if (key == TQt::Key_Backspace || key == SHIFT + TQt::Key_Backspace)
2578 m_view->backspace();
2582 m_view->m_codeCompletion->updateBox ();
2587 if (key == TQt::Key_Tab || key == SHIFT+TQt::Key_Backtab || key == TQt::Key_Backtab)
2589 if (m_doc->invokeTabInterceptor(key)) {
2593 if (m_doc->configFlags() & KateDocumentConfig::cfTabIndents)
2595 if( key == TQt::Key_Tab )
2597 if (m_view->hasSelection() || (m_doc->configFlags() & KateDocumentConfig::cfTabIndentsMode))
2598 m_doc->indent( m_view, cursor.line(), 1 );
2599 else if (m_doc->configFlags() & KateDocumentConfig::cfTabInsertsTab)
2600 m_doc->typeChars ( m_view, TQString (
"\t") );
2602 m_doc->insertIndentChars ( m_view );
2607 m_view->m_codeCompletion->updateBox ();
2612 if (key == SHIFT+TQt::Key_Backtab || key == TQt::Key_Backtab)
2614 m_doc->indent( m_view, cursor.line(), -1 );
2618 m_view->m_codeCompletion->updateBox ();
2624 if ( !(e->state() & ControlButton) && !(e->state() & AltButton)
2625 && m_doc->typeChars ( m_view, e->text() ) )
2630 m_view->m_codeCompletion->updateBox ();
2638 void KateViewInternal::keyReleaseEvent( TQKeyEvent* e )
2643 m_shiftKeyPressed =
true;
2646 if (m_shiftKeyPressed)
2648 m_shiftKeyPressed =
false;
2650 if (m_selChangedByUser)
2652 TQApplication::clipboard()->setSelectionMode(
true );
2654 TQApplication::clipboard()->setSelectionMode(
false );
2656 m_selChangedByUser =
false;
2665 void KateViewInternal::contextMenuEvent ( TQContextMenuEvent * e )
2669 TQPoint p = e->pos();
2671 if ( m_view->m_doc->browserView() )
2673 m_view->contextMenuEvent( e );
2677 if ( e->reason() == TQContextMenuEvent::Keyboard )
2679 makeVisible( cursor, 0 );
2680 p = cursorCoordinates();
2682 else if ( ! m_view->hasSelection() || m_view->config()->persistentSelection() )
2683 placeCursor( e->pos() );
2686 if (m_view->popup()) {
2687 m_view->popup()->popup( mapToGlobal( p ) );
2692 void KateViewInternal::mousePressEvent( TQMouseEvent* e )
2694 switch (e->button())
2696 case TQt::LeftButton:
2697 m_selChangedByUser =
false;
2699 if (possibleTripleClick)
2701 possibleTripleClick =
false;
2703 m_selectionMode = Line;
2705 if ( e->state() & TQt::ShiftButton )
2707 updateSelection( cursor,
true );
2711 m_view->selectLine( cursor );
2714 TQApplication::clipboard()->setSelectionMode(
true );
2716 TQApplication::clipboard()->setSelectionMode(
false );
2720 if ( selectAnchor.line() > m_view->selectStart.line() )
2723 if ( selectAnchor == m_view->selectEnd && selectAnchor.col() == 0 )
2727 selEndCached = m_view->selectEnd;
2732 selStartCached = m_view->selectStart;
2733 if ( m_view->selectEnd.line() > m_view->selectStart.line() )
2734 selEndCached =
KateTextCursor( m_view->selectStart.line()+1, 0 );
2736 selEndCached = m_view->selectEnd;
2741 if ( m_view->selectStart < selectAnchor
2742 && selectAnchor.line() != m_view->selectStart.line() )
2743 updateCursor( m_view->selectStart );
2745 updateCursor( m_view->selectEnd );
2750 else if (m_selectionMode == Default)
2752 m_selectionMode = Mouse;
2755 if ( e->state() & TQt::ShiftButton )
2757 if (selectAnchor.line() < 0)
2758 selectAnchor = cursor;
2762 selStartCached.setLine( -1 );
2765 if( !( e->state() & TQt::ShiftButton ) && isTargetSelected( e->pos() ) )
2767 dragInfo.state = diPending;
2768 dragInfo.start = e->pos();
2772 dragInfo.state = diNone;
2774 if ( e->state() & TQt::ShiftButton )
2776 placeCursor( e->pos(),
true,
false );
2777 if ( selStartCached.line() >= 0 )
2779 if ( cursor > selEndCached )
2781 m_view->setSelection( selStartCached, cursor );
2782 selectAnchor = selStartCached;
2784 else if ( cursor < selStartCached )
2786 m_view->setSelection( cursor, selEndCached );
2787 selectAnchor = selEndCached;
2791 m_view->setSelection( selStartCached, cursor );
2796 m_view->setSelection( selectAnchor, cursor );
2801 placeCursor( e->pos() );
2807 m_scrollTimer.start (50);
2819 void KateViewInternal::mouseDoubleClickEvent(TQMouseEvent *e)
2821 switch (e->button())
2823 case TQt::LeftButton:
2824 m_selectionMode = Word;
2826 if ( e->state() & TQt::ShiftButton )
2835 ce = selectAnchor.col();
2836 if ( ce > 0 && m_doc->highlight()->isInWord( l->getChar( ce ) ) ) {
2837 for (; ce < l->length(); ce++ )
2838 if ( !m_doc->highlight()->isInWord( l->getChar( ce ) ) )
2842 cs = selectAnchor.col() - 1;
2843 if ( cs < m_doc->textLine( selectAnchor.line() ).length()
2844 && m_doc->highlight()->isInWord( l->getChar( cs ) ) ) {
2845 for ( cs--; cs >= 0; cs-- )
2846 if ( !m_doc->highlight()->isInWord( l->getChar( cs ) ) )
2858 selStartCached = selectAnchor;
2859 selEndCached = selectAnchor;
2862 placeCursor( e->pos(),
true );
2873 m_view->clearSelection(
false,
false );
2874 placeCursor( e->pos() );
2875 m_view->selectWord( cursor );
2876 if (m_view->hasSelection())
2878 selectAnchor = selStartCached = m_view->selectStart;
2879 selEndCached = m_view->selectEnd;
2885 m_selectionMode = Default;
2890 if (m_view->hasSelection())
2892 TQApplication::clipboard()->setSelectionMode(
true );
2894 TQApplication::clipboard()->setSelectionMode(
false );
2898 if (m_view->selectStart < selStartCached)
2899 updateCursor( m_view->selectStart );
2901 updateCursor( m_view->selectEnd );
2904 possibleTripleClick =
true;
2905 TQTimer::singleShot ( TQApplication::doubleClickInterval(),
this, TQ_SLOT(tripleClickTimeout()) );
2910 m_scrollTimer.start (50);
2921 void KateViewInternal::tripleClickTimeout()
2923 possibleTripleClick =
false;
2926 void KateViewInternal::mouseReleaseEvent( TQMouseEvent* e )
2928 switch (e->button())
2930 case TQt::LeftButton:
2931 m_selectionMode = Default;
2934 if (m_selChangedByUser)
2936 TQApplication::clipboard()->setSelectionMode(
true );
2938 TQApplication::clipboard()->setSelectionMode(
false );
2941 if ( m_view->selectStart < selectAnchor )
2942 updateCursor( m_view->selectStart );
2944 updateCursor( m_view->selectEnd );
2946 m_selChangedByUser =
false;
2949 if (dragInfo.state == diPending)
2950 placeCursor( e->pos(), e->state() & ShiftButton );
2951 else if (dragInfo.state == diNone)
2952 m_scrollTimer.stop ();
2954 dragInfo.state = diNone;
2959 case TQt::MidButton:
2960 placeCursor( e->pos() );
2962 if( m_doc->isReadWrite() )
2964 TQApplication::clipboard()->setSelectionMode(
true );
2966 TQApplication::clipboard()->setSelectionMode(
false );
2978 void KateViewInternal::mouseMoveEvent( TQMouseEvent* e )
2980 if( e->state() & TQt::LeftButton )
2982 if (dragInfo.state == diPending)
2986 TQPoint p( e->pos() - dragInfo.start );
2994 else if (dragInfo.state == diDragging)
3006 int d = m_view->renderer()->fontHeight();
3011 if (mouseX > width())
3020 if (mouseY > height())
3026 placeCursor( TQPoint( mouseX, mouseY ),
true );
3031 if (isTargetSelected( e->pos() ) ) {
3034 if (m_mouseCursor != ArrowCursor) {
3036 m_mouseCursor = TQt::ArrowCursor;
3040 if (m_mouseCursor != IbeamCursor) {
3042 m_mouseCursor = TQt::IbeamCursor;
3046 if (m_textHintEnabled)
3048 m_textHintTimer.start(m_textHintTimeout);
3049 m_textHintMouseX=e->x();
3050 m_textHintMouseY=e->y();
3055 void KateViewInternal::paintEvent(TQPaintEvent *e)
3057 paintText(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
3060 void KateViewInternal::resizeEvent(TQResizeEvent* e)
3062 bool expandedHorizontally = width() > e->oldSize().width();
3063 bool expandedVertically = height() > e->oldSize().height();
3064 bool heightChanged = height() != e->oldSize().height();
3066 m_madeVisible =
false;
3068 if (heightChanged) {
3069 setAutoCenterLines(m_autoCenterLines,
false);
3070 m_cachedMaxStartPos.setPos(-1, -1);
3073 if (m_view->dynWordWrap()) {
3074 bool dirtied =
false;
3076 for (uint i = 0; i < lineRanges.count(); i++) {
3079 if (lineRanges[i].wrap ||
3080 (!expandedHorizontally && (lineRanges[i].endX - lineRanges[i].startX) > width())) {
3081 dirtied = lineRanges[i].dirty =
true;
3086 if (dirtied || heightChanged) {
3088 leftBorder->update();
3091 if (width() < e->oldSize().width()) {
3092 if (!m_view->wrapCursor()) {
3094 if (cursor.col() > m_doc->lineLength(cursor.line())) {
3095 KateLineRange thisRange = currentRange();
3097 KateTextCursor newCursor(cursor.line(), thisRange.endCol + ((width() - thisRange.xOffset() - (thisRange.endX - thisRange.startX)) / m_view->renderer()->spaceWidth()) - 1);
3098 updateCursor(newCursor);
3106 if (expandedHorizontally && startX() > 0)
3107 scrollColumns(startX() - (width() - e->oldSize().width()));
3110 if (expandedVertically) {
3112 if (startPos() > max)
3117 void KateViewInternal::scrollTimeout ()
3119 if (scrollX || scrollY)
3121 scrollLines (startPos().line() + (scrollY / (
int)m_view->renderer()->fontHeight()));
3122 placeCursor( TQPoint( mouseX, mouseY ),
true );
3126 void KateViewInternal::cursorTimeout ()
3128 m_view->renderer()->setDrawCaret(!m_view->renderer()->drawCaret());
3132 void KateViewInternal::textHintTimeout ()
3134 m_textHintTimer.stop ();
3136 KateLineRange thisRange = yToKateLineRange(m_textHintMouseY);
3138 if (thisRange.line == -1)
return;
3140 if (m_textHintMouseX> (lineMaxCursorX(thisRange) - thisRange.startX))
return;
3142 int realLine = thisRange.line;
3143 int startCol = thisRange.startCol;
3146 m_view->renderer()->textWidth( c, startX() + m_textHintMouseX, startCol);
3150 emit m_view->needTextHint(c.line(), c.col(), tmp);
3152 if (!tmp.isEmpty())
kdDebug(13030)<<
"Hint text: "<<tmp<<
endl;
3155 void KateViewInternal::focusInEvent (TQFocusEvent *)
3157 if (TDEApplication::cursorFlashTime() > 0)
3158 m_cursorTimer.start ( TDEApplication::cursorFlashTime() / 2 );
3160 if (m_textHintEnabled)
3161 m_textHintTimer.start( m_textHintTimeout );
3165 m_doc->setActiveView( m_view );
3167 emit m_view->gotFocus( m_view );
3170 void KateViewInternal::focusOutEvent (TQFocusEvent *)
3172 if( m_view->renderer() && ! m_view->m_codeCompletion->codeCompletionVisible() )
3174 m_cursorTimer.stop();
3176 m_view->renderer()->setDrawCaret(
true);
3178 emit m_view->lostFocus( m_view );
3181 m_textHintTimer.stop();
3184 void KateViewInternal::doDrag()
3186 dragInfo.state = diDragging;
3187 dragInfo.dragObject =
new TQTextDrag(m_view->selection(),
this);
3188 dragInfo.dragObject->drag();
3191 void KateViewInternal::dragEnterEvent( TQDragEnterEvent* event )
3193 event->accept( (TQTextDrag::canDecode(event) && m_doc->isReadWrite()) ||
3194 KURLDrag::canDecode(event) );
3197 void KateViewInternal::dragMoveEvent( TQDragMoveEvent* event )
3200 placeCursor(
event->pos(),
true,
false );
3204 event->acceptAction();
3207 void KateViewInternal::dropEvent( TQDropEvent* event )
3209 if ( KURLDrag::canDecode(event) ) {
3211 emit dropEventPass(event);
3213 }
else if ( TQTextDrag::canDecode(event) && m_doc->isReadWrite() ) {
3217 if (!TQTextDrag::decode(event, text))
3222 if (
event->source() &&
event->source()->inherits(
"KateViewInternal"))
3223 priv = m_doc->ownedView( ((KateViewInternal*)(
event->source()))->m_view );
3226 bool selected = isTargetSelected(
event->pos() );
3228 if( priv && selected ) {
3235 m_doc->editStart ();
3238 if (
event->action() != TQDropEvent::Copy )
3239 m_view->removeSelectedText();
3241 m_doc->insertText( cursor.line(), cursor.col(), text );
3245 placeCursor(
event->pos() );
3247 event->acceptAction();
3252 dragInfo.state = diNone;
3258 void KateViewInternal::clear()
3260 cursor.setPos(0, 0);
3261 displayCursor.setPos(0, 0);
3264 void KateViewInternal::wheelEvent(TQWheelEvent* e)
3266 if (e->state() & ControlButton)
3279 if (m_lineScroll->minValue() != m_lineScroll->maxValue() && e->orientation() != TQt::Horizontal)
3282 if ( e->state() & ShiftButton )
3291 scrollViewLines(-((e->delta() / 120) * TQApplication::wheelScrollLines()));
3294 leftBorder->update();
3296 }
else if (columnScrollingPossible()) {
3297 TQWheelEvent
copy = *e;
3298 TQApplication::sendEvent(m_columnScroll, ©);
3306 void KateViewInternal::startDragScroll()
3308 if ( !m_dragScrollTimer.isActive() ) {
3309 m_dragScrollTimer.start( scrollTime );
3313 void KateViewInternal::stopDragScroll()
3315 m_dragScrollTimer.stop();
3319 void KateViewInternal::doDragScroll()
3321 TQPoint p = this->mapFromGlobal( TQCursor::pos() );
3324 if ( p.y() < scrollMargin ) {
3325 dy = p.y() - scrollMargin;
3326 }
else if ( p.y() > height() - scrollMargin ) {
3327 dy = scrollMargin - (height() - p.y());
3330 if ( p.x() < scrollMargin ) {
3331 dx = p.x() - scrollMargin;
3332 }
else if ( p.x() > width() - scrollMargin ) {
3333 dx = scrollMargin - (width() - p.x());
3339 scrollLines(startPos().line() + dy);
3341 if (columnScrollingPossible () && dx)
3342 scrollColumns(kMin (m_startX + dx, m_columnScroll->maxValue()));
3348 void KateViewInternal::enableTextHints(
int timeout)
3350 m_textHintTimeout=timeout;
3351 m_textHintEnabled=
true;
3352 m_textHintTimer.start(timeout);
3355 void KateViewInternal::disableTextHints()
3357 m_textHintEnabled=
false;
3358 m_textHintTimer.stop ();
3361 bool KateViewInternal::columnScrollingPossible ()
3363 return !m_view->dynWordWrap() && m_columnScroll->isEnabled() && (m_columnScroll->maxValue() > 0);
3367 void KateViewInternal::editStart()
3369 editSessionNumber++;
3371 if (editSessionNumber > 1)
3374 editIsRunning =
true;
3375 editOldCursor = cursor;
3378 void KateViewInternal::editEnd(
int editTagLineStart,
int editTagLineEnd,
bool tagFrom)
3380 if (editSessionNumber == 0)
3383 editSessionNumber--;
3385 if (editSessionNumber > 0)
3388 if (tagFrom && (editTagLineStart <=
int(m_doc->getRealLine(startLine()))))
3391 tagLines (editTagLineStart, tagFrom ? m_doc->lastLine() : editTagLineEnd,
true);
3393 if (editOldCursor == cursor)
3394 updateBracketMarks();
3396 if (m_imPreeditLength <= 0)
3399 if ((editOldCursor != cursor) && (m_imPreeditLength <= 0))
3401 m_madeVisible =
false;
3402 updateCursor ( cursor,
true );
3404 else if ( m_view == m_doc->activeView() )
3406 makeVisible(displayCursor, displayCursor.col());
3409 editIsRunning =
false;
3412 void KateViewInternal::editSetCursor (
const KateTextCursor &cursor)
3414 if (this->cursor != cursor)
3416 this->cursor.setPos (cursor);
3421 void KateViewInternal::viewSelectionChanged ()
3423 if (!m_view->hasSelection())
3425 selectAnchor.setPos (-1, -1);
3426 selStartCached.setPos (-1, -1);
3431 void KateViewInternal::imStartEvent( TQIMEvent *e )
3433 if ( m_doc->m_bReadOnly ) {
3438 if ( m_view->hasSelection() )
3439 m_view->removeSelectedText();
3441 m_imPreeditStartLine = cursor.line();
3442 m_imPreeditStart = cursor.col();
3443 m_imPreeditLength = 0;
3444 m_imPreeditSelStart = m_imPreeditStart;
3446 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
true );
3449 void KateViewInternal::imComposeEvent( TQIMEvent *e )
3451 if ( m_doc->m_bReadOnly ) {
3457 if ( m_imPreeditLength > 0 ) {
3458 cursor.setPos( m_imPreeditStartLine, m_imPreeditStart );
3459 m_doc->removeText( m_imPreeditStartLine, m_imPreeditStart,
3460 m_imPreeditStartLine, m_imPreeditStart + m_imPreeditLength );
3463 m_imPreeditLength = e->text().length();
3464 m_imPreeditSelStart = m_imPreeditStart + e->cursorPos();
3467 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, m_imPreeditStart + m_imPreeditLength,
3468 m_imPreeditSelStart, m_imPreeditSelStart + e->selectionLength(),
3472 m_doc->insertText( m_imPreeditStartLine, m_imPreeditStart, e->text() );
3476 cursor.setPos( m_imPreeditStartLine, m_imPreeditSelStart );
3477 updateCursor( cursor,
true );
3482 void KateViewInternal::imEndEvent( TQIMEvent *e )
3484 if ( m_doc->m_bReadOnly ) {
3489 if ( m_imPreeditLength > 0 ) {
3490 cursor.setPos( m_imPreeditStartLine, m_imPreeditStart );
3491 m_doc->removeText( m_imPreeditStartLine, m_imPreeditStart,
3492 m_imPreeditStartLine, m_imPreeditStart + m_imPreeditLength );
3495 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
false );
3497 if ( e->text().length() > 0 ) {
3498 m_doc->insertText( cursor.line(), cursor.col(), e->text() );
3500 if ( !m_cursorTimer.isActive() && TDEApplication::cursorFlashTime() > 0 )
3501 m_cursorTimer.start ( TDEApplication::cursorFlashTime() / 2 );
3504 updateCursor( cursor,
true );
3507 m_imPreeditStart = 0;
3508 m_imPreeditLength = 0;
3509 m_imPreeditSelStart = 0;
static TQCursor arrowCursor()
static TQCursor ibeamCursor()
Handles all of the work of rendering the text (used for the views and printing)
Simple cursor class with no document pointer.
static int dndEventDelay()
kndbgstream & endl(kndbgstream &s)
kdbgstream kdDebug(int area=0)
int event(const TQString &message, const TQString &text=TQString::null) TDE_DEPRECATED
const TDEShortcut & copy()
const TDEShortcut & end()