Skip to content

Commit

Permalink
editbox: replace lines edited with recreated line text
Browse files Browse the repository at this point in the history
program model now emits a signal when a program line is changed (though
its contents may not have actually changed) or inserted; this signal is
connected to the program changed slot in edit box, which retrieves the
recreated text for the line and replaces the line with this text (unless
the line text is null indicating the line has an error and therefore the
text of the line is not replaced)

the program model line text function was modified to return a null
string if the line has an error; this required a slight change to the
recreator where the output string is initialized to an empty string
instead of being cleared (which sets the string to a null string)

added a 'recreating line' flag to prevent a circular loop when the text
of the line is replaced, which generates a document changed and cursor
moved signals; this flag prevents these signals from being processed
during the text replacement

there are two issues with these changes the need to be resolved: when a
program is initially loaded, the lines are not recreated because the
text cursor is not valid yet (preventing the replacement of text) and
the replacing of text interferes with the undo/redo stack by adding
extra commands in the undo stack for each line replaced
  • Loading branch information
thunder422 committed Dec 15, 2013
1 parent c864bdd commit 4b34bd2
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 24 deletions.
42 changes: 41 additions & 1 deletion editbox.cpp
Expand Up @@ -41,7 +41,8 @@ EditBox::EditBox(ProgramModel *programUnit, QWidget *parent) :
m_modifiedLine(-1),
m_modifiedLineIsNew(false),
m_lineCount(0),
m_cursorValid(false)
m_cursorValid(false),
m_recreatingLine(false)
{
// set the edit box to a fixed width font
QFont font = this->font();
Expand All @@ -65,6 +66,10 @@ EditBox::EditBox(ProgramModel *programUnit, QWidget *parent) :
// FROM PROGRAM CONNECTIONS
//============================

// connect to catch program line changes
connect(m_programUnit, SIGNAL(programChange(int)),
this, SLOT(programChanged(int)));

// connect to catch when an error has been inserted
connect(m_programUnit, SIGNAL(errorInserted(int, ErrorItem)),
this, SLOT(errorInserted(int, ErrorItem)));
Expand Down Expand Up @@ -308,6 +313,11 @@ void EditBox::resetModified(void)

void EditBox::documentChanged(int position, int charsRemoved, int charsAdded)
{
if (m_recreatingLine)
{
return; // change due to recreated line, ignore
}

int linesInserted = 0;
int linesDeleted = 0;
QStringList lines;
Expand Down Expand Up @@ -456,6 +466,10 @@ void EditBox::documentChanged(int position, int charsRemoved, int charsAdded)

void EditBox::cursorMoved(void)
{
if (m_recreatingLine)
{
return; // ignore cursor movements when recreating line
}
if (!m_cursorValid) // waiting for cursor to be valid?
{
m_cursorValid = true; // cursor is now valid
Expand All @@ -480,6 +494,32 @@ void EditBox::setPlainText(const QString &text)
}


// function to received program model line changes
void EditBox::programChanged(int lineNumber)
{
QString lineText = m_programUnit->lineText(lineNumber);
if (lineText.isNull()) // line has error?
{
return; // don't do anything
}
if (!m_cursorValid)
{
return; // FIXME can't replace lines until cursor is valid
}

QTextCursor cursor = textCursor();
cursor.setPosition(document()->findBlockByLineNumber(lineNumber)
.position());
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);

// prevent document changed and cursor moved signals
// from being processed before replacing line text
m_recreatingLine = true;
cursor.insertText(lineText);
m_recreatingLine = false;
}


// function to check if current line was modified and to process it

void EditBox::captureModifiedLine(int offset)
Expand Down
2 changes: 2 additions & 0 deletions editbox.h
Expand Up @@ -77,6 +77,7 @@ public slots:
void documentChanged(int position, int charsRemoved, int charsAdded);
void cursorMoved(void);
void setPlainText(const QString &text);
void programChanged(int lineNumber);

private slots:
void errorListChanged(void);
Expand All @@ -102,6 +103,7 @@ private slots:
m_extraSelections; // error highlight extra selections list
bool m_cursorValid; // flag for when text cursor is valid
QList<ErrorItem> m_errors; // list of errors during startup
bool m_recreatingLine; // change due to recreated text flag
};


Expand Down
50 changes: 28 additions & 22 deletions programmodel.cpp
Expand Up @@ -178,11 +178,16 @@ QString ProgramModel::dictionariesDebugText(void)
// function to return text for a given program line
QString ProgramModel::lineText(int lineIndex)
{
QString string;

LineInfo &lineInfo = m_lineInfo[lineIndex];
RpnList *rpnList = decode(lineInfo);
QString string = m_recreator->recreate(rpnList);
delete rpnList;
return string;
if (lineInfo.errIndex == -1)
{
RpnList *rpnList = decode(lineInfo);
string = m_recreator->recreate(rpnList);
delete rpnList;
}
return string; // return null string if line has error
}


Expand Down Expand Up @@ -292,30 +297,30 @@ bool ProgramModel::updateLine(Operation operation, int lineNumber,
{
LineInfo &lineInfo = m_lineInfo[lineNumber];
RpnList *currentRpnList = decode(lineInfo);
bool same = *rpnList == *currentRpnList;
bool changed = *rpnList != *currentRpnList;
delete currentRpnList;
if (same)
if (changed)
{
delete rpnList; // not needed
return false; // line not changed; nothing more to do here
}
// derefence old line
// (line gets deleted if new line has an error)
dereference(lineInfo);

// derefence old line
// (line gets deleted if new line has an error)
dereference(lineInfo);
// line is different, encode it if there was no translation error
if (errorItem.isEmpty())
{
lineCode = encode(rpnList);
}

// line is different, encode it if there was no translation error
if (errorItem.isEmpty())
{
lineCode = encode(rpnList);
}
delete rpnList; // no longer needed
updateError(lineNumber, lineInfo, errorItem, false);

updateError(lineNumber, lineInfo, errorItem, false);
// replace with new line
m_code.replaceLine(lineInfo.offset, lineInfo.size, lineCode);
m_lineInfo.replace(lineNumber, lineCode.size());
}

// replace with new line
m_code.replaceLine(lineInfo.offset, lineInfo.size, lineCode);
m_lineInfo.replace(lineNumber, lineCode.size());
emit programChange(lineNumber);
delete rpnList; // no longer needed
return changed;
}
else if (operation == Insert_Operation)
{
Expand Down Expand Up @@ -346,6 +351,7 @@ bool ProgramModel::updateLine(Operation operation, int lineNumber,
m_code.insertLine(lineInfo.offset, lineCode);

m_lineInfo.insert(lineNumber, lineInfo);
emit programChange(lineNumber);
}
else if (operation == Remove_Operation)
{
Expand Down
1 change: 1 addition & 0 deletions programmodel.h
Expand Up @@ -231,6 +231,7 @@ class ProgramModel : public QAbstractListModel

signals:
void lineCountChanged(int newLineCount);
void programChange(int lineNumber);
void errorInserted(int errIndex, const ErrorItem &errorItem);
void errorChanged(int errIndex, const ErrorItem &errorItem);
void errorRemoved(int errIndex);
Expand Down
2 changes: 1 addition & 1 deletion recreator.cpp
Expand Up @@ -38,7 +38,7 @@ Recreator::Recreator(void) :
// function to recreate original program text from an rpn list
QString Recreator::recreate(RpnList *rpnList, bool exprMode)
{
m_output.clear();
m_output = "";
for (int i = 0; i < rpnList->count(); i++)
{
RpnItem *rpnItem = rpnList->at(i);
Expand Down

0 comments on commit 4b34bd2

Please sign in to comment.