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

Kate

  • sources
  • kde-4.12
  • applications
  • kate
  • part
  • swapfile
kateswapfile.cpp
Go to the documentation of this file.
1 /* This file is part of the Kate project.
2  *
3  * Copyright (C) 2010 Dominik Haumann <dhaumann kde org>
4  * Copyright (C) 2010 Diana-Victoria Tiriplica <diana.tiriplica@gmail.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "config.h"
23 
24 #include "kateswapfile.h"
25 #include "kateconfig.h"
26 #include "kateswapdiffcreator.h"
27 #include "kateundomanager.h"
28 
29 #include <ktexteditor/view.h>
30 
31 #include <kde_file.h>
32 #include <klocale.h>
33 #include <kicon.h>
34 #include <kstandardguiitem.h>
35 
36 #include <QFileInfo>
37 #include <QDir>
38 #include <QApplication>
39 
40 
41 // swap file version header
42 const static char * const swapFileVersionString = "Kate Swap File 2.0";
43 
44 // tokens for swap files
45 const static qint8 EA_StartEditing = 'S';
46 const static qint8 EA_FinishEditing = 'E';
47 const static qint8 EA_WrapLine = 'W';
48 const static qint8 EA_UnwrapLine = 'U';
49 const static qint8 EA_InsertText = 'I';
50 const static qint8 EA_RemoveText = 'R';
51 
52 namespace Kate {
53 
54 QTimer* SwapFile::s_timer = 0;
55 
56 SwapFile::SwapFile(KateDocument *document)
57  : QObject(document)
58  , m_document(document)
59  , m_trackingEnabled(false)
60  , m_recovered(false)
61  , m_needSync(false)
62 {
63  // fixed version of serialisation
64  m_stream.setVersion (QDataStream::Qt_4_6);
65 
66  // conect the timer
67  connect(syncTimer(), SIGNAL(timeout()), this, SLOT(writeFileToDisk()), Qt::DirectConnection);
68 
69  // connecting the signals
70  connect(&m_document->buffer(), SIGNAL(saved(QString)), this, SLOT(fileSaved(QString)));
71  connect(&m_document->buffer(), SIGNAL(loaded(QString,bool)), this, SLOT(fileLoaded(QString)));
72  connect(m_document, SIGNAL(configChanged()), this, SLOT(configChanged()));
73 
74  // tracking on!
75  setTrackingEnabled (true);
76 }
77 
78 SwapFile::~SwapFile()
79 {
80  // only remove swap file after data recovery (bug #304576)
81  if (!shouldRecover()) {
82  removeSwapFile();
83  }
84 }
85 
86 void SwapFile::configChanged()
87 {
88 }
89 
90 void SwapFile::setTrackingEnabled(bool enable)
91 {
92  if (m_trackingEnabled == enable) {
93  return;
94  }
95 
96  m_trackingEnabled = enable;
97 
98  TextBuffer &buffer = m_document->buffer();
99 
100  if (m_trackingEnabled) {
101  connect(&buffer, SIGNAL(editingStarted()), this, SLOT(startEditing()));
102  connect(&buffer, SIGNAL(editingFinished()), this, SLOT(finishEditing()));
103  connect(m_document, SIGNAL(modifiedChanged(KTextEditor::Document*)), this, SLOT(modifiedChanged()));
104 
105  connect(&buffer, SIGNAL(lineWrapped(KTextEditor::Cursor)), this, SLOT(wrapLine(KTextEditor::Cursor)));
106  connect(&buffer, SIGNAL(lineUnwrapped(int)), this, SLOT(unwrapLine(int)));
107  connect(&buffer, SIGNAL(textInserted(KTextEditor::Cursor,QString)), this, SLOT(insertText(KTextEditor::Cursor,QString)));
108  connect(&buffer, SIGNAL(textRemoved(KTextEditor::Range,QString)), this, SLOT(removeText(KTextEditor::Range)));
109  } else {
110  disconnect(&buffer, SIGNAL(editingStarted()), this, SLOT(startEditing()));
111  disconnect(&buffer, SIGNAL(editingFinished()), this, SLOT(finishEditing()));
112  disconnect(m_document, SIGNAL(modifiedChanged(KTextEditor::Document*)), this, SLOT(modifiedChanged()));
113 
114  disconnect(&buffer, SIGNAL(lineWrapped(KTextEditor::Cursor)), this, SLOT(wrapLine(KTextEditor::Cursor)));
115  disconnect(&buffer, SIGNAL(lineUnwrapped(int)), this, SLOT(unwrapLine(int)));
116  disconnect(&buffer, SIGNAL(textInserted(KTextEditor::Cursor,QString)), this, SLOT(insertText(KTextEditor::Cursor,QString)));
117  disconnect(&buffer, SIGNAL(textRemoved(KTextEditor::Range,QString)), this, SLOT(removeText(KTextEditor::Range)));
118  }
119 }
120 
121 void SwapFile::fileClosed ()
122 {
123  // remove old swap file, file is now closed
124  if (!shouldRecover()) {
125  removeSwapFile();
126  } else {
127  m_document->setReadWrite(true);
128  }
129 
130  // purge filename
131  updateFileName();
132 }
133 
134 KateDocument* SwapFile::document()
135 {
136  return m_document;
137 }
138 
139 bool SwapFile::isValidSwapFile(QDataStream& stream, bool checkDigest) const
140 {
141  // read and check header
142  QByteArray header;
143  stream >> header;
144 
145  if (header != swapFileVersionString) {
146  kWarning( 13020 ) << "Can't open swap file, wrong version";
147  return false;
148  }
149 
150  // read md5 digest
151  QByteArray digest;
152  stream >> digest;
153 // kDebug() << "DIGEST:" << digest << m_document->digest();
154  if (checkDigest && digest != m_document->digest()) {
155  kWarning( 13020 ) << "Can't recover from swap file, digest of document has changed";
156  return false;
157  }
158 
159  return true;
160 }
161 
162 void SwapFile::fileLoaded(const QString&)
163 {
164  // look for swap file
165  if (!updateFileName())
166  return;
167 
168  if (!m_swapfile.exists())
169  {
170  kDebug (13020) << "No swap file";
171  return;
172  }
173 
174  if (!QFileInfo(m_swapfile).isReadable())
175  {
176  kWarning( 13020 ) << "Can't open swap file (missing permissions)";
177  return;
178  }
179 
180  // sanity check
181  QFile peekFile(fileName());
182  if (peekFile.open(QIODevice::ReadOnly)) {
183  QDataStream stream(&peekFile);
184  if (!isValidSwapFile(stream, true)) {
185  removeSwapFile();
186  return;
187  }
188  peekFile.close();
189  } else {
190  kWarning( 13020 ) << "Can't open swap file:" << fileName();
191  return;
192  }
193 
194  // show swap file message
195  m_document->setReadWrite(false);
196  showSwapFileMessage();
197 }
198 
199 void SwapFile::modifiedChanged()
200 {
201  if (!m_document->isModified() && !shouldRecover()) {
202  m_needSync = false;
203  // the file is not modified and we are not in recover mode
204  removeSwapFile();
205  }
206 }
207 
208 void SwapFile::recover()
209 {
210  m_document->setReadWrite(true);
211 
212  // if isOpen() returns true, the swap file likely changed already (appended data)
213  // Example: The document was falsely marked as writable and the user changed
214  // text even though the recover bar was visible. In this case, a replay of
215  // the swap file across wrong document content would happen -> certainly wrong
216  if (m_swapfile.isOpen()) {
217  kWarning( 13020 ) << "Attempt to recover an already modified document. Aborting";
218  removeSwapFile();
219  return;
220  }
221 
222  // if the file doesn't exist, abort (user might have deleted it, or use two editor instances)
223  if (!m_swapfile.open(QIODevice::ReadOnly))
224  {
225  kWarning( 13020 ) << "Can't open swap file";
226  return;
227  }
228 
229  // remember that the file has recovered
230  m_recovered = true;
231 
232  // open data stream
233  m_stream.setDevice(&m_swapfile);
234 
235  // replay the swap file
236  bool success = recover(m_stream);
237 
238  // close swap file
239  m_stream.setDevice(0);
240  m_swapfile.close();
241 
242  if (!success)
243  removeSwapFile();
244 
245  // recover can also be called through the KTE::RecoveryInterface.
246  // Make sure, the message is hidden in this case as well.
247  if (m_swapMessage)
248  m_swapMessage->deleteLater();
249 }
250 
251 bool SwapFile::recover(QDataStream& stream, bool checkDigest)
252 {
253  if (!isValidSwapFile(stream, checkDigest)) {
254  return false;
255  }
256 
257  // disconnect current signals
258  setTrackingEnabled(false);
259 
260  // needed to set undo/redo cursors in a sane way
261  bool firstEditInGroup = false;
262  KTextEditor::Cursor undoCursor = KTextEditor::Cursor::invalid();
263  KTextEditor::Cursor redoCursor = KTextEditor::Cursor::invalid();
264 
265  // replay swapfile
266  bool editRunning = false;
267  bool brokenSwapFile = false;
268  while (!stream.atEnd()) {
269  if (brokenSwapFile)
270  break;
271 
272  qint8 type;
273  stream >> type;
274  switch (type) {
275  case EA_StartEditing: {
276  m_document->editStart();
277  editRunning = true;
278  firstEditInGroup = true;
279  undoCursor = KTextEditor::Cursor::invalid();
280  redoCursor = KTextEditor::Cursor::invalid();
281  break;
282  }
283  case EA_FinishEditing: {
284  m_document->editEnd();
285 
286  // empty editStart() / editEnd() groups exist: only set cursor if required
287  if (!firstEditInGroup) {
288  // set undo/redo cursor of last KateUndoGroup of the undo manager
289  m_document->undoManager()->setUndoRedoCursorsOfLastGroup(undoCursor, redoCursor);
290  m_document->undoManager()->undoSafePoint();
291  }
292  firstEditInGroup = false;
293  editRunning = false;
294  break;
295  }
296  case EA_WrapLine: {
297  if (!editRunning) {
298  brokenSwapFile = true;
299  break;
300  }
301 
302  int line = 0, column = 0;
303  stream >> line >> column;
304 
305  // emulate buffer unwrapLine with document
306  m_document->editWrapLine(line, column, true);
307 
308  // track undo/redo cursor
309  if (firstEditInGroup) {
310  firstEditInGroup = false;
311  undoCursor = KTextEditor::Cursor(line, column);
312  }
313  redoCursor = KTextEditor::Cursor(line + 1, 0);
314  kDebug() << "UNDO" << undoCursor << ", REDO:" << redoCursor;
315 
316  break;
317  }
318  case EA_UnwrapLine: {
319  if (!editRunning) {
320  brokenSwapFile = true;
321  break;
322  }
323 
324  int line = 0;
325  stream >> line;
326 
327  // assert valid line
328  Q_ASSERT (line > 0);
329 
330  const int undoColumn = m_document->lineLength(line - 1);
331 
332  // emulate buffer unwrapLine with document
333  m_document->editUnWrapLine(line - 1, true, 0);
334 
335  // track undo/redo cursor
336  if (firstEditInGroup) {
337  firstEditInGroup = false;
338  undoCursor = KTextEditor::Cursor(line, 0);
339  }
340  redoCursor = KTextEditor::Cursor(line - 1, undoColumn);
341 
342  break;
343  }
344  case EA_InsertText: {
345  if (!editRunning) {
346  brokenSwapFile = true;
347  break;
348  }
349 
350  int line, column;
351  QByteArray text;
352  stream >> line >> column >> text;
353  m_document->insertText(KTextEditor::Cursor(line, column), QString::fromUtf8 (text.data (), text.size()));
354 
355  // track undo/redo cursor
356  if (firstEditInGroup) {
357  firstEditInGroup = false;
358  undoCursor = KTextEditor::Cursor(line, column);
359  }
360  redoCursor = KTextEditor::Cursor(line, column + text.size());
361 
362  break;
363  }
364  case EA_RemoveText: {
365  if (!editRunning) {
366  brokenSwapFile = true;
367  break;
368  }
369 
370  int line, startColumn, endColumn;
371  stream >> line >> startColumn >> endColumn;
372  m_document->removeText (KTextEditor::Range(KTextEditor::Cursor(line, startColumn), KTextEditor::Cursor(line, endColumn)));
373 
374  // track undo/redo cursor
375  if (firstEditInGroup) {
376  firstEditInGroup = false;
377  undoCursor = KTextEditor::Cursor(line, endColumn);
378  }
379  redoCursor = KTextEditor::Cursor(line, startColumn);
380 
381  break;
382  }
383  default: {
384  kWarning( 13020 ) << "Unknown type:" << type;
385  }
386  }
387  }
388 
389  // balanced editStart and editEnd?
390  if (editRunning) {
391  brokenSwapFile = true;
392  m_document->editEnd();
393  }
394 
395  // warn the user if the swap file is not complete
396  if (brokenSwapFile) {
397  kWarning ( 13020 ) << "Some data might be lost";
398  } else {
399  // set sane final cursor, if possible
400  KTextEditor::View * view = m_document->activeView();
401  redoCursor = m_document->undoManager()->lastRedoCursor();
402  if (view && redoCursor.isValid()) {
403  view->setCursorPosition(redoCursor);
404  }
405  }
406 
407  // reconnect the signals
408  setTrackingEnabled(true);
409 
410  return true;
411 }
412 
413 void SwapFile::fileSaved(const QString&)
414 {
415  m_needSync = false;
416 
417  // remove old swap file (e.g. if a file A was "saved as" B)
418  removeSwapFile();
419 
420  // set the name for the new swap file
421  updateFileName();
422 }
423 
424 void SwapFile::startEditing ()
425 {
426  // no swap file, no work
427  if (m_swapfile.fileName().isEmpty())
428  return;
429 
430  // if swap file doesn't exists, open it in WriteOnly mode
431  // if it does, append the data to the existing swap file,
432  // in case you recover and start editing again
433  if (!m_swapfile.exists()) {
434  // TODO set file as read-only
435  m_swapfile.open(QIODevice::WriteOnly);
436  m_stream.setDevice(&m_swapfile);
437 
438  // write file header
439  m_stream << QByteArray (swapFileVersionString);
440 
441  // write md5 digest
442  m_stream << m_document->digest ();
443  } else if (m_stream.device() == 0) {
444  m_swapfile.open(QIODevice::Append);
445  m_stream.setDevice(&m_swapfile);
446  }
447 
448  // format: qint8
449  m_stream << EA_StartEditing;
450 }
451 
452 void SwapFile::finishEditing ()
453 {
454  // skip if not open
455  if (!m_swapfile.isOpen ())
456  return;
457 
458  // write the file to the disk every 15 seconds
459  // skip this if we disabled forced syncing
460  if (!m_document->config()->swapFileNoSync() && !syncTimer()->isActive())
461  syncTimer()->start(15000);
462 
463  // format: qint8
464  m_stream << EA_FinishEditing;
465  m_swapfile.flush();
466 }
467 
468 void SwapFile::wrapLine (const KTextEditor::Cursor &position)
469 {
470  // skip if not open
471  if (!m_swapfile.isOpen ())
472  return;
473 
474  // format: qint8, int, int
475  m_stream << EA_WrapLine << position.line() << position.column();
476 
477  m_needSync = true;
478 }
479 
480 void SwapFile::unwrapLine (int line)
481 {
482  // skip if not open
483  if (!m_swapfile.isOpen ())
484  return;
485 
486  // format: qint8, int
487  m_stream << EA_UnwrapLine << line;
488 
489  m_needSync = true;
490 }
491 
492 void SwapFile::insertText (const KTextEditor::Cursor &position, const QString &text)
493 {
494  // skip if not open
495  if (!m_swapfile.isOpen ())
496  return;
497 
498  // format: qint8, int, int, bytearray
499  m_stream << EA_InsertText << position.line() << position.column() << text.toUtf8 ();
500 
501  m_needSync = true;
502 }
503 
504 void SwapFile::removeText (const KTextEditor::Range &range)
505 {
506  // skip if not open
507  if (!m_swapfile.isOpen ())
508  return;
509 
510  // format: qint8, int, int, int
511  Q_ASSERT (range.start().line() == range.end().line());
512  m_stream << EA_RemoveText
513  << range.start().line() << range.start().column()
514  << range.end().column();
515 
516  m_needSync = true;
517 }
518 
519 bool SwapFile::shouldRecover() const
520 {
521  // should not recover if the file has already recovered in another view
522  if (m_recovered)
523  return false;
524 
525  return !m_swapfile.fileName().isEmpty() && m_swapfile.exists() && m_stream.device() == 0;
526 }
527 
528 void SwapFile::discard()
529 {
530  m_document->setReadWrite(true);
531  removeSwapFile();
532 
533  // discard can also be called through the KTE::RecoveryInterface.
534  // Make sure, the message is hidden in this case as well.
535  if (m_swapMessage)
536  m_swapMessage->deleteLater();
537 }
538 
539 void SwapFile::removeSwapFile()
540 {
541  if (!m_swapfile.fileName().isEmpty() && m_swapfile.exists()) {
542  m_stream.setDevice(0);
543  m_swapfile.close();
544  m_swapfile.remove();
545  }
546 }
547 
548 bool SwapFile::updateFileName()
549 {
550  // first clear filename
551  m_swapfile.setFileName ("");
552 
553  // get the new path
554  QString path = fileName();
555  if (path.isNull())
556  return false;
557 
558  m_swapfile.setFileName(path);
559  return true;
560 }
561 
562 QString SwapFile::fileName()
563 {
564  const KUrl &url = m_document->url();
565  if (url.isEmpty() || !url.isLocalFile())
566  return QString();
567 
568  QString path = url.toLocalFile();
569  int poz = path.lastIndexOf(QDir::separator());
570  path.insert(poz+1, ".");
571  path.append(".kate-swp");
572 
573  return path;
574 }
575 
576 QTimer* SwapFile::syncTimer()
577 {
578  if (s_timer == 0) {
579  s_timer = new QTimer(QApplication::instance());
580  s_timer->setSingleShot(true);
581  }
582 
583  return s_timer;
584 }
585 
586 void SwapFile::writeFileToDisk()
587 {
588  if (m_needSync) {
589  m_needSync = false;
590 
591  #ifndef Q_OS_WIN
592  // ensure that the file is written to disk
593  #ifdef HAVE_FDATASYNC
594  fdatasync (m_swapfile.handle());
595  #else
596  fsync (m_swapfile.handle());
597  #endif
598  #endif
599  }
600 }
601 
602 void SwapFile::showSwapFileMessage()
603 {
604  m_swapMessage = new KTextEditor::Message(i18n("The file was not closed properly."),
605  KTextEditor::Message::Warning);
606  m_swapMessage->setWordWrap(true);
607 
608  QAction* diffAction = new QAction(KIcon("split"), i18n("View Changes"), 0);
609  QAction* recoverAction = new QAction(KIcon("edit-redo"), i18n("Recover Data"), 0);
610  QAction* discardAction = new QAction(KStandardGuiItem::discard().icon(), i18n("Discard"), 0);
611 
612  m_swapMessage->addAction(diffAction, false);
613  m_swapMessage->addAction(recoverAction);
614  m_swapMessage->addAction(discardAction);
615 
616  connect(diffAction, SIGNAL(triggered()), SLOT(showDiff()));
617  connect(recoverAction, SIGNAL(triggered()), SLOT(recover()), Qt::QueuedConnection);
618  connect(discardAction, SIGNAL(triggered()), SLOT(discard()), Qt::QueuedConnection);
619 
620  m_document->postMessage(m_swapMessage);
621 }
622 
623 void SwapFile::showDiff()
624 {
625  // the diff creator deletes itself thorugh deleteLater() when it's done
626  SwapDiffCreator* diffCreator = new SwapDiffCreator(this);
627  diffCreator->viewDiff();
628 }
629 
630 }
631 
632 // kate: space-indent on; indent-width 2; replace-tabs on;
KateDocument::buffer
KateBuffer & buffer()
Get access to buffer of this document.
Definition: katedocument.h:946
KTextEditor::Range::start
Cursor & start()
KateDocument::config
KateDocumentConfig * config()
Configuration.
Definition: katedocument.h:1009
EA_InsertText
static const qint8 EA_InsertText
Definition: kateswapfile.cpp:49
KTextEditor::Cursor::invalid
static Cursor invalid()
Kate::Script::i18n
QScriptValue i18n(QScriptContext *context, QScriptEngine *engine)
i18n("text", arguments [optional])
Definition: katescripthelpers.cpp:186
header
const char header[]
KTextEditor::View::setCursorPosition
virtual bool setCursorPosition(Cursor position)=0
KStandardGuiItem::discard
KGuiItem discard()
KateDocument::setReadWrite
virtual void setReadWrite(bool rw=true)
Definition: katedocument.cpp:2468
kateswapfile.h
KateDocument::activeView
virtual KTextEditor::View * activeView() const
Definition: katedocument.h:156
timeout
int timeout
KateDocument::lineLength
virtual int lineLength(int line) const
Definition: katedocument.cpp:758
Kate::SwapFile::recover
void recover()
Definition: kateswapfile.cpp:208
kateswapdiffcreator.h
Kate::SwapFile::wrapLine
void wrapLine(const KTextEditor::Cursor &position)
Definition: kateswapfile.cpp:468
kstandardguiitem.h
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
KateDocument::undoManager
KateUndoManager * undoManager()
Definition: katedocument.h:338
QString
QObject
Kate::SwapFile::SwapFile
SwapFile(KateDocument *document)
Definition: kateswapfile.cpp:56
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KTextEditor::Cursor
Kate::SwapFile::startEditing
void startEditing()
Definition: kateswapfile.cpp:424
klocale.h
Kate::SwapFile::showDiff
void showDiff()
Definition: kateswapfile.cpp:623
EA_FinishEditing
static const qint8 EA_FinishEditing
Definition: kateswapfile.cpp:46
KParts::ReadOnlyPart::url
KUrl url
KUrl
Kate::SwapFile::discard
void discard()
Definition: kateswapfile.cpp:528
KateDocument::insertText
virtual bool insertText(const KTextEditor::Cursor &position, const QString &s, bool block=false)
Definition: katedocument.cpp:530
Kate::SwapFile::removeText
void removeText(const KTextEditor::Range &range)
Definition: kateswapfile.cpp:504
KTextEditor::Cursor::isValid
virtual bool isValid() const
view.h
KTextEditor::Document
EA_WrapLine
static const qint8 EA_WrapLine
Definition: kateswapfile.cpp:47
Kate::SwapFile::writeFileToDisk
void writeFileToDisk()
Definition: kateswapfile.cpp:586
KIcon
Kate::SwapFile::fileLoaded
void fileLoaded(const QString &filename)
Definition: kateswapfile.cpp:162
Kate::SwapFile::~SwapFile
~SwapFile()
Definition: kateswapfile.cpp:78
KateUndoManager::setUndoRedoCursorsOfLastGroup
void setUndoRedoCursorsOfLastGroup(const KTextEditor::Cursor undoCursor, const KTextEditor::Cursor redoCursor)
Used by the swap file recovery, this function afterwards manipulates the undo/redo cursors of the las...
Definition: kateundomanager.cpp:403
Kate::SwapFile::finishEditing
void finishEditing()
Definition: kateswapfile.cpp:452
Kate::SwapFile::fileName
QString fileName()
Definition: kateswapfile.cpp:562
Kate::SwapFile::modifiedChanged
void modifiedChanged()
Definition: kateswapfile.cpp:199
KateDocument::digest
const QByteArray & digest() const
md5 digest of this document
Definition: katedocument.cpp:4410
KTextEditor::Range
KateDocument
Definition: katedocument.h:74
EA_StartEditing
static const qint8 EA_StartEditing
Definition: kateswapfile.cpp:45
KateUndoManager::undoSafePoint
void undoSafePoint()
Prevent latest KateUndoGroup from being merged with the next one.
Definition: kateundomanager.cpp:190
EA_RemoveText
static const qint8 EA_RemoveText
Definition: kateswapfile.cpp:50
SwapDiffCreator
Definition: kateswapdiffcreator.h:34
KateDocument::editWrapLine
bool editWrapLine(int line, int col, bool newLine=true, bool *newLineAdded=0)
Wrap line.
Definition: katedocument.cpp:1083
Append
Definition: kateviinsertmode.h:41
KTextEditor::Cursor::line
virtual int line() const
Kate::SwapFile::configChanged
void configChanged()
Definition: kateswapfile.cpp:86
KateDocumentConfig::swapFileNoSync
bool swapFileNoSync() const
Definition: kateconfig.cpp:1001
Kate::SwapFile::insertText
void insertText(const KTextEditor::Cursor &position, const QString &text)
Definition: kateswapfile.cpp:492
SwapDiffCreator::viewDiff
void viewDiff()
Definition: kateswapdiffcreator.cpp:42
Kate::SwapFile::fileSaved
void fileSaved(const QString &filename)
Definition: kateswapfile.cpp:413
KateUndoManager::lastRedoCursor
KTextEditor::Cursor lastRedoCursor() const
Returns the redo cursor of the last undo group.
Definition: kateundomanager.cpp:414
KateDocument::editEnd
void editEnd()
End a editor operation.
Definition: katedocument.cpp:796
KTextEditor::Range::end
Cursor & end()
swapFileVersionString
static const char *const swapFileVersionString
Definition: kateswapfile.cpp:42
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Kate::SwapFile::unwrapLine
void unwrapLine(int line)
Definition: kateswapfile.cpp:480
kateundomanager.h
KateDocument::editUnWrapLine
bool editUnWrapLine(int line, bool removeLine=true, int length=0)
Unwrap line.
Definition: katedocument.cpp:1153
KateDocument::postMessage
virtual bool postMessage(KTextEditor::Message *message)
Definition: katedocument.cpp:5498
Kate::SwapFile::shouldRecover
bool shouldRecover() const
Definition: kateswapfile.cpp:519
Kate::SwapFile::showSwapFileMessage
void showSwapFileMessage()
Definition: kateswapfile.cpp:602
KateDocument::editStart
void editStart()
Enclose editor actions with editStart() and editEnd() to group them.
Definition: katedocument.cpp:776
KTextEditor::View
kicon.h
KUrl::isLocalFile
bool isLocalFile() const
kateconfig.h
KTextEditor::Cursor::column
int column() const
KTextEditor::Message
KTextEditor::Message::Warning
EA_UnwrapLine
static const qint8 EA_UnwrapLine
Definition: kateswapfile.cpp:48
KateDocument::removeText
virtual bool removeText(const KTextEditor::Range &range, bool block=false)
Definition: katedocument.cpp:633
QAction
Kate::SwapFile::document
KateDocument * document()
Definition: kateswapfile.cpp:134
KParts::ReadWritePart::isModified
bool isModified() const
Kate::SwapFile::fileClosed
void fileClosed()
Definition: kateswapfile.cpp:121
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:31:52 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
  • Applications
  •   Libraries
  •     libkonq
  • 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