[prev in list] [next in list] [prev in thread] [next in thread]
List: kwrite-devel
Subject: [kate] part: implement line modification system
From: Dominik Haumann <dhdev () gmx ! de>
Date: 2011-09-03 20:32:49
Message-ID: 20110903203249.8CB16A607A () git ! kde ! org
[Download RAW message or body]
Git commit c5946bf2c15bf166be3f83c93c0ac49396582c94 by Dominik Haumann.
Committed on 03/09/2011 at 22:20.
Pushed by dhaumann into branch 'master'.
implement line modification system
TODO:
- unit test
- improve visual appearance
- enable / disable in config page
- optionally show modified lines in scroll bar
- fine tuning
PS: Qt Creator's line modification system is totally buggy :^)
Example: http://wstaw.org/m/2011/09/03/plasma-desktopgz5185.jpg
CCBUG: 200753
CCMAIL: kwrite-devel@kde.org
M +3 -2 part/undo/kateundomanager.h
M +14 -1 part/view/kateviewhelpers.cpp
M +326 -14 part/undo/kateundo.cpp
M +31 -8 part/undo/kateundomanager.cpp
M +34 -1 part/buffer/katetextline.h
M +5 -0 part/buffer/katetextbuffer.h
M +53 -36 part/undo/kateundo.h
M +3 -6 part/document/katedocument.cpp
M +43 -4 part/buffer/katetextblock.cpp
M +9 -0 part/buffer/katetextbuffer.cpp
M +5 -0 part/buffer/katetextblock.h
http://commits.kde.org/kate/c5946bf2c15bf166be3f83c93c0ac49396582c94
diff --git a/part/buffer/katetextblock.cpp b/part/buffer/katetextblock.cpp
index f52f8f3..a3df0dc 100644
--- a/part/buffer/katetextblock.cpp
+++ b/part/buffer/katetextblock.cpp
@@ -89,6 +89,16 @@ void TextBlock::wrapLine (const KTextEditor::Cursor &position)
// create new line and insert it
m_lines.insert (m_lines.begin() + line + 1, TextLine (new TextLineData()));
+ // cases for modification:
+ // 1. line is wrapped in the middle
+ // 2. if empty line is wrapped, mark new line as modified
+ // 3. line-to-be-wrapped is already modified
+ if (position.column() > 0 || text.size() == 0 || \
m_lines.at(line)->markedAsModified()) { + m_lines.at(line + \
1)->markAsModified(true); + } else if (m_lines.at(line)->markedAsSavedOnDisk()) {
+ m_lines.at(line + 1)->markAsSavedOnDisk(true);
+ }
+
// perhaps remove some text from previous line and append it
if (position.column() < text.size ()) {
// text from old line moved first to new one
@@ -96,8 +106,12 @@ void TextBlock::wrapLine (const KTextEditor::Cursor &position)
// now remove wrapped text from old line
text.chop (text.size() - position.column());
+
+ // mark line as modified
+ m_lines.at(line)->markAsModified(true);
}
+
/**
* notify the text history
*/
@@ -173,8 +187,13 @@ void TextBlock::unwrapLine (int line, TextBlock *previousBlock)
previousBlock->m_lines.erase (previousBlock->m_lines.begin() + \
(previousBlock->lines () - 1));
// append text
- int oldSizeOfPreviousLine = newFirst->text().size();
- newFirst->textReadWrite().append (oldFirst->text());
+ const int oldSizeOfPreviousLine = newFirst->text().size();
+ if (oldFirst->length() > 0) {
+ newFirst->textReadWrite().append (oldFirst->text());
+
+ // mark line as modified, since text was appended
+ newFirst->markAsModified(true);
+ }
// patch startLine of this block
--m_startLine;
@@ -244,8 +263,16 @@ void TextBlock::unwrapLine (int line, TextBlock *previousBlock)
}
// easy: just move text to previous line and remove current one
- int oldSizeOfPreviousLine = m_lines.at(line-1)->text().size();
- m_lines.at(line-1)->textReadWrite().append (m_lines.at(line)->text());
+ const int oldSizeOfPreviousLine = m_lines.at(line-1)->length();
+ const int sizeOfCurrentLine = m_lines.at(line)->length();
+ if (sizeOfCurrentLine > 0) {
+ m_lines.at(line-1)->textReadWrite().append (m_lines.at(line)->text());
+ }
+
+ const bool lineChanged = (oldSizeOfPreviousLine > 0 && m_lines.at(line - \
1)->markedAsModified()) + || (sizeOfCurrentLine > 0 && (oldSizeOfPreviousLine > 0 \
|| m_lines.at(line)->markedAsModified())); + \
m_lines.at(line-1)->markAsModified(lineChanged); +
m_lines.erase (m_lines.begin () + line);
/**
@@ -296,6 +323,7 @@ void TextBlock::insertText (const KTextEditor::Cursor &position, \
const QString & // get text
QString &textOfLine = m_lines.at(line)->textReadWrite ();
int oldLength = textOfLine.size ();
+ m_lines.at(line)->markAsModified(true);
// check if valid column
Q_ASSERT (position.column() >= 0);
@@ -369,6 +397,7 @@ void TextBlock::removeText (const KTextEditor::Range &range, \
QString &removedTex
// remove text
textOfLine.remove (range.start().column(), range.end().column() - \
range.start().column()); + m_lines.at(line)->markAsModified(true);
/**
* notify the text history
@@ -515,6 +544,16 @@ void TextBlock::clearBlockContent (TextBlock *targetBlock)
m_lines.clear ();
}
+void TextBlock::markModifiedLinesAsSaved ()
+{
+ // mark all modified lines as saved
+ for (int i = 0; i < m_lines.size(); ++i) {
+ TextLine textLine = m_lines[i];
+ if (textLine->markedAsModified())
+ textLine->markAsSavedOnDisk(true);
+ }
+}
+
void TextBlock::updateRange (TextRange* range)
{
/**
diff --git a/part/buffer/katetextblock.h b/part/buffer/katetextblock.h
index 2b9d050..7b8a48a 100644
--- a/part/buffer/katetextblock.h
+++ b/part/buffer/katetextblock.h
@@ -173,6 +173,11 @@ class KATEPART_TESTS_EXPORT TextBlock {
return m_cachedLineForRanges.contains(range) || \
m_uncachedRanges.contains(range); }
+ /**
+ * Flag all modified text lines as saved on disk.
+ */
+ void markModifiedLinesAsSaved ();
+
private:
/**
* Update a range from this block.
diff --git a/part/buffer/katetextbuffer.cpp b/part/buffer/katetextbuffer.cpp
index 9ea7768..dd1b044 100644
--- a/part/buffer/katetextbuffer.cpp
+++ b/part/buffer/katetextbuffer.cpp
@@ -753,6 +753,9 @@ bool TextBuffer::save (const QString &filename)
kDebug (13020) << "Saved file " << filename << "with codec" << m_textCodec->name()
<< (ok ? "without" : "with") << "errors";
+ if (ok)
+ markModifiedLinesAsSaved();
+
// emit signal on success
if (ok)
emit saved (filename);
@@ -784,6 +787,12 @@ void TextBuffer::notifyAboutRangeChange (KTextEditor::View \
*view, int startLine, }
}
+void TextBuffer::markModifiedLinesAsSaved()
+{
+ foreach(TextBlock* block, m_blocks)
+ block->markModifiedLinesAsSaved ();
+}
+
QList<TextRange *> TextBuffer::rangesForLine (int line, KTextEditor::View *view, \
bool rangesWithAttributeOnly) const {
// get block, this will assert on invalid line
diff --git a/part/buffer/katetextbuffer.h b/part/buffer/katetextbuffer.h
index 2c0ef50..dd716b4 100644
--- a/part/buffer/katetextbuffer.h
+++ b/part/buffer/katetextbuffer.h
@@ -399,6 +399,11 @@ class KATEPART_TESTS_EXPORT TextBuffer : public QObject {
*/
void notifyAboutRangeChange (KTextEditor::View *view, int startLine, int \
endLine, bool rangeWithAttribute);
+ /**
+ * Mark all modified lines as lines saved on disk (modified line system).
+ */
+ void markModifiedLinesAsSaved();
+
public:
/**
* Gets the document to which this buffer is bound.
diff --git a/part/buffer/katetextline.h b/part/buffer/katetextline.h
index a1d5d9f..cd1b540 100644
--- a/part/buffer/katetextline.h
+++ b/part/buffer/katetextline.h
@@ -51,7 +51,9 @@ class KATEPART_TESTS_EXPORT TextLineData {
flagAutoWrapped = 2,
flagFoldingColumnsOutdated = 4,
flagNoIndentationBasedFolding = 8,
- flagNoIndentationBasedFoldingAtStart = 16
+ flagNoIndentationBasedFoldingAtStart = 16,
+ flagLineModified = 32,
+ flagLineSavedOnDisk = 64
};
/**
@@ -131,6 +133,37 @@ class KATEPART_TESTS_EXPORT TextLineData {
return QChar();
}
+ inline void markAsModified(bool modified)
+ {
+ if (modified) {
+ m_flags |= flagLineModified;
+ m_flags &= (~flagLineSavedOnDisk);
+ } else {
+ m_flags &= (~flagLineModified);
+ }
+ }
+
+ inline bool markedAsModified() const
+ {
+ return m_flags & flagLineModified;
+ }
+
+ inline void markAsSavedOnDisk(bool savedOnDisk)
+ {
+ if (savedOnDisk) {
+ m_flags |= flagLineSavedOnDisk;
+ m_flags &= (~flagLineModified);
+ } else {
+ m_flags &= (~flagLineSavedOnDisk);
+ }
+ }
+
+ inline bool markedAsSavedOnDisk() const
+ {
+ return m_flags & flagLineSavedOnDisk;
+ }
+
+
/**
* Set the flag that only positions have changed, not folding region begins/ends \
themselve
* @param set folding columns our of date?
diff --git a/part/document/katedocument.cpp b/part/document/katedocument.cpp
index 76a5ff2..2af3e19 100644
--- a/part/document/katedocument.cpp
+++ b/part/document/katedocument.cpp
@@ -1135,12 +1135,8 @@ bool KateDocument::editWrapLine ( int line, int col, bool \
newLine, bool *newLine
Kate::TextLine nextLine = kateTextLine(line+1);
- int pos = l->length() - col;
-
- if (pos < 0)
- pos = 0;
-
- m_undoManager->slotLineWrapped(line, col, pos, (!nextLine || newLine));
+ const int length = l->length();
+ m_undoManager->slotLineWrapped(line, col, length, (!nextLine || newLine));
if (!nextLine || newLine)
{
@@ -2315,6 +2311,7 @@ bool KateDocument::saveFile()
// (dominik) mark last undo group as not mergeable, otherwise the next
// edit action might be merged and undo will never stop at the saved state
m_undoManager->undoSafePoint();
+ m_undoManager->updateLineModifications();
//
// return success
diff --git a/part/undo/kateundo.cpp b/part/undo/kateundo.cpp
index 2cfa2b1..4ed1aa6 100644
--- a/part/undo/kateundo.cpp
+++ b/part/undo/kateundo.cpp
@@ -29,6 +29,7 @@
KateUndo::KateUndo (KateDocument *document)
: m_document (document)
+, m_lineModFlags(0x00)
{
}
@@ -36,6 +37,130 @@ KateUndo::~KateUndo ()
{
}
+void KateUndo::setFlag(ModificationFlag flag)
+{
+ m_lineModFlags |= flag;
+}
+
+void KateUndo::unsetFlag(ModificationFlag flag)
+{
+ m_lineModFlags &= (~flag);
+}
+
+bool KateUndo::isFlagSet(ModificationFlag flag) const
+{
+ return m_lineModFlags & flag;
+}
+
+KateEditInsertTextUndo::KateEditInsertTextUndo (KateDocument *document, int line, \
int col, const QString &text) + : KateUndo (document)
+ , m_line (line)
+ , m_col (col)
+ , m_text (text)
+{
+ setFlag(RedoLine1Modified);
+ Kate::TextLine tl = document->plainKateTextLine(line);
+ if (tl->markedAsModified()) {
+ setFlag(UndoLine1Modified);
+ }
+ if (tl->markedAsSavedOnDisk()) {
+ setFlag(UndoLine1Saved);
+ }
+}
+
+KateEditRemoveTextUndo::KateEditRemoveTextUndo (KateDocument *document, int line, \
int col, const QString &text) + : KateUndo (document)
+ , m_line (line)
+ , m_col (col)
+ , m_text (text)
+{
+ setFlag(RedoLine1Modified);
+ Kate::TextLine tl = document->plainKateTextLine(line);
+ if (tl->markedAsModified()) {
+ setFlag(UndoLine1Modified);
+ }
+ if (tl->markedAsSavedOnDisk()) {
+ setFlag(UndoLine1Saved);
+ }
+}
+
+KateEditWrapLineUndo::KateEditWrapLineUndo (KateDocument *document, int line, int \
col, int len, bool newLine) + : KateUndo (document)
+ , m_line (line)
+ , m_col (col)
+ , m_len (len)
+ , m_newLine (newLine)
+{
+ Kate::TextLine tl = document->plainKateTextLine(line);
+ if (col < len || tl->markedAsModified()) {
+ setFlag(RedoLine1Modified);
+ } else if (tl->markedAsSavedOnDisk()) {
+ setFlag(RedoLine1Saved);
+ }
+
+ if (col > 0 || len == 0 || tl->markedAsModified()) {
+ setFlag(RedoLine2Modified);
+ } else if (tl->markedAsSavedOnDisk()) {
+ setFlag(RedoLine2Saved);
+ }
+
+ if (tl->markedAsModified()) {
+ setFlag(UndoLine1Modified);
+ }
+ if (tl->markedAsSavedOnDisk()) {
+ setFlag(UndoLine1Saved);
+ }
+}
+
+KateEditUnWrapLineUndo::KateEditUnWrapLineUndo (KateDocument *document, int line, \
int col, int len, bool removeLine) + : KateUndo (document)
+ , m_line (line)
+ , m_col (col)
+ , m_len (len)
+ , m_removeLine (removeLine)
+{
+ setFlag(RedoLine1Modified);
+
+ Kate::TextLine tl = document->plainKateTextLine(line);
+ if (tl->markedAsModified()) {
+ setFlag(UndoLine1Modified);
+ }
+ if (tl->markedAsSavedOnDisk()) {
+ setFlag(UndoLine1Saved);
+ }
+
+ Kate::TextLine nextLine = document->plainKateTextLine(line + 1);
+ if (nextLine->markedAsModified()) {
+ setFlag(UndoLine2Modified);
+ }
+ if (nextLine->markedAsSavedOnDisk()) {
+ setFlag(UndoLine2Saved);
+ }
+}
+
+KateEditInsertLineUndo::KateEditInsertLineUndo (KateDocument *document, int line, \
const QString &text) + : KateUndo (document)
+ , m_line (line)
+ , m_text (text)
+{
+ setFlag(RedoLine1Modified);
+}
+
+KateEditRemoveLineUndo::KateEditRemoveLineUndo (KateDocument *document, int line, \
const QString &text) + : KateUndo (document)
+ , m_line (line)
+ , m_text (text)
+{
+ Kate::TextLine tl = document->plainKateTextLine(line);
+ if (tl->markedAsModified()) {
+ setFlag(UndoLine1Modified);
+ }
+ if (tl->markedAsSavedOnDisk()) {
+ setFlag(UndoLine1Saved);
+ }
+}
+
+
bool KateUndo::isEmpty() const
{
return false;
@@ -90,98 +215,244 @@ void KateEditInsertTextUndo::undo ()
{
KateDocument *doc = document();
- doc->editRemoveText (m_line, m_col, len());
+ doc->editRemoveText (m_line, m_col, len());
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(UndoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(UndoLine1Saved));
}
void KateEditRemoveTextUndo::undo ()
{
KateDocument *doc = document();
- doc->editInsertText (m_line, m_col, m_text);
+ doc->editInsertText (m_line, m_col, m_text);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(UndoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(UndoLine1Saved));
}
void KateEditWrapLineUndo::undo ()
{
KateDocument *doc = document();
- doc->editUnWrapLine (m_line, m_newLine, m_len);
+ doc->editUnWrapLine (m_line, m_newLine, m_len);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(UndoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(UndoLine1Saved));
}
void KateEditUnWrapLineUndo::undo ()
{
KateDocument *doc = document();
- doc->editWrapLine (m_line, m_col, m_removeLine);
+ doc->editWrapLine (m_line, m_col, m_removeLine);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(UndoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(UndoLine1Saved));
+
+ Kate::TextLine nextLine = doc->plainKateTextLine(m_line + 1);
+ nextLine->markAsModified(isFlagSet(UndoLine2Modified));
+ nextLine->markAsSavedOnDisk(isFlagSet(UndoLine2Saved));
}
void KateEditInsertLineUndo::undo ()
{
KateDocument *doc = document();
- doc->editRemoveLine (m_line);
+ doc->editRemoveLine (m_line);
+
+ // no line modification needed, since the line is removed
}
void KateEditRemoveLineUndo::undo ()
{
KateDocument *doc = document();
- doc->editInsertLine (m_line, m_text);
+ doc->editInsertLine (m_line, m_text);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(UndoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(UndoLine1Saved));
}
void KateEditMarkLineAutoWrappedUndo::undo ()
{
KateDocument *doc = document();
- doc->editMarkLineAutoWrapped (m_line, m_autowrapped);
+ doc->editMarkLineAutoWrapped (m_line, m_autowrapped);
}
void KateEditRemoveTextUndo::redo ()
{
KateDocument *doc = document();
- doc->editRemoveText (m_line, m_col, len());
+ doc->editRemoveText (m_line, m_col, len());
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(RedoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(RedoLine1Saved));
}
void KateEditInsertTextUndo::redo ()
{
KateDocument *doc = document();
- doc->editInsertText (m_line, m_col, m_text);
+ doc->editInsertText (m_line, m_col, m_text);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(RedoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(RedoLine1Saved));
}
void KateEditUnWrapLineUndo::redo ()
{
KateDocument *doc = document();
- doc->editUnWrapLine (m_line, m_removeLine, m_len);
+ doc->editUnWrapLine (m_line, m_removeLine, m_len);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(RedoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(RedoLine1Saved));
}
void KateEditWrapLineUndo::redo ()
{
KateDocument *doc = document();
- doc->editWrapLine (m_line, m_col, m_newLine);
+ doc->editWrapLine (m_line, m_col, m_newLine);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(RedoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(RedoLine1Saved));
+
+ Kate::TextLine nextLine = doc->plainKateTextLine(m_line + 1);
+ nextLine->markAsModified(isFlagSet(RedoLine2Modified));
+ nextLine->markAsSavedOnDisk(isFlagSet(RedoLine2Saved));
}
void KateEditRemoveLineUndo::redo ()
{
KateDocument *doc = document();
- doc->editRemoveLine (m_line);
+ doc->editRemoveLine (m_line);
+
+ // no line modification needed, since the line is removed
}
void KateEditInsertLineUndo::redo ()
{
KateDocument *doc = document();
- doc->editInsertLine (m_line, m_text);
+ doc->editInsertLine (m_line, m_text);
+
+ Kate::TextLine tl = doc->plainKateTextLine(m_line);
+ tl->markAsModified(isFlagSet(RedoLine1Modified));
+ tl->markAsSavedOnDisk(isFlagSet(RedoLine1Saved));
}
void KateEditMarkLineAutoWrappedUndo::redo ()
{
KateDocument *doc = document();
- doc->editMarkLineAutoWrapped (m_line, m_autowrapped);
+ doc->editMarkLineAutoWrapped (m_line, m_autowrapped);
+}
+
+void KateEditInsertTextUndo::updateRedoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (!lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(RedoLine1Modified);
+ setFlag(RedoLine1Saved);
+ }
+}
+
+void KateEditInsertTextUndo::updateUndoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (!lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(UndoLine1Modified);
+ setFlag(UndoLine1Saved);
+ }
+}
+
+void KateEditRemoveTextUndo::updateRedoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (!lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(RedoLine1Modified);
+ setFlag(RedoLine1Saved);
+ }
+}
+
+void KateEditRemoveTextUndo::updateUndoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (!lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(UndoLine1Modified);
+ setFlag(UndoLine1Saved);
+ }
+}
+
+void KateEditWrapLineUndo::updateRedoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (isFlagSet(RedoLine1Modified) && !lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(RedoLine1Modified);
+ setFlag(RedoLine1Saved);
+ }
+
+ if (isFlagSet(RedoLine2Modified) && !lines.testBit(m_line + 1)) {
+ lines.setBit(m_line + 1);
+
+ unsetFlag(RedoLine2Modified);
+ setFlag(RedoLine2Saved);
+ }
+}
+
+void KateEditWrapLineUndo::updateUndoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (isFlagSet(UndoLine1Modified) && !lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(UndoLine1Modified);
+ setFlag(UndoLine1Saved);
+ }
+}
+
+void KateEditUnWrapLineUndo::updateRedoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (isFlagSet(RedoLine1Modified) && !lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(RedoLine1Modified);
+ setFlag(RedoLine1Saved);
+ }
+}
+
+void KateEditUnWrapLineUndo::updateUndoSavedOnDiskFlag(QBitArray & lines)
+{
+ if (isFlagSet(UndoLine1Modified) && !lines.testBit(m_line)) {
+ lines.setBit(m_line);
+
+ unsetFlag(UndoLine1Modified);
+ setFlag(UndoLine1Saved);
+ }
+
+ if (isFlagSet(UndoLine2Modified) && !lines.testBit(m_line + 1)) {
+ lines.setBit(m_line + 1);
+
+ unsetFlag(UndoLine2Modified);
+ setFlag(UndoLine2Saved);
+ }
}
KateUndoGroup::KateUndoGroup (KateUndoManager *manager, const KTextEditor::Cursor \
&cursorPosition, const KTextEditor::Range &selectionRange) @@ -291,6 +562,47 @@ void \
KateUndoGroup::safePoint (bool safePoint) m_safePoint=safePoint;
}
+void KateUndoGroup::flagSavedAsModified()
+{
+ foreach (KateUndo *item, m_items) {
+ if (item->isFlagSet(KateUndo::UndoLine1Saved)) {
+ item->unsetFlag(KateUndo::UndoLine1Saved);
+ item->setFlag(KateUndo::UndoLine1Modified);
+ }
+
+ if (item->isFlagSet(KateUndo::UndoLine2Saved)) {
+ item->unsetFlag(KateUndo::UndoLine2Saved);
+ item->setFlag(KateUndo::UndoLine2Modified);
+ }
+
+ if (item->isFlagSet(KateUndo::RedoLine1Saved)) {
+ item->unsetFlag(KateUndo::RedoLine1Saved);
+ item->setFlag(KateUndo::RedoLine1Modified);
+ }
+
+ if (item->isFlagSet(KateUndo::RedoLine2Saved)) {
+ item->unsetFlag(KateUndo::RedoLine2Saved);
+ item->setFlag(KateUndo::RedoLine2Modified);
+ }
+ }
+}
+
+void KateUndoGroup::markUndoAsSaved(QBitArray & lines)
+{
+ for (int i = m_items.size() - 1; i >= 0; --i) {
+ KateUndo* item = m_items[i];
+ item->updateUndoSavedOnDiskFlag(lines);
+ }
+}
+
+void KateUndoGroup::markRedoAsSaved(QBitArray & lines)
+{
+ for (int i = m_items.size() - 1; i >= 0; --i) {
+ KateUndo* item = m_items[i];
+ item->updateRedoSavedOnDiskFlag(lines);
+ }
+}
+
KTextEditor::Document *KateUndoGroup::document()
{
return m_manager->document();
diff --git a/part/undo/kateundo.h b/part/undo/kateundo.h
index 6ee28a2..66db181 100644
--- a/part/undo/kateundo.h
+++ b/part/undo/kateundo.h
@@ -25,6 +25,7 @@
#include <QtCore/QList>
#include <ktexteditor/range.h>
+#include <QtCore/QBitArray>
class KateUndoManager;
class KateDocument;
@@ -110,17 +111,37 @@ class KateUndo
* the document the undo item belongs to
*/
KateDocument *m_document;
+
+ //
+ // Line modification system
+ //
+ public:
+ enum ModificationFlag {
+ UndoLine1Modified = 1,
+ UndoLine2Modified = 2,
+ UndoLine1Saved = 4,
+ UndoLine2Saved = 8,
+ RedoLine1Modified = 16,
+ RedoLine2Modified = 32,
+ RedoLine1Saved = 64,
+ RedoLine2Saved = 128
+ };
+
+ void setFlag(ModificationFlag flag);
+ void unsetFlag(ModificationFlag flag);
+ bool isFlagSet(ModificationFlag flag) const;
+
+ virtual void updateUndoSavedOnDiskFlag(QBitArray & lines) { Q_UNUSED(lines) }
+ virtual void updateRedoSavedOnDiskFlag(QBitArray & lines) { Q_UNUSED(lines) }
+
+ private:
+ uchar m_lineModFlags;
};
class KateEditInsertTextUndo : public KateUndo
{
public:
- KateEditInsertTextUndo (KateDocument *document, int line, int col, const QString \
&text)
- : KateUndo (document)
- , m_line (line)
- , m_col (col)
- , m_text (text)
- {}
+ KateEditInsertTextUndo (KateDocument *document, int line, int col, const QString \
&text);
/**
* @copydoc KateUndo::isEmpty()
@@ -147,6 +168,9 @@ class KateEditInsertTextUndo : public KateUndo
*/
KateUndo::UndoType type() const { return KateUndo::editInsertText; }
+ void updateUndoSavedOnDiskFlag(QBitArray & lines);
+ void updateRedoSavedOnDiskFlag(QBitArray & lines);
+
private:
int len() const { return m_text.length(); }
@@ -159,12 +183,7 @@ class KateEditInsertTextUndo : public KateUndo
class KateEditRemoveTextUndo : public KateUndo
{
public:
- KateEditRemoveTextUndo (KateDocument *document, int line, int col, const QString \
&text)
- : KateUndo (document)
- , m_line (line)
- , m_col (col)
- , m_text (text)
- {}
+ KateEditRemoveTextUndo (KateDocument *document, int line, int col, const QString \
&text);
/**
* @copydoc KateUndo::isEmpty()
@@ -191,6 +210,10 @@ class KateEditRemoveTextUndo : public KateUndo
*/
KateUndo::UndoType type() const { return KateUndo::editRemoveText; }
+ void updateUndoSavedOnDiskFlag(QBitArray & lines);
+ void updateRedoSavedOnDiskFlag(QBitArray & lines);
+
+
private:
int len() const { return m_text.length(); }
@@ -232,13 +255,7 @@ class KateEditMarkLineAutoWrappedUndo : public KateUndo
class KateEditWrapLineUndo : public KateUndo
{
public:
- KateEditWrapLineUndo (KateDocument *document, int line, int col, int len, bool \
newLine)
- : KateUndo (document)
- , m_line (line)
- , m_col (col)
- , m_len (len)
- , m_newLine (newLine)
- {}
+ KateEditWrapLineUndo (KateDocument *document, int line, int col, int len, bool \
newLine);
/**
* @copydoc KateUndo::undo()
@@ -255,6 +272,9 @@ class KateEditWrapLineUndo : public KateUndo
*/
KateUndo::UndoType type() const { return KateUndo::editWrapLine; }
+ void updateUndoSavedOnDiskFlag(QBitArray & lines);
+ void updateRedoSavedOnDiskFlag(QBitArray & lines);
+
private:
const int m_line;
const int m_col;
@@ -265,13 +285,7 @@ class KateEditWrapLineUndo : public KateUndo
class KateEditUnWrapLineUndo : public KateUndo
{
public:
- KateEditUnWrapLineUndo (KateDocument *document, int line, int col, int len, bool \
removeLine)
- : KateUndo (document)
- , m_line (line)
- , m_col (col)
- , m_len (len)
- , m_removeLine (removeLine)
- {}
+ KateEditUnWrapLineUndo (KateDocument *document, int line, int col, int len, bool \
removeLine);
/**
* @copydoc KateUndo::undo()
@@ -288,6 +302,9 @@ class KateEditUnWrapLineUndo : public KateUndo
*/
KateUndo::UndoType type() const { return KateUndo::editUnWrapLine; }
+ void updateUndoSavedOnDiskFlag(QBitArray & lines);
+ void updateRedoSavedOnDiskFlag(QBitArray & lines);
+
private:
const int m_line;
const int m_col;
@@ -298,11 +315,7 @@ class KateEditUnWrapLineUndo : public KateUndo
class KateEditInsertLineUndo : public KateUndo
{
public:
- KateEditInsertLineUndo (KateDocument *document, int line, const QString &text)
- : KateUndo (document)
- , m_line (line)
- , m_text (text)
- {}
+ KateEditInsertLineUndo (KateDocument *document, int line, const QString &text);
/**
* @copydoc KateUndo::undo()
@@ -327,11 +340,7 @@ class KateEditInsertLineUndo : public KateUndo
class KateEditRemoveLineUndo : public KateUndo
{
public:
- KateEditRemoveLineUndo (KateDocument *document, int line, const QString &text)
- : KateUndo (document)
- , m_line (line)
- , m_text (text)
- {}
+ KateEditRemoveLineUndo (KateDocument *document, int line, const QString &text);
/**
* @copydoc KateUndo::undo()
@@ -401,6 +410,14 @@ class KateUndoGroup
*/
bool isEmpty() const { return m_items.isEmpty(); }
+ /**
+ * Change all LineSaved flags to LineModified of the line modification system.
+ */
+ void flagSavedAsModified();
+
+ void markUndoAsSaved(QBitArray & lines);
+ void markRedoAsSaved(QBitArray & lines);
+
private:
KTextEditor::Document *document();
diff --git a/part/undo/kateundomanager.cpp b/part/undo/kateundomanager.cpp
index a39dd79..df3048c 100644
--- a/part/undo/kateundomanager.cpp
+++ b/part/undo/kateundomanager.cpp
@@ -22,6 +22,8 @@
#include "katedocument.h"
#include "kateundo.h"
+#include <QBitArray>
+
KateUndoManager::KateUndoManager (KateDocument *doc)
: QObject (doc)
, m_document (doc)
@@ -152,10 +154,10 @@ void KateUndoManager::slotMarkLineAutoWrapped(int line, bool \
autowrapped)
addUndoItem(new KateEditMarkLineAutoWrappedUndo(m_document, line, autowrapped));
}
-void KateUndoManager::slotLineWrapped(int line, int col, int pos, bool newLine)
+void KateUndoManager::slotLineWrapped(int line, int col, int length, bool newLine)
{
if (m_editCurrentUndo != 0) // do we care about notifications?
- addUndoItem(new KateEditWrapLineUndo(m_document, line, col, pos, newLine));
+ addUndoItem(new KateEditWrapLineUndo(m_document, line, col, length, newLine));
}
void KateUndoManager::slotLineUnWrapped(int line, int col, int length, bool \
lineRemoved) @@ -327,6 +329,7 @@ void KateUndoManager::updateModified()
{
if ( currentPattern == patterns[patternIndex] )
{
+ // Note: m_document->setModified() calls KateUndoManager::setModified!
m_document->setModified( false );
// (dominik) whenever the doc is not modified, succeeding edits
// should not be merged
@@ -359,16 +362,15 @@ void KateUndoManager::clearRedo()
emit undoChanged ();
}
-void KateUndoManager::setModified(bool m) {
- if ( m == false )
+void KateUndoManager::setModified(bool modified)
+{
+ if ( !modified )
{
- if ( ! undoItems.isEmpty() )
- {
+ if ( ! undoItems.isEmpty() ) {
lastUndoGroupWhenSaved = undoItems.last();
}
- if ( ! redoItems.isEmpty() )
- {
+ if ( ! redoItems.isEmpty() ) {
lastRedoGroupWhenSaved = redoItems.last();
}
@@ -377,6 +379,27 @@ void KateUndoManager::setModified(bool m) {
}
}
+void KateUndoManager::updateLineModifications()
+{
+ // change LineSaved flag of all undo & redo items to LineModified
+ foreach (KateUndoGroup* undoGroup, undoItems)
+ undoGroup->flagSavedAsModified();
+
+ foreach (KateUndoGroup* undoGroup, redoItems)
+ undoGroup->flagSavedAsModified();
+
+ // iterate all undo/redo items to find out, which item sets the flag LineSaved
+ QBitArray lines(document()->lines(), false);
+ for (int i = undoItems.size() - 1; i >= 0; --i) {
+ undoItems[i]->markRedoAsSaved(lines);
+ }
+
+ lines.fill(false);
+ for (int i = redoItems.size() - 1; i >= 0; --i) {
+ redoItems[i]->markUndoAsSaved(lines);
+ }
+}
+
void KateUndoManager::updateConfig ()
{
emit undoChanged ();
diff --git a/part/undo/kateundomanager.h b/part/undo/kateundomanager.h
index 9e60640..5c3541d 100644
--- a/part/undo/kateundomanager.h
+++ b/part/undo/kateundomanager.h
@@ -88,8 +88,9 @@ class KATEPART_TESTS_EXPORT KateUndoManager : public QObject
bool isActive() const { return m_isActive; }
- void setModified( bool m );
+ void setModified( bool modified );
void updateConfig ();
+ void updateLineModifications();
public Q_SLOTS:
/**
@@ -143,7 +144,7 @@ class KATEPART_TESTS_EXPORT KateUndoManager : public QObject
/**
* Notify KateUndoManager that a line was wrapped.
*/
- void slotLineWrapped(int line, int col, int pos, bool newLine);
+ void slotLineWrapped(int line, int col, int length, bool newLine);
/**
* Notify KateUndoManager that a line was un-wrapped.
diff --git a/part/view/kateviewhelpers.cpp b/part/view/kateviewhelpers.cpp
index 3164108..fd15f98 100644
--- a/part/view/kateviewhelpers.cpp
+++ b/part/view/kateviewhelpers.cpp
@@ -1271,7 +1271,20 @@ void KateIconBorder::paintBorder (int /*x*/, int y, int \
/*width*/, int height) oldInfo = info;
}
- lnX += iconPaneWidth + 2;
+ lnX += iconPaneWidth;
+ }
+
+ // modified line system
+ if (realLine > -1) {
+ Kate::TextLine tl = m_doc->plainKateTextLine(realLine);
+ if (tl->markedAsModified()) {
+ p.setPen(Qt::red);
+ p.fillRect(lnX, y, 2, h, QColor(242, 155, 104));
+ }
+ if (tl->markedAsSavedOnDisk()) {
+ p.setPen(Qt::darkGreen);
+ p.fillRect(lnX, y, 2, h, QColor(119, 183, 83));
+ }
}
}
}
_______________________________________________
KWrite-Devel mailing list
KWrite-Devel@kde.org
https://mail.kde.org/mailman/listinfo/kwrite-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic