Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve loading files #6

Merged
merged 1 commit into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions CMakeLists.txt.user
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 14.0.1, 2024-09-23T15:38:14. -->
<!-- Written by QtCreator 14.0.1, 2024-10-01T02:22:16. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
Expand Down Expand Up @@ -94,22 +94,22 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 6.7.2 (System)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 6.7.2 (System)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{5fcd4be8-31fb-480b-a925-a47ce5b3bbaf}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMake.Build.Type">Debug</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
<value type="QString" key="CMake.Initial.Parameters">-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_BUILD_TYPE:STRING=Debug
-DCMAKE_GENERATOR:STRING=Ninja</value>
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
<value type="QString" key="CMake.Source.Directory">/data/Code/Qt/Notepad--</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/Code/Qt/Notepad--/build/Desktop-Debug</value>
Expand Down Expand Up @@ -160,14 +160,14 @@
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
<value type="QString" key="CMake.Initial.Parameters">-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_GENERATOR:STRING=Ninja</value>
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
<value type="QString" key="CMake.Source.Directory">/data/Code/Qt/Notepad--</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/Code/Qt/Notepad--/build/Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
Expand Down Expand Up @@ -243,7 +243,7 @@
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/data/Code/Qt/Notepad--/build/Desktop-Debug</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/data/Code/Qt/Notepad--/build/Desktop-Release</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
Expand Down
94 changes: 48 additions & 46 deletions src/document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,21 @@ Document::Document(const QString &filePath, QWidget *parent)

// Connect worker signals
connect(m_fileLoaderWorker, &FileLoaderWorker::loadingStarted, this, &Document::onLoadingStarted);
connect(m_fileLoaderWorker, &FileLoaderWorker::loadingProgress, this, &Document::onLoadingProgress);
connect(m_fileLoaderWorker, &FileLoaderWorker::errorOccurred, this, &Document::onLoadingError);
connect(m_fileLoaderWorker, &FileLoaderWorker::contentLoaded, this, &Document::insertContentIntoEditor);
connect(m_fileLoaderWorker, &FileLoaderWorker::contentLoaded, this, &Document::onContentLoaded);
connect(m_fileLoaderWorker, &FileLoaderWorker::loadingProgress, this, &Document::onLoadingProgress, Qt::UniqueConnection);
connect(m_fileLoaderWorker, &FileLoaderWorker::contentLoaded, this, &Document::onContentLoaded, Qt::UniqueConnection);
connect(m_fileLoaderWorker, &FileLoaderWorker::fileSizeDetermined, this, &Document::onFileSizeDetermined);

connect(m_fileLoaderWorker, &FileLoaderWorker::savingStarted, this, &Document::onSavingStarted);
connect(m_fileLoaderWorker, &FileLoaderWorker::savingProgress, this, &Document::onSavingProgress);
connect(m_fileLoaderWorker, &FileLoaderWorker::savingFinished, this, &Document::onSavingFinished);
connect(this, &Document::savingProgress, m_progressBar, &QProgressBar::setValue);

connect(m_fileLoaderWorker, &FileLoaderWorker::loadingProgress, this, &Document::onLoadingProgress, Qt::UniqueConnection);
/*
connect(m_fileLoaderWorker, &FileLoaderWorker::loadingProgress, this, [this](int progress) {
QMetaObject::invokeMethod(m_progressBar, "setValue", Qt::QueuedConnection, Q_ARG(int, progress));
});
*/

connect(m_fileLoaderWorker, &FileLoaderWorker::loadingFinished, this, &Document::onLoadingFinished);
connect(m_fileLoaderWorker, &FileLoaderWorker::savingFinished, this, &Document::onSavingFinished);
Expand Down Expand Up @@ -109,13 +109,17 @@ Document::~Document() {
}

void Document::onLoadingStarted() {
m_totalBytesInserted = 0; // Reset bytes inserted when loading starts
m_totalBytesRead = 0; // Reset bytes read
m_lastSmoothedProgress = 0; // Reset progress tracking
qDebug() << "Loading started for document:" << m_filePath;
m_statusLabel->setText("Loading File...");
m_progressBar->setValue(0);
m_progressBar->setVisible(true);
m_statusLabel->setVisible(true);
}


void Document::onSavingStarted() {
m_isSaving = true;
m_statusLabel->setText("Saving File...");
Expand All @@ -126,9 +130,8 @@ void Document::onSavingStarted() {
void Document::onLoadingProgress(int progress) {
if (progress - m_lastSmoothedProgress >= m_smoothProgressUpdateInterval || progress == 100) {
m_lastSmoothedProgress = progress;
m_progressBar->setValue(progress);

qDebug() << "Smooth progress updated to:" << progress;
QMetaObject::invokeMethod(m_progressBar, "setValue", Qt::QueuedConnection, Q_ARG(int, progress));
qDebug() << "Progress bar updated with progress: " << progress;
}

if (progress == 100) {
Expand All @@ -147,8 +150,14 @@ void Document::onSavingProgress(int progress) {

void Document::onLoadingFinished() {
m_isLoading = false;
emit loadingProgress(100);
emit loadingProgress(100); // Ensure progress is 100%
emit hideProgressBar(); // Hide the progress bar when loading finishes

// Move the cursor to the first line after file is loaded
editor->moveCursor(QTextCursor::Start);
editor->ensureCursorVisible(); // Ensure the cursor is visible
qDebug() << "Cursor moved to the first line after file loaded";

qDebug() << "Loading finished, m_isLoading = " << m_isLoading;
}

Expand All @@ -163,15 +172,6 @@ void Document::onLoadingError(const QString &error) {
m_statusLabel->setText("Error: " + error);
}

void Document::insertContentIntoEditor(const QString &content) {
if (m_totalBytesRead == 0) {
qDebug() << "Inserting initial content into the editor...";
editor->clear(); // Clear existing content if any
}
editor->insertPlainText(content);
m_originalText = content; // Save the original content for comparison
}

void Document::setFilePath(const QString &path) {
m_filePath = path;
qDebug() << "File path set to:" << m_filePath;
Expand Down Expand Up @@ -225,11 +225,6 @@ void Document::saveFileAs(const QString &newFilePath) {
saveFile();
}

bool Document::checkForUnsavedChanges() {
QString currentText = editor->toPlainText(); // Get the current text in the editor
return !compareText(currentText, m_originalText); // Compare current text with the original text
}

bool Document::closeDocument() {
qDebug() << "Checking document close: isLoading=" << m_isLoading << ", isSaving=" << m_isSaving;
if (m_isLoading || m_isSaving) {
Expand Down Expand Up @@ -365,49 +360,56 @@ void Document::onFileSizeDetermined(qint64 fileSize) {
qDebug() << "File size set in Document: " << m_fileSize;
}

// onContentLoaded (handles content loading and progress updates)
void Document::onContentLoaded(const QString &chunk) {
if (m_fileSize <= 0) {
qDebug() << "onContentLoaded: Invalid file size!";
return;
}

m_totalBytesRead += chunk.size();
// For small files, insert content directly
if (m_fileSize < 4096) { // For files smaller than 4KB, insert directly
editor->moveCursor(QTextCursor::End);
editor->insertPlainText(chunk);
m_totalBytesInserted += chunk.size();
emit loadingProgress(100); // Mark progress as 100% for small files
emit loadingFinished();
return;
}

// Buffer more content before updating the editor
m_bufferedContent += chunk;
// Buffer for large files
m_totalBytesRead += chunk.size(); // Track bytes read
m_bufferedContent += chunk; // Add to the buffer

// Calculate a dynamic buffer size (e.g., 1% of file size or 1MB minimum)
qint64 dynamicBufferSize = std::max(m_fileSize / 100, static_cast<qint64>(1 * 1024 * 1024));
// Use a dynamic buffer size (1% of file size or at least 4KB)
qint64 dynamicBufferSize = std::max(m_fileSize / 100, static_cast<qint64>(4096));

// Insert content when buffered size reaches the threshold
if (m_bufferedContent.size() >= dynamicBufferSize) {
editor->moveCursor(QTextCursor::End);
qDebug() << "Buffered content size before inserting: " << m_bufferedContent.size();

// Insert content with proper line breaks
editor->insertPlainText(m_bufferedContent);
m_bufferedContent.clear(); // Clear buffer after insertion

QCoreApplication::processEvents(); // Keep UI responsive
QMetaObject::invokeMethod(this, [this]() {
editor->moveCursor(QTextCursor::End);
editor->insertPlainText(m_bufferedContent); // Insert buffered content
m_totalBytesInserted += m_bufferedContent.size(); // Track bytes inserted
m_bufferedContent.clear(); // Clear the buffer
}, Qt::QueuedConnection);
}

// Update progress bar
emit loadingProgress(static_cast<int>((m_totalBytesRead * 100) / m_fileSize));
// Update progress based on inserted content
int progress = static_cast<int>((m_totalBytesInserted * 100) / m_fileSize);
if (progress > m_lastSmoothedProgress || progress == 100) {
emit loadingProgress(progress);
m_lastSmoothedProgress = progress;
}

// Handle loading finished
// Handle finished loading case
if (m_totalBytesRead >= m_fileSize) {
emit loadingFinished();

// Insert remaining buffered content
if (!m_bufferedContent.isEmpty()) {
editor->moveCursor(QTextCursor::End);
editor->insertPlainText(m_bufferedContent);
m_totalBytesInserted += m_bufferedContent.size();
m_bufferedContent.clear();
}

// Move cursor to the first line after loading completes
editor->moveCursor(QTextCursor::Start);

// Clear status label after loading completes
m_statusLabel->setText("");
emit hideProgressBar();
}
}
5 changes: 2 additions & 3 deletions src/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public slots:
void onLoadingProgress(int progress);
void onLoadingFinished();
void onLoadingError(const QString &error);
void insertContentIntoEditor(const QString &content);
void onSavingStarted();

private slots:
Expand Down Expand Up @@ -83,16 +82,16 @@ private slots:

QString m_filePath;
QString m_fileExtension;
QString m_originalText;
QFile m_file;
CodeEditor *editor;
QSyntaxHighlighter *syntaxHighlighter;
qint64 m_fileSize;
QMap<qint64, QString> m_changedSegments;
QString m_currentText;
QString m_language;
int m_lastProgress;
int m_lastProgress = 0;
int m_lastSmoothedProgress = 0;
int m_smoothProgressUpdateInterval = 1;
qint64 m_totalBytesInserted = 0;
};

58 changes: 18 additions & 40 deletions src/fileloaderworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,55 +43,33 @@ qint64 calculateChunkSize(qint64 fileSize) {
void FileLoaderWorker::startLoading() {
QFile file(m_filePath);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file:" << m_filePath;
emit loadingError("File could not be opened.");
return;
}

m_fileSize = file.size();
if (m_fileSize <= 0) {
emit loadingError("startLoading: File size is invalid!");
return;
}

emit fileSizeDetermined(m_fileSize);

// Calculate an appropriate chunk size
qint64 chunkSize = calculateChunkSize(m_fileSize);

// Use QTextStream for reading the file as text
QTextStream in(&file);
in.setEncoding(QStringConverter::Utf8);

qint64 bytesRead = 0;

// Reading loop
while (!in.atEnd()) {
QString buffer = in.read(chunkSize); // Read text data as UTF-8
qDebug() << "Read chunk of size:" << buffer.size() << "Bytes read so far:" << bytesRead;
QString buffer = in.read(chunkSize);
if (buffer.isEmpty()) break;

if (buffer.isEmpty()) {
qDebug() << "Read an empty buffer. Aborting...";
break;
}

bytesRead += buffer.toUtf8().size(); // Update bytesRead based on the UTF-8 size
qDebug() << "Total bytes read after update:" << bytesRead << "File size:" << m_fileSize;

emit contentLoaded(buffer);
bytesRead += buffer.toUtf8().size();
emit contentLoaded(buffer); // Emit content after every chunk is read

// Update progress bar
int progress = static_cast<int>((bytesRead * 100) / m_fileSize);
qDebug() << "Progress updated to:" << progress << "%";
emit loadingProgress(progress);
emit loadingProgress(progress); // Update progress based on bytes read so far

QCoreApplication::processEvents(); // Keep the UI responsive
}

// Finalize the loading process
if (bytesRead >= m_fileSize) {
qDebug() << "Loading finished, total bytes read:" << bytesRead;
emit loadingFinished();
} else {
qDebug() << "File not fully read. Bytes read:" << bytesRead;
}
}

Expand Down Expand Up @@ -156,20 +134,20 @@ void FileLoaderWorker::loadFile(const QString &filePath) {
QTextStream in(&file);

while (!in.atEnd()) {
QString chunk = in.read(chunkSize); // Read text in chunks
bytesRead += chunk.toUtf8().size(); // Count the number of bytes read (UTF-8)
QString buffer = in.read(chunkSize); // Read the file chunk
if (buffer.isEmpty()) {
qDebug() << "Read an empty buffer. Stopping at bytesRead: " << bytesRead;
break;
}

bufferedContent += chunk;
bytesRead += buffer.toUtf8().size(); // Update the total bytes read
qDebug() << "Read chunk of size: " << buffer.size() << " Total bytesRead: " << bytesRead;

// Emit content when the buffer reaches the chunk size
if (bufferedContent.size() >= chunkSize) {
emit contentLoaded(bufferedContent);
bufferedContent.clear();
QCoreApplication::processEvents(); // Keep UI responsive
}
emit contentLoaded(buffer);

// Emit progress
int progress = static_cast<int>((bytesRead * 100) / fileSize);
// Update progress bar
int progress = static_cast<int>((bytesRead * 100) / m_fileSize);
qDebug() << "Updated progress: " << progress << "%";
emit loadingProgress(progress);
}

Expand Down