Skip to content

Commit

Permalink
Merge pull request #6 from yousefvand/dev
Browse files Browse the repository at this point in the history
improve loading files
  • Loading branch information
yousefvand authored Sep 30, 2024
2 parents 56d5144 + 895936d commit 8f8988b
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 102 deletions.
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

0 comments on commit 8f8988b

Please sign in to comment.