• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • applications API Reference
  • KDE Home
  • Contact Us
 

Kate

  • kde-4.14
  • applications
  • kate
  • part
  • view
kateviewinternal.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
3  Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
4  Copyright (C) 2002,2003 Christoph Cullmann <cullmann@kde.org>
5  Copyright (C) 2002-2007 Hamish Rodda <rodda@kde.org>
6  Copyright (C) 2003 Anakim Border <aborder@sources.sourceforge.net>
7  Copyright (C) 2007 Mirko Stocker <me@misto.ch>
8  Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
9  Copyright (C) 2008 Erlend Hamberg <ehamberg@gmail.com>
10 
11  Based on:
12  KWriteView : Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
13 
14  This library is free software; you can redistribute it and/or
15  modify it under the terms of the GNU Library General Public
16  License version 2 as published by the Free Software Foundation.
17 
18  This library is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Library General Public License for more details.
22 
23  You should have received a copy of the GNU Library General Public License
24  along with this library; see the file COPYING.LIB. If not, write to
25  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26  Boston, MA 02110-1301, USA.
27 */
28 
29 #include "kateviewinternal.h"
30 #include "kateviewinternal.moc"
31 
32 #include "kateview.h"
33 #include "kateviewhelpers.h"
34 #include "katehighlight.h"
35 #include "katebuffer.h"
36 #include "katerenderer.h"
37 #include "kateconfig.h"
38 #include "katelayoutcache.h"
39 #include "katecompletionwidget.h"
40 #include "kateviinputmodemanager.h"
41 #include "katesearchbar.h"
42 #include "spellcheck/spellingmenu.h"
43 #include "kateviewaccessible.h"
44 #include "katetextanimation.h"
45 #include "katemessagewidget.h"
46 
47 #include <ktexteditor/movingrange.h>
48 #include <kcursor.h>
49 #include <kdebug.h>
50 #include <kapplication.h>
51 #include <kglobalsettings.h>
52 
53 #include <QtCore/QMimeData>
54 #include <QtGui/QPainter>
55 #include <QtGui/QClipboard>
56 #include <QtGui/QPixmap>
57 #include <QtGui/QKeyEvent>
58 #include <QtGui/QLayout>
59 #include <QToolTip>
60 
61 static const bool debugPainting = false;
62 
63 KateViewInternal::KateViewInternal(KateView *view)
64  : QWidget (view)
65  , editSessionNumber (0)
66  , editIsRunning (false)
67  , m_view (view)
68  , m_cursor(doc()->buffer(), KTextEditor::Cursor(0, 0), Kate::TextCursor::MoveOnInsert)
69  , m_mouse()
70  , m_possibleTripleClick (false)
71  , m_completionItemExpanded (false)
72  , m_bm(doc()->newMovingRange(KTextEditor::Range::invalid(), KTextEditor::MovingRange::DoNotExpand))
73  , m_bmStart(doc()->newMovingRange(KTextEditor::Range::invalid(), KTextEditor::MovingRange::DoNotExpand))
74  , m_bmEnd(doc()->newMovingRange(KTextEditor::Range::invalid(), KTextEditor::MovingRange::DoNotExpand))
75  , m_bmLastFlashPos(doc()->newMovingCursor(KTextEditor::Cursor::invalid()))
76  , m_dummy (0)
77 
78  // stay on cursor will avoid that the view scroll around on press return at beginning
79  , m_startPos (doc()->buffer(), KTextEditor::Cursor (0, 0), Kate::TextCursor::StayOnInsert)
80 
81  , m_visibleLineCount(0)
82  , m_madeVisible(false)
83  , m_shiftKeyPressed (false)
84  , m_autoCenterLines(0)
85  , m_minLinesVisible(0)
86  , m_selChangedByUser (false)
87  , m_selectAnchor (-1, -1)
88  , m_selectionMode( Default )
89  , m_layoutCache(new KateLayoutCache(renderer(), this))
90  , m_preserveX(false)
91  , m_preservedX(0)
92  , m_cachedMaxStartPos(-1, -1)
93  , m_dragScrollTimer(this)
94  , m_scrollTimer (this)
95  , m_cursorTimer (this)
96  , m_textHintTimer (this)
97  , m_textHintEnabled(false)
98  , m_textHintPos(-1, -1)
99  , m_imPreeditRange(0)
100  , m_viInputMode(false)
101  , m_viInputModeManager (0)
102 {
103  setMinimumSize (0,0);
104  setAttribute(Qt::WA_OpaquePaintEvent);
105  setAttribute(Qt::WA_InputMethodEnabled);
106 
107  // invalidate m_selectionCached.start(), or keyb selection is screwed initially
108  m_selectionCached = KTextEditor::Range::invalid();
109 
110  // bracket markers are only for this view and should not be printed
111  m_bm->setView (m_view);
112  m_bmStart->setView (m_view);
113  m_bmEnd->setView (m_view);
114  m_bm->setAttributeOnlyForViews (true);
115  m_bmStart->setAttributeOnlyForViews (true);
116  m_bmEnd->setAttributeOnlyForViews (true);
117 
118  // use z depth defined in moving ranges interface
119  m_bm->setZDepth (-1000.0);
120  m_bmStart->setZDepth (-1000.0);
121  m_bmEnd->setZDepth (-1000.0);
122 
123  // update mark attributes
124  updateBracketMarkAttributes();
125 
126  //
127  // scrollbar for lines
128  //
129  m_lineScroll = new KateScrollBar(Qt::Vertical, this);
130  m_lineScroll->show();
131  m_lineScroll->setTracking (true);
132  m_lineScroll->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding );
133 
134  // Hijack the line scroller's controls, so we can scroll nicely for word-wrap
135  connect(m_lineScroll, SIGNAL(actionTriggered(int)), SLOT(scrollAction(int)));
136  connect(m_lineScroll, SIGNAL(sliderMoved(int)), SLOT(scrollLines(int)));
137  connect(m_lineScroll, SIGNAL(sliderMMBMoved(int)), SLOT(scrollLines(int)));
138  connect(m_lineScroll, SIGNAL(valueChanged(int)), SLOT(scrollLines(int)));
139 
140  // catch wheel events, completing the hijack
141  m_lineScroll->installEventFilter(this);
142 
143  //
144  // scrollbar for columns
145  //
146  m_columnScroll = new QScrollBar(Qt::Horizontal,m_view);
147 
148  if (m_view->dynWordWrap())
149  m_columnScroll->hide();
150  else
151  m_columnScroll->show();
152 
153  m_columnScroll->setTracking(true);
154  m_startX = 0;
155 
156  connect(m_columnScroll, SIGNAL(valueChanged(int)), SLOT(scrollColumns(int)));
157 
158  // bottom corner box
159  m_dummy = new QWidget(m_view);
160  m_dummy->setFixedSize(m_lineScroll->width(), m_columnScroll->sizeHint().height());
161  m_dummy->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
162 
163  if (m_view->dynWordWrap())
164  m_dummy->hide();
165  else
166  m_dummy->show();
167 
168  cache()->setWrap(m_view->dynWordWrap());
169 
170  //
171  // iconborder ;)
172  //
173  m_leftBorder = new KateIconBorder( this, m_view );
174  m_leftBorder->show ();
175 
176  // update view if folding ranges change
177  connect( &m_view->textFolding(), SIGNAL(foldingRangesChanged()), SLOT(slotRegionVisibilityChanged()));
178 
179  m_displayCursor.setPosition(0, 0);
180 
181  setAcceptDrops( true );
182 
183  // event filter
184  installEventFilter(this);
185 
186  // set initial cursor
187  m_mouseCursor = Qt::IBeamCursor;
188  setCursor(m_mouseCursor);
189 
190  // call mouseMoveEvent also if no mouse button is pressed
191  setMouseTracking(true);
192 
193  m_dragInfo.state = diNone;
194 
195  // timers
196  connect( &m_dragScrollTimer, SIGNAL(timeout()),
197  this, SLOT(doDragScroll()) );
198 
199  connect( &m_scrollTimer, SIGNAL(timeout()),
200  this, SLOT(scrollTimeout()) );
201 
202  connect( &m_cursorTimer, SIGNAL(timeout()),
203  this, SLOT(cursorTimeout()) );
204 
205  connect( &m_textHintTimer, SIGNAL(timeout()),
206  this, SLOT(textHintTimeout()) );
207 
208  // selection changed to set anchor
209  connect( m_view, SIGNAL(selectionChanged(KTextEditor::View*)),
210  this, SLOT(viewSelectionChanged()) );
211 
212 #ifndef QT_NO_ACCESSIBILITY
213 #if QT_VERSION >= 0x040800
214  QAccessible::installFactory(accessibleInterfaceFactory);
215 #endif
216 #endif
217 
218  // update is called in KateView, after construction and layout is over
219  // but before any other kateviewinternal call
220 }
221 
222 KateViewInternal::~KateViewInternal ()
223 {
224  // delete text animation object here, otherwise it updates the view in its destructor
225  if (m_textAnimation) {
226  delete m_textAnimation;
227  }
228 
229 #ifndef QT_NO_ACCESSIBILITY
230 #if QT_VERSION >= 0x040800
231  QAccessible::removeFactory(accessibleInterfaceFactory);
232 #endif
233 #endif
234 
235  // kill preedit ranges
236  delete m_imPreeditRange;
237  qDeleteAll (m_imPreeditRangeChildren);
238 
239  delete m_viInputModeManager;
240 
241  // delete bracket markers
242  delete m_bm;
243  delete m_bmStart;
244  delete m_bmEnd;
245 }
246 
247 void KateViewInternal::prepareForDynWrapChange()
248 {
249  // Which is the current view line?
250  m_wrapChangeViewLine = cache()->displayViewLine(m_displayCursor, true);
251 }
252 
253 void KateViewInternal::dynWrapChanged()
254 {
255  m_dummy->setFixedSize(m_lineScroll->width(), m_columnScroll->sizeHint().height());
256  if (m_view->dynWordWrap())
257  {
258  m_columnScroll->hide();
259  m_dummy->hide();
260 
261  }
262  else
263  {
264  // column scrollbar + bottom corner box
265  m_columnScroll->show();
266  m_dummy->show();
267  }
268 
269  cache()->setWrap(m_view->dynWordWrap());
270  updateView();
271 
272  if (m_view->dynWordWrap())
273  scrollColumns(0);
274 
275  // Determine where the cursor should be to get the cursor on the same view line
276  if (m_wrapChangeViewLine != -1) {
277  KTextEditor::Cursor newStart = viewLineOffset(m_displayCursor, -m_wrapChangeViewLine);
278  makeVisible(newStart, newStart.column(), true);
279 
280  } else {
281  update();
282  }
283 }
284 
285 KTextEditor::Cursor KateViewInternal::endPos() const
286 {
287  // Hrm, no lines laid out at all??
288  if (!cache()->viewCacheLineCount())
289  return KTextEditor::Cursor();
290 
291  for (int i = qMin(linesDisplayed() - 1, cache()->viewCacheLineCount() - 1); i >= 0; i--) {
292  const KateTextLayout& thisLine = cache()->viewLine(i);
293 
294  if (thisLine.line() == -1) continue;
295 
296  if (thisLine.virtualLine() >= m_view->textFolding().visibleLines()) {
297  // Cache is too out of date
298  return KTextEditor::Cursor(m_view->textFolding().visibleLines() - 1, doc()->lineLength(m_view->textFolding().visibleLineToLine(m_view->textFolding().visibleLines() - 1)));
299  }
300 
301  return KTextEditor::Cursor(thisLine.virtualLine(), thisLine.wrap() ? thisLine.endCol() - 1 : thisLine.endCol());
302  }
303 
304  return KTextEditor::Cursor();
305 }
306 
307 int KateViewInternal::endLine() const
308 {
309  return endPos().line();
310 }
311 
312 KateTextLayout KateViewInternal::yToKateTextLayout(int y) const
313 {
314  if (y < 0 || y > size().height())
315  return KateTextLayout::invalid();
316 
317  int range = y / renderer()->lineHeight();
318 
319  // lineRanges is always bigger than 0, after the initial updateView call
320  if (range >= 0 && range < cache()->viewCacheLineCount())
321  return cache()->viewLine(range);
322 
323  return KateTextLayout::invalid();
324 }
325 
326 int KateViewInternal::lineToY(int viewLine) const
327 {
328  return (viewLine-startLine()) * renderer()->lineHeight();
329 }
330 
331 void KateViewInternal::slotIncFontSizes()
332 {
333  renderer()->increaseFontSizes();
334  update();
335 }
336 
337 void KateViewInternal::slotDecFontSizes()
338 {
339  renderer()->decreaseFontSizes();
340  update();
341 }
342 
346 void KateViewInternal::scrollLines ( int line )
347 {
348  KTextEditor::Cursor newPos(line, 0);
349  scrollPos(newPos);
350 }
351 
352 // This can scroll less than one true line
353 void KateViewInternal::scrollViewLines(int offset)
354 {
355  KTextEditor::Cursor c = viewLineOffset(startPos(), offset);
356  scrollPos(c);
357 
358  bool blocked = m_lineScroll->blockSignals(true);
359  m_lineScroll->setValue(startLine());
360  m_lineScroll->blockSignals(blocked);
361 }
362 
363 void KateViewInternal::scrollAction( int action )
364 {
365  switch (action) {
366  case QAbstractSlider::SliderSingleStepAdd:
367  scrollNextLine();
368  break;
369 
370  case QAbstractSlider::SliderSingleStepSub:
371  scrollPrevLine();
372  break;
373 
374  case QAbstractSlider::SliderPageStepAdd:
375  scrollNextPage();
376  break;
377 
378  case QAbstractSlider::SliderPageStepSub:
379  scrollPrevPage();
380  break;
381 
382  case QAbstractSlider::SliderToMinimum:
383  top_home();
384  break;
385 
386  case QAbstractSlider::SliderToMaximum:
387  bottom_end();
388  break;
389  }
390 }
391 
392 void KateViewInternal::scrollNextPage()
393 {
394  scrollViewLines(qMax( linesDisplayed() - 1, 0 ));
395 }
396 
397 void KateViewInternal::scrollPrevPage()
398 {
399  scrollViewLines(-qMax( linesDisplayed() - 1, 0 ));
400 }
401 
402 void KateViewInternal::scrollPrevLine()
403 {
404  scrollViewLines(-1);
405 }
406 
407 void KateViewInternal::scrollNextLine()
408 {
409  scrollViewLines(1);
410 }
411 
412 KTextEditor::Cursor KateViewInternal::maxStartPos(bool changed)
413 {
414  cache()->setAcceptDirtyLayouts(true);
415 
416  if (m_cachedMaxStartPos.line() == -1 || changed)
417  {
418  KTextEditor::Cursor end(m_view->textFolding().visibleLines() - 1, doc()->lineLength(m_view->textFolding().visibleLineToLine(m_view->textFolding().visibleLines() - 1)));
419 
420  if (m_view->config()->scrollPastEnd())
421  m_cachedMaxStartPos = viewLineOffset(end, -m_minLinesVisible);
422  else
423  m_cachedMaxStartPos = viewLineOffset(end, -(linesDisplayed() - 1));
424  }
425 
426  cache()->setAcceptDirtyLayouts(false);
427 
428  return m_cachedMaxStartPos;
429 }
430 
431 // c is a virtual cursor
432 void KateViewInternal::scrollPos(KTextEditor::Cursor& c, bool force, bool calledExternally)
433 {
434  if (!force && ((!m_view->dynWordWrap() && c.line() == startLine()) || c == startPos()))
435  return;
436 
437  if (c.line() < 0)
438  c.setLine(0);
439 
440  KTextEditor::Cursor limit = maxStartPos();
441  if (c > limit) {
442  c = limit;
443 
444  // Re-check we're not just scrolling to the same place
445  if (!force && ((!m_view->dynWordWrap() && c.line() == startLine()) || c == startPos()))
446  return;
447  }
448 
449  int viewLinesScrolled = 0;
450 
451  // only calculate if this is really used and useful, could be wrong here, please recheck
452  // for larger scrolls this makes 2-4 seconds difference on my xeon with dyn. word wrap on
453  // try to get it really working ;)
454  bool viewLinesScrolledUsable = !force
455  && (c.line() >= startLine() - linesDisplayed() - 1)
456  && (c.line() <= endLine() + linesDisplayed() + 1);
457 
458  if (viewLinesScrolledUsable) {
459  viewLinesScrolled = cache()->displayViewLine(c);
460  }
461 
462  m_startPos.setPosition(c);
463 
464  // set false here but reversed if we return to makeVisible
465  m_madeVisible = false;
466 
467  if (viewLinesScrolledUsable)
468  {
469  int lines = linesDisplayed();
470  if (m_view->textFolding().visibleLines() < lines) {
471  KTextEditor::Cursor end(m_view->textFolding().visibleLines() - 1, doc()->lineLength(m_view->textFolding().visibleLineToLine(m_view->textFolding().visibleLines() - 1)));
472  lines = qMin(linesDisplayed(), cache()->displayViewLine(end) + 1);
473  }
474 
475  Q_ASSERT(lines >= 0);
476 
477  if (!calledExternally && qAbs(viewLinesScrolled) < lines)
478  {
479  updateView(false, viewLinesScrolled);
480 
481  int scrollHeight = -(viewLinesScrolled * (int)renderer()->lineHeight());
482 
483  // scroll excluding child widgets (floating notifications)
484  scroll(0, scrollHeight, rect());
485  m_leftBorder->scroll(0, scrollHeight);
486 
487  if ((m_view->m_floatTopMessageWidget && m_view->m_floatTopMessageWidget->isVisible())
488  || (m_view->m_bottomMessageWidget && m_view->m_bottomMessageWidget->isVisible()))
489  {
490  // NOTE: on some machines we must update if the floating widget is visible
491  // otherwise strange painting bugs may occur during scrolling...
492  update();
493  }
494 
495  emit m_view->verticalScrollPositionChanged( m_view, c );
496  emit m_view->displayRangeChanged(m_view);
497  return;
498  }
499  }
500 
501  updateView();
502  update();
503  m_leftBorder->update();
504  emit m_view->verticalScrollPositionChanged( m_view, c );
505  emit m_view->displayRangeChanged(m_view);
506 }
507 
508 void KateViewInternal::scrollColumns ( int x )
509 {
510  if (x < 0)
511  x = 0;
512 
513  if (x > m_columnScroll->maximum())
514  x = m_columnScroll->maximum();
515 
516  if (x == m_startX)
517  return;
518 
519  int dx = m_startX - x;
520  m_startX = x;
521 
522  if (qAbs(dx) < width()) {
523  // scroll excluding child widgets (floating notifications)
524  scroll(dx, 0, rect());
525  } else
526  update();
527 
528  emit m_view->horizontalScrollPositionChanged( m_view );
529  emit m_view->displayRangeChanged(m_view);
530 
531  bool blocked = m_columnScroll->blockSignals(true);
532  m_columnScroll->setValue(m_startX);
533  m_columnScroll->blockSignals(blocked);
534 }
535 
536 // If changed is true, the lines that have been set dirty have been updated.
537 void KateViewInternal::updateView(bool changed, int viewLinesScrolled)
538 {
539  doUpdateView(changed, viewLinesScrolled);
540 
541  if (changed)
542  updateDirty();
543 }
544 
545 void KateViewInternal::doUpdateView(bool changed, int viewLinesScrolled)
546 {
547  if(!isVisible() && !viewLinesScrolled && !changed )
548  return; //When this view is not visible, don't do anything
549 
550  bool blocked = m_lineScroll->blockSignals(true);
551 
552  if (width() != cache()->viewWidth()) {
553  cache()->setViewWidth(width());
554  changed = true;
555  }
556 
557  /* It was observed that height() could be negative here --
558  when the main Kate view has 0 as size (during creation),
559  and there frame arount KateViewInternal. In which
560  case we'd set the view cache to 0 (or less!) lines, and
561  start allocating huge chunks of data, later. */
562  int newSize = (qMax (0, height()) / renderer()->lineHeight()) + 1;
563  cache()->updateViewCache(startPos(), newSize, viewLinesScrolled);
564  m_visibleLineCount = newSize;
565 
566  KTextEditor::Cursor maxStart = maxStartPos(changed);
567  int maxLineScrollRange = maxStart.line();
568  if (m_view->dynWordWrap() && maxStart.column() != 0)
569  maxLineScrollRange++;
570  m_lineScroll->setRange(0, maxLineScrollRange);
571 
572  m_lineScroll->setValue(startPos().line());
573  m_lineScroll->setSingleStep(1);
574  m_lineScroll->setPageStep(qMax (0, height()) / renderer()->lineHeight());
575  m_lineScroll->blockSignals(blocked);
576 
577  KateViewConfig::ScrollbarMode show_scrollbars = static_cast<KateViewConfig::ScrollbarMode>(view()->config()->showScrollbars());
578 
579  bool visible = ( (show_scrollbars == KateViewConfig::AlwaysOn) ||
580  ((show_scrollbars == KateViewConfig::ShowWhenNeeded) && (maxLineScrollRange != 0)) );
581  bool visible_dummy = visible;
582 
583  m_lineScroll->setVisible( visible );
584 
585  if (!m_view->dynWordWrap())
586  {
587  int max = maxLen(startLine()) - width();
588  if (max < 0)
589  max = 0;
590 
591  // if we lose the ability to scroll horizontally, move view to the far-left
592  if (max == 0)
593  {
594  scrollColumns(0);
595  }
596 
597  blocked = m_columnScroll->blockSignals(true);
598 
599  // disable scrollbar
600  m_columnScroll->setDisabled (max == 0);
601 
602  visible = ( (show_scrollbars == KateViewConfig::AlwaysOn) ||
603  ((show_scrollbars == KateViewConfig::ShowWhenNeeded) && (max != 0)) );
604  visible_dummy &= visible;
605  m_columnScroll->setVisible( visible );
606 
607  m_columnScroll->setRange(0, max);
608 
609  m_columnScroll->setValue(m_startX);
610 
611  // Approximate linescroll
612  m_columnScroll->setSingleStep(renderer()->config()->fontMetrics().width('a'));
613  m_columnScroll->setPageStep(width());
614 
615  m_columnScroll->blockSignals(blocked);
616  } else {
617  visible_dummy = false;
618  }
619 
620  m_dummy->setVisible( visible_dummy );
621 }
622 
627 void KateViewInternal::makeVisible (const KTextEditor::Cursor& c, int endCol, bool force, bool center, bool calledExternally)
628 {
629  //kDebug(13030) << "MakeVisible start " << startPos() << " end " << endPos() << " -> request: " << c;// , new start [" << scroll.line << "," << scroll.col << "] lines " << (linesDisplayed() - 1) << " height " << height();
630  // if the line is in a folded region, unfold all the way up
631  //if ( doc()->foldingTree()->findNodeForLine( c.line )->visible )
632  // kDebug(13030)<<"line ("<<c.line<<") should be visible";
633 
634  if ( force )
635  {
636  KTextEditor::Cursor scroll = c;
637  scrollPos(scroll, force, calledExternally);
638  }
639  else if (center && (c < startPos() || c > endPos()))
640  {
641  KTextEditor::Cursor scroll = viewLineOffset(c, -int(linesDisplayed()) / 2);
642  scrollPos(scroll, false, calledExternally);
643  }
644  else if ( c > viewLineOffset(startPos(), linesDisplayed() - m_minLinesVisible - 1) )
645  {
646  KTextEditor::Cursor scroll = viewLineOffset(c, -(linesDisplayed() - m_minLinesVisible - 1));
647  scrollPos(scroll, false, calledExternally);
648  }
649  else if ( c < viewLineOffset(startPos(), m_minLinesVisible) )
650  {
651  KTextEditor::Cursor scroll = viewLineOffset(c, -m_minLinesVisible);
652  scrollPos(scroll, false, calledExternally);
653  }
654  else
655  {
656  // Check to see that we're not showing blank lines
657  KTextEditor::Cursor max = maxStartPos();
658  if (startPos() > max) {
659  scrollPos(max, max.column(), calledExternally);
660  }
661  }
662 
663  if (!m_view->dynWordWrap() && (endCol != -1 || m_view->wrapCursor()))
664  {
665  KTextEditor::Cursor rc = toRealCursor(c);
666  int sX = renderer()->cursorToX(cache()->textLayout(rc), rc, !m_view->wrapCursor());
667 
668  int sXborder = sX-8;
669  if (sXborder < 0)
670  sXborder = 0;
671 
672  if (sX < m_startX)
673  scrollColumns (sXborder);
674  else if (sX > m_startX + width())
675  scrollColumns (sX - width() + 8);
676  }
677 
678  m_madeVisible = !force;
679 
680 #ifndef QT_NO_ACCESSIBILITY
681 #if QT_VERSION >= 0x040800
682  QAccessible::updateAccessibility( this, KateCursorAccessible::ChildId, QAccessible::Focus );
683 #endif
684 #endif
685 }
686 
687 void KateViewInternal::slotRegionVisibilityChanged()
688 {
689  kDebug(13030);
690  cache()->clear();
691 
692  m_cachedMaxStartPos.setLine(-1);
693  KTextEditor::Cursor max = maxStartPos();
694  if (startPos() > max)
695  scrollPos(max);
696 
697  // if text was folded: make sure the cursor is on a visible line
698  qint64 foldedRangeId = -1;
699  if (!m_view->textFolding().isLineVisible (m_cursor.line(), &foldedRangeId)) {
700  KTextEditor::Range foldingRange = m_view->textFolding().foldingRange(foldedRangeId);
701  Q_ASSERT(foldingRange.start().isValid());
702 
703  // set cursor to start of folding region
704  updateCursor(foldingRange.start(), true);
705  }
706 
707  updateView();
708  update();
709  m_leftBorder->update();
710  emit m_view->displayRangeChanged(m_view);
711 }
712 
713 void KateViewInternal::slotRegionBeginEndAddedRemoved(unsigned int)
714 {
715  kDebug(13030);
716  // FIXME: performance problem
717  m_leftBorder->update();
718 }
719 
720 void KateViewInternal::showEvent ( QShowEvent *e )
721 {
722  updateView ();
723 
724  QWidget::showEvent (e);
725 }
726 
727 int KateViewInternal::linesDisplayed() const
728 {
729  int h = height();
730 
731  // catch zero heights, even if should not happen
732  int fh = qMax (1, renderer()->lineHeight());
733 
734  // default to 1, there is always one line around....
735  // too many places calc with linesDisplayed() - 1
736  return qMax (1, (h - (h % fh)) / fh);
737 }
738 
739 QPoint KateViewInternal::cursorToCoordinate( const KTextEditor::Cursor & cursor, bool realCursor, bool includeBorder ) const
740 {
741  if (cursor.line() >= doc()->lines()) {
742  return QPoint(-1, -1);
743  }
744  int viewLine = cache()->displayViewLine(realCursor ? toVirtualCursor(cursor) : cursor, true);
745 
746  if (viewLine < 0 || viewLine >= cache()->viewCacheLineCount())
747  return QPoint(-1, -1);
748 
749  int y = (int)viewLine * renderer()->lineHeight();
750 
751  KateTextLayout layout = cache()->viewLine(viewLine);
752  int x = 0;
753 
754  // only set x value if we have a valid layout (bug #171027)
755  if (layout.isValid())
756  x = (int)layout.lineLayout().cursorToX(cursor.column());
757 // else
758 // kDebug() << "Invalid Layout";
759 
760  if (includeBorder) x += m_leftBorder->width();
761 
762  x -= startX();
763 
764  return QPoint(x, y);
765 }
766 
767 QPoint KateViewInternal::cursorCoordinates(bool includeBorder) const
768 {
769  return cursorToCoordinate(m_displayCursor, false, includeBorder);
770 }
771 
772 KTextEditor::Cursor KateViewInternal::findMatchingBracket()
773 {
774  KTextEditor::Cursor c;
775 
776  if (!m_bm->toRange().isValid())
777  return KTextEditor::Cursor::invalid();
778 
779  Q_ASSERT(m_bmEnd->toRange().isValid());
780  Q_ASSERT(m_bmStart->toRange().isValid());
781 
782  if (m_bmStart->toRange().contains(m_cursor) || m_bmStart->end() == m_cursor.toCursor()) {
783  c = m_bmEnd->end();
784  } else if (m_bmEnd->toRange().contains(m_cursor) || m_bmEnd->end() == m_cursor.toCursor()) {
785  c = m_bmStart->start();
786  } else {
787  // should never happen: a range exists, but the cursor position is
788  // neither at the start nor at the end...
789  return KTextEditor::Cursor::invalid();
790  }
791 
792  return c;
793 }
794 
795 void KateViewInternal::doReturn()
796 {
797  doc()->newLine( m_view );
798  m_leftBorder->updateViRelLineNumbers();
799  updateView();
800 }
801 
802 void KateViewInternal::doSmartNewline()
803 {
804  int ln = m_cursor.line();
805  Kate::TextLine line = doc()->kateTextLine(ln);
806  int col = qMin(m_cursor.column(), line->firstChar());
807  if (col != -1) {
808  while (line->length() > col &&
809  !(line->at(col).isLetterOrNumber() || line->at(col) == QLatin1Char('_')) &&
810  col < m_cursor.column()) ++col;
811  } else {
812  col = line->length(); // stay indented
813  }
814  doc()->editStart();
815  doc()->editWrapLine(ln, m_cursor.column());
816  doc()->insertText(KTextEditor::Cursor(ln + 1, 0), line->string(0, col));
817  doc()->editEnd();
818 
819  updateView();
820 }
821 
822 void KateViewInternal::doDelete()
823 {
824  doc()->del( m_view, m_cursor );
825 }
826 
827 void KateViewInternal::doBackspace()
828 {
829  doc()->backspace( m_view, m_cursor );
830 }
831 
832 void KateViewInternal::doTabulator()
833 {
834  doc()->insertTab( m_view, m_cursor );
835 }
836 
837 void KateViewInternal::doTranspose()
838 {
839  doc()->transpose( m_cursor );
840 }
841 
842 void KateViewInternal::doDeletePrevWord()
843 {
844  doc()->editStart();
845  wordPrev( true );
846  KTextEditor::Range selection = m_view->selectionRange();
847  m_view->removeSelectedText();
848  doc()->editEnd();
849  tagRange(selection, true);
850  updateDirty();
851 }
852 
853 void KateViewInternal::doDeleteNextWord()
854 {
855  doc()->editStart();
856  wordNext( true );
857  KTextEditor::Range selection = m_view->selectionRange();
858  m_view->removeSelectedText();
859  doc()->editEnd();
860  tagRange(selection, true);
861  updateDirty();
862 }
863 
864 class CalculatingCursor : public KTextEditor::Cursor {
865 public:
866  // These constructors constrain their arguments to valid positions
867  // before only the third one did, but that leads to crashs
868  // see bug 227449
869  CalculatingCursor(KateViewInternal* vi)
870  : KTextEditor::Cursor()
871  , m_vi(vi)
872  {
873  makeValid();
874  }
875 
876  CalculatingCursor(KateViewInternal* vi, const KTextEditor::Cursor& c)
877  : KTextEditor::Cursor(c)
878  , m_vi(vi)
879  {
880  makeValid();
881  }
882 
883  CalculatingCursor(KateViewInternal* vi, int line, int col)
884  : KTextEditor::Cursor(line, col)
885  , m_vi(vi)
886  {
887  makeValid();
888  }
889 
890 
891  virtual CalculatingCursor& operator+=( int n ) = 0;
892 
893  virtual CalculatingCursor& operator-=( int n ) = 0;
894 
895  CalculatingCursor& operator++() { return operator+=( 1 ); }
896 
897  CalculatingCursor& operator--() { return operator-=( 1 ); }
898 
899  void makeValid() {
900  setLine(qBound( 0, line(), int( doc()->lines() - 1 ) ) );
901  if (view()->wrapCursor())
902  m_column = qBound( 0, column(), doc()->lineLength( line() ) );
903  else
904  m_column = qMax( 0, column() );
905  Q_ASSERT( valid() );
906  }
907 
908  void toEdge( KateViewInternal::Bias bias ) {
909  if( bias == KateViewInternal::left ) m_column = 0;
910  else if( bias == KateViewInternal::right ) m_column = doc()->lineLength( line() );
911  }
912 
913  bool atEdge() const { return atEdge( KateViewInternal::left ) || atEdge( KateViewInternal::right ); }
914 
915  bool atEdge( KateViewInternal::Bias bias ) const {
916  switch( bias ) {
917  case KateViewInternal::left: return column() == 0;
918  case KateViewInternal::none: return atEdge();
919  case KateViewInternal::right: return column() >= doc()->lineLength( line() );
920  default: Q_ASSERT(false); return false;
921  }
922  }
923 
924 protected:
925  bool valid() const {
926  return line() >= 0 &&
927  line() < doc()->lines() &&
928  column() >= 0 &&
929  (!view()->wrapCursor() || column() <= doc()->lineLength( line() ));
930  }
931  KateView* view() { return m_vi->m_view; }
932  const KateView* view() const { return m_vi->m_view; }
933  KateDocument* doc() { return view()->doc(); }
934  const KateDocument* doc() const { return view()->doc(); }
935  KateViewInternal* m_vi;
936 };
937 
938 class BoundedCursor : public CalculatingCursor {
939 public:
940  BoundedCursor(KateViewInternal* vi)
941  : CalculatingCursor( vi ) {}
942  BoundedCursor(KateViewInternal* vi, const KTextEditor::Cursor& c )
943  : CalculatingCursor( vi, c ) {}
944  BoundedCursor(KateViewInternal* vi, int line, int col )
945  : CalculatingCursor( vi, line, col ) {}
946  virtual CalculatingCursor& operator+=( int n ) {
947  KateLineLayoutPtr thisLine = m_vi->cache()->line(line());
948  if (!thisLine->isValid()) {
949  kWarning() << "Did not retrieve valid layout for line " << line();
950  return *this;
951  }
952 
953  const bool wrapCursor = view()->wrapCursor();
954  int maxColumn = -1;
955  if (n >= 0) {
956  for (int i = 0; i < n; i++) {
957  if (m_column >= thisLine->length()) {
958  if (wrapCursor) {
959  break;
960 
961  } else if (view()->dynWordWrap()) {
962  // Don't go past the edge of the screen in dynamic wrapping mode
963  if (maxColumn == -1)
964  maxColumn = thisLine->length() + ((m_vi->width() - thisLine->widthOfLastLine()) / m_vi->renderer()->spaceWidth()) - 1;
965 
966  if (m_column >= maxColumn) {
967  m_column = maxColumn;
968  break;
969  }
970 
971  ++m_column;
972 
973  } else {
974  ++m_column;
975  }
976 
977  } else {
978  m_column = thisLine->layout()->nextCursorPosition(m_column);
979  }
980  }
981  } else {
982  for (int i = 0; i > n; i--) {
983  if (m_column >= thisLine->length())
984  --m_column;
985  else if (m_column == 0)
986  break;
987  else
988  m_column = thisLine->layout()->previousCursorPosition(m_column);
989  }
990  }
991 
992  Q_ASSERT( valid() );
993  return *this;
994  }
995  virtual CalculatingCursor& operator-=( int n ) {
996  return operator+=( -n );
997  }
998 };
999 
1000 class WrappingCursor : public CalculatingCursor {
1001 public:
1002  WrappingCursor(KateViewInternal* vi)
1003  : CalculatingCursor( vi) {}
1004  WrappingCursor(KateViewInternal* vi, const KTextEditor::Cursor& c )
1005  : CalculatingCursor( vi, c ) {}
1006  WrappingCursor(KateViewInternal* vi, int line, int col )
1007  : CalculatingCursor( vi, line, col ) {}
1008 
1009  virtual CalculatingCursor& operator+=( int n ) {
1010  KateLineLayoutPtr thisLine = m_vi->cache()->line(line());
1011  if (!thisLine->isValid()) {
1012  kWarning() << "Did not retrieve a valid layout for line " << line();
1013  return *this;
1014  }
1015 
1016  if (n >= 0) {
1017  for (int i = 0; i < n; i++) {
1018  if (m_column >= thisLine->length()) {
1019  // Have come to the end of a line
1020  if (line() >= doc()->lines() - 1)
1021  // Have come to the end of the document
1022  break;
1023 
1024  // Advance to the beginning of the next line
1025  m_column = 0;
1026  setLine(line() + 1);
1027 
1028  // Retrieve the next text range
1029  thisLine = m_vi->cache()->line(line());
1030  if (!thisLine->isValid()) {
1031  kWarning() << "Did not retrieve a valid layout for line " << line();
1032  return *this;
1033  }
1034 
1035  continue;
1036  }
1037 
1038  m_column = thisLine->layout()->nextCursorPosition(m_column);
1039  }
1040 
1041  } else {
1042  for (int i = 0; i > n; i--) {
1043  if (m_column == 0) {
1044  // Have come to the start of the document
1045  if (line() == 0)
1046  break;
1047 
1048  // Start going back to the end of the last line
1049  setLine(line() - 1);
1050 
1051  // Retrieve the next text range
1052  thisLine = m_vi->cache()->line(line());
1053  if (!thisLine->isValid()) {
1054  kWarning() << "Did not retrieve a valid layout for line " << line();
1055  return *this;
1056  }
1057 
1058  // Finish going back to the end of the last line
1059  m_column = thisLine->length();
1060 
1061  continue;
1062  }
1063 
1064  if (m_column > thisLine->length())
1065  --m_column;
1066  else
1067  m_column = thisLine->layout()->previousCursorPosition(m_column);
1068  }
1069  }
1070 
1071  Q_ASSERT(valid());
1072  return *this;
1073  }
1074  virtual CalculatingCursor& operator-=( int n ) {
1075  return operator+=( -n );
1076  }
1077 };
1078 
1079 void KateViewInternal::moveChar( KateViewInternal::Bias bias, bool sel )
1080 {
1081  KTextEditor::Cursor c;
1082  if ( m_view->wrapCursor() ) {
1083  c = WrappingCursor( this, m_cursor ) += bias;
1084  } else {
1085  c = BoundedCursor( this, m_cursor ) += bias;
1086  }
1087 
1088  updateSelection( c, sel );
1089  updateCursor( c );
1090 }
1091 
1092 void KateViewInternal::cursorPrevChar( bool sel )
1093 {
1094  if ( ! m_view->wrapCursor() && m_cursor.column() == 0 )
1095  return;
1096 
1097  moveChar( KateViewInternal::left, sel );
1098 }
1099 
1100 void KateViewInternal::cursorNextChar( bool sel )
1101 {
1102  moveChar( KateViewInternal::right, sel );
1103 }
1104 
1105 void KateViewInternal::wordPrev( bool sel )
1106 {
1107  WrappingCursor c( this, m_cursor );
1108 
1109  // First we skip backwards all space.
1110  // Then we look up into which category the current position falls:
1111  // 1. a "word" character
1112  // 2. a "non-word" character (except space)
1113  // 3. the beginning of the line
1114  // and skip all preceding characters that fall into this class.
1115  // The code assumes that space is never part of the word character class.
1116 
1117  KateHighlighting* h = doc()->highlight();
1118  if( !c.atEdge( left ) ) {
1119 
1120  while( !c.atEdge( left ) && doc()->line( c.line() )[ c.column() - 1 ].isSpace() )
1121  --c;
1122  }
1123  if( c.atEdge( left ) )
1124  {
1125  --c;
1126  }
1127  else if( h->isInWord( doc()->line( c.line() )[ c.column() - 1 ] ) )
1128  {
1129  while( !c.atEdge( left ) && h->isInWord( doc()->line( c.line() )[ c.column() - 1 ] ) )
1130  --c;
1131  }
1132  else
1133  {
1134  while( !c.atEdge( left )
1135  && !h->isInWord( doc()->line( c.line() )[ c.column() - 1 ] )
1136  // in order to stay symmetric to wordLeft()
1137  // we must not skip space preceding a non-word sequence
1138  && !doc()->line( c.line() )[ c.column() - 1 ].isSpace() )
1139  {
1140  --c;
1141  }
1142  }
1143 
1144  updateSelection( c, sel );
1145  updateCursor( c );
1146 }
1147 
1148 void KateViewInternal::wordNext( bool sel )
1149 {
1150  WrappingCursor c( this, m_cursor );
1151 
1152  // We look up into which category the current position falls:
1153  // 1. a "word" character
1154  // 2. a "non-word" character (except space)
1155  // 3. the end of the line
1156  // and skip all following characters that fall into this class.
1157  // If the skipped characters are followed by space, we skip that too.
1158  // The code assumes that space is never part of the word character class.
1159 
1160  KateHighlighting* h = doc()->highlight();
1161  if( c.atEdge( right ) )
1162  {
1163  ++c;
1164  }
1165  else if( h->isInWord( doc()->line( c.line() )[ c.column() ] ) )
1166  {
1167  while( !c.atEdge( right ) && h->isInWord( doc()->line( c.line() )[ c.column() ] ) )
1168  ++c;
1169  }
1170  else
1171  {
1172  while( !c.atEdge( right )
1173  && !h->isInWord( doc()->line( c.line() )[ c.column() ] )
1174  // we must not skip space, because if that space is followed
1175  // by more non-word characters, we would skip them, too
1176  && !doc()->line( c.line() )[ c.column() ].isSpace() )
1177  {
1178  ++c;
1179  }
1180  }
1181 
1182  while( !c.atEdge( right ) && doc()->line( c.line() )[ c.column() ].isSpace() )
1183  ++c;
1184 
1185  updateSelection( c, sel );
1186  updateCursor( c );
1187 }
1188 
1189 void KateViewInternal::moveEdge( KateViewInternal::Bias bias, bool sel )
1190 {
1191  BoundedCursor c( this, m_cursor );
1192  c.toEdge( bias );
1193  updateSelection( c, sel );
1194  updateCursor( c );
1195 }
1196 
1197 void KateViewInternal::home( bool sel )
1198 {
1199  if (m_view->dynWordWrap() && currentLayout().startCol()) {
1200  // Allow us to go to the real start if we're already at the start of the view line
1201  if (m_cursor.column() != currentLayout().startCol()) {
1202  KTextEditor::Cursor c = currentLayout().start();
1203  updateSelection( c, sel );
1204  updateCursor( c );
1205  return;
1206  }
1207  }
1208 
1209  if( !doc()->config()->smartHome() ) {
1210  moveEdge( left, sel );
1211  return;
1212  }
1213 
1214  Kate::TextLine l = doc()->kateTextLine( m_cursor.line() );
1215 
1216  if (!l)
1217  return;
1218 
1219  KTextEditor::Cursor c = m_cursor;
1220  int lc = l->firstChar();
1221 
1222  if( lc < 0 || c.column() == lc ) {
1223  c.setColumn(0);
1224  } else {
1225  c.setColumn(lc);
1226  }
1227 
1228  updateSelection( c, sel );
1229  updateCursor( c, true );
1230 }
1231 
1232 void KateViewInternal::end( bool sel )
1233 {
1234  KateTextLayout layout = currentLayout();
1235 
1236  if (m_view->dynWordWrap() && layout.wrap()) {
1237  // Allow us to go to the real end if we're already at the end of the view line
1238  if (m_cursor.column() < layout.endCol() - 1) {
1239  KTextEditor::Cursor c(m_cursor.line(), layout.endCol() - 1);
1240  updateSelection( c, sel );
1241  updateCursor( c );
1242  return;
1243  }
1244  }
1245 
1246  if( !doc()->config()->smartHome() ) {
1247  moveEdge( right, sel );
1248  return;
1249  }
1250 
1251  Kate::TextLine l = doc()->kateTextLine( m_cursor.line() );
1252 
1253  if (!l)
1254  return;
1255 
1256  // "Smart End", as requested in bugs #78258 and #106970
1257  if (m_cursor.column() == doc()->lineLength(m_cursor.line())) {
1258  KTextEditor::Cursor c = m_cursor;
1259  c.setColumn(l->lastChar() + 1);
1260  updateSelection(c, sel);
1261  updateCursor(c, true);
1262  } else {
1263  moveEdge(right, sel);
1264  }
1265 }
1266 
1267 KateTextLayout KateViewInternal::currentLayout() const
1268 {
1269  return cache()->textLayout(m_cursor);
1270 }
1271 
1272 KateTextLayout KateViewInternal::previousLayout() const
1273 {
1274  int currentViewLine = cache()->viewLine(m_cursor);
1275 
1276  if (currentViewLine)
1277  return cache()->textLayout(m_cursor.line(), currentViewLine - 1);
1278  else
1279  return cache()->textLayout(m_view->textFolding().visibleLineToLine(m_displayCursor.line() - 1), -1);
1280 }
1281 
1282 KateTextLayout KateViewInternal::nextLayout() const
1283 {
1284  int currentViewLine = cache()->viewLine(m_cursor) + 1;
1285 
1286  if (currentViewLine >= cache()->line(m_cursor.line())->viewLineCount()) {
1287  currentViewLine = 0;
1288  return cache()->textLayout(m_view->textFolding().visibleLineToLine(m_displayCursor.line() + 1), currentViewLine);
1289  } else {
1290  return cache()->textLayout(m_cursor.line(), currentViewLine);
1291  }
1292 }
1293 
1294 /*
1295  * This returns the cursor which is offset by (offset) view lines.
1296  * This is the main function which is called by code not specifically dealing with word-wrap.
1297  * The opposite conversion (cursor to offset) can be done with cache()->displayViewLine().
1298  *
1299  * The cursors involved are virtual cursors (ie. equivalent to m_displayCursor)
1300  */
1301 
1302 KTextEditor::Cursor KateViewInternal::viewLineOffset(const KTextEditor::Cursor& virtualCursor, int offset, bool keepX)
1303 {
1304  if (!m_view->dynWordWrap()) {
1305  KTextEditor::Cursor ret(qMin((int)m_view->textFolding().visibleLines() - 1, virtualCursor.line() + offset), 0);
1306 
1307  if (ret.line() < 0)
1308  ret.setLine(0);
1309 
1310  if (keepX) {
1311  int realLine = m_view->textFolding().visibleLineToLine(ret.line());
1312  KateTextLayout t = cache()->textLayout(realLine, 0);
1313  Q_ASSERT(t.isValid());
1314 
1315  ret.setColumn(renderer()->xToCursor(t, m_preservedX, !m_view->wrapCursor()).column());
1316  }
1317 
1318  return ret;
1319  }
1320 
1321  KTextEditor::Cursor realCursor = virtualCursor;
1322  realCursor.setLine(m_view->textFolding().visibleLineToLine(m_view->textFolding().lineToVisibleLine(virtualCursor.line())));
1323 
1324  int cursorViewLine = cache()->viewLine(realCursor);
1325 
1326  int currentOffset = 0;
1327  int virtualLine = 0;
1328 
1329  bool forwards = (offset > 0) ? true : false;
1330 
1331  if (forwards) {
1332  currentOffset = cache()->lastViewLine(realCursor.line()) - cursorViewLine;
1333  if (offset <= currentOffset) {
1334  // the answer is on the same line
1335  KateTextLayout thisLine = cache()->textLayout(realCursor.line(), cursorViewLine + offset);
1336  Q_ASSERT(thisLine.virtualLine() == virtualCursor.line());
1337  return KTextEditor::Cursor(virtualCursor.line(), thisLine.startCol());
1338  }
1339 
1340  virtualLine = virtualCursor.line() + 1;
1341 
1342  } else {
1343  offset = -offset;
1344  currentOffset = cursorViewLine;
1345  if (offset <= currentOffset) {
1346  // the answer is on the same line
1347  KateTextLayout thisLine = cache()->textLayout(realCursor.line(), cursorViewLine - offset);
1348  Q_ASSERT(thisLine.virtualLine() == (int) m_view->textFolding().lineToVisibleLine(virtualCursor.line()));
1349  return KTextEditor::Cursor(virtualCursor.line(), thisLine.startCol());
1350  }
1351 
1352  virtualLine = virtualCursor.line() - 1;
1353  }
1354 
1355  currentOffset++;
1356 
1357  while (virtualLine >= 0 && virtualLine < (int)m_view->textFolding().visibleLines())
1358  {
1359  int realLine = m_view->textFolding().visibleLineToLine(virtualLine);
1360  KateLineLayoutPtr thisLine = cache()->line(realLine, virtualLine);
1361  if (!thisLine)
1362  break;
1363 
1364  for (int i = 0; i < thisLine->viewLineCount(); ++i) {
1365  if (offset == currentOffset) {
1366  KateTextLayout thisViewLine = thisLine->viewLine(i);
1367 
1368  if (!forwards) {
1369  // We actually want it the other way around
1370  int requiredViewLine = cache()->lastViewLine(realLine) - thisViewLine.viewLine();
1371  if (requiredViewLine != thisViewLine.viewLine()) {
1372  thisViewLine = thisLine->viewLine(requiredViewLine);
1373  }
1374  }
1375 
1376  KTextEditor::Cursor ret(virtualLine, thisViewLine.startCol());
1377 
1378  // keep column position
1379  if (keepX) {
1380  KTextEditor::Cursor realCursor = toRealCursor(virtualCursor);
1381  KateTextLayout t = cache()->textLayout(realCursor);
1382  // renderer()->cursorToX(t, realCursor, !m_view->wrapCursor());
1383 
1384  realCursor = renderer()->xToCursor(thisViewLine, m_preservedX, !m_view->wrapCursor());
1385  ret.setColumn(realCursor.column());
1386  }
1387 
1388  return ret;
1389  }
1390 
1391  currentOffset++;
1392  }
1393 
1394  if (forwards)
1395  virtualLine++;
1396  else
1397  virtualLine--;
1398  }
1399 
1400  // Looks like we were asked for something a bit exotic.
1401  // Return the max/min valid position.
1402  if (forwards)
1403  return KTextEditor::Cursor(m_view->textFolding().visibleLines() - 1, doc()->lineLength(m_view->textFolding().visibleLineToLine (m_view->textFolding().visibleLines() - 1)));
1404  else
1405  return KTextEditor::Cursor(0, 0);
1406 }
1407 
1408 int KateViewInternal::lineMaxCursorX(const KateTextLayout& range)
1409 {
1410  if (!m_view->wrapCursor() && !range.wrap())
1411  return INT_MAX;
1412 
1413  int maxX = range.endX();
1414 
1415  if (maxX && range.wrap()) {
1416  QChar lastCharInLine = doc()->kateTextLine(range.line())->at(range.endCol() - 1);
1417  maxX -= renderer()->config()->fontMetrics().width(lastCharInLine);
1418  }
1419 
1420  return maxX;
1421 }
1422 
1423 int KateViewInternal::lineMaxCol(const KateTextLayout& range)
1424 {
1425  int maxCol = range.endCol();
1426 
1427  if (maxCol && range.wrap())
1428  maxCol--;
1429 
1430  return maxCol;
1431 }
1432 
1433 void KateViewInternal::cursorUp(bool sel)
1434 {
1435  if(!sel && m_view->completionWidget()->isCompletionActive()) {
1436  m_view->completionWidget()->cursorUp();
1437  return;
1438  }
1439 
1440  if (m_displayCursor.line() == 0 && (!m_view->dynWordWrap() || cache()->viewLine(m_cursor) == 0))
1441  return;
1442 
1443  m_preserveX = true;
1444 
1445  KateTextLayout thisLine = currentLayout();
1446  // This is not the first line because that is already simplified out above
1447  KateTextLayout pRange = previousLayout();
1448 
1449  // Ensure we're in the right spot
1450  Q_ASSERT(m_cursor.line() == thisLine.line());
1451  Q_ASSERT(m_cursor.column() >= thisLine.startCol());
1452  Q_ASSERT(!thisLine.wrap() || m_cursor.column() < thisLine.endCol());
1453 
1454  KTextEditor::Cursor c = renderer()->xToCursor(pRange, m_preservedX, !m_view->wrapCursor());
1455 
1456  updateSelection( c, sel );
1457  updateCursor( c );
1458 }
1459 
1460 void KateViewInternal::cursorDown(bool sel)
1461 {
1462  if(!sel && m_view->completionWidget()->isCompletionActive()) {
1463  m_view->completionWidget()->cursorDown();
1464  return;
1465  }
1466 
1467  if ((m_displayCursor.line() >= m_view->textFolding().visibleLines() - 1) && (!m_view->dynWordWrap() || cache()->viewLine(m_cursor) == cache()->lastViewLine(m_cursor.line())))
1468  return;
1469 
1470  m_preserveX = true;
1471 
1472  KateTextLayout thisLine = currentLayout();
1473  // This is not the last line because that is already simplified out above
1474  KateTextLayout nRange = nextLayout();
1475 
1476  // Ensure we're in the right spot
1477  Q_ASSERT((m_cursor.line() == thisLine.line()) &&
1478  (m_cursor.column() >= thisLine.startCol()) &&
1479  (!thisLine.wrap() || m_cursor.column() < thisLine.endCol()));
1480 
1481  KTextEditor::Cursor c = renderer()->xToCursor(nRange, m_preservedX, !m_view->wrapCursor());
1482 
1483  updateSelection(c, sel);
1484  updateCursor(c);
1485 }
1486 
1487 void KateViewInternal::cursorToMatchingBracket( bool sel )
1488 {
1489  KTextEditor::Cursor c = findMatchingBracket();
1490 
1491  if (c.isValid()) {
1492  updateSelection( c, sel );
1493  updateCursor( c );
1494  }
1495 }
1496 
1497 void KateViewInternal::topOfView( bool sel )
1498 {
1499  KTextEditor::Cursor c = viewLineOffset(startPos(), m_minLinesVisible);
1500  updateSelection( toRealCursor(c), sel );
1501  updateCursor( toRealCursor(c) );
1502 }
1503 
1504 void KateViewInternal::bottomOfView( bool sel )
1505 {
1506  KTextEditor::Cursor c = viewLineOffset(endPos(), -m_minLinesVisible);
1507  updateSelection( toRealCursor(c), sel );
1508  updateCursor( toRealCursor(c) );
1509 }
1510 
1511 // lines is the offset to scroll by
1512 void KateViewInternal::scrollLines( int lines, bool sel )
1513 {
1514  KTextEditor::Cursor c = viewLineOffset(m_displayCursor, lines, true);
1515 
1516  // Fix the virtual cursor -> real cursor
1517  c.setLine(m_view->textFolding().visibleLineToLine(c.line()));
1518 
1519  updateSelection( c, sel );
1520  updateCursor( c );
1521 }
1522 
1523 // This is a bit misleading... it's asking for the view to be scrolled, not the cursor
1524 void KateViewInternal::scrollUp()
1525 {
1526  KTextEditor::Cursor newPos = viewLineOffset(startPos(), -1);
1527  scrollPos(newPos);
1528 }
1529 
1530 void KateViewInternal::scrollDown()
1531 {
1532  KTextEditor::Cursor newPos = viewLineOffset(startPos(), 1);
1533  scrollPos(newPos);
1534 }
1535 
1536 void KateViewInternal::setAutoCenterLines(int viewLines, bool updateView)
1537 {
1538  m_autoCenterLines = viewLines;
1539  m_minLinesVisible = qMin(int((linesDisplayed() - 1)/2), m_autoCenterLines);
1540  if (updateView)
1541  KateViewInternal::updateView();
1542 }
1543 
1544 void KateViewInternal::pageUp( bool sel, bool half )
1545 {
1546  if (m_view->isCompletionActive()) {
1547  m_view->completionWidget()->pageUp();
1548  return;
1549  }
1550 
1551  // remember the view line and x pos
1552  int viewLine = cache()->displayViewLine(m_displayCursor);
1553  bool atTop = startPos().atStartOfDocument();
1554 
1555  // Adjust for an auto-centering cursor
1556  int lineadj = m_minLinesVisible;
1557 
1558  int linesToScroll;
1559  if ( ! half )
1560  linesToScroll = -qMax( (linesDisplayed() - 1) - lineadj, 0 );
1561  else
1562  linesToScroll = -qMax( (linesDisplayed()/2 - 1) - lineadj, 0 );
1563 
1564  m_preserveX = true;
1565 
1566  if (!doc()->pageUpDownMovesCursor () && !atTop) {
1567  KTextEditor::Cursor newStartPos = viewLineOffset(startPos(), linesToScroll - 1);
1568  scrollPos(newStartPos);
1569 
1570  // put the cursor back approximately where it was
1571  KTextEditor::Cursor newPos = toRealCursor(viewLineOffset(newStartPos, viewLine, true));
1572 
1573  KateTextLayout newLine = cache()->textLayout(newPos);
1574 
1575  newPos = renderer()->xToCursor(newLine, m_preservedX, !m_view->wrapCursor());
1576 
1577  m_preserveX = true;
1578  updateSelection( newPos, sel );
1579  updateCursor(newPos);
1580 
1581  } else {
1582  scrollLines( linesToScroll, sel );
1583  }
1584 }
1585 
1586 void KateViewInternal::pageDown( bool sel ,bool half)
1587 {
1588  if (m_view->isCompletionActive()) {
1589  m_view->completionWidget()->pageDown();
1590  return;
1591  }
1592 
1593  // remember the view line
1594  int viewLine = cache()->displayViewLine(m_displayCursor);
1595  bool atEnd = startPos() >= m_cachedMaxStartPos;
1596 
1597  // Adjust for an auto-centering cursor
1598  int lineadj = m_minLinesVisible;
1599 
1600  int linesToScroll;
1601  if ( ! half )
1602  linesToScroll = qMax( (linesDisplayed() - 1) - lineadj, 0 );
1603  else
1604  linesToScroll = qMax( (linesDisplayed()/2 - 1) - lineadj, 0 );
1605 
1606  m_preserveX = true;
1607 
1608  if (!doc()->pageUpDownMovesCursor () && !atEnd) {
1609  KTextEditor::Cursor newStartPos = viewLineOffset(startPos(), linesToScroll + 1);
1610  scrollPos(newStartPos);
1611 
1612  // put the cursor back approximately where it was
1613  KTextEditor::Cursor newPos = toRealCursor(viewLineOffset(newStartPos, viewLine, true));
1614 
1615  KateTextLayout newLine = cache()->textLayout(newPos);
1616 
1617  newPos = renderer()->xToCursor(newLine, m_preservedX, !m_view->wrapCursor());
1618 
1619  m_preserveX = true;
1620  updateSelection( newPos, sel );
1621  updateCursor(newPos);
1622 
1623  } else {
1624  scrollLines( linesToScroll, sel );
1625  }
1626 }
1627 
1628 int KateViewInternal::maxLen(int startLine)
1629 {
1630  Q_ASSERT(!m_view->dynWordWrap());
1631 
1632  int displayLines = (m_view->height() / renderer()->lineHeight()) + 1;
1633 
1634  int maxLen = 0;
1635 
1636  for (int z = 0; z < displayLines; z++) {
1637  int virtualLine = startLine + z;
1638 
1639  if (virtualLine < 0 || virtualLine >= (int)m_view->textFolding().visibleLines())
1640  break;
1641 
1642  maxLen = qMax(maxLen, cache()->line(m_view->textFolding().visibleLineToLine(virtualLine))->width());
1643  }
1644 
1645  return maxLen;
1646 }
1647 
1648 bool KateViewInternal::columnScrollingPossible ()
1649 {
1650  return !m_view->dynWordWrap() && m_columnScroll->isEnabled() && (m_columnScroll->maximum() > 0);
1651 }
1652 
1653 void KateViewInternal::top( bool sel )
1654 {
1655  KTextEditor::Cursor newCursor(0, 0);
1656 
1657  newCursor = renderer()->xToCursor(cache()->textLayout(newCursor), m_preservedX, !m_view->wrapCursor());
1658 
1659  updateSelection( newCursor, sel );
1660  updateCursor( newCursor );
1661 }
1662 
1663 void KateViewInternal::bottom( bool sel )
1664 {
1665  KTextEditor::Cursor newCursor(doc()->lastLine(), 0);
1666 
1667  newCursor = renderer()->xToCursor(cache()->textLayout(newCursor), m_preservedX, !m_view->wrapCursor());
1668 
1669  updateSelection( newCursor, sel );
1670  updateCursor( newCursor );
1671 }
1672 
1673 void KateViewInternal::top_home( bool sel )
1674 {
1675  if (m_view->isCompletionActive()) {
1676  m_view->completionWidget()->top();
1677  return;
1678  }
1679 
1680  KTextEditor::Cursor c( 0, 0 );
1681  updateSelection( c, sel );
1682  updateCursor( c );
1683 }
1684 
1685 void KateViewInternal::bottom_end( bool sel )
1686 {
1687  if (m_view->isCompletionActive()) {
1688  m_view->completionWidget()->bottom();
1689  return;
1690  }
1691 
1692  KTextEditor::Cursor c( doc()->lastLine(), doc()->lineLength( doc()->lastLine() ) );
1693  updateSelection( c, sel );
1694  updateCursor( c );
1695 }
1696 
1697 void KateViewInternal::updateSelection( const KTextEditor::Cursor& _newCursor, bool keepSel )
1698 {
1699  KTextEditor::Cursor newCursor = _newCursor;
1700  if( keepSel )
1701  {
1702  if ( !m_view->selection() || (m_selectAnchor.line() == -1)
1703  //don't kill the selection if we have a persistent selection and
1704  //the cursor is inside or at the boundaries of the selected area
1705  || (m_view->config()->persistentSelection()
1706  && !(m_view->selectionRange().contains(m_cursor)
1707  || m_view->selectionRange().boundaryAtCursor(m_cursor))) )
1708  {
1709  m_selectAnchor = m_cursor;
1710  setSelection( KTextEditor::Range(m_cursor, newCursor) );
1711  }
1712  else
1713  {
1714  bool doSelect = true;
1715  switch (m_selectionMode)
1716  {
1717  case Word:
1718  {
1719  // Restore selStartCached if needed. It gets nuked by
1720  // viewSelectionChanged if we drag the selection into non-existence,
1721  // which can legitimately happen if a shift+DC selection is unable to
1722  // set a "proper" (i.e. non-empty) cached selection, e.g. because the
1723  // start was on something that isn't a word. Word select mode relies
1724  // on the cached selection being set properly, even if it is empty
1725  // (i.e. selStartCached == selEndCached).
1726  if ( !m_selectionCached.isValid() )
1727  m_selectionCached.start() = m_selectionCached.end();
1728 
1729  int c;
1730  if ( newCursor > m_selectionCached.start() )
1731  {
1732  m_selectAnchor = m_selectionCached.start();
1733 
1734  Kate::TextLine l = doc()->kateTextLine( newCursor.line() );
1735 
1736  c = newCursor.column();
1737  if ( c > 0 && doc()->highlight()->isInWord( l->at( c-1 ) ) ) {
1738  for ( ; c < l->length(); c++ )
1739  if ( !doc()->highlight()->isInWord( l->at( c ) ) )
1740  break;
1741  }
1742 
1743  newCursor.setColumn( c );
1744  }
1745  else if ( newCursor < m_selectionCached.start() )
1746  {
1747  m_selectAnchor = m_selectionCached.end();
1748 
1749  Kate::TextLine l = doc()->kateTextLine( newCursor.line() );
1750 
1751  c = newCursor.column();
1752  if ( c > 0 && c < doc()->lineLength( newCursor.line() )
1753  && doc()->highlight()->isInWord( l->at( c ) )
1754  && doc()->highlight()->isInWord( l->at( c-1 ) ) ) {
1755  for ( c -= 2; c >= 0; c-- )
1756  if ( !doc()->highlight()->isInWord( l->at( c ) ) )
1757  break;
1758  newCursor.setColumn( c+1 );
1759  }
1760  }
1761  else
1762  doSelect = false;
1763 
1764  }
1765  break;
1766  case Line:
1767  if ( !m_selectionCached.isValid() ) {
1768  m_selectionCached = KTextEditor::Range(endLine(), 0, endLine(), 0);
1769  }
1770  if ( newCursor.line() > m_selectionCached.start().line() )
1771  {
1772  if (newCursor.line() + 1 >= doc()->lines() )
1773  newCursor.setColumn( doc()->line( newCursor.line() ).length() );
1774  else
1775  newCursor.setPosition( newCursor.line() + 1, 0 );
1776  // Grow to include the entire line
1777  m_selectAnchor = m_selectionCached.start();
1778  m_selectAnchor.setColumn( 0 );
1779  }
1780  else if ( newCursor.line() < m_selectionCached.start().line() )
1781  {
1782  newCursor.setColumn( 0 );
1783  // Grow to include entire line
1784  m_selectAnchor = m_selectionCached.end();
1785  if ( m_selectAnchor.column() > 0 )
1786  {
1787  if ( m_selectAnchor.line()+1 >= doc()->lines() )
1788  m_selectAnchor.setColumn( doc()->line( newCursor.line() ).length() );
1789  else
1790  m_selectAnchor.setPosition( m_selectAnchor.line() + 1, 0 );
1791  }
1792  }
1793  else // same line, ignore
1794  doSelect = false;
1795  break;
1796  case Mouse:
1797  {
1798  if ( !m_selectionCached.isValid() )
1799  break;
1800 
1801  if ( newCursor > m_selectionCached.end() )
1802  m_selectAnchor = m_selectionCached.start();
1803  else if ( newCursor < m_selectionCached.start() )
1804  m_selectAnchor = m_selectionCached.end();
1805  else
1806  doSelect = false;
1807  }
1808  break;
1809  default: /* nothing special to do */;
1810  }
1811 
1812  if ( doSelect )
1813  setSelection( KTextEditor::Range(m_selectAnchor, newCursor) );
1814  else if ( m_selectionCached.isValid() ) // we have a cached selection, so we restore that
1815  setSelection( m_selectionCached );
1816  }
1817 
1818  m_selChangedByUser = true;
1819  }
1820  else if ( !m_view->config()->persistentSelection() )
1821  {
1822  m_view->clearSelection();
1823 
1824  m_selectionCached = KTextEditor::Range::invalid();
1825  m_selectAnchor = KTextEditor::Cursor::invalid();
1826  }
1827 
1828 #ifndef QT_NO_ACCESSIBILITY
1829 #if QT_VERSION >= 0x040800
1830  QAccessible::updateAccessibility(this, 0, QAccessible::TextSelectionChanged);
1831 #endif
1832 #endif
1833 }
1834 
1835 void KateViewInternal::setCaretStyle( KateRenderer::caretStyles style, bool repaint )
1836 {
1837  renderer()->setCaretStyle( style );
1838 
1839  if ( repaint ) {
1840  if ( m_cursorTimer.isActive() &&
1841  KApplication::cursorFlashTime() > 0 ) {
1842  m_cursorTimer.start( KApplication::cursorFlashTime() / 2 );
1843  }
1844  renderer()->setDrawCaret(true);
1845  paintCursor();
1846  }
1847 }
1848 
1849 void KateViewInternal::setSelection( const KTextEditor::Range &range )
1850 {
1851  disconnect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(viewSelectionChanged()));
1852  m_view->setSelection(range);
1853  connect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(viewSelectionChanged()));
1854 }
1855 
1856 void KateViewInternal::moveCursorToSelectionEdge()
1857 {
1858  if (!m_view->selection())
1859  return;
1860 
1861  int tmp = m_minLinesVisible;
1862  m_minLinesVisible = 0;
1863 
1864  if ( m_view->selectionRange().start() < m_selectAnchor )
1865  updateCursor( m_view->selectionRange().start() );
1866  else
1867  updateCursor( m_view->selectionRange().end() );
1868 
1869  m_minLinesVisible = tmp;
1870 }
1871 
1872 void KateViewInternal::updateCursor( const KTextEditor::Cursor& newCursor, bool force, bool center, bool calledExternally )
1873 {
1874  if ( !force && (m_cursor.toCursor() == newCursor) )
1875  {
1876  m_displayCursor = toVirtualCursor(newCursor);
1877  if ( !m_madeVisible && m_view == doc()->activeView() )
1878  {
1879  // unfold if required
1880  m_view->textFolding().ensureLineIsVisible ( newCursor.line() );
1881 
1882  makeVisible ( m_displayCursor, m_displayCursor.column(), false, center, calledExternally );
1883  }
1884 
1885  return;
1886  }
1887 
1888  if (m_cursor.line() != newCursor.line()) {
1889  m_leftBorder->updateViRelLineNumbers();
1890  }
1891 
1892  // unfold if required
1893  m_view->textFolding().ensureLineIsVisible ( newCursor.line() );
1894 
1895  KTextEditor::Cursor oldDisplayCursor = m_displayCursor;
1896 
1897  m_displayCursor = toVirtualCursor(newCursor);
1898  m_cursor.setPosition( newCursor );
1899 
1900  if ( m_view == doc()->activeView() )
1901  makeVisible ( m_displayCursor, m_displayCursor.column(), false, center, calledExternally );
1902 
1903  updateBracketMarks();
1904 
1905  // It's efficient enough to just tag them both without checking to see if they're on the same view line
1906 /* kdDebug()<<"oldDisplayCursor:"<<oldDisplayCursor<<endl;
1907  kdDebug()<<"m_displayCursor:"<<m_displayCursor<<endl;*/
1908  tagLine(oldDisplayCursor);
1909  tagLine(m_displayCursor);
1910 
1911  updateMicroFocus();
1912 
1913  if (m_cursorTimer.isActive ())
1914  {
1915  if ( KApplication::cursorFlashTime() > 0 )
1916  m_cursorTimer.start( KApplication::cursorFlashTime() / 2 );
1917  renderer()->setDrawCaret(true);
1918  }
1919 
1920  // Remember the maximum X position if requested
1921  if (m_preserveX)
1922  m_preserveX = false;
1923  else
1924  m_preservedX = renderer()->cursorToX(cache()->textLayout(m_cursor), m_cursor, !m_view->wrapCursor());
1925 
1926  //kDebug(13030) << "m_preservedX: " << m_preservedX << " (was "<< oldmaxx << "), m_cursorX: " << m_cursorX;
1927  //kDebug(13030) << "Cursor now located at real " << cursor.line << "," << cursor.col << ", virtual " << m_displayCursor.line << ", " << m_displayCursor.col << "; Top is " << startLine() << ", " << startPos().col;
1928 
1929  cursorMoved();
1930 
1931  updateDirty(); //paintText(0, 0, width(), height(), true);
1932 
1933  emit m_view->cursorPositionChanged(m_view, m_cursor);
1934 }
1935 
1936 void KateViewInternal::updateBracketMarkAttributes()
1937 {
1938  KTextEditor::Attribute::Ptr bracketFill = KTextEditor::Attribute::Ptr(new KTextEditor::Attribute());
1939  bracketFill->setBackground(m_view->m_renderer->config()->highlightedBracketColor());
1940  bracketFill->setBackgroundFillWhitespace(false);
1941  if (QFontInfo(renderer()->currentFont()).fixedPitch()) {
1942  // make font bold only for fixed fonts, otherwise text jumps around
1943  bracketFill->setFontBold();
1944  }
1945 
1946  m_bmStart->setAttribute(bracketFill);
1947  m_bmEnd->setAttribute(bracketFill);
1948 
1949  if (m_view->m_renderer->config()->showWholeBracketExpression()) {
1950  KTextEditor::Attribute::Ptr expressionFill = KTextEditor::Attribute::Ptr(new KTextEditor::Attribute());
1951  expressionFill->setBackground(m_view->m_renderer->config()->highlightedBracketColor());
1952  expressionFill->setBackgroundFillWhitespace(false);
1953 
1954  m_bm->setAttribute(expressionFill);
1955  } else {
1956  m_bm->setAttribute(KTextEditor::Attribute::Ptr(new KTextEditor::Attribute()));
1957  }
1958 }
1959 
1960 void KateViewInternal::updateBracketMarks()
1961 {
1962  // add some limit to this, this is really endless on big files without limit
1963  int maxLines = 5000;
1964  KTextEditor::Range newRange;
1965  doc()->newBracketMark( m_cursor, newRange, maxLines );
1966 
1967  // new range valid, then set ranges to it
1968  if (newRange.isValid ()) {
1969  if (m_bm->toRange() == newRange) {
1970  return;
1971  }
1972 
1973  // modify full range
1974  m_bm->setRange (newRange);
1975 
1976  // modify start and end ranges
1977  m_bmStart->setRange (KTextEditor::Range (m_bm->start(), KTextEditor::Cursor (m_bm->start().line(), m_bm->start().column() + 1)));
1978  m_bmEnd->setRange (KTextEditor::Range (m_bm->end(), KTextEditor::Cursor (m_bm->end().line(), m_bm->end().column() + 1)));
1979 
1980  // flash matching bracket
1981  if (!renderer()->config()->animateBracketMatching()) {
1982  return;
1983  }
1984  const KTextEditor::Cursor flashPos = (m_cursor == m_bmStart->start() || m_cursor == m_bmStart->end()) ? m_bmEnd->start() : m_bm->start();
1985  if (flashPos != m_bmLastFlashPos->toCursor()) {
1986  m_bmLastFlashPos->setPosition(flashPos);
1987 
1988  KTextEditor::Attribute::Ptr attribute = doc()->attributeAt(flashPos);
1989  attribute->setBackground(m_view->m_renderer->config()->highlightedBracketColor());
1990  attribute->setFontBold(m_bmStart->attribute()->fontBold());
1991 
1992  flashChar(flashPos, attribute);
1993  }
1994  return;
1995  }
1996 
1997  // new range was invalid
1998  m_bm->setRange (KTextEditor::Range::invalid());
1999  m_bmStart->setRange (KTextEditor::Range::invalid());
2000  m_bmEnd->setRange (KTextEditor::Range::invalid());
2001  m_bmLastFlashPos->setPosition (KTextEditor::Cursor::invalid());
2002 }
2003 
2004 bool KateViewInternal::tagLine(const KTextEditor::Cursor& virtualCursor)
2005 {
2006  // FIXME may be a more efficient way for this
2007  if ((int)m_view->textFolding().visibleLineToLine(virtualCursor.line()) > doc()->lastLine())
2008  return false;
2009  // End FIXME
2010 
2011  int viewLine = cache()->displayViewLine(virtualCursor, true);
2012  if (viewLine >= 0 && viewLine < cache()->viewCacheLineCount()) {
2013  cache()->viewLine(viewLine).setDirty();
2014  m_leftBorder->update (0, lineToY(viewLine), m_leftBorder->width(), renderer()->lineHeight());
2015  return true;
2016  }
2017  return false;
2018 }
2019 
2020 bool KateViewInternal::tagLines( int start, int end, bool realLines )
2021 {
2022  return tagLines(KTextEditor::Cursor(start, 0), KTextEditor::Cursor(end, -1), realLines);
2023 }
2024 
2025 bool KateViewInternal::tagLines(KTextEditor::Cursor start, KTextEditor::Cursor end, bool realCursors)
2026 {
2027  if (realCursors)
2028  {
2029  cache()->relayoutLines(start.line(), end.line());
2030 
2031  //kDebug(13030)<<"realLines is true";
2032  start = toVirtualCursor(start);
2033  end = toVirtualCursor(end);
2034 
2035  } else {
2036  cache()->relayoutLines(toRealCursor(start).line(), toRealCursor(end).line());
2037  }
2038 
2039  if (end.line() < startLine())
2040  {
2041  //kDebug(13030)<<"end<startLine";
2042  return false;
2043  }
2044  // Used to be > endLine(), but cache may not be valid when checking, so use a
2045  // less optimal but still adequate approximation (potential overestimation but minimal performance difference)
2046  if (start.line() > startLine() + cache()->viewCacheLineCount())
2047  {
2048  //kDebug(13030)<<"start> endLine"<<start<<" "<<(endLine());
2049  return false;
2050  }
2051 
2052  cache()->updateViewCache(startPos());
2053 
2054  //kDebug(13030) << "tagLines( [" << start << "], [" << end << "] )";
2055 
2056  bool ret = false;
2057 
2058  for (int z = 0; z < cache()->viewCacheLineCount(); z++)
2059  {
2060  KateTextLayout& line = cache()->viewLine(z);
2061  if ((line.virtualLine() > start.line() || (line.virtualLine() == start.line() && line.endCol() >= start.column() && start.column() != -1)) &&
2062  (line.virtualLine() < end.line() || (line.virtualLine() == end.line() && (line.startCol() <= end.column() || end.column() == -1)))) {
2063  ret = true;
2064  break;
2065  //kDebug(13030) << "Tagged line " << line.line();
2066  }
2067  }
2068 
2069  if (!m_view->dynWordWrap())
2070  {
2071  int y = lineToY( start.line() );
2072  // FIXME is this enough for when multiple lines are deleted
2073  int h = (end.line() - start.line() + 2) * renderer()->lineHeight();
2074  if (end.line() >= m_view->textFolding().visibleLines() - 1)
2075  h = height();
2076 
2077  m_leftBorder->update (0, y, m_leftBorder->width(), h);
2078  }
2079  else
2080  {
2081  // FIXME Do we get enough good info in editRemoveText to optimize this more?
2082  //bool justTagged = false;
2083  for (int z = 0; z < cache()->viewCacheLineCount(); z++)
2084  {
2085  KateTextLayout& line = cache()->viewLine(z);
2086  if (!line.isValid() ||
2087  ((line.virtualLine() > start.line() || (line.virtualLine() == start.line() && line.endCol() >= start.column() && start.column() != -1)) &&
2088  (line.virtualLine() < end.line() || (line.virtualLine() == end.line() && (line.startCol() <= end.column() || end.column() == -1)))))
2089  {
2090  //justTagged = true;
2091  m_leftBorder->update (0, z * renderer()->lineHeight(), m_leftBorder->width(), m_leftBorder->height());
2092  break;
2093  }
2094  /*else if (justTagged)
2095  {
2096  justTagged = false;
2097  leftBorder->update (0, z * doc()->viewFont.fontHeight, leftBorder->width(), doc()->viewFont.fontHeight);
2098  break;
2099  }*/
2100  }
2101  }
2102 
2103  return ret;
2104 }
2105 
2106 bool KateViewInternal::tagRange(const KTextEditor::Range& range, bool realCursors)
2107 {
2108  return tagLines(range.start(), range.end(), realCursors);
2109 }
2110 
2111 void KateViewInternal::tagAll()
2112 {
2113  // clear the cache...
2114  cache()->clear ();
2115 
2116  m_leftBorder->updateFont();
2117  m_leftBorder->update();
2118 }
2119 
2120 void KateViewInternal::paintCursor()
2121 {
2122  if (tagLine(m_displayCursor))
2123  updateDirty(); //paintText (0,0,width(), height(), true);
2124 }
2125 
2126 // Point in content coordinates
2127 void KateViewInternal::placeCursor( const QPoint& p, bool keepSelection, bool updateSelection )
2128 {
2129  KateTextLayout thisLine = yToKateTextLayout(p.y());
2130  KTextEditor::Cursor c;
2131 
2132  if (!thisLine.isValid()) // probably user clicked below the last line -> use the last line
2133  thisLine = cache()->textLayout(doc()->lines() - 1, -1);
2134 
2135  c = renderer()->xToCursor(thisLine, startX() + p.x(), !m_view->wrapCursor());
2136 
2137  if (c.line () < 0 || c.line() >= doc()->lines()) {
2138  return;
2139  }
2140 
2141  if (updateSelection)
2142  KateViewInternal::updateSelection( c, keepSelection );
2143 
2144  int tmp = m_minLinesVisible;
2145  m_minLinesVisible = 0;
2146  updateCursor( c );
2147  m_minLinesVisible = tmp;
2148 
2149  if (updateSelection && keepSelection)
2150  moveCursorToSelectionEdge();
2151 }
2152 
2153 // Point in content coordinates
2154 bool KateViewInternal::isTargetSelected( const QPoint& p )
2155 {
2156  const KateTextLayout& thisLine = yToKateTextLayout(p.y());
2157  if (!thisLine.isValid())
2158  return false;
2159 
2160  return m_view->cursorSelected(renderer()->xToCursor(thisLine, startX() + p.x(), !m_view->wrapCursor()));
2161 }
2162 
2163 //BEGIN EVENT HANDLING STUFF
2164 
2165 bool KateViewInternal::eventFilter( QObject *obj, QEvent *e )
2166 {
2167  if (obj == m_lineScroll)
2168  {
2169  // the second condition is to make sure a scroll on the vertical bar doesn't cause a horizontal scroll ;)
2170  if (e->type() == QEvent::Wheel && m_lineScroll->minimum() != m_lineScroll->maximum())
2171  {
2172  wheelEvent((QWheelEvent*)e);
2173  return true;
2174  }
2175 
2176  // continue processing
2177  return QWidget::eventFilter( obj, e );
2178  }
2179 
2180  switch( e->type() )
2181  {
2182  case QEvent::ChildAdded:
2183  case QEvent::ChildRemoved: {
2184  QChildEvent* c = static_cast<QChildEvent*>(e);
2185  if (c->added()) {
2186  c->child()->installEventFilter(this);
2187  /*foreach (QWidget* child, c->child()->findChildren<QWidget*>())
2188  child->installEventFilter(this);*/
2189 
2190  } else if (c->removed()) {
2191  c->child()->removeEventFilter(this);
2192 
2193  /*foreach (QWidget* child, c->child()->findChildren<QWidget*>())
2194  child->removeEventFilter(this);*/
2195  }
2196  } break;
2197 
2198  case QEvent::ShortcutOverride:
2199  {
2200  QKeyEvent *k = static_cast<QKeyEvent *>(e);
2201 
2202  if (k->key() == Qt::Key_Escape && k->modifiers() == Qt::NoModifier) {
2203  if (m_view->isCompletionActive()) {
2204  m_view->abortCompletion();
2205  k->accept();
2206  //kDebug() << obj << "shortcut override" << k->key() << "aborting completion";
2207  return true;
2208  } else if (m_view->bottomViewBar()->isVisible()) {
2209  m_view->bottomViewBar()->hideCurrentBarWidget();
2210  k->accept();
2211  //kDebug() << obj << "shortcut override" << k->key() << "closing view bar";
2212  return true;
2213  } else if (!m_view->config()->persistentSelection() && m_view->selection()) {
2214  if (!m_view->viInputMode()) // Vim mode handles clearing selections itself.
2215  {
2216  m_view->clearSelection();
2217  }
2218  k->accept();
2219  //kDebug() << obj << "shortcut override" << k->key() << "clearing selection";
2220  return true;
2221  }
2222  }
2223 
2224  // if vi input mode key stealing is on, override kate shortcuts
2225  if (m_view->viInputMode() && m_view->viInputModeStealKeys() && ( m_view->getCurrentViMode() != InsertMode ||
2226  k->modifiers() == Qt::ControlModifier || k->key() == Qt::Key_Insert ) ) {
2227  k->accept();
2228  return true;
2229  }
2230 
2231  } break;
2232 
2233  case QEvent::KeyPress:
2234  {
2235  QKeyEvent *k = static_cast<QKeyEvent *>(e);
2236 
2237  // Override all other single key shortcuts which do not use a modifier other than Shift
2238  if (obj == this && (!k->modifiers() || k->modifiers() == Qt::ShiftModifier)) {
2239  keyPressEvent( k );
2240  if (k->isAccepted()) {
2241  //kDebug() << obj << "shortcut override" << k->key() << "using keystroke";
2242  return true;
2243  }
2244  }
2245 
2246  //kDebug() << obj << "shortcut override" << k->key() << "ignoring";
2247  } break;
2248 
2249  case QEvent::DragMove:
2250  {
2251  QPoint currentPoint = ((QDragMoveEvent*) e)->pos();
2252 
2253  QRect doNotScrollRegion( s_scrollMargin, s_scrollMargin,
2254  width() - s_scrollMargin * 2,
2255  height() - s_scrollMargin * 2 );
2256 
2257  if ( !doNotScrollRegion.contains( currentPoint ) )
2258  {
2259  startDragScroll();
2260  // Keep sending move events
2261  ( (QDragMoveEvent*)e )->accept( QRect(0,0,0,0) );
2262  }
2263 
2264  dragMoveEvent((QDragMoveEvent*)e);
2265  } break;
2266 
2267  case QEvent::DragLeave:
2268  // happens only when pressing ESC while dragging
2269  stopDragScroll();
2270  break;
2271 
2272  case QEvent::WindowBlocked:
2273  // next focus originates from an internal dialog:
2274  // don't show the modonhd prompt
2275  if (isVisible()) {
2276  doc()->ignoreModifiedOnDiskOnce();
2277  }
2278  break;
2279 
2280  default:
2281  break;
2282  }
2283 
2284  return QWidget::eventFilter( obj, e );
2285 }
2286 
2287 void KateViewInternal::keyPressEvent( QKeyEvent* e )
2288 {
2289  if( e->key() == Qt::Key_Left && e->modifiers() == Qt::AltModifier ) {
2290  m_view->emitNavigateLeft();
2291  e->setAccepted(true);
2292  return;
2293  }
2294  if( e->key() == Qt::Key_Right && e->modifiers() == Qt::AltModifier ) {
2295  m_view->emitNavigateRight();
2296  e->setAccepted(true);
2297  return;
2298  }
2299  if( e->key() == Qt::Key_Up && e->modifiers() == Qt::AltModifier ) {
2300  m_view->emitNavigateUp();
2301  e->setAccepted(true);
2302  return;
2303  }
2304  if( e->key() == Qt::Key_Down && e->modifiers() == Qt::AltModifier ) {
2305  m_view->emitNavigateDown();
2306  e->setAccepted(true);
2307  return;
2308  }
2309  if( e->key() == Qt::Key_Return && e->modifiers() == Qt::AltModifier ) {
2310  m_view->emitNavigateAccept();
2311  e->setAccepted(true);
2312  return;
2313  }
2314  if( e->key() == Qt::Key_Backspace && e->modifiers() == Qt::AltModifier ) {
2315  m_view->emitNavigateBack();
2316  e->setAccepted(true);
2317  return;
2318  }
2319 
2320  if( e->key() == Qt::Key_Alt && m_view->completionWidget()->isCompletionActive() ) {
2321  m_completionItemExpanded = m_view->completionWidget()->toggleExpanded(true);
2322  m_view->completionWidget()->resetHadNavigation();
2323  m_altDownTime = QTime::currentTime();
2324  }
2325 
2326  // Note: AND'ing with <Shift> is a quick hack to fix Key_Enter
2327  const int key = e->key() | (e->modifiers() & Qt::ShiftModifier);
2328 
2329  if (m_view->isCompletionActive()
2330  && !m_view->viInputMode() /* Vi input mode needs to handle completion keypresses itself for e.g. mappings */)
2331  {
2332  if( key == Qt::Key_Enter || key == Qt::Key_Return ) {
2333  m_view->completionWidget()->execute();
2334  e->accept();
2335  return;
2336  }
2337  }
2338 
2339  if ( m_view->viInputMode() ) {
2340  if ( getViInputModeManager()->getCurrentViMode() == InsertMode
2341  || getViInputModeManager()->getCurrentViMode() == ReplaceMode ) {
2342  if ( getViInputModeManager()->handleKeypress( e ) ) {
2343  return;
2344  } else if ( e->modifiers() != Qt::NoModifier && e->modifiers() != Qt::ShiftModifier ) {
2345  // re-post key events not handled if they have a modifier other than shift
2346  QEvent *copy = new QKeyEvent ( e->type(), e->key(), e->modifiers(), e->text(),
2347  e->isAutoRepeat(), e->count() );
2348  QCoreApplication::postEvent( parent(), copy );
2349  }
2350  } else { // !InsertMode
2351  if ( !getViInputModeManager()->handleKeypress( e ) ) {
2352  // we didn't need that keypress, un-steal it :-)
2353  QEvent *copy = new QKeyEvent ( e->type(), e->key(), e->modifiers(), e->text(),
2354  e->isAutoRepeat(), e->count() );
2355  QCoreApplication::postEvent( parent(), copy );
2356  }
2357  m_view->updateViModeBarCmd();
2358  return;
2359  }
2360  }
2361 
2362  if( !doc()->isReadWrite() )
2363  {
2364  e->ignore();
2365  return;
2366  }
2367 
2368  if ((key == Qt::Key_Return) || (key == Qt::Key_Enter) || (key == Qt::SHIFT + Qt::Key_Return) || (key == Qt::SHIFT + Qt::Key_Enter))
2369  {
2370  doReturn();
2371  e->accept();
2372  return;
2373  }
2374 
2375  if (key == Qt::Key_Backspace || key == Qt::SHIFT + Qt::Key_Backspace)
2376  {
2377  //m_view->backspace();
2378  e->accept();
2379 
2380  return;
2381  }
2382 
2383  if (key == Qt::Key_Tab || key == Qt::SHIFT+Qt::Key_Backtab || key == Qt::Key_Backtab)
2384  {
2385  if(m_view->completionWidget()->isCompletionActive())
2386  {
2387  e->accept();
2388  m_view->completionWidget()->tab(key != Qt::Key_Tab);
2389  return;
2390  }
2391 
2392  if( key == Qt::Key_Tab )
2393  {
2394  uint tabHandling = doc()->config()->tabHandling();
2395  // convert tabSmart into tabInsertsTab or tabIndents:
2396  if (tabHandling == KateDocumentConfig::tabSmart)
2397  {
2398  // multiple lines selected
2399  if (m_view->selection() && !m_view->selectionRange().onSingleLine())
2400  {
2401  tabHandling = KateDocumentConfig::tabIndents;
2402  }
2403 
2404  // otherwise: take look at cursor position
2405  else
2406  {
2407  // if the cursor is at or before the first non-space character
2408  // or on an empty line,
2409  // Tab indents, otherwise it inserts a tab character.
2410  Kate::TextLine line = doc()->kateTextLine( m_cursor.line() );
2411  int first = line->firstChar();
2412  if (first < 0 || m_cursor.column() <= first)
2413  tabHandling = KateDocumentConfig::tabIndents;
2414  else
2415  tabHandling = KateDocumentConfig::tabInsertsTab;
2416  }
2417  }
2418 
2419  if (tabHandling == KateDocumentConfig::tabInsertsTab)
2420  doc()->typeChars( m_view, QString("\t") );
2421  else
2422  doc()->indent( m_view->selection() ? m_view->selectionRange() : KTextEditor::Range(m_cursor.line(), 0, m_cursor.line(), 0), 1 );
2423 
2424  e->accept();
2425 
2426  return;
2427  }
2428  else if (doc()->config()->tabHandling() != KateDocumentConfig::tabInsertsTab)
2429  {
2430  // key == Qt::SHIFT+Qt::Key_Backtab || key == Qt::Key_Backtab
2431  doc()->indent( m_view->selection() ? m_view->selectionRange() : KTextEditor::Range(m_cursor.line(), 0, m_cursor.line(), 0), -1 );
2432  e->accept();
2433 
2434  return;
2435  }
2436  }
2437 
2438  if ( !(e->modifiers() & Qt::ControlModifier) && !e->text().isEmpty() && doc()->typeChars ( m_view, e->text() ) )
2439  {
2440  e->accept();
2441 
2442  return;
2443  }
2444 
2445  // allow composition of AltGr + (q|2|3) on windows
2446  static const int altGR = Qt::ControlModifier | Qt::AltModifier;
2447  if( (e->modifiers() & altGR) == altGR && !e->text().isEmpty() && doc()->typeChars ( m_view, e->text() ) )
2448  {
2449  e->accept();
2450 
2451  return;
2452  }
2453 
2454  e->ignore();
2455 }
2456 
2457 void KateViewInternal::keyReleaseEvent( QKeyEvent* e )
2458 {
2459  if( e->key() == Qt::Key_Alt && m_view->completionWidget()->isCompletionActive() && ((m_completionItemExpanded && (m_view->completionWidget()->hadNavigation() || m_altDownTime.msecsTo(QTime::currentTime()) > 300)) || (!m_completionItemExpanded && !m_view->completionWidget()->hadNavigation())) ) {
2460 
2461  m_view->completionWidget()->toggleExpanded(false, true);
2462  }
2463 
2464  if ((e->modifiers() & Qt::SHIFT) == Qt::SHIFT)
2465  {
2466  m_shiftKeyPressed = true;
2467  }
2468  else
2469  {
2470  if (m_shiftKeyPressed)
2471  {
2472  m_shiftKeyPressed = false;
2473 
2474  if (m_selChangedByUser)
2475  {
2476  if (m_view->selection())
2477  QApplication::clipboard()->setText(m_view->selectionText (), QClipboard::Selection);
2478 
2479  m_selChangedByUser = false;
2480  }
2481  }
2482  }
2483 
2484  e->ignore();
2485  return;
2486 }
2487 
2488 void KateViewInternal::contextMenuEvent ( QContextMenuEvent * e )
2489 {
2490  // try to show popup menu
2491 
2492  QPoint p = e->pos();
2493 
2494  if ( doc()->browserView() )
2495  {
2496  m_view->contextMenuEvent( e );
2497  return;
2498  }
2499 
2500  if ( e->reason() == QContextMenuEvent::Keyboard )
2501  {
2502  makeVisible( m_displayCursor, 0 );
2503  p = cursorCoordinates(false);
2504  p.rx() -= startX();
2505  }
2506  else if ( ! m_view->selection() || m_view->config()->persistentSelection() )
2507  placeCursor( e->pos() );
2508 
2509  // popup is a qguardedptr now
2510  if (m_view->contextMenu()) {
2511  m_view->spellingMenu()->setUseMouseForMisspelledRange((e->reason() == QContextMenuEvent::Mouse));
2512  m_view->contextMenu()->popup( mapToGlobal( p ) );
2513  e->accept ();
2514  }
2515 }
2516 
2517 void KateViewInternal::mousePressEvent( QMouseEvent* e )
2518 {
2519  switch (e->button())
2520  {
2521  case Qt::LeftButton:
2522  m_selChangedByUser = false;
2523 
2524  if (m_possibleTripleClick)
2525  {
2526  m_possibleTripleClick = false;
2527 
2528  m_selectionMode = Line;
2529 
2530  if ( e->modifiers() & Qt::ShiftModifier )
2531  {
2532  updateSelection( m_cursor, true );
2533  }
2534  else
2535  {
2536  m_view->selectLine( m_cursor );
2537  if (m_view->selection())
2538  m_selectAnchor = m_view->selectionRange().start();
2539  }
2540 
2541  if (m_view->selection())
2542  QApplication::clipboard()->setText(m_view->selectionText (), QClipboard::Selection);
2543 
2544  // Keep the line at the select anchor selected during further
2545  // mouse selection
2546  if ( m_selectAnchor.line() > m_view->selectionRange().start().line() )
2547  {
2548  // Preserve the last selected line
2549  if ( m_selectAnchor == m_view->selectionRange().end() && m_selectAnchor.column() == 0 )
2550  m_selectionCached.start().setPosition( m_selectAnchor.line()-1, 0 );
2551  else
2552  m_selectionCached.start().setPosition( m_selectAnchor.line(), 0 );
2553  m_selectionCached.end() = m_view->selectionRange().end();
2554  }
2555  else
2556  {
2557  // Preserve the first selected line
2558  m_selectionCached.start() = m_view->selectionRange().start();
2559  if ( m_view->selectionRange().end().line() > m_view->selectionRange().start().line() )
2560  m_selectionCached.end().setPosition( m_view->selectionRange().start().line()+1, 0 );
2561  else
2562  m_selectionCached.end() = m_view->selectionRange().end();
2563  }
2564 
2565  moveCursorToSelectionEdge();
2566 
2567  m_scrollX = 0;
2568  m_scrollY = 0;
2569  m_scrollTimer.start (50);
2570 
2571  e->accept();
2572  return;
2573  }
2574  else if ( m_selectionMode == Default )
2575  {
2576  m_selectionMode = Mouse;
2577  }
2578 
2579  // request the software keyboard, if any
2580  if ( e->button() == Qt::LeftButton && qApp->autoSipEnabled() )
2581  {
2582  QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( style()->styleHint( QStyle::SH_RequestSoftwareInputPanel ) );
2583  if ( hasFocus() || behavior == QStyle::RSIP_OnMouseClick )
2584  {
2585  QEvent event( QEvent::RequestSoftwareInputPanel );
2586  QApplication::sendEvent( this, &event );
2587  }
2588  }
2589 
2590  if ( e->modifiers() & Qt::ShiftModifier )
2591  {
2592  if ( !m_selectAnchor.isValid() )
2593  m_selectAnchor = m_cursor;
2594  }
2595  else
2596  {
2597  m_selectionCached = KTextEditor::Range::invalid();
2598  }
2599 
2600  if( !(e->modifiers() & Qt::ShiftModifier) && isTargetSelected( e->pos() ) )
2601  {
2602  m_dragInfo.state = diPending;
2603  m_dragInfo.start = e->pos();
2604  }
2605  else
2606  {
2607  m_dragInfo.state = diNone;
2608 
2609  if ( e->modifiers() & Qt::ShiftModifier )
2610  {
2611  placeCursor( e->pos(), true, false );
2612  if ( m_selectionCached.start().isValid() )
2613  {
2614  if ( m_cursor.toCursor() < m_selectionCached.start() )
2615  m_selectAnchor = m_selectionCached.end();
2616  else
2617  m_selectAnchor = m_selectionCached.start();
2618  }
2619  setSelection( KTextEditor::Range( m_selectAnchor, m_cursor ) );
2620  }
2621  else
2622  {
2623  placeCursor( e->pos() );
2624  }
2625 
2626  m_scrollX = 0;
2627  m_scrollY = 0;
2628 
2629  m_scrollTimer.start (50);
2630  }
2631 
2632  e->accept ();
2633  break;
2634 
2635  default:
2636  e->ignore ();
2637  break;
2638  }
2639 }
2640 
2641 void KateViewInternal::mouseDoubleClickEvent(QMouseEvent *e)
2642 {
2643  switch (e->button())
2644  {
2645  case Qt::LeftButton:
2646  m_selectionMode = Word;
2647 
2648  if ( e->modifiers() & Qt::ShiftModifier )
2649  {
2650  KTextEditor::Range oldSelection = m_view->selectionRange();
2651 
2652  // Now select the word under the select anchor
2653  int cs, ce;
2654  Kate::TextLine l = doc()->kateTextLine( m_selectAnchor.line() );
2655 
2656  ce = m_selectAnchor.column();
2657  if ( ce > 0 && doc()->highlight()->isInWord( l->at(ce) ) ) {
2658  for (; ce < l->length(); ce++ )
2659  if ( !doc()->highlight()->isInWord( l->at(ce) ) )
2660  break;
2661  }
2662 
2663  cs = m_selectAnchor.column() - 1;
2664  if ( cs < doc()->lineLength( m_selectAnchor.line() )
2665  && doc()->highlight()->isInWord( l->at(cs) ) ) {
2666  for ( cs--; cs >= 0; cs-- )
2667  if ( !doc()->highlight()->isInWord( l->at(cs) ) )
2668  break;
2669  }
2670 
2671  // ...and keep it selected
2672  if (cs+1 < ce)
2673  {
2674  m_selectionCached.start().setPosition( m_selectAnchor.line(), cs+1 );
2675  m_selectionCached.end().setPosition( m_selectAnchor.line(), ce );
2676  }
2677  else
2678  {
2679  m_selectionCached.start() = m_selectAnchor;
2680  m_selectionCached.end() = m_selectAnchor;
2681  }
2682  // Now word select to the mouse cursor
2683  placeCursor( e->pos(), true );
2684  }
2685  else
2686  {
2687  // first clear the selection, otherwise we run into bug #106402
2688  // ...and set the cursor position, for the same reason (otherwise there
2689  // are *other* idiosyncrasies we can't fix without reintroducing said
2690  // bug)
2691  // Parameters: don't redraw, and don't emit selectionChanged signal yet
2692  m_view->clearSelection( false, false );
2693  placeCursor( e->pos() );
2694  m_view->selectWord( m_cursor );
2695  cursorToMatchingBracket(true);
2696 
2697  if (m_view->selection())
2698  {
2699  m_selectAnchor = m_view->selectionRange().start();
2700  m_selectionCached = m_view->selectionRange();
2701  }
2702  else
2703  {
2704  m_selectAnchor = m_cursor;
2705  m_selectionCached = KTextEditor::Range(m_cursor, m_cursor);
2706  }
2707  }
2708 
2709  // Move cursor to end (or beginning) of selected word
2710  if (m_view->selection())
2711  QApplication::clipboard()->setText( m_view->selectionText(), QClipboard::Selection );
2712 
2713  moveCursorToSelectionEdge();
2714  m_possibleTripleClick = true;
2715  QTimer::singleShot ( QApplication::doubleClickInterval(), this, SLOT(tripleClickTimeout()) );
2716 
2717  m_scrollX = 0;
2718  m_scrollY = 0;
2719 
2720  m_scrollTimer.start (50);
2721 
2722  e->accept ();
2723  break;
2724 
2725  default:
2726  e->ignore ();
2727  break;
2728  }
2729 }
2730 
2731 void KateViewInternal::tripleClickTimeout()
2732 {
2733  m_possibleTripleClick = false;
2734 }
2735 
2736 void KateViewInternal::mouseReleaseEvent( QMouseEvent* e )
2737 {
2738  switch (e->button())
2739  {
2740  case Qt::LeftButton:
2741  m_selectionMode = Default;
2742 // m_selectionCached.start().setLine( -1 );
2743 
2744  if (m_selChangedByUser)
2745  {
2746  if (m_view->selection()) {
2747  QApplication::clipboard()->setText(m_view->selectionText (), QClipboard::Selection);
2748  }
2749  moveCursorToSelectionEdge();
2750 
2751  m_selChangedByUser = false;
2752  }
2753 
2754  if (m_dragInfo.state == diPending)
2755  placeCursor( e->pos(), e->modifiers() & Qt::ShiftModifier );
2756  else if (m_dragInfo.state == diNone)
2757  m_scrollTimer.stop ();
2758 
2759  m_dragInfo.state = diNone;
2760 
2761  e->accept ();
2762  break;
2763 
2764  case Qt::MidButton:
2765  placeCursor( e->pos() );
2766 
2767  if( doc()->isReadWrite() ) {
2768  QString clipboard = QApplication::clipboard()->text(QClipboard::Selection);
2769  m_view->paste( &clipboard );
2770  }
2771 
2772  e->accept ();
2773  break;
2774 
2775  default:
2776  e->ignore ();
2777  break;
2778  }
2779 }
2780 
2781 void KateViewInternal::leaveEvent( QEvent* )
2782 {
2783  m_textHintTimer.stop();
2784 
2785  // fix bug 194452, scrolling keeps going if you scroll via mouse drag and press and other mouse
2786  // button outside the view area
2787  if (m_dragInfo.state == diNone)
2788  m_scrollTimer.stop ();
2789 }
2790 
2791 KTextEditor::Cursor KateViewInternal::coordinatesToCursor(const QPoint& _coord, bool includeBorder) const
2792 {
2793  QPoint coord(_coord);
2794 
2795  KTextEditor::Cursor ret = KTextEditor::Cursor::invalid();
2796 
2797  if (includeBorder) coord.rx() -= m_leftBorder->width();
2798  coord.rx() += startX();
2799 
2800  const KateTextLayout& thisLine = yToKateTextLayout(coord.y());
2801  if (thisLine.isValid())
2802  ret = renderer()->xToCursor(thisLine, coord.x(), !m_view->wrapCursor());
2803 
2804  if (ret.column() == view()->document()->lineLength(ret.line())) {
2805  // The cursor is beyond the end of the line; in that case the renderer
2806  // gives the index of the character behind the last one.
2807  return KTextEditor::Cursor::invalid();
2808  }
2809 
2810  return ret;
2811 }
2812 
2813 void KateViewInternal::mouseMoveEvent( QMouseEvent* e )
2814 {
2815  KTextEditor::Cursor newPosition = coordinatesToCursor (e->pos(), false);
2816  if (newPosition != m_mouse) {
2817  m_mouse = newPosition;
2818  mouseMoved();
2819  }
2820 
2821  if( e->buttons() & Qt::LeftButton )
2822  {
2823  if (m_dragInfo.state == diPending)
2824  {
2825  // we had a mouse down, but haven't confirmed a drag yet
2826  // if the mouse has moved sufficiently, we will confirm
2827  QPoint p( e->pos() - m_dragInfo.start );
2828 
2829  // we've left the drag square, we can start a real drag operation now
2830  if( p.manhattanLength() > KGlobalSettings::dndEventDelay() )
2831  doDrag();
2832 
2833  return;
2834  }
2835  else if (m_dragInfo.state == diDragging)
2836  {
2837  // Don't do anything after a canceled drag until the user lets go of
2838  // the mouse button!
2839  return;
2840  }
2841 
2842  m_mouseX = e->x();
2843  m_mouseY = e->y();
2844 
2845  m_scrollX = 0;
2846  m_scrollY = 0;
2847  int d = renderer()->lineHeight();
2848 
2849  if (m_mouseX < 0)
2850  m_scrollX = -d;
2851 
2852  if (m_mouseX > width())
2853  m_scrollX = d;
2854 
2855  if (m_mouseY < 0)
2856  {
2857  m_mouseY = 0;
2858  m_scrollY = -d;
2859  }
2860 
2861  if (m_mouseY > height())
2862  {
2863  m_mouseY = height();
2864  m_scrollY = d;
2865  }
2866 
2867  placeCursor( QPoint( m_mouseX, m_mouseY ), true );
2868 
2869  }
2870  else
2871  {
2872  if (isTargetSelected( e->pos() ) ) {
2873  // mouse is over selected text. indicate that the text is draggable by setting
2874  // the arrow cursor as other Qt text editing widgets do
2875  if (m_mouseCursor != Qt::ArrowCursor) {
2876  m_mouseCursor = Qt::ArrowCursor;
2877  setCursor(m_mouseCursor);
2878  }
2879  } else {
2880  // normal text cursor
2881  if (m_mouseCursor != Qt::IBeamCursor) {
2882  m_mouseCursor = Qt::IBeamCursor;
2883  setCursor(m_mouseCursor);
2884  }
2885  }
2886  //We need to check whether the mouse position is actually within the widget,
2887  //because other widgets like the icon border forward their events to this,
2888  //and we will create invalid text hint requests if we don't check
2889  if (m_textHintEnabled && geometry().contains(parentWidget()->mapFromGlobal(e->globalPos())))
2890  {
2891  if ( QToolTip::isVisible() ) {
2892  QToolTip::hideText();
2893  }
2894  m_textHintTimer.start(m_textHintTimeout);
2895  m_textHintPos = e->pos();
2896  }
2897  }
2898 }
2899 
2900 void KateViewInternal::updateDirty( )
2901 {
2902  uint h = renderer()->lineHeight();
2903 
2904  int currentRectStart = -1;
2905  int currentRectEnd = -1;
2906 
2907  QRegion updateRegion;
2908 
2909  {
2910  for (int i = 0; i < cache()->viewCacheLineCount(); ++i) {
2911  if (cache()->viewLine(i).isDirty()) {
2912  if (currentRectStart == -1) {
2913  currentRectStart = h * i;
2914  currentRectEnd = h;
2915  } else {
2916  currentRectEnd += h;
2917  }
2918 
2919  } else if (currentRectStart != -1) {
2920  updateRegion += QRect(0, currentRectStart, width(), currentRectEnd);
2921  currentRectStart = -1;
2922  currentRectEnd = -1;
2923  }
2924  }
2925  }
2926 
2927 
2928  if (currentRectStart != -1)
2929  updateRegion += QRect(0, currentRectStart, width(), currentRectEnd);
2930 
2931  if (!updateRegion.isEmpty()) {
2932  if (debugPainting) kDebug( 13030 ) << k_funcinfo << "Update dirty region " << updateRegion;
2933  update(updateRegion);
2934  }
2935 }
2936 
2937 void KateViewInternal::hideEvent(QHideEvent* e)
2938 {
2939  Q_UNUSED(e);
2940  if(m_view->isCompletionActive())
2941  m_view->completionWidget()->abortCompletion();
2942 }
2943 
2944 void KateViewInternal::paintEvent(QPaintEvent *e)
2945 {
2946  if (debugPainting) kDebug (13030) << "GOT PAINT EVENT: Region" << e->region();
2947 
2948  const QRect& unionRect = e->rect();
2949 
2950  int xStart = startX() + unionRect.x();
2951  int xEnd = xStart + unionRect.width();
2952  uint h = renderer()->lineHeight();
2953  uint startz = (unionRect.y() / h);
2954  uint endz = startz + 1 + (unionRect.height() / h);
2955  uint lineRangesSize = cache()->viewCacheLineCount();
2956 
2957  QPainter paint(this);
2958  paint.setRenderHints (QPainter::Antialiasing);
2959 
2960  paint.save();
2961 
2962  // TODO put in the proper places
2963  if ( !m_view->viInputMode() ) {
2964  setCaretStyle( m_view->isOverwriteMode() ? KateRenderer::Block : KateRenderer::Line );
2965  }
2966  renderer()->setShowTabs(doc()->config()->showTabs());
2967  renderer()->setShowTrailingSpaces(doc()->config()->showSpaces());
2968 
2969  int sy = startz * h;
2970  paint.translate(unionRect.x(), startz * h);
2971 
2972  for (uint z=startz; z <= endz; z++)
2973  {
2974  if ( (z >= lineRangesSize) || (cache()->viewLine(z).line() == -1) )
2975  {
2976  if (!(z >= lineRangesSize))
2977  cache()->viewLine(z).setDirty(false);
2978 
2979  paint.fillRect( 0, 0, unionRect.width(), h, renderer()->config()->backgroundColor() );
2980  }
2981  else
2982  {
2983  //kDebug( 13030 )<<"KateViewInternal::paintEvent(QPaintEvent *e):cache()->viewLine"<<z;
2984  KateTextLayout& thisLine = cache()->viewLine(z);
2985 
2986  /* If viewLine() returns non-zero, then a document line was split
2987  in several visual lines, and we're trying to paint visual line
2988  that is not the first. In that case, this line was already
2989  painted previously, since KateRenderer::paintTextLine paints
2990  all visual lines.
2991  Except if we're at the start of the region that needs to
2992  be painted -- when no previous calls to paintTextLine were made.
2993  */
2994  if (!thisLine.viewLine() || z == startz) {
2995  // Don't bother if we're not in the requested update region
2996  if (!e->region().contains(QRect(unionRect.x(), startz * h, unionRect.width(), h)))
2997  continue;
2998 
2999  //kDebug (13030) << "paint text: line: " << thisLine.line() << " viewLine " << thisLine.viewLine() << " x: " << unionRect.x() << " y: " << sy
3000  // << " width: " << xEnd-xStart << " height: " << h << endl;
3001 
3002  if (thisLine.viewLine())
3003  paint.translate(QPoint(0, h * - thisLine.viewLine()));
3004 
3005  // The paintTextLine function should be well behaved, but if not, this clipping may be needed
3006  //paint.setClipRect(QRect(xStart, 0, xEnd - xStart, h * (thisLine.kateLineLayout()->viewLineCount())));
3007 
3008  KTextEditor::Cursor pos = m_cursor;
3009  renderer()->paintTextLine(paint, thisLine.kateLineLayout(), xStart, xEnd, &pos);
3010 
3011  //paint.setClipping(false);
3012 
3013  if (thisLine.viewLine())
3014  paint.translate(0, h * thisLine.viewLine());
3015 
3016  thisLine.setDirty(false);
3017  }
3018  }
3019 
3020  paint.translate(0, h);
3021  sy += h;
3022  }
3023 
3024  paint.restore();
3025  if (m_textAnimation)
3026  m_textAnimation->draw(paint);
3027 }
3028 
3029 void KateViewInternal::resizeEvent(QResizeEvent* e)
3030 {
3031  bool expandedHorizontally = width() > e->oldSize().width();
3032  bool expandedVertically = height() > e->oldSize().height();
3033  bool heightChanged = height() != e->oldSize().height();
3034 
3035  m_dummy->setFixedSize(m_lineScroll->width(), m_columnScroll->sizeHint().height());
3036  m_madeVisible = false;
3037 
3038  if (heightChanged) {
3039  setAutoCenterLines(m_autoCenterLines, false);
3040  m_cachedMaxStartPos.setPosition(-1, -1);
3041  }
3042 
3043  if (m_view->dynWordWrap()) {
3044  bool dirtied = false;
3045 
3046  for (int i = 0; i < cache()->viewCacheLineCount(); i++) {
3047  // find the first dirty line
3048  // the word wrap updateView algorithm is forced to check all lines after a dirty one
3049  KateTextLayout viewLine = cache()->viewLine(i);
3050 
3051  if (viewLine.wrap() || viewLine.isRightToLeft() || viewLine.width() > width()) {
3052  dirtied = true;
3053  viewLine.setDirty();
3054  break;
3055  }
3056  }
3057 
3058  if (dirtied || heightChanged) {
3059  updateView(true);
3060  m_leftBorder->update();
3061  }
3062  } else {
3063  updateView();
3064 
3065  if (expandedHorizontally && startX() > 0)
3066  scrollColumns(startX() - (width() - e->oldSize().width()));
3067  }
3068 
3069  if (width() < e->oldSize().width() && !m_view->wrapCursor()) {
3070  // May have to restrain cursor to new smaller width...
3071  if (m_cursor.column() > doc()->lineLength(m_cursor.line())) {
3072  KateTextLayout thisLine = currentLayout();
3073 
3074  KTextEditor::Cursor newCursor(m_cursor.line(), thisLine.endCol() + ((width() - thisLine.xOffset() - (thisLine.width()- m_startX)) / renderer()->spaceWidth()) - 1);
3075  if (newCursor.column() < m_cursor.column())
3076  updateCursor(newCursor);
3077  }
3078  }
3079 
3080 
3081  if (expandedVertically) {
3082  KTextEditor::Cursor max = maxStartPos();
3083  if (startPos() > max) {
3084  scrollPos(max);
3085  return; // already fired displayRangeChanged
3086  }
3087  }
3088  emit m_view->displayRangeChanged(m_view);
3089 }
3090 
3091 void KateViewInternal::scrollTimeout ()
3092 {
3093  if (m_scrollX || m_scrollY)
3094  {
3095  scrollLines (startPos().line() + (m_scrollY / (int) renderer()->lineHeight()));
3096  placeCursor( QPoint( m_mouseX, m_mouseY ), true );
3097  }
3098 }
3099 
3100 void KateViewInternal::cursorTimeout ()
3101 {
3102  if (!debugPainting && !m_view->viInputMode()) {
3103  renderer()->setDrawCaret(!renderer()->drawCaret());
3104  paintCursor();
3105  }
3106 }
3107 
3108 void KateViewInternal::textHintTimeout ()
3109 {
3110  m_textHintTimer.stop ();
3111 
3112  KTextEditor::Cursor c = coordinatesToCursor(m_textHintPos, false);
3113  if (!c.isValid()) return;
3114 
3115  QString tmp;
3116 
3117  emit m_view->needTextHint(c, tmp);
3118 
3119  if (!tmp.isEmpty()) {
3120  kDebug(13030) << "Hint text: " << tmp;
3121  QPoint pos(startX() + m_textHintPos.x(), m_textHintPos.y());
3122  QToolTip::showText(mapToGlobal(pos), tmp);
3123  }
3124 }
3125 
3126 void KateViewInternal::focusInEvent (QFocusEvent *)
3127 {
3128  if (KApplication::cursorFlashTime() > 0)
3129  m_cursorTimer.start ( KApplication::cursorFlashTime() / 2 );
3130 
3131  paintCursor();
3132 
3133  doc()->setActiveView( m_view );
3134 
3135  // this will handle focus stuff in kateview
3136  m_view->slotGotFocus ();
3137 }
3138 
3139 void KateViewInternal::focusOutEvent (QFocusEvent *)
3140 {
3141  //if (m_view->isCompletionActive())
3142  //m_view->abortCompletion();
3143 
3144  m_cursorTimer.stop();
3145  m_view->renderer()->setDrawCaret(true);
3146  paintCursor();
3147 
3148  m_textHintTimer.stop();
3149 
3150  m_view->slotLostFocus ();
3151 }
3152 
3153 void KateViewInternal::doDrag()
3154 {
3155  m_dragInfo.state = diDragging;
3156  m_dragInfo.dragObject = new QDrag(this);
3157  QMimeData *mimeData=new QMimeData();
3158  mimeData->setText(m_view->selectionText());
3159  m_dragInfo.dragObject->setMimeData(mimeData);
3160  m_dragInfo.dragObject->start(Qt::MoveAction);
3161 }
3162 
3163 void KateViewInternal::dragEnterEvent( QDragEnterEvent* event )
3164 {
3165  if (event->source()==this) event->setDropAction(Qt::MoveAction);
3166  event->setAccepted( (event->mimeData()->hasText() && doc()->isReadWrite()) ||
3167  KUrl::List::canDecode(event->mimeData()) );
3168 }
3169 
3170 void KateViewInternal::fixDropEvent(QDropEvent* event) {
3171  if (event->source()!=this) event->setDropAction(Qt::CopyAction);
3172  else {
3173  Qt::DropAction action=Qt::MoveAction;
3174 #ifdef Q_WS_MAC
3175  if(event->keyboardModifiers() & Qt::AltModifier)
3176  action = Qt::CopyAction;
3177 #else
3178  if (event->keyboardModifiers() & Qt::ControlModifier)
3179  action = Qt::CopyAction;
3180 #endif
3181  event->setDropAction(action);
3182  }
3183 }
3184 
3185 void KateViewInternal::dragMoveEvent( QDragMoveEvent* event )
3186 {
3187  // track the cursor to the current drop location
3188  placeCursor( event->pos(), true, false );
3189 
3190  // important: accept action to switch between copy and move mode
3191  // without this, the text will always be copied.
3192  fixDropEvent(event);
3193 }
3194 
3195 void KateViewInternal::dropEvent( QDropEvent* event )
3196 {
3197  if ( KUrl::List::canDecode(event->mimeData()) ) {
3198 
3199  emit dropEventPass(event);
3200 
3201  } else if ( event->mimeData()->hasText() && doc()->isReadWrite() ) {
3202 
3203  QString text=event->mimeData()->text();
3204 
3205  // is the source our own document?
3206  bool priv = false;
3207  if (KateViewInternal* vi = qobject_cast<KateViewInternal*>(event->source()))
3208  priv = doc()->ownedView( vi->m_view );
3209 
3210  // dropped on a text selection area?
3211  bool selected = m_view->cursorSelected(m_cursor);
3212 
3213  fixDropEvent(event);
3214 
3215  if( priv && selected && event->dropAction() != Qt::CopyAction ) {
3216  // this is a drag that we started and dropped on our selection
3217  // ignore this case
3218  return;
3219  }
3220 
3221  // fix the cursor position before editStart(), so that it is correctly
3222  // stored for the undo action
3223  KTextEditor::Cursor targetCursor(m_cursor); // backup current cursor
3224  int selectionWidth = m_view->selectionRange().columnWidth(); // for block selection
3225  int selectionHeight = m_view->selectionRange().numberOfLines(); // for block selection
3226 
3227  if ( event->dropAction() != Qt::CopyAction ) {
3228  editSetCursor(m_view->selectionRange().end());
3229  } else {
3230  m_view->clearSelection();
3231  }
3232 
3233  // use one transaction
3234  doc()->editStart ();
3235 
3236  // on move: remove selected text; on copy: duplicate text
3237  doc()->insertText(targetCursor, text, m_view->blockSelection());
3238 
3239  Kate::TextCursor startCursor(doc()->buffer(), targetCursor, KTextEditor::MovingCursor::MoveOnInsert);
3240 
3241  if ( event->dropAction() != Qt::CopyAction )
3242  m_view->removeSelectedText();
3243 
3244  Kate::TextCursor endCursor1(doc()->buffer(), startCursor, KTextEditor::MovingCursor::MoveOnInsert);
3245 
3246  if ( !m_view->blockSelection() ) {
3247  endCursor1.move(text.length());
3248  } else {
3249  endCursor1.setColumn(startCursor.column()+selectionWidth);
3250  endCursor1.setLine(startCursor.line()+selectionHeight);
3251  }
3252 
3253  KTextEditor::Cursor endCursor(endCursor1);
3254  kDebug( 13030 )<<startCursor<<"---("<<text.length()<<")---"<<endCursor;
3255  setSelection(KTextEditor::Range(startCursor,endCursor));
3256  editSetCursor(endCursor);
3257 
3258  doc()->editEnd ();
3259 
3260  event->acceptProposedAction();
3261  updateView();
3262  }
3263 
3264  // finally finish drag and drop mode
3265  m_dragInfo.state = diNone;
3266  // important, because the eventFilter`s DragLeave does not occur
3267  stopDragScroll();
3268 }
3269 //END EVENT HANDLING STUFF
3270 
3271 void KateViewInternal::clear()
3272 {
3273  m_startPos.setPosition (0, 0);
3274  m_displayCursor = KTextEditor::Cursor(0, 0);
3275  m_cursor.setPosition(0, 0);
3276  cache()->clear();
3277  updateView(true);
3278 }
3279 
3280 void KateViewInternal::wheelEvent(QWheelEvent* e)
3281 {
3282  // zoom text, if ctrl is pressed
3283  if (e->modifiers() == Qt::ControlModifier) {
3284  if (e->delta() > 0) {
3285  slotIncFontSizes();
3286  } else {
3287  slotDecFontSizes();
3288  }
3289  e->accept();
3290  return;
3291  }
3292 
3293  // scroll up/down or left/right, if possible
3294  if (m_lineScroll->minimum() != m_lineScroll->maximum() && e->orientation() != Qt::Horizontal) {
3295  // React to this as a vertical event
3296  if ( e->modifiers() & Qt::ShiftModifier ) {
3297  if (e->delta() > 0)
3298  scrollPrevPage();
3299  else
3300  scrollNextPage();
3301  } else {
3302  const int scrollLines = QApplication::wheelScrollLines();
3303  scrollViewLines(e->delta() > 0 ? -scrollLines : scrollLines);
3304  e->accept();
3305  return;
3306  }
3307 
3308  } else if (columnScrollingPossible()) {
3309  QWheelEvent copy = *e;
3310  QApplication::sendEvent(m_columnScroll, &copy);
3311 
3312  } else {
3313  e->ignore();
3314  }
3315 }
3316 
3317 void KateViewInternal::startDragScroll()
3318 {
3319  if ( !m_dragScrollTimer.isActive() ) {
3320  m_dragScrollTimer.start( s_scrollTime );
3321  }
3322 }
3323 
3324 void KateViewInternal::stopDragScroll()
3325 {
3326  m_dragScrollTimer.stop();
3327  updateView();
3328 }
3329 
3330 void KateViewInternal::doDragScroll()
3331 {
3332  QPoint p = this->mapFromGlobal( QCursor::pos() );
3333 
3334  int dx = 0, dy = 0;
3335  if ( p.y() < s_scrollMargin ) {
3336  dy = p.y() - s_scrollMargin;
3337  } else if ( p.y() > height() - s_scrollMargin ) {
3338  dy = s_scrollMargin - (height() - p.y());
3339  }
3340 
3341  if ( p.x() < s_scrollMargin ) {
3342  dx = p.x() - s_scrollMargin;
3343  } else if ( p.x() > width() - s_scrollMargin ) {
3344  dx = s_scrollMargin - (width() - p.x());
3345  }
3346 
3347  dy /= 4;
3348 
3349  if (dy)
3350  scrollLines(startPos().line() + dy);
3351 
3352  if (columnScrollingPossible () && dx)
3353  scrollColumns(qMin (m_startX + dx, m_columnScroll->maximum()));
3354 
3355  if (!dy && !dx)
3356  stopDragScroll();
3357 }
3358 
3359 void KateViewInternal::enableTextHints(int timeout)
3360 {
3361  if (timeout >= 0) {
3362  m_textHintTimeout = timeout;
3363  m_textHintEnabled = true;
3364  m_textHintTimer.start(timeout);
3365  } else {
3366  kWarning() << "Attempt to enable text hints with negative timeout:" << timeout;
3367  }
3368 }
3369 
3370 void KateViewInternal::disableTextHints()
3371 {
3372  if (m_textHintEnabled) {
3373  m_textHintEnabled = false;
3374  m_textHintTimer.stop ();
3375  }
3376 }
3377 
3378 //BEGIN EDIT STUFF
3379 void KateViewInternal::editStart()
3380 {
3381  editSessionNumber++;
3382 
3383  if (editSessionNumber > 1)
3384  return;
3385 
3386  editIsRunning = true;
3387  editOldCursor = m_cursor;
3388  editOldSelection = m_view->selectionRange();
3389 }
3390 
3391 void KateViewInternal::editEnd(int editTagLineStart, int editTagLineEnd, bool tagFrom)
3392 {
3393  if (editSessionNumber == 0)
3394  return;
3395 
3396  editSessionNumber--;
3397 
3398  if (editSessionNumber > 0)
3399  return;
3400 
3401  // fix start position, might have moved from column 0
3402  // try to clever calculate the right start column for the tricky dyn word wrap case
3403  int col = 0;
3404  if (m_view->dynWordWrap()) {
3405  if (KateLineLayoutPtr layout = cache()->line(m_startPos.line())) {
3406  int index = layout->viewLineForColumn (m_startPos.column());
3407  if (index >= 0 && index < layout->viewLineCount())
3408  col = layout->viewLine (index).startCol();
3409  }
3410  }
3411  m_startPos.setPosition (m_startPos.line(), col);
3412 
3413  if (tagFrom && (editTagLineStart <= int(m_view->textFolding().visibleLineToLine(startLine()))))
3414  tagAll();
3415  else
3416  tagLines (editTagLineStart, tagFrom ? qMax(doc()->lastLine() + 1, editTagLineEnd) : editTagLineEnd, true);
3417 
3418  if (editOldCursor == m_cursor.toCursor())
3419  updateBracketMarks();
3420 
3421  updateView(true);
3422 
3423  if (editOldCursor != m_cursor.toCursor() || m_view == doc()->activeView())
3424  {
3425  // Only scroll the view to the cursor if the insertion happens at the cursor.
3426  // This might not be the case for e.g. collaborative editing, when a remote user
3427  // inserts text at a position not at the caret.
3428  if ( m_cursor.line() >= editTagLineStart && m_cursor.line() <= editTagLineEnd ) {
3429  m_madeVisible = false;
3430  updateCursor ( m_cursor, true );
3431  }
3432  }
3433 
3438  if (editOldSelection != m_view->selectionRange()
3439  || (editOldSelection.isValid() && !editOldSelection.isEmpty() && !(editTagLineStart > editOldSelection.end().line() && editTagLineEnd < editOldSelection.start().line())))
3440  emit m_view->selectionChanged (m_view);
3441 
3442  editIsRunning = false;
3443 }
3444 
3445 void KateViewInternal::editSetCursor (const KTextEditor::Cursor &_cursor)
3446 {
3447  if (m_cursor.toCursor() != _cursor)
3448  {
3449  m_cursor.setPosition(_cursor);
3450  }
3451 }
3452 //END
3453 
3454 void KateViewInternal::viewSelectionChanged ()
3455 {
3456  if (!m_view->selection()) {
3457  m_selectAnchor = KTextEditor::Cursor::invalid();
3458  } else {
3459  m_selectAnchor = m_view->selectionRange().start();
3460  }
3461  // Do NOT nuke the entire range! The reason is that a shift+DC selection
3462  // might (correctly) set the range to be empty (i.e. start() == end()), and
3463  // subsequent dragging might shrink the selection into non-existence. When
3464  // this happens, we use the cached end to restore the cached start so that
3465  // updateSelection is not confused. See also comments in updateSelection.
3466  m_selectionCached.start() = KTextEditor::Cursor::invalid();
3467 }
3468 
3469 KateLayoutCache* KateViewInternal::cache( ) const
3470 {
3471  return m_layoutCache;
3472 }
3473 
3474 KTextEditor::Cursor KateViewInternal::toRealCursor( const KTextEditor::Cursor & virtualCursor ) const
3475 {
3476  return KTextEditor::Cursor(m_view->textFolding().visibleLineToLine(virtualCursor.line()), virtualCursor.column());
3477 }
3478 
3479 KTextEditor::Cursor KateViewInternal::toVirtualCursor( const KTextEditor::Cursor & realCursor ) const
3480 {
3485  if (realCursor.line() < 0)
3486  return KTextEditor::Cursor::invalid ();
3487 
3488  return KTextEditor::Cursor(m_view->textFolding().lineToVisibleLine(realCursor.line()), realCursor.column());
3489 }
3490 
3491 KateRenderer * KateViewInternal::renderer( ) const
3492 {
3493  return m_view->renderer();
3494 }
3495 
3496 void KateViewInternal::mouseMoved( )
3497 {
3498  m_view->notifyMousePositionChanged(m_mouse);
3499  m_view->updateRangesIn (KTextEditor::Attribute::ActivateMouseIn);
3500 }
3501 
3502 void KateViewInternal::cursorMoved( )
3503 {
3504  m_view->updateRangesIn (KTextEditor::Attribute::ActivateCaretIn);
3505 #ifndef QT_NO_ACCESSIBILITY
3506 #if QT_VERSION >= 0x040800
3507  QAccessible::updateAccessibility(this, 0, QAccessible::TextCaretMoved);
3508 #endif
3509 #endif
3510 }
3511 
3512 bool KateViewInternal::rangeAffectsView(const KTextEditor::Range& range, bool realCursors) const
3513 {
3514  int startLine = m_startPos.line();
3515  int endLine = startLine + (int)m_visibleLineCount;
3516 
3517  if ( realCursors ) {
3518  startLine = (int)m_view->textFolding().visibleLineToLine(startLine);
3519  endLine = (int)m_view->textFolding().visibleLineToLine(endLine);
3520  }
3521 
3522  return (range.end().line() >= startLine) || (range.start().line() <= endLine);
3523 }
3524 
3525 //BEGIN IM INPUT STUFF
3526 QVariant KateViewInternal::inputMethodQuery ( Qt::InputMethodQuery query ) const
3527 {
3528  switch (query) {
3529  case Qt::ImMicroFocus: {
3530  // Cursor placement code is changed for Asian input method that
3531  // shows candidate window. This behavior is same as Qt/E 2.3.7
3532  // which supports Asian input methods. Asian input methods need
3533  // start point of IM selection text to place candidate window as
3534  // adjacent to the selection text.
3535  return QRect (cursorToCoordinate(m_cursor, true, false), QSize(0, renderer()->lineHeight()));
3536  }
3537 
3538  case Qt::ImFont:
3539  return renderer()->currentFont();
3540 
3541  case Qt::ImCursorPosition:
3542  return m_cursor.column();
3543 
3544  case Qt::ImAnchorPosition:
3545  // If selectAnchor is at the same line, return the real anchor position
3546  // Otherwise return the same position of cursor
3547  if (m_view->selection() && m_selectAnchor.line() == m_cursor.line())
3548  return m_selectAnchor.column();
3549  else
3550  return m_cursor.column();
3551 
3552  case Qt::ImSurroundingText:
3553  if (Kate::TextLine l = doc()->kateTextLine(m_cursor.line()))
3554  return l->string();
3555  else
3556  return QString();
3557 
3558  case Qt::ImCurrentSelection:
3559  if (m_view->selection())
3560  return m_view->selectionText();
3561  else
3562  return QString();
3563  default:
3564  /* values: ImMaximumTextLength */
3565  break;
3566  }
3567 
3568  return QWidget::inputMethodQuery(query);
3569 }
3570 
3571 void KateViewInternal::inputMethodEvent(QInputMethodEvent* e)
3572 {
3573  if ( doc()->readOnly() ) {
3574  e->ignore();
3575  return;
3576  }
3577 
3578  //kDebug( 13030 ) << "Event: cursor" << m_cursor << "commit" << e->commitString() << "preedit" << e->preeditString() << "replacement start" << e->replacementStart() << "length" << e->replacementLength();
3579 
3580  if (!m_imPreeditRange) {
3581  m_imPreeditRange = doc()->newMovingRange (KTextEditor::Range(m_cursor, m_cursor), KTextEditor::MovingRange::ExpandLeft | KTextEditor::MovingRange::ExpandRight);
3582  }
3583 
3584  if (!m_imPreeditRange->toRange().isEmpty()) {
3585  doc()->inputMethodStart();
3586  doc()->removeText(*m_imPreeditRange);
3587  doc()->inputMethodEnd();
3588  }
3589 
3590  if (!e->commitString().isEmpty() || e->replacementLength()) {
3591  m_view->removeSelectedText();
3592 
3593  KTextEditor::Range preeditRange = *m_imPreeditRange;
3594 
3595  KTextEditor::Cursor start(m_imPreeditRange->start().line(), m_imPreeditRange->start().column() + e->replacementStart());
3596  KTextEditor::Cursor removeEnd = start + KTextEditor::Cursor(0, e->replacementLength());
3597 
3598  doc()->editStart();
3599  if (start != removeEnd)
3600  doc()->removeText(KTextEditor::Range(start, removeEnd));
3601  if (!e->commitString().isEmpty()) {
3602  // if the input method event is text that should be inserted, call KateDocument::typeChars()
3603  // with the text. that method will handle the input and take care of overwrite mode, etc.
3604  doc()->typeChars(m_view, e->commitString());
3605  }
3606  doc()->editEnd();
3607 
3608  // Revert to the same range as above
3609  m_imPreeditRange->setRange(preeditRange);
3610  }
3611 
3612  if (!e->preeditString().isEmpty()) {
3613  doc()->inputMethodStart();
3614  doc()->insertText(m_imPreeditRange->start(), e->preeditString());
3615  doc()->inputMethodEnd();
3616  // The preedit range gets automatically repositioned
3617  }
3618 
3619  // Finished this input method context?
3620  if (m_imPreeditRange && e->preeditString().isEmpty()) {
3621  // delete the range and reset the pointer
3622  delete m_imPreeditRange;
3623  m_imPreeditRange = 0L;
3624  qDeleteAll (m_imPreeditRangeChildren);
3625  m_imPreeditRangeChildren.clear ();
3626 
3627  if ( KApplication::cursorFlashTime() > 0 )
3628  renderer()->setDrawCaret(false);
3629  renderer()->setCaretOverrideColor(QColor());
3630 
3631  e->accept();
3632  return;
3633  }
3634 
3635  KTextEditor::Cursor newCursor = m_cursor;
3636  bool hideCursor = false;
3637  QColor caretColor;
3638 
3639  if (m_imPreeditRange) {
3640  qDeleteAll (m_imPreeditRangeChildren);
3641  m_imPreeditRangeChildren.clear ();
3642 
3643  int decorationColumn = 0;
3644  foreach (const QInputMethodEvent::Attribute &a, e->attributes()) {
3645  if (a.type == QInputMethodEvent::Cursor) {
3646  newCursor = m_imPreeditRange->start() + KTextEditor::Cursor(0, a.start);
3647  hideCursor = !a.length;
3648  QColor c = qvariant_cast<QColor>(a.value);
3649  if (c.isValid())
3650  caretColor = c;
3651 
3652  } else if (a.type == QInputMethodEvent::TextFormat) {
3653  QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
3654  if (f.isValid() && decorationColumn <= a.start) {
3655  KTextEditor::Range fr(m_imPreeditRange->start().line(), m_imPreeditRange->start().column() + a.start, m_imPreeditRange->start().line(), m_imPreeditRange->start().column() + a.start + a.length);
3656  KTextEditor::MovingRange* formatRange = doc()->newMovingRange (fr);
3657  KTextEditor::Attribute::Ptr attribute(new KTextEditor::Attribute());
3658  attribute->merge(f);
3659  formatRange->setAttribute(attribute);
3660  decorationColumn = a.start + a.length;
3661  m_imPreeditRangeChildren.push_back (formatRange);
3662  }
3663  }
3664  }
3665  }
3666 
3667  renderer()->setDrawCaret(hideCursor);
3668  renderer()->setCaretOverrideColor(caretColor);
3669 
3670  if (newCursor != m_cursor.toCursor())
3671  updateCursor(newCursor);
3672 
3673  e->accept();
3674 }
3675 
3676 //END IM INPUT STUFF
3677 
3678 ViMode KateViewInternal::getCurrentViMode()
3679 {
3680  return getViInputModeManager()->getCurrentViMode();
3681 }
3682 
3683 KateViInputModeManager* KateViewInternal::getViInputModeManager()
3684 {
3685  if (!m_viInputModeManager) {
3686  m_viInputModeManager = new KateViInputModeManager(m_view, this);
3687  }
3688 
3689  return m_viInputModeManager;
3690 }
3691 
3692 KateViInputModeManager* KateViewInternal::resetViInputModeManager()
3693 {
3694  if (m_viInputModeManager) {
3695  delete m_viInputModeManager;
3696  }
3697  m_viInputModeManager = new KateViInputModeManager(m_view, this);
3698 
3699  return m_viInputModeManager;
3700 }
3701 
3702 void KateViewInternal::flashChar(const KTextEditor::Cursor & pos, KTextEditor::Attribute::Ptr attribute)
3703 {
3704  Q_ASSERT(pos.isValid());
3705  Q_ASSERT(!attribute.isNull());
3706 
3707  // if line is folded away, do nothing
3708  if (!m_view->textFolding().isLineVisible (pos.line())) {
3709  return;
3710  }
3711 
3712  KTextEditor::Range range(pos, KTextEditor::Cursor(pos.line(), pos.column() + 1));
3713  if (m_textAnimation) m_textAnimation->deleteLater();
3714  m_textAnimation = new KateTextAnimation(range, attribute, this);
3715 }
3716 
3717 // kate: space-indent on; indent-width 2; replace-tabs on;
KateViewInternal::editEnd
void editEnd(int editTagLineStart, int editTagLineEnd, bool tagFrom)
Definition: kateviewinternal.cpp:3391
QWidget::layout
QLayout * layout() const
QInputMethodEvent::preeditString
const QString & preeditString() const
QHideEvent
KateDocument::line
virtual QString line(int line) const
Definition: katedocument.cpp:447
KateViewInternal::cursorPrevChar
void cursorPrevChar(bool sel=false)
Definition: kateviewinternal.cpp:1092
QList::clear
void clear()
InsertMode
Definition: kateviinputmodemanager.h:50
KateDocument::config
KateDocumentConfig * config()
Configuration.
Definition: katedocument.h:1009
KateRenderer::cursorToX
int cursorToX(const KateTextLayout &range, int col, bool returnPastLine=false) const
Returns the x position of cursor col on the line range.
Definition: katerenderer.cpp:1048
KateViewInternal::resizeEvent
virtual void resizeEvent(QResizeEvent *)
Definition: kateviewinternal.cpp:3029
KateRendererConfig::showWholeBracketExpression
bool showWholeBracketExpression() const
Definition: kateconfig.cpp:2751
QDropEvent::source
QWidget * source() const
QEvent
KateViewInternal::doReturn
void doReturn()
Definition: kateviewinternal.cpp:795
QResizeEvent
QWidget
KateViewInternal::doBackspace
void doBackspace()
Definition: kateviewinternal.cpp:827
katehighlight.h
QKeyEvent::modifiers
Qt::KeyboardModifiers modifiers() const
QTextCharFormat::isValid
bool isValid() const
KateViewInternal::dragEnterEvent
virtual void dragEnterEvent(QDragEnterEvent *)
Definition: kateviewinternal.cpp:3163
KateDocument::ignoreModifiedOnDiskOnce
void ignoreModifiedOnDiskOnce()
Definition: katedocument.cpp:4696
kateview.h
QScrollBar::sizeHint
virtual QSize sizeHint() const
KateTextLayout::startCol
int startCol() const
Definition: katetextlayout.cpp:127
QEvent::type
Type type() const
QApplication::doubleClickInterval
int doubleClickInterval()
KateRenderer::Block
Definition: katerenderer.h:71
QPoint::rx
int & rx()
KateIconBorder::updateFont
void updateFont()
Definition: kateviewhelpers.cpp:1421
KateRendererConfig::highlightedBracketColor
const QColor & highlightedBracketColor() const
Definition: kateconfig.cpp:2424
KateRenderer::currentFont
const QFont & currentFont() const
Definition: katerenderer.cpp:805
KateView::clearSelection
bool clearSelection()
Definition: kateview.cpp:1991
KateViewInternal::KateViewInternal
KateViewInternal(KateView *view)
Definition: kateviewinternal.cpp:63
QSize::width
int width() const
QInputMethodEvent::replacementStart
int replacementStart() const
KateDocument::newMovingRange
virtual KTextEditor::MovingRange * newMovingRange(const KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors=KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::EmptyBehavior emptyBehavior=KTextEditor::MovingRange::AllowEmpty)
Create a new moving range for this document.
Definition: katedocument.cpp:4741
KateViewInternal::startPos
KTextEditor::Cursor startPos() const
Definition: kateviewinternal.h:125
KateView::selectWord
void selectWord(const KTextEditor::Cursor &cursor)
Definition: kateview.cpp:2154
QWidget::setCursor
void setCursor(const QCursor &)
KateViewInternal::focusInEvent
virtual void focusInEvent(QFocusEvent *)
Definition: kateviewinternal.cpp:3126
QInputMethodEvent::Attribute
QDropEvent::mimeData
const QMimeData * mimeData() const
QPainter::fillRect
void fillRect(const QRectF &rectangle, const QBrush &brush)
KateViewInternal::topOfView
void topOfView(bool sel=false)
Definition: kateviewinternal.cpp:1497
KateView::renderer
KateRenderer * renderer()
Definition: kateview.cpp:1664
KateViewInternal::tagRange
bool tagRange(const KTextEditor::Range &range, bool realCursors)
Definition: kateviewinternal.cpp:2106
KateRenderer::spaceWidth
qreal spaceWidth() const
Definition: katerenderer.cpp:907
KateView::document
KTextEditor::Document * document() const
Definition: kateview.cpp:2824
KateView::isCompletionActive
virtual bool isCompletionActive() const
Definition: kateview.cpp:2341
katerenderer.h
KateTextLayout::line
int line() const
Definition: katetextlayout.cpp:93
KateView::bottomViewBar
KateViewBar * bottomViewBar() const
Definition: kateview.cpp:3008
KateViewInternal::mouseDoubleClickEvent
virtual void mouseDoubleClickEvent(QMouseEvent *)
Definition: kateviewinternal.cpp:2641
KateViewInternal::slotDecFontSizes
void slotDecFontSizes()
Definition: kateviewinternal.cpp:337
KateCompletionWidget::pageDown
void pageDown()
Definition: katecompletionwidget.cpp:1095
QInputMethodEvent
QList::push_back
void push_back(const T &value)
KateDocument::highlight
KateHighlighting * highlight() const
Definition: katedocument.cpp:4701
kateviewaccessible.h
QAbstractSlider::setRange
void setRange(int min, int max)
KateViewConfig::AlwaysOn
Definition: kateconfig.h:447
Kate::TextCursor::column
int column() const
Retrieve the column on which this cursor is situated.
Definition: katetextcursor.h:141
KateView::dynWordWrap
bool dynWordWrap() const
Definition: kateview.h:244
QWidget::updateMicroFocus
void updateMicroFocus()
QDragMoveEvent
KateRenderer::setCaretOverrideColor
void setCaretOverrideColor(const QColor &color)
Set a brush with which to override drawing of the caret.
Definition: katerenderer.cpp:1083
QPaintEvent::region
const QRegion & region() const
KateDocument::activeView
virtual KTextEditor::View * activeView() const
Definition: katedocument.h:156
KateDocument::transpose
void transpose(const KTextEditor::Cursor &)
Definition: katedocument.cpp:2695
QChar
KateDocumentConfig::tabIndents
Definition: kateconfig.h:196
KateViewInternal::keyPressEvent
virtual void keyPressEvent(QKeyEvent *)
Definition: kateviewinternal.cpp:2287
KateViewInternal::bottomOfView
void bottomOfView(bool sel=false)
Definition: kateviewinternal.cpp:1504
QKeyEvent::count
int count() const
KateDocument::lineLength
virtual int lineLength(int line) const
Definition: katedocument.cpp:758
KateViewInternal::dropEvent
virtual void dropEvent(QDropEvent *)
Definition: kateviewinternal.cpp:3195
KateViewInternal::clear
void clear()
Definition: kateviewinternal.cpp:3271
QWidget::style
QStyle * style() const
KateViewInternal::top_home
void top_home(bool sel=false)
Definition: kateviewinternal.cpp:1673
KateViewInternal::editSetCursor
void editSetCursor(const KTextEditor::Cursor &cursor)
Definition: kateviewinternal.cpp:3445
KateCompletionWidget::cursorDown
void cursorDown()
Definition: katecompletionwidget.cpp:1065
QMouseEvent::x
int x() const
QMouseEvent::y
int y() const
Kate::TextFolding::visibleLineToLine
int visibleLineToLine(int visibleLine) const
Convert a visible line number to a line number in the text buffer.
Definition: katetextfolding.cpp:422
KateTextLayout::isValid
bool isValid() const
Definition: katetextlayout.cpp:88
KateViewInternal::inputMethodQuery
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const
IM input stuff.
Definition: kateviewinternal.cpp:3526
KateViewInternal::pageUp
void pageUp(bool sel=false, bool half=false)
Definition: kateviewinternal.cpp:1544
QAccessible::removeFactory
void removeFactory(InterfaceFactory factory)
KateViewInternal::cursorToCoordinate
QPoint cursorToCoordinate(const KTextEditor::Cursor &cursor, bool realCursor=true, bool includeBorder=true) const
Definition: kateviewinternal.cpp:739
QWheelEvent
ReplaceMode
Definition: kateviinputmodemanager.h:54
QDropEvent::pos
const QPoint & pos() const
QWidget::y
int y() const
KateViewInternal::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *)
Definition: kateviewinternal.cpp:2736
QWidget::isVisible
bool isVisible() const
QWidget::mapToGlobal
QPoint mapToGlobal(const QPoint &pos) const
KateLayoutCache::textLayout
KateTextLayout textLayout(const KTextEditor::Cursor &realCursor)
Returns the layout describing the text line which is occupied by realCursor.
Definition: katelayoutcache.cpp:337
QPainter::save
void save()
KateViInputModeManager
Definition: kateviinputmodemanager.h:68
QScrollBar
KateTextLayout::start
KTextEditor::Cursor start() const
Definition: katetextlayout.cpp:135
QWidget::setAttribute
void setAttribute(Qt::WidgetAttribute attribute, bool on)
KateViewInternal::KateIconBorder
friend class KateIconBorder
Definition: kateviewinternal.h:63
KateView::emitNavigateUp
void emitNavigateUp()
Definition: kateview.h:371
QTime::msecsTo
int msecsTo(const QTime &t) const
KateRenderer::increaseFontSizes
void increaseFontSizes()
Change to a different font (soon to be font set?)
Definition: katerenderer.cpp:140
QRect::height
int height() const
KateView::contextMenu
QMenu * contextMenu() const
Definition: kateview.cpp:2844
KateDocument::inputMethodEnd
void inputMethodEnd()
Definition: katedocument.cpp:850
QRect::x
int x() const
QRect::y
int y() const
QAbstractSlider::setPageStep
void setPageStep(int)
KateViewInternal::hideEvent
virtual void hideEvent(QHideEvent *e)
Definition: kateviewinternal.cpp:2937
KateViewInternal::wordNext
void wordNext(bool sel=false)
Definition: kateviewinternal.cpp:1148
QWidget::hasFocus
bool hasFocus() const
QPoint
KateTextAnimation
This class is used to flash text in the text view.
Definition: katetextanimation.h:41
QMouseEvent
QMouseEvent::buttons
Qt::MouseButtons buttons() const
QMimeData::hasText
bool hasText() const
QKeyEvent::isAutoRepeat
bool isAutoRepeat() const
KateViewInternal::focusOutEvent
virtual void focusOutEvent(QFocusEvent *)
Definition: kateviewinternal.cpp:3139
KateLayoutCache::clear
void clear()
Definition: katelayoutcache.cpp:517
KateCompletionWidget::resetHadNavigation
void resetHadNavigation()
Definition: katecompletionwidget.cpp:971
QChildEvent::child
QObject * child() const
KateViewInternal::scrollDown
void scrollDown()
Definition: kateviewinternal.cpp:1530
KateViewInternal::none
Definition: kateviewinternal.h:74
KateView::textFolding
Kate::TextFolding & textFolding()
Folding handler for this view.
Definition: kateview.h:574
KateViewInternal::doSmartNewline
void doSmartNewline()
Definition: kateviewinternal.cpp:802
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
KateRendererConfig::animateBracketMatching
bool animateBracketMatching() const
Definition: kateconfig.cpp:2772
QWidget::inputMethodQuery
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const
QToolTip::showText
void showText(const QPoint &pos, const QString &text, QWidget *w)
KateTextLayout::setDirty
bool setDirty(bool dirty=true)
Definition: katetextlayout.cpp:42
KateDocument::indent
void indent(KTextEditor::Range range, int change)
Definition: katedocument.cpp:2899
KateView::needTextHint
void needTextHint(const KTextEditor::Cursor &position, QString &text)
KateDocument::backspace
void backspace(KateView *view, const KTextEditor::Cursor &)
Definition: katedocument.cpp:2726
QFontMetricsF::width
qreal width(const QString &text) const
QMimeData
QWidget::update
void update()
KateTextLayout::endCol
int endCol(bool indicateEOL=false) const
Return the end column of this text line.
Definition: katetextlayout.cpp:140
KateRenderer::xToCursor
KTextEditor::Cursor xToCursor(const KateTextLayout &range, int x, bool returnPastLine=false) const
Returns the real cursor which is occupied by the specified x value, or that closest to it...
Definition: katerenderer.cpp:1071
QPoint::x
int x() const
QPoint::y
int y() const
KateViewInternal::doDeletePrevWord
void doDeletePrevWord()
Definition: kateviewinternal.cpp:842
KateViewInternal::Bias
Bias
Definition: kateviewinternal.h:71
KateView::cursorSelected
bool cursorSelected(const KTextEditor::Cursor &cursor)
Definition: kateview.cpp:2083
QWidget::geometry
const QRect & geometry() const
KateViewInternal::top
void top(bool sel=false)
Definition: kateviewinternal.cpp:1653
kateviewhelpers.h
Kate::TextCursor::setPosition
void setPosition(const TextCursor &position)
Fast way to set the current cursor position to position.
Definition: katetextcursor.cpp:64
katebuffer.h
KateViewInternal::startX
int startX() const
Definition: kateviewinternal.h:127
KateDocument::lastLine
int lastLine() const
gets the last line number (lines() - 1)
Definition: katedocument.h:691
debugPainting
static const bool debugPainting
Definition: kateviewinternal.cpp:61
KateViewInternal::tagLines
bool tagLines(int start, int end, bool realLines=false)
Definition: kateviewinternal.cpp:2020
KateRenderer::setShowTrailingSpaces
void setShowTrailingSpaces(bool showSpaces)
Set whether a mark should be painted for trailing spaces.
Definition: katerenderer.cpp:110
KateViewInternal::doDeleteNextWord
void doDeleteNextWord()
Definition: kateviewinternal.cpp:853
KateViewInternal::slotIncFontSizes
void slotIncFontSizes()
Definition: kateviewinternal.cpp:331
KateViewInternal::yToKateTextLayout
KateTextLayout yToKateTextLayout(int y) const
Definition: kateviewinternal.cpp:312
QInputMethodEvent::replacementLength
int replacementLength() const
KateLayoutCache::setAcceptDirtyLayouts
void setAcceptDirtyLayouts(bool accept)
Definition: katelayoutcache.cpp:565
QWidget::width
width
KateView::selectionRange
virtual const KTextEditor::Range & selectionRange() const
Definition: kateview.cpp:2815
kateviinputmodemanager.h
QWidget::size
QSize size() const
QPaintEvent::rect
const QRect & rect() const
KateViewInternal::cursorToMatchingBracket
void cursorToMatchingBracket(bool sel=false)
Definition: kateviewinternal.cpp:1487
KateDocument::setActiveView
void setActiveView(KTextEditor::View *)
Definition: katedocument.cpp:2552
QWidget::setMinimumSize
void setMinimumSize(const QSize &)
KateViewInternal::bottom
void bottom(bool sel=false)
Definition: kateviewinternal.cpp:1663
KateRenderer
Handles all of the work of rendering the text (used for the views and printing)
Definition: katerenderer.h:50
KateView::displayRangeChanged
void displayRangeChanged(KateView *view)
KateView::completionWidget
KateCompletionWidget * completionWidget() const
Definition: kateview.cpp:2346
KateDocument::insertText
virtual bool insertText(const KTextEditor::Cursor &position, const QString &s, bool block=false)
Definition: katedocument.cpp:530
QRect
KateTextLayout::xOffset
int xOffset() const
Definition: katetextlayout.cpp:55
KateViewInternal::BoundedCursor
friend class BoundedCursor
Definition: kateviewinternal.h:66
KateRenderer::setShowTabs
void setShowTabs(bool showTabs)
Set whether a mark should be painted to help identifying tabs.
Definition: katerenderer.cpp:105
KateCompletionWidget::toggleExpanded
bool toggleExpanded(bool forceExpand=false, bool forceUnExpand=false)
Returns whether the current item was expanded/unexpanded.
Definition: katecompletionwidget.cpp:983
QWidget::isEnabled
bool isEnabled() const
QWidget::showEvent
virtual void showEvent(QShowEvent *event)
KateViewConfig::showScrollbars
int showScrollbars() const
Definition: kateconfig.cpp:1573
QMouseEvent::globalPos
const QPoint & globalPos() const
KateTextLayout::isRightToLeft
bool isRightToLeft() const
Definition: katetextlayout.cpp:215
KateView::contextMenuEvent
void contextMenuEvent(QContextMenuEvent *)
Definition: kateview.cpp:1283
QEvent::isAccepted
bool isAccepted() const
QEvent::ignore
void ignore()
KateViewInternal::cursorNextChar
void cursorNextChar(bool sel=false)
Definition: kateviewinternal.cpp:1100
KateViewInternal::mousePressEvent
virtual void mousePressEvent(QMouseEvent *)
Definition: kateviewinternal.cpp:2517
KateDocument::newBracketMark
void newBracketMark(const KTextEditor::Cursor &start, KTextEditor::Range &bm, int maxLines=-1)
Definition: katedocument.cpp:3573
QAccessible::updateAccessibility
void updateAccessibility(QObject *object, int child, Event reason)
QToolTip::isVisible
bool isVisible()
QObject::installEventFilter
void installEventFilter(QObject *filterObj)
QMenu::popup
void popup(const QPoint &p, QAction *atAction)
KateViewInternal::flashChar
void flashChar(const KTextEditor::Cursor &pos, KTextEditor::Attribute::Ptr attribute)
Definition: kateviewinternal.cpp:3702
KateTextLayout::viewLine
int viewLine() const
Return the index of this visual line inside the document line (KateLineLayout).
Definition: katetextlayout.cpp:109
QWidget::x
int x() const
KateRenderer::config
KateRendererConfig * config() const
Configuration.
Definition: katerenderer.h:362
QSharedPointer
KateView::setSelection
virtual bool setSelection(const KTextEditor::Range &selection)
Definition: kateview.cpp:1956
QApplication::clipboard
QClipboard * clipboard()
KateViewInternal::cursorUp
void cursorUp(bool sel=false)
Definition: kateviewinternal.cpp:1433
KateRenderer::decreaseFontSizes
void decreaseFontSizes()
Definition: katerenderer.cpp:148
KateLayoutCache::lastViewLine
int lastViewLine(int realLine)
Definition: katelayoutcache.cpp:466
QWheelEvent::orientation
Qt::Orientation orientation() const
QContextMenuEvent
QShowEvent
KateViewConfig::ScrollbarMode
ScrollbarMode
Definition: kateconfig.h:446
QObject
QChildEvent::added
bool added() const
katelayoutcache.h
KateViewInternal::left
Definition: kateviewinternal.h:73
QResizeEvent::oldSize
const QSize & oldSize() const
QMouseEvent::button
Qt::MouseButton button() const
KateCompletionWidget::bottom
void bottom()
Definition: katecompletionwidget.cpp:1138
KateViewInternal::tagAll
void tagAll()
Definition: kateviewinternal.cpp:2111
KateViewInternal::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *)
Definition: kateviewinternal.cpp:2813
QDropEvent
KateDocumentConfig::tabInsertsTab
Definition: kateconfig.h:195
QPainter
KateLayoutCache::line
KateLineLayoutPtr line(int realLine, int virtualLine=-1)
Returns the KateLineLayout for the specified line.
Definition: katelayoutcache.cpp:280
QDrag
KateViewInternal
Definition: kateviewinternal.h:58
KateViewInternal::keyReleaseEvent
virtual void keyReleaseEvent(QKeyEvent *)
Definition: kateviewinternal.cpp:2457
QString::isEmpty
bool isEmpty() const
QCoreApplication::sendEvent
bool sendEvent(QObject *receiver, QEvent *event)
Kate::TextFolding::foldingRange
KTextEditor::Range foldingRange(qint64 id) const
Returns the folding range associated with id.
Definition: katetextfolding.cpp:159
QKeyEvent::text
QString text() const
KateDocument::lines
virtual int lines() const
Definition: katedocument.cpp:753
QTextLine::cursorToX
qreal cursorToX(int *cursorPos, Edge edge) const
Kate::TextCursor::line
int line() const
Retrieve the line on which this cursor is situated.
Definition: katetextcursor.cpp:132
KateCompletionWidget::top
void top()
Definition: katecompletionwidget.cpp:1125
KateCompletionWidget::cursorUp
void cursorUp()
Definition: katecompletionwidget.cpp:1080
QWidget::pos
QPoint pos() const
KateViewConfig::persistentSelection
bool persistentSelection() const
Definition: kateconfig.cpp:1777
QMimeData::setText
void setText(const QString &text)
katecompletionwidget.h
QDropEvent::setDropAction
void setDropAction(Qt::DropAction action)
KateViewInternal::setCaretStyle
void setCaretStyle(KateRenderer::caretStyles style, bool repaint=false)
Set the caret's style.
Definition: kateviewinternal.cpp:1835
kateviewinternal.h
KateView::emitNavigateDown
void emitNavigateDown()
Definition: kateview.h:374
katesearchbar.h
QObject::eventFilter
virtual bool eventFilter(QObject *watched, QEvent *event)
KateTextLayout::kateLineLayout
KateLineLayoutPtr kateLineLayout() const
Definition: katetextlayout.cpp:122
KateViewInternal::end
void end(bool sel=false)
Definition: kateviewinternal.cpp:1232
QRect::contains
bool contains(const QPoint &point, bool proper) const
KateView::blockSelection
virtual bool blockSelection() const
Definition: kateview.cpp:2221
ViMode
ViMode
The four vi modes supported by Kate's vi input mode.
Definition: kateviinputmodemanager.h:48
KateDocument::newLine
void newLine(KateView *view)
Definition: katedocument.cpp:2660
QString
KateViewInternal::editStart
void editStart()
Definition: kateviewinternal.cpp:3379
QWidget::hide
void hide()
QAbstractSlider::minimum
minimum
KateRenderer::Line
Definition: katerenderer.h:70
QColor
KateViewInternal::paintEvent
virtual void paintEvent(QPaintEvent *e)
Definition: kateviewinternal.cpp:2944
KateView::emitNavigateAccept
void emitNavigateAccept()
Definition: kateview.h:377
KateView::updateRangesIn
void updateRangesIn(KTextEditor::Attribute::ActivationType activationType)
check if ranges changed for mouse in and caret in
Definition: kateview.cpp:3169
KateViewInternal::doTabulator
void doTabulator()
Definition: kateviewinternal.cpp:832
KateViewInternal::doDelete
void doDelete()
Definition: kateviewinternal.cpp:822
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
KateLayoutCache
This class handles Kate's caching of layouting information (in KateLineLayout and KateTextLayout)...
Definition: katelayoutcache.h:77
KateView::selection
virtual bool selection() const
Definition: kateview.cpp:2033
QWidget::rect
QRect rect() const
KateLayoutCache::viewLine
KateTextLayout & viewLine(int viewLine)
Returns the layout of the corresponding line in the view.
Definition: katelayoutcache.cpp:358
KateDocument::typeChars
bool typeChars(KateView *type, const QString &realChars)
Type chars in a view.
Definition: katedocument.cpp:2595
KateView
Definition: kateview.h:77
QWidget::setAcceptDrops
void setAcceptDrops(bool on)
isInWord
static bool isInWord(const KTextEditor::View *view, const KTextEditor::Cursor &position, QChar c)
Definition: katekeywordcompletion.cpp:118
QInputEvent::modifiers
Qt::KeyboardModifiers modifiers() const
QRegion::contains
bool contains(const QPoint &p) const
QFontInfo
QTextFormat
KateView::spellingMenu
KateSpellingMenu * spellingMenu()
Definition: kateview.cpp:3102
QChildEvent
QChildEvent::removed
bool removed() const
Kate::TextFolding::lineToVisibleLine
int lineToVisibleLine(int line) const
Convert a text buffer line to a visible line number.
Definition: katetextfolding.cpp:366
KateViewInternal::updateDirty
void updateDirty()
Definition: kateviewinternal.cpp:2900
QTextCharFormat
QKeyEvent::key
int key() const
QEvent::accept
void accept()
QObject::blockSignals
bool blockSignals(bool block)
QPoint::manhattanLength
int manhattanLength() const
KateDocument::attributeAt
virtual KTextEditor::Attribute::Ptr attributeAt(const KTextEditor::Cursor &position)
Definition: katedocument.cpp:5395
KateDocument
Definition: katedocument.h:74
QSize
KateView::selectLine
void selectLine(const KTextEditor::Cursor &cursor)
Definition: kateview.cpp:2174
QWidget::setFixedSize
void setFixedSize(const QSize &s)
KateViewInternal::dropEventPass
void dropEventPass(QDropEvent *)
QLatin1Char
KateLayoutCache::setViewWidth
void setViewWidth(int width)
Definition: katelayoutcache.cpp:524
KateViewInternal::doTranspose
void doTranspose()
Definition: kateviewinternal.cpp:837
KateViewInternal::right
Definition: kateviewinternal.h:75
QAbstractSlider::setValue
void setValue(int)
KateDocument::del
void del(KateView *view, const KTextEditor::Cursor &)
Definition: katedocument.cpp:2806
KateViewInternal::wordPrev
void wordPrev(bool sel=false)
Definition: kateviewinternal.cpp:1105
KateViewInternal::pageDown
void pageDown(bool sel=false, bool half=false)
Definition: kateviewinternal.cpp:1586
QTimer::stop
void stop()
QToolTip::hideText
void hideText()
KateViewInternal::endLine
int endLine() const
Definition: kateviewinternal.cpp:307
KateDocument::kateTextLine
Kate::TextLine kateTextLine(uint i)
Definition: katedocument.cpp:4706
KateRenderer::caretStyles
caretStyles
Style of Caret.
Definition: katerenderer.h:69
QInputMethodEvent::attributes
const QList< Attribute > & attributes() const
KateLayoutCache::setWrap
void setWrap(bool wrap)
Definition: katelayoutcache.cpp:546
KateDocument::editWrapLine
bool editWrapLine(int line, int col, bool newLine=true, bool *newLineAdded=0)
Wrap line.
Definition: katedocument.cpp:1083
QWheelEvent::delta
int delta() const
Kate::TextFolding::isLineVisible
bool isLineVisible(int line, qint64 *foldedRangeId=0) const
Query if a given line is visible.
Definition: katetextfolding.cpp:281
QPainter::setRenderHints
void setRenderHints(QFlags< QPainter::RenderHint > hints, bool on)
QPainter::restore
void restore()
QTime::currentTime
QTime currentTime()
KateViewInternal::KateScrollBar
friend class KateScrollBar
Definition: kateviewinternal.h:64
QClipboard::text
QString text(Mode mode) const
KateViewInternal::wheelEvent
virtual void wheelEvent(QWheelEvent *e)
Definition: kateviewinternal.cpp:3280
KateViewInternal::contextMenuEvent
void contextMenuEvent(QContextMenuEvent *e)
Definition: kateviewinternal.cpp:2488
QKeyEvent
KateCompletionWidget::isCompletionActive
bool isCompletionActive() const
Definition: katecompletionwidget.cpp:748
KateView::removeSelectedText
bool removeSelectedText()
Definition: kateview.cpp:2046
katetextanimation.h
KateViewInternal::dragMoveEvent
virtual void dragMoveEvent(QDragMoveEvent *)
Definition: kateviewinternal.cpp:3185
KateViewBar::hideCurrentBarWidget
void hideCurrentBarWidget()
Hides currently shown bar widget.
Definition: kateviewhelpers.cpp:2568
QContextMenuEvent::pos
const QPoint & pos() const
KateTextLayout
This class represents one visible line of text; with dynamic wrapping, many KateTextLayouts can be ne...
Definition: katetextlayout.h:38
KateViInputModeManager::handleKeypress
bool handleKeypress(const QKeyEvent *e)
feed key the given key press to the command parser
Definition: kateviinputmodemanager.cpp:113
QRect::width
int width() const
QWidget::fontMetrics
QFontMetrics fontMetrics() const
QCursor::pos
QPoint pos()
QDragEnterEvent
KateView::viInputMode
bool viInputMode() const
Definition: kateview.cpp:1530
KateTextLayout::width
int width() const
Definition: katetextlayout.cpp:202
spellingmenu.h
KateViewInternal::prepareForDynWrapChange
void prepareForDynWrapChange()
Definition: kateviewinternal.cpp:247
KateView::updateViModeBarCmd
void updateViModeBarCmd()
Update vi mode statusbar with the (partial) vi command being typed.
Definition: kateview.cpp:1575
QAbstractSlider::setSingleStep
void setSingleStep(int)
KateLayoutCache::relayoutLines
void relayoutLines(int startRealLine, int endRealLine)
Definition: katelayoutcache.cpp:552
KateView::getCurrentViMode
ViMode getCurrentViMode() const
Definition: kateview.cpp:1582
KateTextLayout::virtualLine
int virtualLine() const
Definition: katetextlayout.cpp:101
KateViewInternal::endPos
KTextEditor::Cursor endPos() const
Definition: kateviewinternal.cpp:285
Kate::TextCursor
Class representing a 'clever' text cursor.
Definition: katetextcursor.h:43
KateRenderer::setCaretStyle
void setCaretStyle(KateRenderer::caretStyles style)
Set the style of caret to be painted.
Definition: katerenderer.cpp:100
KateDocument::editEnd
void editEnd()
End a editor operation.
Definition: katedocument.cpp:796
QWidget::parentWidget
QWidget * parentWidget() const
KateSpellingMenu::setUseMouseForMisspelledRange
void setUseMouseForMisspelledRange(bool b)
This method has to be called before the menu is shown in response to a context menu event...
Definition: spellingmenu.cpp:161
KateHighlighting
Definition: katehighlight.h:119
KateCompletionWidget::tab
void tab(bool shift)
Definition: katecompletionwidget.cpp:1327
QWidget::mapFromGlobal
QPoint mapFromGlobal(const QPoint &pos) const
KateViewInternal::disableTextHints
void disableTextHints()
Definition: kateviewinternal.cpp:3370
KateCompletionWidget::hadNavigation
bool hadNavigation() const
Definition: katecompletionwidget.cpp:967
QWidget::QWidget
QWidget(QWidget *parent, QFlags< Qt::WindowType > f)
KateTextLayout::isDirty
bool isDirty() const
Definition: katetextlayout.cpp:34
KateRenderer::paintTextLine
void paintTextLine(QPainter &paint, KateLineLayoutPtr range, int xStart, int xEnd, const KTextEditor::Cursor *cursor=0L)
This is the ultimate function to perform painting of a text line.
Definition: katerenderer.cpp:506
Kate::TextFolding::ensureLineIsVisible
void ensureLineIsVisible(int line)
Ensure that a given line will be visible.
Definition: katetextfolding.cpp:313
KateViewConfig::ShowWhenNeeded
Definition: kateconfig.h:448
QSize::height
int height() const
KateViewConfig::scrollPastEnd
bool scrollPastEnd() const
Definition: kateconfig.cpp:1997
KateCompletionWidget::pageUp
void pageUp()
Definition: katecompletionwidget.cpp:1110
KateViewInternal::startLine
int startLine() const
Definition: kateviewinternal.h:126
QApplication::wheelScrollLines
int wheelScrollLines()
KateViewInternal::home
void home(bool sel=false)
Definition: kateviewinternal.cpp:1197
KateView::selectionText
virtual QString selectionText() const
Definition: kateview.cpp:2041
QString::length
int length() const
KateRenderer::lineHeight
int lineHeight() const
Definition: katerenderer.cpp:825
KateRendererConfig::backgroundColor
const QColor & backgroundColor() const
Definition: kateconfig.cpp:2327
KateDocument::ownedView
bool ownedView(KateView *)
Definition: katedocument.cpp:2560
QPainter::translate
void translate(const QPointF &offset)
KateView::wrapCursor
bool wrapCursor() const
Definition: kateview.cpp:2262
QWidget::setMouseTracking
void setMouseTracking(bool enable)
KateTextLayout::endX
int endX() const
Definition: katetextlayout.cpp:194
KateLayoutCache::displayViewLine
int displayViewLine(const KTextEditor::Cursor &virtualCursor, bool limitToVisible=false)
Definition: katelayoutcache.cpp:405
QDropEvent::dropAction
Qt::DropAction dropAction() const
KateViewInternal::showEvent
virtual void showEvent(QShowEvent *)
Definition: kateviewinternal.cpp:720
QRegion::isEmpty
bool isEmpty() const
QTimer::start
void start(int msec)
KateViewInternal::leaveEvent
virtual void leaveEvent(QEvent *)
Definition: kateviewinternal.cpp:2781
KateDocument::inputMethodStart
void inputMethodStart()
Definition: katedocument.cpp:845
QAbstractSlider::setTracking
void setTracking(bool enable)
KateDocument::insertTab
void insertTab(KateView *view, const KTextEditor::Cursor &)
Definition: katedocument.cpp:2914
KateTextLayout::lineLayout
const QTextLine & lineLayout() const
Definition: katetextlayout.cpp:117
KateViewInternal::~KateViewInternal
~KateViewInternal()
Definition: kateviewinternal.cpp:222
KateView::abortCompletion
virtual void abortCompletion()
Definition: kateview.cpp:2359
QClipboard::setText
void setText(const QString &text, Mode mode)
KateViewInternal::enableTextHints
void enableTextHints(int timeout)
Definition: kateviewinternal.cpp:3359
KateViewInternal::view
KateView * view() const
Definition: kateviewinternal.h:81
KateView::viInputModeStealKeys
bool viInputModeStealKeys() const
Definition: kateview.cpp:1535
KateView::emitNavigateLeft
void emitNavigateLeft()
Definition: kateview.h:365
QWidget::show
void show()
QWidget::scroll
void scroll(int dx, int dy)
KateViewInternal::tagLine
bool tagLine(const KTextEditor::Cursor &virtualCursor)
Definition: kateviewinternal.cpp:2004
KateRendererConfig::fontMetrics
const QFontMetricsF & fontMetrics() const
Definition: kateconfig.cpp:2284
QMouseEvent::pos
const QPoint & pos() const
KateView::isOverwriteMode
bool isOverwriteMode() const
Return values for "save" related commands.
Definition: kateview.cpp:1214
KateView::emitNavigateBack
void emitNavigateBack()
Definition: kateview.h:380
KateViewInternal::WrappingCursor
friend class WrappingCursor
Definition: kateviewinternal.h:67
QWidget::setDisabled
void setDisabled(bool disable)
QPaintEvent
KateViewInternal::cursorDown
void cursorDown(bool sel=false)
Definition: kateviewinternal.cpp:1460
KateViewInternal::eventFilter
virtual bool eventFilter(QObject *obj, QEvent *e)
Definition: kateviewinternal.cpp:2165
KateDocument::editStart
void editStart()
Enclose editor actions with editStart() and editEnd() to group them.
Definition: katedocument.cpp:776
QContextMenuEvent::reason
Reason reason() const
KateViInputModeManager::getCurrentViMode
ViMode getCurrentViMode() const
Definition: kateviinputmodemanager.cpp:451
QCoreApplication::postEvent
void postEvent(QObject *receiver, QEvent *event)
KateView::emitNavigateRight
void emitNavigateRight()
Definition: kateview.h:368
QTimer::isActive
bool isActive() const
QAbstractSlider::maximum
maximum
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KateLayoutCache::viewCacheLineCount
int viewCacheLineCount() const
Definition: katelayoutcache.cpp:364
QObject::parent
QObject * parent() const
KateCompletionWidget::abortCompletion
void abortCompletion()
Definition: katecompletionwidget.cpp:753
katemessagewidget.h
KateView::config
KateViewConfig * config()
Configuration.
Definition: kateview.h:653
KateHighlighting::isInWord
bool isInWord(QChar c, int attrib=0) const
Definition: katehighlight.cpp:1122
KateRenderer::setDrawCaret
void setDrawCaret(bool drawCaret)
Set whether the caret (text cursor) will be drawn.
Definition: katerenderer.cpp:95
KateLayoutCache::updateViewCache
void updateViewCache(const KTextEditor::Cursor &startPos, int newViewLineCount=-1, int viewLinesScrolled=0)
Definition: katelayoutcache.cpp:159
Kate::TextFolding::visibleLines
int visibleLines() const
Query number of visible lines.
Definition: katetextfolding.cpp:340
QAccessible::installFactory
void installFactory(InterfaceFactory factory)
KateIconBorder::updateViRelLineNumbers
void updateViRelLineNumbers()
Definition: kateviewhelpers.cpp:1356
kateconfig.h
QWidget::event
virtual bool event(QEvent *event)
KateTextLayout::invalid
static KateTextLayout invalid()
Definition: katetextlayout.cpp:210
QFocusEvent
KateLineLayoutPtr
KSharedPtr< KateLineLayout > KateLineLayoutPtr
Definition: katelinelayout.h:120
QInputMethodEvent::commitString
const QString & commitString() const
KateViewInternal::cursorCoordinates
QPoint cursorCoordinates(bool includeBorder=true) const
Definition: kateviewinternal.cpp:767
KateViewInternal::scrollUp
void scrollUp()
Definition: kateviewinternal.cpp:1524
KateDocument::removeText
virtual bool removeText(const KTextEditor::Range &range, bool block=false)
Definition: katedocument.cpp:633
KateViewInternal::bottom_end
void bottom_end(bool sel=false)
Definition: kateviewinternal.cpp:1685
QObject::removeEventFilter
void removeEventFilter(QObject *obj)
KateCompletionWidget::execute
void execute()
Definition: katecompletionwidget.cpp:797
QWidget::height
int height() const
KateViewInternal::dynWrapChanged
void dynWrapChanged()
Definition: kateviewinternal.cpp:253
KateDocumentConfig::tabHandling
uint tabHandling() const
Definition: kateconfig.cpp:513
KateTextLayout::wrap
bool wrap() const
Definition: katetextlayout.cpp:173
QRegion
KateViewInternal::coordinatesToCursor
KTextEditor::Cursor coordinatesToCursor(const QPoint &coord, bool includeBorder=true) const
Definition: kateviewinternal.cpp:2791
KateView::paste
void paste(const QString *textToPaste=0)
Definition: kateview.cpp:2399
QColor::isValid
bool isValid() const
QDropEvent::keyboardModifiers
Qt::KeyboardModifiers keyboardModifiers() const
QTimer::singleShot
singleShot
KateViewInternal::findMatchingBracket
KTextEditor::Cursor findMatchingBracket()
Definition: kateviewinternal.cpp:772
QVariant
KateDocumentConfig::tabSmart
indents in leading space, otherwise inserts tab
Definition: kateconfig.h:197
KateViewInternal::inputMethodEvent
virtual void inputMethodEvent(QInputMethodEvent *e)
Definition: kateviewinternal.cpp:3571
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:59 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal