• 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
  • buffer
katetextbuffer.cpp
Go to the documentation of this file.
1 /* This file is part of the Kate project.
2  *
3  * Copyright (C) 2010 Christoph Cullmann <cullmann@kde.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include "config.h"
22 
23 #include "katetextbuffer.h"
24 #include "katetextloader.h"
25 
26 // this is unfortunate, but needed for performance
27 #include "katedocument.h"
28 #include "kateview.h"
29 
30 // fdatasync
31 #include <kde_file.h>
32 
33 #include <KSaveFile>
34 #include <kdeversion.h>
35 
36 #if 0
37 #define EDIT_DEBUG kDebug()
38 #else
39 #define EDIT_DEBUG if (0) kDebug()
40 #endif
41 
42 namespace Kate {
43 
44 TextBuffer::TextBuffer (KateDocument *parent, int blockSize)
45  : QObject (parent)
46  , m_document (parent)
47  , m_history (*this)
48  , m_blockSize (blockSize)
49  , m_lines (0)
50  , m_lastUsedBlock (0)
51  , m_revision (0)
52  , m_editingTransactions (0)
53  , m_editingLastRevision (0)
54  , m_editingLastLines (0)
55  , m_editingMinimalLineChanged (-1)
56  , m_editingMaximalLineChanged (-1)
57  , m_encodingProberType (KEncodingProber::Universal)
58  , m_fallbackTextCodec (0)
59  , m_textCodec (0)
60  , m_generateByteOrderMark (false)
61  , m_endOfLineMode (eolUnix)
62  , m_newLineAtEof (false)
63  , m_lineLengthLimit (4096)
64 {
65  // minimal block size must be > 0
66  Q_ASSERT (m_blockSize > 0);
67 
68  // create initial state
69  clear ();
70 }
71 
72 TextBuffer::~TextBuffer ()
73 {
74  // remove document pointer, this will avoid any notifyAboutRangeChange to have a effect
75  m_document = 0;
76 
77  // not allowed during editing
78  Q_ASSERT (m_editingTransactions == 0);
79 
80  // kill all ranges, work on copy, they will remove themself from the hash
81  QSet<TextRange *> copyRanges = m_ranges;
82  qDeleteAll (copyRanges);
83  Q_ASSERT (m_ranges.empty());
84 
85  // clean out all cursors and lines, only cursors belonging to range will survive
86  foreach(TextBlock* block, m_blocks)
87  block->deleteBlockContent ();
88 
89  // delete all blocks, now that all cursors are really deleted
90  // else asserts in destructor of blocks will fail!
91  qDeleteAll (m_blocks);
92  m_blocks.clear ();
93 
94  // kill all invalid cursors, do this after block deletion, to uncover if they might be still linked in blocks
95  QSet<TextCursor *> copyCursors = m_invalidCursors;
96  qDeleteAll (copyCursors);
97  Q_ASSERT (m_invalidCursors.empty());
98 }
99 
100 void TextBuffer::invalidateRanges()
101 {
102  // invalidate all ranges, work on copy, they might delete themself...
103  QSet<TextRange *> copyRanges = m_ranges;
104  foreach (TextRange *range, copyRanges)
105  range->setRange (KTextEditor::Cursor::invalid(), KTextEditor::Cursor::invalid());
106 }
107 
108 void TextBuffer::clear ()
109 {
110  // not allowed during editing
111  Q_ASSERT (m_editingTransactions == 0);
112 
113  invalidateRanges();
114 
115  // new block for empty buffer
116  TextBlock *newBlock = new TextBlock (this, 0);
117  newBlock->appendLine (QString());
118 
119  // clean out all cursors and lines, either move them to newBlock or invalidate them, if belonging to a range
120  foreach(TextBlock* block, m_blocks)
121  block->clearBlockContent (newBlock);
122 
123  // kill all buffer blocks
124  qDeleteAll (m_blocks);
125  m_blocks.clear ();
126 
127  // insert one block with one empty line
128  m_blocks.append (newBlock);
129 
130  // reset lines and last used block
131  m_lines = 1;
132  m_lastUsedBlock = 0;
133 
134  // reset revision
135  m_revision = 0;
136 
137  // reset bom detection
138  m_generateByteOrderMark = false;
139 
140  // reset the filter device
141  m_mimeTypeForFilterDev = "text/plain";
142 
143  // clear edit history
144  m_history.clear ();
145 
146  // we got cleared
147  emit cleared ();
148 }
149 
150 TextLine TextBuffer::line (int line) const
151 {
152  // get block, this will assert on invalid line
153  int blockIndex = blockForLine (line);
154 
155  // get line
156  return m_blocks.at(blockIndex)->line (line);
157 }
158 
159 QString TextBuffer::text () const
160 {
161  QString text;
162 
163  // combine all blocks
164  foreach(TextBlock* block, m_blocks)
165  block->text (text);
166 
167  // return generated string
168  return text;
169 }
170 
171 bool TextBuffer::startEditing ()
172 {
173  // increment transaction counter
174  ++m_editingTransactions;
175 
176  // if not first running transaction, do nothing
177  if (m_editingTransactions > 1)
178  return false;
179 
180  // reset information about edit...
181  m_editingLastRevision = m_revision;
182  m_editingLastLines = m_lines;
183  m_editingMinimalLineChanged = -1;
184  m_editingMaximalLineChanged = -1;
185 
186  // transaction has started
187  emit editingStarted ();
188 
189  // first transaction started
190  return true;
191 }
192 
193 bool TextBuffer::finishEditing ()
194 {
195  // only allowed if still transactions running
196  Q_ASSERT (m_editingTransactions > 0);
197 
198  // decrement counter
199  --m_editingTransactions;
200 
201  // if not last running transaction, do nothing
202  if (m_editingTransactions > 0)
203  return false;
204 
205  // assert that if buffer changed, the line ranges are set and valid!
206  Q_ASSERT (!editingChangedBuffer() || (m_editingMinimalLineChanged != -1 && m_editingMaximalLineChanged != -1));
207  Q_ASSERT (!editingChangedBuffer() || (m_editingMinimalLineChanged <= m_editingMaximalLineChanged));
208  Q_ASSERT (!editingChangedBuffer() || (m_editingMinimalLineChanged >= 0 && m_editingMinimalLineChanged < m_lines));
209  Q_ASSERT (!editingChangedBuffer() || (m_editingMaximalLineChanged >= 0 && m_editingMaximalLineChanged < m_lines));
210 
211  // transaction has finished
212  emit editingFinished ();
213 
214  // last transaction finished
215  return true;
216 }
217 
218 void TextBuffer::wrapLine (const KTextEditor::Cursor &position)
219 {
220  // debug output for REAL low-level debugging
221  EDIT_DEBUG << "wrapLine" << position;
222 
223  // only allowed if editing transaction running
224  Q_ASSERT (m_editingTransactions > 0);
225 
226  // get block, this will assert on invalid line
227  int blockIndex = blockForLine (position.line());
228 
235  ++m_lines; // first alter the line counter, as functions called will need the valid one
236  m_blocks.at(blockIndex)->wrapLine (position, blockIndex);
237 
238  // remember changes
239  ++m_revision;
240 
241  // update changed line interval
242  if (position.line() < m_editingMinimalLineChanged || m_editingMinimalLineChanged == -1)
243  m_editingMinimalLineChanged = position.line();
244 
245  if (position.line() <= m_editingMaximalLineChanged)
246  ++m_editingMaximalLineChanged;
247  else
248  m_editingMaximalLineChanged = position.line() + 1;
249 
250  // balance the changed block if needed
251  balanceBlock (blockIndex);
252 
253  // emit signal about done change
254  emit lineWrapped (position);
255 }
256 
257 void TextBuffer::unwrapLine (int line)
258 {
259  // debug output for REAL low-level debugging
260  EDIT_DEBUG << "unwrapLine" << line;
261 
262  // only allowed if editing transaction running
263  Q_ASSERT (m_editingTransactions > 0);
264 
265  // line 0 can't be unwrapped
266  Q_ASSERT (line > 0);
267 
268  // get block, this will assert on invalid line
269  int blockIndex = blockForLine (line);
270 
271  // is this the first line in the block?
272  bool firstLineInBlock = (line == m_blocks.at(blockIndex)->startLine());
273 
280  m_blocks.at(blockIndex)->unwrapLine (line, (blockIndex > 0) ? m_blocks.at(blockIndex-1) : 0, firstLineInBlock ? (blockIndex - 1) : blockIndex);
281  --m_lines;
282 
283  // decrement index for later fixup, if we modified the block in front of the found one
284  if (firstLineInBlock)
285  --blockIndex;
286 
287  // remember changes
288  ++m_revision;
289 
290  // update changed line interval
291  if ((line - 1) < m_editingMinimalLineChanged || m_editingMinimalLineChanged == -1)
292  m_editingMinimalLineChanged = line - 1;
293 
294  if (line <= m_editingMaximalLineChanged)
295  --m_editingMaximalLineChanged;
296  else
297  m_editingMaximalLineChanged = line -1;
298 
299  // balance the changed block if needed
300  balanceBlock (blockIndex);
301 
302  // emit signal about done change
303  emit lineUnwrapped (line);
304 }
305 
306 void TextBuffer::insertText (const KTextEditor::Cursor &position, const QString &text)
307 {
308  // debug output for REAL low-level debugging
309  EDIT_DEBUG << "insertText" << position << text;
310 
311  // only allowed if editing transaction running
312  Q_ASSERT (m_editingTransactions > 0);
313 
314  // skip work, if no text to insert
315  if (text.isEmpty())
316  return;
317 
318  // get block, this will assert on invalid line
319  int blockIndex = blockForLine (position.line());
320 
321  // let the block handle the insertText
322  m_blocks.at(blockIndex)->insertText (position, text);
323 
324  // remember changes
325  ++m_revision;
326 
327  // update changed line interval
328  if (position.line () < m_editingMinimalLineChanged || m_editingMinimalLineChanged == -1)
329  m_editingMinimalLineChanged = position.line ();
330 
331  if (position.line () > m_editingMaximalLineChanged)
332  m_editingMaximalLineChanged = position.line ();
333 
334  // emit signal about done change
335  emit textInserted (position, text);
336 }
337 
338 void TextBuffer::removeText (const KTextEditor::Range &range)
339 {
340  // debug output for REAL low-level debugging
341  EDIT_DEBUG << "removeText" << range;
342 
343  // only allowed if editing transaction running
344  Q_ASSERT (m_editingTransactions > 0);
345 
346  // only ranges on one line are supported
347  Q_ASSERT (range.start().line() == range.end().line());
348 
349  // start column <= end column and >= 0
350  Q_ASSERT (range.start().column() <= range.end().column());
351  Q_ASSERT (range.start().column() >= 0);
352 
353  // skip work, if no text to remove
354  if (range.isEmpty())
355  return;
356 
357  // get block, this will assert on invalid line
358  int blockIndex = blockForLine (range.start().line());
359 
360  // let the block handle the removeText, retrieve removed text
361  QString text;
362  m_blocks.at(blockIndex)->removeText (range, text);
363 
364  // remember changes
365  ++m_revision;
366 
367  // update changed line interval
368  if (range.start().line() < m_editingMinimalLineChanged || m_editingMinimalLineChanged == -1)
369  m_editingMinimalLineChanged = range.start().line();
370 
371  if (range.start().line() > m_editingMaximalLineChanged)
372  m_editingMaximalLineChanged = range.start().line();
373 
374  // emit signal about done change
375  emit textRemoved (range, text);
376 }
377 
378 int TextBuffer::blockForLine (int line) const
379 {
380  // only allow valid lines
381  if ((line < 0) || (line >= lines()))
382  qFatal ("out of range line requested in text buffer (%d out of [0, %d[)", line, lines());
383 
384  // we need blocks and last used block should not be negative
385  Q_ASSERT (!m_blocks.isEmpty());
386  Q_ASSERT (m_lastUsedBlock >= 0);
387 
391  if (m_lastUsedBlock < m_blocks.size()) {
396  TextBlock* block = m_blocks[m_lastUsedBlock];
397  const int start = block->startLine();
398  const int lines = block->lines ();
399  if (start <= line && line < (start + lines))
400  return m_lastUsedBlock;
401  }
402 
408  int blockStart = 0;
409  int blockEnd = m_blocks.size() - 1;
410  while (blockEnd >= blockStart) {
411  // get middle and ensure it is OK
412  int middle = blockStart + ((blockEnd - blockStart) / 2);
413  Q_ASSERT (middle >= 0);
414  Q_ASSERT (middle < m_blocks.size());
415 
416  // facts bout this block
417  TextBlock* block = m_blocks[middle];
418  const int start = block->startLine();
419  const int lines = block->lines ();
420 
421  // right block found, remember it and return it
422  if (start <= line && line < (start + lines)) {
423  m_lastUsedBlock = middle;
424  return middle;
425  }
426 
427  // half our stuff ;)
428  if (line < start)
429  blockEnd = middle - 1;
430  else
431  blockStart = middle + 1;
432  }
433 
434  // we should always find a block
435  qFatal ("line requested in text buffer (%d out of [0, %d[), no block found", line, lines());
436  return -1;
437 }
438 
439 void TextBuffer::fixStartLines (int startBlock)
440 {
441  // only allow valid start block
442  Q_ASSERT (startBlock >= 0);
443  Q_ASSERT (startBlock < m_blocks.size());
444 
445  // new start line for next block
446  TextBlock* block = m_blocks.at(startBlock);
447  int newStartLine = block->startLine () + block->lines ();
448 
449  // fixup block
450  for (int index = startBlock + 1; index < m_blocks.size(); ++index) {
451  // set new start line
452  block = m_blocks.at(index);
453  block->setStartLine (newStartLine);
454 
455  // calculate next start line
456  newStartLine += block->lines ();
457  }
458 }
459 
460 void TextBuffer::balanceBlock (int index)
461 {
465  TextBlock *blockToBalance = m_blocks.at(index);
466 
467  // first case, too big one, split it
468  if (blockToBalance->lines () >= 2 * m_blockSize) {
469  // half the block
470  int halfSize = blockToBalance->lines () / 2;
471 
472  // create and insert new block behind current one, already set right start line
473  TextBlock *newBlock = blockToBalance->splitBlock (halfSize);
474  Q_ASSERT (newBlock);
475  m_blocks.insert (m_blocks.begin() + index + 1, newBlock);
476 
477  // split is done
478  return;
479  }
480 
481  // second case: possibly too small block
482 
483  // if only one block, no chance to unite
484  // same if this is first block, we always append to previous one
485  if (index == 0)
486  return;
487 
488  // block still large enough, do nothing
489  if (2 * blockToBalance->lines () > m_blockSize)
490  return;
491 
492  // unite small block with predecessor
493  TextBlock *targetBlock = m_blocks.at(index-1);
494 
495  // merge block
496  blockToBalance->mergeBlock (targetBlock);
497 
498  // delete old block
499  delete blockToBalance;
500  m_blocks.erase (m_blocks.begin() + index);
501 }
502 
503 void TextBuffer::debugPrint (const QString &title) const
504 {
505  // print header with title
506  printf ("%s (lines: %d bs: %d)\n", qPrintable (title), m_lines, m_blockSize);
507 
508  // print all blocks
509  for (int i = 0; i < m_blocks.size(); ++i)
510  m_blocks.at(i)->debugPrint (i);
511 }
512 
513 bool TextBuffer::load (const QString &filename, bool &encodingErrors, bool &tooLongLinesWrapped, bool enforceTextCodec)
514 {
515  // fallback codec must exist
516  Q_ASSERT (m_fallbackTextCodec);
517 
518  // codec must be set!
519  Q_ASSERT (m_textCodec);
520 
524  clear ();
525 
529  Kate::TextLoader file (filename, m_encodingProberType);
530 
538  for (int i = 0; i < (enforceTextCodec ? 1 : 4); ++i) {
542  for (int b = 1; b < m_blocks.size(); ++b) {
543  TextBlock* block = m_blocks.at(b);
544  block->clearLines ();
545  delete block;
546  }
547  m_blocks.resize (1);
548 
552  m_blocks.last()->clearLines ();
553  m_lines = 0;
554 
561  QTextCodec *codec = m_textCodec;
562  if (i == 1)
563  codec = 0;
564  else if (i == 2)
565  codec = m_fallbackTextCodec;
566 
567  if (!file.open (codec)) {
568  // create one dummy textline, in any case
569  m_blocks.last()->appendLine (QString());
570  m_lines++;
571  return false;
572  }
573 
574  // read in all lines...
575  encodingErrors = false;
576  while ( !file.eof() )
577  {
578  // read line
579  int offset = 0, length = 0;
580  bool currentError = !file.readLine (offset, length);
581  encodingErrors = encodingErrors || currentError;
582 
583  // bail out on encoding error, if not last round!
584  if (encodingErrors && i < (enforceTextCodec ? 0 : 3)) {
585  kDebug (13020) << "Failed try to load file" << filename << "with codec" <<
586  (file.textCodec() ? file.textCodec()->name() : "(null)");
587  break;
588  }
589 
590  // get unicode data for this line
591  const QChar *unicodeData = file.unicode () + offset;
592 
596  do {
600  int lineLength = length;
601  if ((m_lineLengthLimit > 0) && (lineLength > m_lineLengthLimit)) {
605  int spacePosition = m_lineLengthLimit-1;
606  for (int testPosition = m_lineLengthLimit-1; (testPosition >= 0) && (testPosition >= (m_lineLengthLimit - (m_lineLengthLimit/10))); --testPosition) {
610  if (unicodeData[testPosition].isSpace() || unicodeData[testPosition].isPunct()) {
611  spacePosition = testPosition;
612  break;
613  }
614  }
615 
619  lineLength = spacePosition+1;
620  length -= lineLength;
621  tooLongLinesWrapped = true;
622  } else {
626  length = 0;
627  }
628 
633  QString textLine (unicodeData, lineLength);
634  unicodeData += lineLength;
635 
639  if (m_blocks.last()->lines() >= m_blockSize)
640  m_blocks.append (new TextBlock (this, m_blocks.last()->startLine() + m_blocks.last()->lines()));
641 
645  m_blocks.last()->appendLine (textLine);
646  ++m_lines;
647  } while (length > 0);
648  }
649 
650  // if no encoding error, break out of reading loop
651  if (!encodingErrors) {
652  // remember used codec, might change bom setting
653  setTextCodec (file.textCodec ());
654  break;
655  }
656  }
657 
658  // save md5sum of file on disk
659  setDigest (file.digest ());
660 
661  // remember if BOM was found
662  if (file.byteOrderMarkFound ())
663  setGenerateByteOrderMark (true);
664 
665  // remember eol mode, if any found in file
666  if (file.eol() != eolUnknown)
667  setEndOfLineMode (file.eol());
668 
669  // remember mime type for filter device
670  m_mimeTypeForFilterDev = file.mimeTypeForFilterDev ();
671 
672  // assert that one line is there!
673  Q_ASSERT (m_lines > 0);
674 
675  // report CODEC + ERRORS
676  kDebug (13020) << "Loaded file " << filename << "with codec" << m_textCodec->name()
677  << (encodingErrors ? "with" : "without") << "encoding errors";
678 
679  // report BOM
680  kDebug (13020) << (file.byteOrderMarkFound () ? "Found" : "Didn't find") << "byte order mark";
681 
682  // report filter device mime-type
683  kDebug (13020) << "used filter device for mime-type" << m_mimeTypeForFilterDev;
684 
685  // emit success
686  emit loaded (filename, encodingErrors);
687 
688  // file loading worked, modulo encoding problems
689  return true;
690 }
691 
692 const QByteArray &TextBuffer::digest () const
693 {
694  return m_digest;
695 }
696 
697 void TextBuffer::setDigest (const QByteArray & md5sum)
698 {
699  m_digest = md5sum;
700 }
701 
702 void TextBuffer::setTextCodec (QTextCodec *codec)
703 {
704  m_textCodec = codec;
705 
706  // enforce bom for some encodings
707  int mib = m_textCodec->mibEnum ();
708  if (mib == 1013 || mib == 1014 || mib == 1015) // utf16
709  setGenerateByteOrderMark (true);
710  if (mib == 1017 || mib == 1018 || mib == 1019) // utf32
711  setGenerateByteOrderMark (true);
712 }
713 
714 bool TextBuffer::save (const QString &filename)
715 {
716  // codec must be set!
717  Q_ASSERT (m_textCodec);
718 
722  KSaveFile saveFile (filename);
723 
724 #if KDE_IS_VERSION(4,10,3)
725 
729  saveFile.setDirectWriteFallback (true);
730 #endif
731 
735  if (!saveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
736  return false;
737  }
738 
742  QIODevice *file = KFilterDev::device (&saveFile, m_mimeTypeForFilterDev, false);
743  const bool deleteFile = file;
744  if (!file)
745  file = &saveFile;
746 
750  if (deleteFile) {
751  if (!file->open (QIODevice::WriteOnly)) {
752  delete file;
753  return false;
754  }
755  }
756 
760  QTextStream stream (file);
761  stream.setCodec (QTextCodec::codecForName("UTF-16"));
762 
763  // set the correct codec
764  stream.setCodec (m_textCodec);
765 
766  // generate byte order mark?
767  stream.setGenerateByteOrderMark (generateByteOrderMark());
768 
769  // our loved eol string ;)
770  QString eol = "\n"; //m_doc->config()->eolString ();
771  if (endOfLineMode() == eolDos)
772  eol = QString ("\r\n");
773  else if (endOfLineMode() == eolMac)
774  eol = QString ("\r");
775 
776  // just dump the lines out ;)
777  for (int i = 0; i < m_lines; ++i)
778  {
779  // get line to save
780  Kate::TextLine textline = line (i);
781 
782  stream << textline->text();
783 
784  // append correct end of line string
785  if ((i+1) < m_lines)
786  stream << eol;
787  }
788 
789  if (m_newLineAtEof) {
790  Q_ASSERT(m_lines > 0); // see .h file
791  const Kate::TextLine lastLine = line (m_lines - 1);
792  const int firstChar = lastLine->firstChar();
793  if (firstChar > -1 || lastLine->length() > 0) {
794  stream << eol;
795  }
796  }
797 
798  // flush stream
799  stream.flush ();
800 
801  // close and delete file
802  if (deleteFile) {
803  file->close ();
804  delete file;
805  }
806 
807  // flush file
808  if (!saveFile.flush())
809  return false;
810 
811 #ifndef Q_OS_WIN
812  // ensure that the file is written to disk
813 #ifdef HAVE_FDATASYNC
814  fdatasync (saveFile.handle());
815 #else
816  fsync (saveFile.handle());
817 #endif
818 #endif
819 
820  // did save work?
821  // only finalize if stream status == OK
822  bool ok = (stream.status() == QTextStream::Ok) && saveFile.finalize();
823 
824  // remember this revision as last saved if we had success!
825  if (ok)
826  m_history.setLastSavedRevision ();
827 
828  // report CODEC + ERRORS
829  kDebug (13020) << "Saved file " << filename << "with codec" << m_textCodec->name()
830  << (ok ? "without" : "with") << "errors";
831 
832  if (ok)
833  markModifiedLinesAsSaved();
834 
835  // emit signal on success
836  if (ok)
837  emit saved (filename);
838 
839  // return success or not
840  return ok;
841 }
842 
843 void TextBuffer::notifyAboutRangeChange (KTextEditor::View *view, int startLine, int endLine, bool rangeWithAttribute)
844 {
848  if (!m_document)
849  return;
850 
855  const QList<KTextEditor::View *> &views = m_document->views ();
856  foreach(KTextEditor::View* curView, views) {
857  // filter wrong views
858  if (view && view != curView)
859  continue;
860 
861  // notify view, it is really a kate view
862  static_cast<KateView *> (curView)->notifyAboutRangeChange (startLine, endLine, rangeWithAttribute);
863  }
864 }
865 
866 void TextBuffer::markModifiedLinesAsSaved()
867 {
868  foreach(TextBlock* block, m_blocks)
869  block->markModifiedLinesAsSaved ();
870 }
871 
872 QList<TextRange *> TextBuffer::rangesForLine (int line, KTextEditor::View *view, bool rangesWithAttributeOnly) const
873 {
874  // get block, this will assert on invalid line
875  const int blockIndex = blockForLine (line);
876 
877  // get the ranges of the right block
878  QList<TextRange *> rightRanges;
879  foreach (const QSet<TextRange *> &ranges, m_blocks.at(blockIndex)->rangesForLine (line)) {
880  foreach (TextRange * const range, ranges) {
884  if (rangesWithAttributeOnly && !range->hasAttribute())
885  continue;
886 
890  if (!view && range->attributeOnlyForViews())
891  continue;
892 
896  if (range->view() && range->view() != view)
897  continue;
898 
902  if (range->startInternal().lineInternal() <= line && line <= range->endInternal().lineInternal())
903  rightRanges.append (range);
904  }
905  }
906 
907  // return right ranges
908  return rightRanges;
909 }
910 
911 }
Kate::TextBuffer::line
TextLine line(int line) const
Retrieve a text line.
Definition: katetextbuffer.cpp:150
QIODevice
QTextStream::setCodec
void setCodec(QTextCodec *codec)
Kate::TextBuffer::setGenerateByteOrderMark
void setGenerateByteOrderMark(bool generateByteOrderMark)
Generate byte order mark on save.
Definition: katetextbuffer.h:130
Kate::TextBuffer::editingChangedBuffer
bool editingChangedBuffer() const
Query information from the last editing transaction: was the content of the buffer changed...
Definition: katetextbuffer.h:250
Kate::TextBuffer::eolMac
Definition: katetextbuffer.h:63
Kate::TextBuffer::endOfLineMode
EndOfLineMode endOfLineMode() const
Get end of line mode.
Definition: katetextbuffer.h:149
kateview.h
Kate::TextRange::startInternal
const TextCursor & startInternal() const
Non-virtual version of start(), which is faster.
Definition: katetextrange.h:125
QTextStream::setGenerateByteOrderMark
void setGenerateByteOrderMark(bool generate)
Kate::TextLoader::eol
TextBuffer::EndOfLineMode eol() const
Detected end of line mode for this file.
Definition: katetextloader.h:125
QTextCodec::name
virtual QByteArray name() const =0
katetextbuffer.h
QByteArray
Kate::TextBuffer::eolDos
Definition: katetextbuffer.h:62
EDIT_DEBUG
#define EDIT_DEBUG
Definition: katetextbuffer.cpp:39
QChar
Kate::TextLoader::eof
bool eof() const
end of file reached?
Definition: katetextloader.h:118
Kate::TextBuffer::debugPrint
void debugPrint(const QString &title) const
Debug output, print whole buffer content with line numbers and line length.
Definition: katetextbuffer.cpp:503
Kate::TextBlock::lines
int lines() const
Number of lines in this block.
Definition: katetextblock.h:90
Kate::TextBuffer::lineUnwrapped
void lineUnwrapped(int line)
A line got unwrapped.
Kate::TextBuffer::digest
const QByteArray & digest() const
md5 digest of the document on disk, set either through file loading in openFile() or in KateDocument:...
Definition: katetextbuffer.cpp:692
Kate::TextLoader::textCodec
QTextCodec * textCodec() const
Get codec for this loader.
Definition: katetextloader.h:149
Kate::TextBuffer::finishEditing
virtual bool finishEditing()
Finish an editing transaction.
Definition: katetextbuffer.cpp:193
katedocument.h
QTextStream::status
Status status() const
Kate::TextBuffer::lineWrapped
void lineWrapped(const KTextEditor::Cursor &position)
A line got wrapped.
Kate::TextBuffer::editingStarted
void editingStarted()
Editing transaction has started.
Kate::TextBuffer::saved
void saved(const QString &filename)
Buffer saved successfully a file.
QIODevice::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
Kate::TextCursor::lineInternal
int lineInternal() const
Non-virtual version of line(), which is faster.
Definition: katetextcursor.h:127
QIODevice::close
virtual void close()
Kate::TextBlock::startLine
int startLine() const
Start line of this block.
Definition: katetextblock.h:60
Kate::TextBuffer::wrapLine
virtual void wrapLine(const KTextEditor::Cursor &position)
Wrap line at given cursor position.
Definition: katetextbuffer.cpp:218
Kate::TextBuffer::textInserted
void textInserted(const KTextEditor::Cursor &position, const QString &text)
Text got inserted.
Kate::TextBuffer::load
virtual bool load(const QString &filename, bool &encodingErrors, bool &tooLongLinesWrapped, bool enforceTextCodec)
Load the given file.
Definition: katetextbuffer.cpp:513
Kate::TextBlock::deleteBlockContent
void deleteBlockContent()
Delete the block content, delete all lines and delete all cursors not bound to ranges.
Definition: katetextblock.cpp:544
Kate::TextRange::endInternal
const TextCursor & endInternal() const
Nonvirtual version of end(), which is faster.
Definition: katetextrange.h:137
QTextStream
Kate::TextBuffer::startEditing
virtual bool startEditing()
Start an editing transaction, the wrapLine/unwrapLine/insertText and removeText functions are only to...
Definition: katetextbuffer.cpp:171
Kate::TextBuffer::TextBlock
friend class TextBlock
Definition: katetextbuffer.h:51
Kate::TextBuffer::insertText
virtual void insertText(const KTextEditor::Cursor &position, const QString &text)
Insert text at given cursor position.
Definition: katetextbuffer.cpp:306
Kate::TextBuffer::editingFinished
void editingFinished()
Editing transaction has finished.
Kate::TextBuffer::~TextBuffer
virtual ~TextBuffer()
Destruct the text buffer Virtual, we allow inheritance.
Definition: katetextbuffer.cpp:72
Kate::TextLoader::byteOrderMarkFound
bool byteOrderMarkFound() const
BOM found?
Definition: katetextloader.h:131
Kate::TextBlock::clearBlockContent
void clearBlockContent(TextBlock *targetBlock)
Clear the block content, delete all lines, move all cursors not bound to range to given block at 0...
Definition: katetextblock.cpp:556
QList::append
void append(const T &value)
Kate::TextBuffer::cleared
void cleared()
Buffer got cleared.
QSharedPointer
QObject
Kate::TextBuffer::setTextCodec
void setTextCodec(QTextCodec *codec)
Set codec for this buffer to use for load/save.
Definition: katetextbuffer.cpp:702
Kate::TextBuffer::setDigest
void setDigest(const QByteArray &md5sum)
Set the md5sum of this buffer.
Definition: katetextbuffer.cpp:697
Kate::TextLoader::open
bool open(QTextCodec *codec)
open file with given codec
Definition: katetextloader.h:92
Kate::TextBuffer::invalidateRanges
void invalidateRanges()
Invalidate all ranges in this buffer.
Definition: katetextbuffer.cpp:100
QSet
QString
QList< KTextEditor::View * >
QTextCodec
katetextloader.h
QChar::isPunct
bool isPunct() const
KateView
Definition: kateview.h:77
Kate::TextBlock::appendLine
void appendLine(const QString &textOfLine)
Append a new line with given text.
Definition: katetextblock.cpp:67
Kate::TextBuffer::textRemoved
void textRemoved(const KTextEditor::Range &range, const QString &text)
Text got removed.
KateDocument
Definition: katedocument.h:74
Kate::TextBuffer::removeText
virtual void removeText(const KTextEditor::Range &range)
Remove text at given range.
Definition: katetextbuffer.cpp:338
QTextCodec::mibEnum
virtual int mibEnum() const =0
Kate::TextLoader::digest
QByteArray digest()
Definition: katetextloader.h:357
Kate::TextRange::hasAttribute
bool hasAttribute() const
Definition: katetextrange.h:179
Kate::TextBuffer::save
virtual bool save(const QString &filename)
Save the current buffer content to the given file.
Definition: katetextbuffer.cpp:714
Kate::TextBuffer::unwrapLine
virtual void unwrapLine(int line)
Unwrap given line.
Definition: katetextbuffer.cpp:257
Kate::TextBlock::clearLines
void clearLines()
Clear the lines.
Definition: katetextblock.cpp:72
Kate::TextBuffer::rangesForLine
QList< TextRange * > rangesForLine(int line, KTextEditor::View *view, bool rangesWithAttributeOnly) const
Return the ranges which affect the given line.
Definition: katetextbuffer.cpp:872
Kate::TextBuffer::lines
int lines() const
Lines currently stored in this buffer.
Definition: katetextbuffer.h:189
Kate::TextBuffer::setEndOfLineMode
void setEndOfLineMode(EndOfLineMode endOfLineMode)
Set end of line mode for this buffer, not allowed to be set to unknown.
Definition: katetextbuffer.h:143
Kate::TextBuffer::eolUnknown
Definition: katetextbuffer.h:60
QTextStream::flush
void flush()
Kate::TextBuffer::TextBuffer
TextBuffer(KateDocument *parent, int blockSize=64)
Construct an empty text buffer.
Definition: katetextbuffer.cpp:44
Kate::TextLoader::readLine
bool readLine(int &offset, int &length)
read a line, return length + offset in unicode data
Definition: katetextloader.h:157
Kate::TextRange::attributeOnlyForViews
bool attributeOnlyForViews() const
Is this range's attribute only visible in views, not for example prints? Default is false...
Definition: katetextrange.h:211
Kate::TextLoader::mimeTypeForFilterDev
const QString & mimeTypeForFilterDev() const
mime type used to create filter dev
Definition: katetextloader.h:137
QTextCodec::codecForName
QTextCodec * codecForName(const QByteArray &name)
Kate::TextRange::setRange
void setRange(const KTextEditor::Range &range)
Set the range of this range.
Definition: katetextrange.cpp:122
Kate::TextBuffer::generateByteOrderMark
bool generateByteOrderMark() const
Generate byte order mark on save?
Definition: katetextbuffer.h:136
KateDocument::views
virtual const QList< KTextEditor::View * > & views() const
Definition: katedocument.cpp:309
Kate::TextBuffer::text
QString text() const
Retrieve text of complete buffer.
Definition: katetextbuffer.cpp:159
Kate::TextLoader
File Loader, will handle reading of files + detecting encoding.
Definition: katetextloader.h:44
Kate::TextLoader::unicode
const QChar * unicode() const
internal unicode data array
Definition: katetextloader.h:143
Kate::TextBlock::text
void text(QString &text) const
Retrieve text of block.
Definition: katetextblock.cpp:77
Kate::TextRange::view
KTextEditor::View * view() const
Gets the active view for this range.
Definition: katetextrange.h:156
Kate::TextRange
Class representing a 'clever' text range.
Definition: katetextrange.h:46
Kate::TextBuffer::loaded
void loaded(const QString &filename, bool encodingErrors)
Buffer loaded successfully a file.
Kate::TextBuffer::clear
virtual void clear()
Clears the buffer, reverts to initial empty state.
Definition: katetextbuffer.cpp:108
Kate::TextBlock
Class representing a text block.
Definition: katetextblock.h:42
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:58 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