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, TQT_TQOBJECT(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, TQT_SIGNAL(prevPage()), TQT_SLOT(scrollPrevPage()));
120 connect(m_lineScroll, TQT_SIGNAL(nextPage()), TQT_SLOT(scrollNextPage()));
122 connect(m_lineScroll, TQT_SIGNAL(prevLine()), TQT_SLOT(scrollPrevLine()));
123 connect(m_lineScroll, TQT_SIGNAL(nextLine()), TQT_SLOT(scrollNextLine()));
125 connect(m_lineScroll, TQT_SIGNAL(sliderMoved(
int)), TQT_SLOT(scrollLines(
int)));
126 connect(m_lineScroll, TQT_SIGNAL(sliderMMBMoved(
int)), TQT_SLOT(scrollLines(
int)));
129 m_lineScroll->installEventFilter(
this);
134 m_columnScroll =
new TQScrollBar(Qt::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, TQT_SIGNAL( valueChanged (
int) ),
146 this, TQT_SLOT( scrollColumns (
int) ) );
151 leftBorder =
new KateIconBorder(
this, m_view );
154 connect( leftBorder, TQT_SIGNAL(toggleRegionVisibility(
unsigned int)),
155 m_doc->foldingTree(), TQT_SLOT(toggleRegionVisibility(
unsigned int)));
157 connect( doc->foldingTree(), TQT_SIGNAL(regionVisibilityChangedAt(
unsigned int)),
158 this, TQT_SLOT(slotRegionVisibilityChangedAt(
unsigned int)));
159 connect( doc, TQT_SIGNAL(codeFoldingUpdated()),
160 this, TQT_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, TQT_SIGNAL( timeout() ),
186 this, TQT_SLOT( doDragScroll() ) );
188 connect( &m_scrollTimer, TQT_SIGNAL( timeout() ),
189 this, TQT_SLOT( scrollTimeout() ) );
191 connect( &m_cursorTimer, TQT_SIGNAL( timeout() ),
192 this, TQT_SLOT( cursorTimeout() ) );
194 connect( &m_textHintTimer, TQT_SIGNAL( timeout() ),
195 this, TQT_SLOT( textHintTimeout() ) );
198 connect( m_view, TQT_SIGNAL( selectionChanged() ),
199 this, TQT_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 && QABS(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 (QABS(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, Qt::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, Qt::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, Qt::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, Qt::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, Qt::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, Qt::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, Qt::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, Qt::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 (TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(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() == Qt::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 + Qt::Key_Return) || (key == SHIFT + Qt::Key_Enter)) {
2529 m_view->m_codeCompletion->doComplete();
2535 if( !m_doc->isReadWrite() )
2541 if ((key == Qt::Key_Return) || (key == Qt::Key_Enter))
2543 m_view->keyReturn();
2548 if ((key == SHIFT + Qt::Key_Return) || (key == SHIFT + Qt::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 == Qt::Key_Backspace || key == SHIFT + Qt::Key_Backspace)
2578 m_view->backspace();
2582 m_view->m_codeCompletion->updateBox ();
2587 if (key == Qt::Key_Tab || key == SHIFT+Qt::Key_Backtab || key == Qt::Key_Backtab)
2589 if (m_doc->invokeTabInterceptor(key)) {
2593 if (m_doc->configFlags() & KateDocumentConfig::cfTabIndents)
2595 if( key == Qt::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+Qt::Key_Backtab || key == Qt::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 Qt::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 Qt::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, TQT_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 Qt::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;
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() & Qt::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 (m_lineScroll->minValue() != m_lineScroll->maxValue() && e->orientation() != Qt::Horizontal) {
3268 if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) {
3274 scrollViewLines(-((e->delta() / 120) * TQApplication::wheelScrollLines()));
3277 leftBorder->update();
3280 }
else if (columnScrollingPossible()) {
3281 TQWheelEvent
copy = *e;
3282 TQApplication::sendEvent(m_columnScroll, ©);
3289 void KateViewInternal::startDragScroll()
3291 if ( !m_dragScrollTimer.isActive() ) {
3292 m_dragScrollTimer.start( scrollTime );
3296 void KateViewInternal::stopDragScroll()
3298 m_dragScrollTimer.stop();
3302 void KateViewInternal::doDragScroll()
3304 TQPoint p = this->mapFromGlobal( TQCursor::pos() );
3307 if ( p.y() < scrollMargin ) {
3308 dy = p.y() - scrollMargin;
3309 }
else if ( p.y() > height() - scrollMargin ) {
3310 dy = scrollMargin - (height() - p.y());
3313 if ( p.x() < scrollMargin ) {
3314 dx = p.x() - scrollMargin;
3315 }
else if ( p.x() > width() - scrollMargin ) {
3316 dx = scrollMargin - (width() - p.x());
3322 scrollLines(startPos().line() + dy);
3324 if (columnScrollingPossible () && dx)
3325 scrollColumns(kMin (m_startX + dx, m_columnScroll->maxValue()));
3331 void KateViewInternal::enableTextHints(
int timeout)
3333 m_textHintTimeout=timeout;
3334 m_textHintEnabled=
true;
3335 m_textHintTimer.start(timeout);
3338 void KateViewInternal::disableTextHints()
3340 m_textHintEnabled=
false;
3341 m_textHintTimer.stop ();
3344 bool KateViewInternal::columnScrollingPossible ()
3346 return !m_view->dynWordWrap() && m_columnScroll->isEnabled() && (m_columnScroll->maxValue() > 0);
3350 void KateViewInternal::editStart()
3352 editSessionNumber++;
3354 if (editSessionNumber > 1)
3357 editIsRunning =
true;
3358 editOldCursor = cursor;
3361 void KateViewInternal::editEnd(
int editTagLineStart,
int editTagLineEnd,
bool tagFrom)
3363 if (editSessionNumber == 0)
3366 editSessionNumber--;
3368 if (editSessionNumber > 0)
3371 if (tagFrom && (editTagLineStart <=
int(m_doc->getRealLine(startLine()))))
3374 tagLines (editTagLineStart, tagFrom ? m_doc->lastLine() : editTagLineEnd,
true);
3376 if (editOldCursor == cursor)
3377 updateBracketMarks();
3379 if (m_imPreeditLength <= 0)
3382 if ((editOldCursor != cursor) && (m_imPreeditLength <= 0))
3384 m_madeVisible =
false;
3385 updateCursor ( cursor,
true );
3387 else if ( m_view == m_doc->activeView() )
3389 makeVisible(displayCursor, displayCursor.col());
3392 editIsRunning =
false;
3395 void KateViewInternal::editSetCursor (
const KateTextCursor &cursor)
3397 if (this->cursor != cursor)
3399 this->cursor.setPos (cursor);
3404 void KateViewInternal::viewSelectionChanged ()
3406 if (!m_view->hasSelection())
3408 selectAnchor.setPos (-1, -1);
3409 selStartCached.setPos (-1, -1);
3414 void KateViewInternal::imStartEvent( TQIMEvent *e )
3416 if ( m_doc->m_bReadOnly ) {
3421 if ( m_view->hasSelection() )
3422 m_view->removeSelectedText();
3424 m_imPreeditStartLine = cursor.line();
3425 m_imPreeditStart = cursor.col();
3426 m_imPreeditLength = 0;
3427 m_imPreeditSelStart = m_imPreeditStart;
3429 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
true );
3432 void KateViewInternal::imComposeEvent( TQIMEvent *e )
3434 if ( m_doc->m_bReadOnly ) {
3440 if ( m_imPreeditLength > 0 ) {
3441 cursor.setPos( m_imPreeditStartLine, m_imPreeditStart );
3442 m_doc->removeText( m_imPreeditStartLine, m_imPreeditStart,
3443 m_imPreeditStartLine, m_imPreeditStart + m_imPreeditLength );
3446 m_imPreeditLength = e->text().length();
3447 m_imPreeditSelStart = m_imPreeditStart + e->cursorPos();
3450 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, m_imPreeditStart + m_imPreeditLength,
3451 m_imPreeditSelStart, m_imPreeditSelStart + e->selectionLength(),
3455 m_doc->insertText( m_imPreeditStartLine, m_imPreeditStart, e->text() );
3459 cursor.setPos( m_imPreeditStartLine, m_imPreeditSelStart );
3460 updateCursor( cursor,
true );
3465 void KateViewInternal::imEndEvent( TQIMEvent *e )
3467 if ( m_doc->m_bReadOnly ) {
3472 if ( m_imPreeditLength > 0 ) {
3473 cursor.setPos( m_imPreeditStartLine, m_imPreeditStart );
3474 m_doc->removeText( m_imPreeditStartLine, m_imPreeditStart,
3475 m_imPreeditStartLine, m_imPreeditStart + m_imPreeditLength );
3478 m_view->setIMSelectionValue( m_imPreeditStartLine, m_imPreeditStart, 0, 0, 0,
false );
3480 if ( e->text().length() > 0 ) {
3481 m_doc->insertText( cursor.line(), cursor.col(), e->text() );
3483 if ( !m_cursorTimer.isActive() && TDEApplication::cursorFlashTime() > 0 )
3484 m_cursorTimer.start ( TDEApplication::cursorFlashTime() / 2 );
3487 updateCursor( cursor,
true );
3490 m_imPreeditStart = 0;
3491 m_imPreeditLength = 0;
3492 m_imPreeditSelStart = 0;
Simple cursor class with no document pointer.
int key(StdAccel) KDE_DEPRECATED
static int dndEventDelay()
kdbgstream kdDebug(int area=0)
Handles all of the work of rendering the text (used for the views and printing)
const TDEShortcut & end()
static TQCursor arrowCursor()
static TQCursor ibeamCursor()
const TDEShortcut & copy()
kndbgstream & endl(kndbgstream &s)