mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2025-11-13 05:22:49 -05:00
@ -19,6 +19,7 @@
|
||||
|
||||
#include "ChatModel.hpp"
|
||||
#include <utils/aspects.h>
|
||||
#include <QDateTime>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QtQml>
|
||||
@ -324,7 +325,9 @@ void ChatModel::updateToolResult(
|
||||
QString("ERROR: Parsed JSON is not an object, is array=%1").arg(doc.isArray()));
|
||||
} else {
|
||||
QJsonObject editData = doc.object();
|
||||
QString editId = editData["edit_id"].toString();
|
||||
|
||||
// Generate unique edit ID based on timestamp
|
||||
QString editId = QString("edit_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
||||
|
||||
LOG_MESSAGE(QString("Adding FileEdit message, editId=%1").arg(editId));
|
||||
|
||||
@ -332,7 +335,7 @@ void ChatModel::updateToolResult(
|
||||
Message fileEditMsg;
|
||||
fileEditMsg.role = ChatRole::FileEdit;
|
||||
fileEditMsg.content = result;
|
||||
fileEditMsg.id = editId.isEmpty() ? QString("edit_%1").arg(requestId) : editId;
|
||||
fileEditMsg.id = editId;
|
||||
m_messages.append(fileEditMsg);
|
||||
endInsertRows();
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "Logger.hpp"
|
||||
#include "settings/GeneralSettings.hpp"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonDocument>
|
||||
@ -45,7 +46,6 @@ void FileEditItem::parseFromContent(const QString &content)
|
||||
int markerPos = content.indexOf(marker);
|
||||
|
||||
if (markerPos == -1) {
|
||||
LOG_MESSAGE(QString("FileEditItem: ERROR - no marker found"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -56,42 +56,37 @@ void FileEditItem::parseFromContent(const QString &content)
|
||||
QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8(), &parseError);
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
LOG_MESSAGE(QString("FileEditItem: JSON parse error at offset %1: %2")
|
||||
.arg(parseError.offset)
|
||||
.arg(parseError.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!doc.isObject()) {
|
||||
LOG_MESSAGE(QString("FileEditItem: ERROR - parsed JSON is not an object"));
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject editData = doc.object();
|
||||
|
||||
m_editId = editData["edit_id"].toString();
|
||||
m_filePath = editData["file_path"].toString();
|
||||
m_editMode = editData["mode"].toString();
|
||||
m_originalContent = editData["original_content"].toString();
|
||||
m_newContent = editData["new_content"].toString();
|
||||
m_contextBefore = editData["context_before"].toString();
|
||||
m_contextAfter = editData["context_after"].toString();
|
||||
m_editId = QString("edit_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
||||
m_mode = editData["mode"].toString();
|
||||
m_filePath = editData["filepath"].toString();
|
||||
m_newText = editData["new_text"].toString();
|
||||
m_searchText = editData["search_text"].toString();
|
||||
m_lineNumber = editData["line_number"].toInt(-1);
|
||||
m_lineBefore = editData["line_before"].toString();
|
||||
m_lineAfter = editData["line_after"].toString();
|
||||
|
||||
m_addedLines = m_newContent.split('\n').size();
|
||||
m_removedLines = m_originalContent.split('\n').size();
|
||||
if (m_mode.isEmpty()) {
|
||||
m_mode = m_searchText.isEmpty() ? "insert_after" : "replace";
|
||||
}
|
||||
|
||||
LOG_MESSAGE(QString("FileEditItem: parsed successfully, editId=%1, filePath=%2")
|
||||
.arg(m_editId, m_filePath));
|
||||
m_addedLines = m_newText.split('\n').size();
|
||||
m_removedLines = m_searchText.isEmpty() ? 0 : m_searchText.split('\n').size();
|
||||
|
||||
emit editIdChanged();
|
||||
emit modeChanged();
|
||||
emit filePathChanged();
|
||||
emit editModeChanged();
|
||||
emit originalContentChanged();
|
||||
emit newContentChanged();
|
||||
emit contextBeforeChanged();
|
||||
emit contextAfterChanged();
|
||||
emit searchTextChanged();
|
||||
emit newTextChanged();
|
||||
emit lineBeforeChanged();
|
||||
emit lineAfterChanged();
|
||||
emit addedLinesChanged();
|
||||
emit removedLinesChanged();
|
||||
|
||||
@ -153,18 +148,132 @@ void FileEditItem::revertEdit()
|
||||
|
||||
void FileEditItem::performApply()
|
||||
{
|
||||
LOG_MESSAGE(QString("FileEditItem: applying edit %1 to %2").arg(m_editId, m_filePath));
|
||||
|
||||
QString currentContent = readFile(m_filePath);
|
||||
if (currentContent.isNull()) {
|
||||
rejectWithError(QString("Failed to read file: %1").arg(m_filePath));
|
||||
return;
|
||||
}
|
||||
m_originalContent = currentContent;
|
||||
|
||||
bool success = false;
|
||||
QString editedContent = applyEditToContent(currentContent, success);
|
||||
if (!success) {
|
||||
rejectWithError("Failed to apply edit: could not find context. File may have been modified.");
|
||||
QString editedContent;
|
||||
|
||||
if (m_mode == "insert_after") {
|
||||
if (m_lineBefore.isEmpty()) {
|
||||
editedContent = m_newText + currentContent;
|
||||
} else {
|
||||
QList<int> positions;
|
||||
int pos = 0;
|
||||
while ((pos = currentContent.indexOf(m_lineBefore, pos)) != -1) {
|
||||
positions.append(pos);
|
||||
pos += m_lineBefore.length();
|
||||
}
|
||||
|
||||
if (positions.isEmpty()) {
|
||||
rejectWithError("Failed to apply edit: line_before not found");
|
||||
return;
|
||||
}
|
||||
|
||||
int matchedPosition = -1;
|
||||
|
||||
if (!m_lineAfter.isEmpty()) {
|
||||
for (int beforePos : positions) {
|
||||
int afterPos = beforePos + m_lineBefore.length();
|
||||
if (afterPos + m_lineAfter.length() <= currentContent.length()) {
|
||||
QString actualAfter = currentContent.mid(afterPos, m_lineAfter.length());
|
||||
if (actualAfter == m_lineAfter) {
|
||||
matchedPosition = afterPos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (matchedPosition == -1) {
|
||||
rejectWithError("Failed to apply edit: line_before found but line_after context doesn't match");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
matchedPosition = positions.first() + m_lineBefore.length();
|
||||
}
|
||||
|
||||
editedContent = currentContent;
|
||||
editedContent.insert(matchedPosition, m_newText);
|
||||
}
|
||||
|
||||
} else if (m_mode == "replace") {
|
||||
if (m_searchText.isEmpty()) {
|
||||
rejectWithError("REPLACE mode requires search_text to be specified");
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasLineBefore = !m_lineBefore.isEmpty();
|
||||
bool hasLineAfter = !m_lineAfter.isEmpty();
|
||||
|
||||
QList<int> searchPositions;
|
||||
int pos = 0;
|
||||
while ((pos = currentContent.indexOf(m_searchText, pos)) != -1) {
|
||||
searchPositions.append(pos);
|
||||
pos += m_searchText.length();
|
||||
}
|
||||
|
||||
if (searchPositions.isEmpty()) {
|
||||
rejectWithError("Failed to apply edit: search_text not found. File may have been modified.");
|
||||
return;
|
||||
}
|
||||
|
||||
int matchedPosition = -1;
|
||||
const int MAX_CONTEXT_DISTANCE = 500;
|
||||
|
||||
for (int searchPos : searchPositions) {
|
||||
bool beforeMatches = true;
|
||||
bool afterMatches = true;
|
||||
|
||||
if (hasLineBefore) {
|
||||
int searchStart = qMax(0, searchPos - MAX_CONTEXT_DISTANCE);
|
||||
int beforePos = currentContent.lastIndexOf(m_lineBefore, searchPos - 1);
|
||||
|
||||
if (beforePos >= searchStart && beforePos < searchPos) {
|
||||
beforeMatches = true;
|
||||
} else {
|
||||
beforeMatches = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasLineAfter) {
|
||||
int afterPos = searchPos + m_searchText.length();
|
||||
int searchEnd = qMin(currentContent.length(), afterPos + MAX_CONTEXT_DISTANCE);
|
||||
int foundAfterPos = currentContent.indexOf(m_lineAfter, afterPos);
|
||||
|
||||
if (foundAfterPos >= afterPos && foundAfterPos < searchEnd) {
|
||||
afterMatches = true;
|
||||
} else {
|
||||
afterMatches = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isMatch = false;
|
||||
|
||||
if (hasLineBefore && hasLineAfter) {
|
||||
isMatch = beforeMatches && afterMatches;
|
||||
} else if (hasLineBefore && !hasLineAfter) {
|
||||
isMatch = beforeMatches;
|
||||
} else if (!hasLineBefore && hasLineAfter) {
|
||||
isMatch = afterMatches;
|
||||
} else {
|
||||
isMatch = true;
|
||||
}
|
||||
|
||||
if (isMatch) {
|
||||
matchedPosition = searchPos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matchedPosition == -1) {
|
||||
rejectWithError("Failed to apply edit: search_text found but context verification failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
editedContent = currentContent;
|
||||
editedContent.replace(matchedPosition, m_searchText.length(), m_newText);
|
||||
|
||||
} else {
|
||||
rejectWithError(QString("Unknown edit mode: %1").arg(m_mode));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -178,22 +287,7 @@ void FileEditItem::performApply()
|
||||
|
||||
void FileEditItem::performRevert()
|
||||
{
|
||||
LOG_MESSAGE(QString("FileEditItem: reverting edit %1 for %2").arg(m_editId, m_filePath));
|
||||
|
||||
QString currentContent = readFile(m_filePath);
|
||||
if (currentContent.isNull()) {
|
||||
rejectWithError(QString("Failed to read file for revert: %1").arg(m_filePath));
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
QString revertedContent = applyReverseEdit(currentContent, success);
|
||||
if (!success) {
|
||||
rejectWithError("Failed to revert edit: could not find changes in current file.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!writeFile(m_filePath, revertedContent)) {
|
||||
if (!writeFile(m_filePath, m_originalContent)) {
|
||||
rejectWithError(QString("Failed to write reverted file: %1").arg(m_filePath));
|
||||
return;
|
||||
}
|
||||
@ -203,14 +297,12 @@ void FileEditItem::performRevert()
|
||||
|
||||
void FileEditItem::rejectWithError(const QString &errorMessage)
|
||||
{
|
||||
LOG_MESSAGE(errorMessage);
|
||||
setStatus(EditStatus::Rejected);
|
||||
setStatusMessage(errorMessage);
|
||||
}
|
||||
|
||||
void FileEditItem::finishWithSuccess(EditStatus status, const QString &message)
|
||||
{
|
||||
LOG_MESSAGE(message);
|
||||
setStatus(status);
|
||||
setStatusMessage(message);
|
||||
}
|
||||
@ -237,7 +329,6 @@ bool FileEditItem::writeFile(const QString &filePath, const QString &content)
|
||||
{
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
LOG_MESSAGE(QString("Could not open file for writing: %1").arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -247,7 +338,6 @@ bool FileEditItem::writeFile(const QString &filePath, const QString &content)
|
||||
file.close();
|
||||
|
||||
if (stream.status() != QTextStream::Ok) {
|
||||
LOG_MESSAGE(QString("Error writing to file: %1").arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -258,7 +348,6 @@ QString FileEditItem::readFile(const QString &filePath)
|
||||
{
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
LOG_MESSAGE(QString("Could not open file for reading: %1").arg(filePath));
|
||||
return QString();
|
||||
}
|
||||
|
||||
@ -270,184 +359,6 @@ QString FileEditItem::readFile(const QString &filePath)
|
||||
return content;
|
||||
}
|
||||
|
||||
QString FileEditItem::applyEditToContent(const QString &content, bool &success)
|
||||
{
|
||||
success = false;
|
||||
QStringList lines = content.split('\n');
|
||||
|
||||
if (m_editMode == "replace") {
|
||||
QString searchPattern = m_contextBefore + m_searchText + m_contextAfter;
|
||||
int pos = content.indexOf(searchPattern);
|
||||
|
||||
if (pos == -1 && !m_contextBefore.isEmpty()) {
|
||||
pos = content.indexOf(m_searchText);
|
||||
}
|
||||
|
||||
if (pos != -1) {
|
||||
QString result = content;
|
||||
int searchPos = result.indexOf(m_searchText, pos);
|
||||
if (searchPos != -1) {
|
||||
result.replace(searchPos, m_searchText.length(), m_newContent);
|
||||
success = true;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
|
||||
} else if (m_editMode == "insert_before" || m_editMode == "insert_after") {
|
||||
int targetLine = -1;
|
||||
|
||||
if (!m_contextBefore.isEmpty() || !m_contextAfter.isEmpty()) {
|
||||
for (int i = 0; i < lines.size(); ++i) {
|
||||
bool contextMatches = true;
|
||||
|
||||
if (!m_contextBefore.isEmpty()) {
|
||||
QStringList beforeLines = m_contextBefore.split('\n');
|
||||
if (i >= beforeLines.size()) {
|
||||
bool allMatch = true;
|
||||
for (int j = 0; j < beforeLines.size(); ++j) {
|
||||
if (lines[i - beforeLines.size() + j].trimmed()
|
||||
!= beforeLines[j].trimmed()) {
|
||||
allMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allMatch)
|
||||
contextMatches = false;
|
||||
} else {
|
||||
contextMatches = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (contextMatches && !m_contextAfter.isEmpty()) {
|
||||
QStringList afterLines = m_contextAfter.split('\n');
|
||||
if (i + afterLines.size() < lines.size()) {
|
||||
bool allMatch = true;
|
||||
for (int j = 0; j < afterLines.size(); ++j) {
|
||||
if (lines[i + 1 + j].trimmed() != afterLines[j].trimmed()) {
|
||||
allMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allMatch)
|
||||
contextMatches = false;
|
||||
} else {
|
||||
contextMatches = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (contextMatches && targetLine == -1) {
|
||||
targetLine = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetLine == -1 && m_lineNumber > 0 && m_lineNumber <= lines.size()) {
|
||||
targetLine = m_lineNumber - 1;
|
||||
}
|
||||
|
||||
if (targetLine != -1) {
|
||||
if (m_editMode == "insert_before") {
|
||||
lines.insert(targetLine, m_newContent);
|
||||
} else {
|
||||
lines.insert(targetLine + 1, m_newContent);
|
||||
}
|
||||
success = true;
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
return content;
|
||||
|
||||
} else if (m_editMode == "append") {
|
||||
success = true;
|
||||
return content + (content.endsWith('\n') ? "" : "\n") + m_newContent + "\n";
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
QString FileEditItem::applyReverseEdit(const QString &content, bool &success)
|
||||
{
|
||||
success = false;
|
||||
QStringList lines = content.split('\n');
|
||||
|
||||
if (m_editMode == "replace") {
|
||||
int pos = content.indexOf(m_newContent);
|
||||
if (pos != -1) {
|
||||
QString result = content;
|
||||
result.replace(pos, m_newContent.length(), m_originalContent);
|
||||
success = true;
|
||||
return result;
|
||||
}
|
||||
return content;
|
||||
|
||||
} else if (m_editMode == "insert_before" || m_editMode == "insert_after") {
|
||||
for (int i = 0; i < lines.size(); ++i) {
|
||||
if (lines[i].trimmed() == m_newContent.trimmed()) {
|
||||
bool contextMatches = true;
|
||||
|
||||
if (!m_contextBefore.isEmpty()) {
|
||||
QStringList beforeLines = m_contextBefore.split('\n');
|
||||
if (i >= beforeLines.size()) {
|
||||
for (int j = 0; j < beforeLines.size(); ++j) {
|
||||
if (lines[i - beforeLines.size() + j].trimmed() != beforeLines[j].trimmed()) {
|
||||
contextMatches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
contextMatches = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (contextMatches && !m_contextAfter.isEmpty()) {
|
||||
QStringList afterLines = m_contextAfter.split('\n');
|
||||
if (i + 1 + afterLines.size() <= lines.size()) {
|
||||
for (int j = 0; j < afterLines.size(); ++j) {
|
||||
if (lines[i + 1 + j].trimmed() != afterLines[j].trimmed()) {
|
||||
contextMatches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
contextMatches = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (contextMatches) {
|
||||
lines.removeAt(i);
|
||||
success = true;
|
||||
return lines.join('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
return content;
|
||||
|
||||
} else if (m_editMode == "append") {
|
||||
QString suffix1 = m_newContent + "\n";
|
||||
QString suffix2 = "\n" + m_newContent + "\n";
|
||||
|
||||
if (content.endsWith(suffix1)) {
|
||||
QString result = content.left(content.length() - suffix1.length());
|
||||
success = true;
|
||||
return result;
|
||||
} else if (content.endsWith(suffix2)) {
|
||||
QString result = content.left(content.length() - suffix2.length()) + "\n";
|
||||
success = true;
|
||||
return result;
|
||||
} else if (content.endsWith(m_newContent)) {
|
||||
QString result = content.left(content.length() - m_newContent.length());
|
||||
success = true;
|
||||
return result;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
bool FileEditItem::acquireFileLock(const QString &filePath)
|
||||
{
|
||||
QMutexLocker locker(&s_fileLockMutex);
|
||||
@ -457,17 +368,13 @@ bool FileEditItem::acquireFileLock(const QString &filePath)
|
||||
}
|
||||
|
||||
s_lockedFiles.insert(filePath);
|
||||
LOG_MESSAGE(QString("FileEditItem: acquired lock for %1").arg(filePath));
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileEditItem::releaseFileLock(const QString &filePath)
|
||||
{
|
||||
QMutexLocker locker(&s_fileLockMutex);
|
||||
|
||||
if (s_lockedFiles.remove(filePath)) {
|
||||
LOG_MESSAGE(QString("FileEditItem: released lock for %1").arg(filePath));
|
||||
}
|
||||
s_lockedFiles.remove(filePath);
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::Chat
|
||||
|
||||
@ -47,12 +47,12 @@ public:
|
||||
static constexpr int MAX_RETRY_COUNT = 10;
|
||||
|
||||
Q_PROPERTY(QString editId READ editId NOTIFY editIdChanged FINAL)
|
||||
Q_PROPERTY(QString mode READ mode NOTIFY modeChanged FINAL)
|
||||
Q_PROPERTY(QString filePath READ filePath NOTIFY filePathChanged FINAL)
|
||||
Q_PROPERTY(QString editMode READ editMode NOTIFY editModeChanged FINAL)
|
||||
Q_PROPERTY(QString originalContent READ originalContent NOTIFY originalContentChanged FINAL)
|
||||
Q_PROPERTY(QString newContent READ newContent NOTIFY newContentChanged FINAL)
|
||||
Q_PROPERTY(QString contextBefore READ contextBefore NOTIFY contextBeforeChanged FINAL)
|
||||
Q_PROPERTY(QString contextAfter READ contextAfter NOTIFY contextAfterChanged FINAL)
|
||||
Q_PROPERTY(QString searchText READ searchText NOTIFY searchTextChanged FINAL)
|
||||
Q_PROPERTY(QString newText READ newText NOTIFY newTextChanged FINAL)
|
||||
Q_PROPERTY(QString lineBefore READ lineBefore NOTIFY lineBeforeChanged FINAL)
|
||||
Q_PROPERTY(QString lineAfter READ lineAfter NOTIFY lineAfterChanged FINAL)
|
||||
Q_PROPERTY(int addedLines READ addedLines NOTIFY addedLinesChanged FINAL)
|
||||
Q_PROPERTY(int removedLines READ removedLines NOTIFY removedLinesChanged FINAL)
|
||||
Q_PROPERTY(EditStatus status READ status NOTIFY statusChanged FINAL)
|
||||
@ -62,12 +62,12 @@ public:
|
||||
explicit FileEditItem(QQuickItem *parent = nullptr);
|
||||
|
||||
QString editId() const { return m_editId; }
|
||||
QString mode() const { return m_mode; }
|
||||
QString filePath() const { return m_filePath; }
|
||||
QString editMode() const { return m_editMode; }
|
||||
QString originalContent() const { return m_originalContent; }
|
||||
QString newContent() const { return m_newContent; }
|
||||
QString contextBefore() const { return m_contextBefore; }
|
||||
QString contextAfter() const { return m_contextAfter; }
|
||||
QString searchText() const { return m_searchText; }
|
||||
QString newText() const { return m_newText; }
|
||||
QString lineBefore() const { return m_lineBefore; }
|
||||
QString lineAfter() const { return m_lineAfter; }
|
||||
int addedLines() const { return m_addedLines; }
|
||||
int removedLines() const { return m_removedLines; }
|
||||
EditStatus status() const { return m_status; }
|
||||
@ -79,12 +79,12 @@ public:
|
||||
|
||||
signals:
|
||||
void editIdChanged();
|
||||
void modeChanged();
|
||||
void filePathChanged();
|
||||
void editModeChanged();
|
||||
void originalContentChanged();
|
||||
void newContentChanged();
|
||||
void contextBeforeChanged();
|
||||
void contextAfterChanged();
|
||||
void searchTextChanged();
|
||||
void newTextChanged();
|
||||
void lineBeforeChanged();
|
||||
void lineAfterChanged();
|
||||
void addedLinesChanged();
|
||||
void removedLinesChanged();
|
||||
void statusChanged();
|
||||
@ -101,8 +101,6 @@ private:
|
||||
|
||||
bool writeFile(const QString &filePath, const QString &content);
|
||||
QString readFile(const QString &filePath);
|
||||
QString applyEditToContent(const QString &content, bool &success);
|
||||
QString applyReverseEdit(const QString &content, bool &success);
|
||||
|
||||
static bool acquireFileLock(const QString &filePath);
|
||||
static void releaseFileLock(const QString &filePath);
|
||||
@ -110,14 +108,13 @@ private:
|
||||
static QSet<QString> s_lockedFiles;
|
||||
|
||||
QString m_editId;
|
||||
QString m_mode;
|
||||
QString m_filePath;
|
||||
QString m_editMode;
|
||||
QString m_originalContent;
|
||||
QString m_newContent;
|
||||
QString m_contextBefore;
|
||||
QString m_contextAfter;
|
||||
QString m_searchText;
|
||||
int m_lineNumber = -1;
|
||||
QString m_newText;
|
||||
QString m_lineBefore;
|
||||
QString m_lineAfter;
|
||||
QString m_originalContent; // Stored when applying edit
|
||||
int m_addedLines = 0;
|
||||
int m_removedLines = 0;
|
||||
EditStatus m_status = EditStatus::Pending;
|
||||
|
||||
@ -153,14 +153,7 @@ FileEditItem {
|
||||
id: headerText
|
||||
Layout.fillWidth: true
|
||||
text: {
|
||||
var modeText = ""
|
||||
switch(root.editMode) {
|
||||
case "replace": modeText = qsTr("Replace"); break;
|
||||
case "insert_before": modeText = qsTr("Insert Before"); break;
|
||||
case "insert_after": modeText = qsTr("Insert After"); break;
|
||||
case "append": modeText = qsTr("Append"); break;
|
||||
default: modeText = root.editMode;
|
||||
}
|
||||
var modeText = root.searchText.length > 0 ? qsTr("Replace") : qsTr("Append")
|
||||
return qsTr("%1: %2 (+%3 -%4)")
|
||||
.arg(modeText)
|
||||
.arg(root.filePath)
|
||||
@ -224,21 +217,6 @@ FileEditItem {
|
||||
spacing: 4
|
||||
visible: opacity > 0
|
||||
|
||||
TextEdit {
|
||||
Layout.fillWidth: true
|
||||
visible: root.contextBefore.length > 0
|
||||
text: root.contextBefore
|
||||
font.family: root.codeFontFamily
|
||||
font.pixelSize: root.codeFontSize
|
||||
color: palette.mid
|
||||
wrapMode: TextEdit.Wrap
|
||||
opacity: 0.6
|
||||
readOnly: true
|
||||
selectByMouse: true
|
||||
selectByKeyboard: true
|
||||
textFormat: TextEdit.PlainText
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: oldContentText.implicitHeight + 8
|
||||
@ -246,7 +224,7 @@ FileEditItem {
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: Qt.rgba(1, 0.2, 0.2, 0.3)
|
||||
visible: root.originalContent.length > 0
|
||||
visible: root.searchText.length > 0
|
||||
|
||||
TextEdit {
|
||||
id: oldContentText
|
||||
@ -256,7 +234,7 @@ FileEditItem {
|
||||
top: parent.top
|
||||
margins: 4
|
||||
}
|
||||
text: "- " + root.originalContent
|
||||
text: root.searchText
|
||||
font.family: root.codeFontFamily
|
||||
font.pixelSize: root.codeFontSize
|
||||
color: Qt.rgba(1, 0.2, 0.2, 0.9)
|
||||
@ -284,7 +262,7 @@ FileEditItem {
|
||||
top: parent.top
|
||||
margins: 4
|
||||
}
|
||||
text: "+ " + root.newContent
|
||||
text: root.newText
|
||||
font.family: root.codeFontFamily
|
||||
font.pixelSize: root.codeFontSize
|
||||
color: Qt.rgba(0.2, 0.8, 0.2, 0.9)
|
||||
@ -296,21 +274,6 @@ FileEditItem {
|
||||
}
|
||||
}
|
||||
|
||||
TextEdit {
|
||||
Layout.fillWidth: true
|
||||
visible: root.contextAfter.length > 0
|
||||
text: root.contextAfter
|
||||
font.family: root.codeFontFamily
|
||||
font.pixelSize: root.codeFontSize
|
||||
color: palette.mid
|
||||
wrapMode: TextEdit.Wrap
|
||||
opacity: 0.6
|
||||
readOnly: true
|
||||
selectByMouse: true
|
||||
selectByKeyboard: true
|
||||
textFormat: TextEdit.PlainText
|
||||
}
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
visible: root.statusMessage.length > 0
|
||||
|
||||
Reference in New Issue
Block a user