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>
50#include <tqclipboard.h>
54KateViewInternal::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);
220KateViewInternal::~KateViewInternal ()
224void KateViewInternal::prepareForDynWrapChange()
227 m_wrapChangeViewLine = displayViewLine(displayCursor,
true);
230void 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;
291uint KateViewInternal::endLine()
const
293 return endPos().line();
296KateLineRange 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];
307int KateViewInternal::lineToY(uint viewLine)
const
309 return (viewLine-startLine()) * m_view->renderer()->fontHeight();
312void KateViewInternal::slotIncFontSizes()
314 m_view->renderer()->increaseFontSizes();
317void KateViewInternal::slotDecFontSizes()
319 m_view->renderer()->decreaseFontSizes();
325void KateViewInternal::scrollLines (
int line )
332void KateViewInternal::scrollViewLines(
int offset)
337 m_lineScroll->blockSignals(
true);
338 m_lineScroll->setValue(startLine());
339 m_lineScroll->blockSignals(
false);
342void KateViewInternal::scrollNextPage()
344 scrollViewLines(kMax( (
int)linesDisplayed() - 1, 0 ));
347void KateViewInternal::scrollPrevPage()
349 scrollViewLines(-kMax( (
int)linesDisplayed() - 1, 0 ));
352void KateViewInternal::scrollPrevLine()
357void 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;
379void 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();
448void 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);
470void 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);
715void 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);
764void 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;
817void KateViewInternal::slotRegionVisibilityChangedAt(
unsigned int)
819 kdDebug(13030) <<
"slotRegionVisibilityChangedAt()" <<
endl;
820 m_cachedMaxStartPos.setLine(-1);
822 if (startPos() > max)
827 leftBorder->update();
830void KateViewInternal::slotCodeFoldingChanged()
832 leftBorder->update();
835void KateViewInternal::slotRegionBeginEndAddedRemoved(
unsigned int)
837 kdDebug(13030) <<
"slotRegionBeginEndAddedRemoved()" <<
endl;
839 leftBorder->update();
842void KateViewInternal::showEvent ( TQShowEvent *e )
846 TQWidget::showEvent (e);
849uint KateViewInternal::linesDisplayed()
const
852 int fh = m_view->renderer()->fontHeight();
854 return (h - (h % fh)) / fh;
857TQPoint 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);
870void 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());
893void KateViewInternal::doReturn()
896 m_doc->newLine( c,
this );
901void KateViewInternal::doDelete()
903 m_doc->del( m_view, cursor );
904 if (m_view->m_codeCompletion->codeCompletionVisible()) {
905 m_view->m_codeCompletion->updateBox();
909void KateViewInternal::doBackspace()
911 m_doc->backspace( m_view, cursor );
912 if (m_view->m_codeCompletion->codeCompletionVisible()) {
913 m_view->m_codeCompletion->updateBox();
917void KateViewInternal::doTranspose()
919 m_doc->transpose( cursor );
922void KateViewInternal::doDeleteWordLeft()
925 m_view->removeSelectedText();
929void 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;
1004class 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 );
1050class 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() );
1092void 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 );
1138void 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();
1149void KateViewInternal::cursorRight(
bool sel )
1151 moveChar( right_b, sel );
1152 if (m_view->m_codeCompletion->codeCompletionVisible()) {
1153 m_view->m_codeCompletion->updateBox();
1157void 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 );
1200void 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 );
1241void KateViewInternal::moveEdge( Bias bias,
bool sel )
1243 BoundedCursor c(
this, cursor );
1245 updateSelection( c, sel );
1249void 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 );
1290void 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);
1334KateLineRange 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);
1399KateLineRange KateViewInternal::currentRange()
1403 return range(cursor);
1406KateLineRange 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);
1416KateLineRange 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);
1428KateLineRange 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);
1443KateLineRange 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;
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;
1483int 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))
1534uint 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;
1549uint 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));
1680int 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);
1710int KateViewInternal::lineMaxCol(
const KateLineRange& range)
1712 int maxCol = range.endCol;
1714 if (maxCol && range.wrap)
1720void 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 );
1787void 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);
1857void KateViewInternal::cursorToMatchingBracket(
bool sel )
1861 if( !m_doc->findMatchingBracket( start, end ) )
1868 end.setCol(
end.col() + 1);
1870 updateSelection( end, sel );
1871 updateCursor( end );
1874void KateViewInternal::topOfView(
bool sel )
1876 KateTextCursor c = viewLineOffset(startPos(), m_minLinesVisible);
1877 updateSelection( c, sel );
1881void KateViewInternal::bottomOfView(
bool sel )
1885 updateSelection( c, sel );
1890void KateViewInternal::scrollLines(
int lines,
bool sel )
1895 c.setLine(m_doc->getRealLine(c.line()));
1897 updateSelection( c, sel );
1902void KateViewInternal::scrollUp()
1908void KateViewInternal::scrollDown()
1914void KateViewInternal::setAutoCenterLines(
int viewLines,
bool updateView)
1916 m_autoCenterLines = viewLines;
1917 m_minLinesVisible = kMin(
int((linesDisplayed() - 1)/2), m_autoCenterLines);
1919 KateViewInternal::updateView();
1922void 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 );
1971void 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 );
2020int 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);
2042void KateViewInternal::top(
bool sel )
2045 m_view->renderer()->textWidth( c, cXPos );
2046 updateSelection( c, sel );
2050void KateViewInternal::bottom(
bool sel )
2053 m_view->renderer()->textWidth( c, cXPos );
2054 updateSelection( c, sel );
2058void 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 );
2070void 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 );
2082void 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 );
2212void 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();
2271void 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);
2324bool 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());
2335bool 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());
2406void KateViewInternal::tagAll()
2409 for (uint z = 0; z < lineRanges.size(); z++)
2411 lineRanges[z].dirty =
true;
2414 leftBorder->updateFont();
2415 leftBorder->update ();
2418void KateViewInternal::paintCursor()
2420 if (tagLine(displayCursor))
2421 paintText (0,0,width(), height(),
true);
2425void 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 );
2457bool 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 );
2472bool 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 );
2550void 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 ();
2671void 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;
2698void 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 ) );
2725void 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);
2852void 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);
2954void KateViewInternal::tripleClickTimeout()
2956 possibleTripleClick =
false;
2959void 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 );
3011void 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();
3088void KateViewInternal::paintEvent(TQPaintEvent *e)
3090 paintText(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
3093void 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)
3150void KateViewInternal::scrollTimeout ()
3152 if (scrollX || scrollY)
3154 scrollLines (startPos().line() + (scrollY / (
int)m_view->renderer()->fontHeight()));
3155 placeCursor( TQPoint( mouseX, mouseY ),
true );
3159void KateViewInternal::cursorTimeout ()
3161 m_view->renderer()->setDrawCaret(!m_view->renderer()->drawCaret());
3165void 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;
3188void 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 );
3203void 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();
3217void KateViewInternal::doDrag()
3219 dragInfo.state = diDragging;
3220 dragInfo.dragObject =
new TQTextDrag(m_view->selection(),
this);
3221 dragInfo.dragObject->drag();
3224void KateViewInternal::dragEnterEvent( TQDragEnterEvent* event )
3226 event->accept( (TQTextDrag::canDecode(event) && m_doc->isReadWrite()) ||
3227 KURLDrag::canDecode(event) );
3230void KateViewInternal::dragMoveEvent( TQDragMoveEvent* event )
3233 placeCursor(
event->pos(),
true,
false );
3237 event->acceptAction();
3240void 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;
3291void KateViewInternal::clear()
3293 cursor.setPos(0, 0);
3294 displayCursor.setPos(0, 0);
3297void 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, ©);
3339void KateViewInternal::startDragScroll()
3341 if ( !m_dragScrollTimer.isActive() ) {
3342 m_dragScrollTimer.start( scrollTime );
3346void KateViewInternal::stopDragScroll()
3348 m_dragScrollTimer.stop();
3352void 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()));
3381void KateViewInternal::enableTextHints(
int timeout)
3383 m_textHintTimeout=timeout;
3384 m_textHintEnabled=
true;
3385 m_textHintTimer.start(timeout);
3388void KateViewInternal::disableTextHints()
3390 m_textHintEnabled=
false;
3391 m_textHintTimer.stop ();
3394bool KateViewInternal::columnScrollingPossible ()
3396 return !m_view->dynWordWrap() && m_columnScroll->isEnabled() && (m_columnScroll->maxValue() > 0);
3400void KateViewInternal::editStart()
3402 editSessionNumber++;
3404 if (editSessionNumber > 1)
3407 editIsRunning =
true;
3408 editOldCursor = cursor;
3411void 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;
3445void KateViewInternal::editSetCursor (
const KateTextCursor &cursor)
3447 if (this->cursor != cursor)
3449 this->cursor.setPos (cursor);
3454void KateViewInternal::viewSelectionChanged ()
3456 if (!m_view->hasSelection())
3458 selectAnchor.setPos (-1, -1);
3459 selStartCached.setPos (-1, -1);
3464void 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 );
3482void 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 );
3515void 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;
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()