From 0b557fb021731221c0916555fdf42944032f8aaa Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Wed, 14 Aug 2024 22:34:19 +0330 Subject: [PATCH 1/7] redundant CodeEditor removed Signed-off-by: Remisa Yousefvand --- CodeEditor.cpp | 145 ------------------------------------- CodeEditor.h | 55 -------------- examples/1GBfile.sh | 9 ++- examples/file-generator.sh | 19 +++++ 4 files changed, 24 insertions(+), 204 deletions(-) delete mode 100644 CodeEditor.cpp delete mode 100644 CodeEditor.h create mode 100755 examples/file-generator.sh diff --git a/CodeEditor.cpp b/CodeEditor.cpp deleted file mode 100644 index 37ac40d..0000000 --- a/CodeEditor.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "CodeEditor.h" -#include -#include - -CodeEditor::CodeEditor(QWidget *parent) - : QPlainTextEdit(parent), lineNumberArea(new LineNumberArea(this)) -{ - // Set text color to black - QPalette p = this->palette(); - p.setColor(QPalette::Text, Qt::black); - this->setPalette(p); - - // Set background color to white - this->setStyleSheet("QPlainTextEdit { background-color: white; }"); - - // Set a monospaced font - QFont font; - font.setFamily("Sans Serif"); // Monospaced font - font.setFixedPitch(true); - font.setPointSize(12); // Adjust size if necessary - this->setFont(font); - - connect(this, &CodeEditor::blockCountChanged, this, &CodeEditor::updateLineNumberAreaWidth); - connect(this, &CodeEditor::updateRequest, this, &CodeEditor::updateLineNumberArea); - connect(this, &CodeEditor::cursorPositionChanged, this, &CodeEditor::highlightCurrentLine); - - updateLineNumberAreaWidth(0); - highlightCurrentLine(); -} - -int CodeEditor::lineNumberAreaWidth() -{ - int digits = 1; - int max = qMax(1, blockCount()); - while (max >= 10) { - max /= 10; - ++digits; - } - - // Ensure there's enough space for numbers - int space = 5 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits; - - return space; -} - -void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) -{ - setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); -} - -void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) -{ - if (dy) - lineNumberArea->scroll(0, dy); - else - lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); - - if (rect.contains(viewport()->rect())) - updateLineNumberAreaWidth(0); -} - -void CodeEditor::resizeEvent(QResizeEvent *e) -{ - QPlainTextEdit::resizeEvent(e); - - QRect cr = contentsRect(); - lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); -} - -void CodeEditor::highlightCurrentLine() -{ - QList extraSelections; - - if (!isReadOnly()) { - QTextEdit::ExtraSelection selection; - - QColor lineColor = QColor(Qt::yellow).lighter(160); - - selection.format.setBackground(lineColor); - selection.format.setProperty(QTextFormat::FullWidthSelection, true); - selection.cursor = textCursor(); - selection.cursor.clearSelection(); - extraSelections.append(selection); - } - - setExtraSelections(extraSelections); -} - -void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) -{ - QPainter painter(lineNumberArea); - painter.fillRect(event->rect(), Qt::lightGray); - - QTextBlock block = firstVisibleBlock(); - int blockNumber = block.blockNumber(); - int top = static_cast(blockBoundingGeometry(block).translated(contentOffset()).top()); - int bottom = top + static_cast(blockBoundingRect(block).height()); - - // Get the current line number - int currentLineNumber = textCursor().blockNumber(); - - // Loop through each block and draw line numbers - while (block.isValid() && top <= event->rect().bottom()) { - if (block.isVisible() && bottom >= event->rect().top()) { - QString number = QString::number(blockNumber + 1); - - // Check if this is the current line - if (blockNumber == currentLineNumber) { - // Set bold font for the current line number - QFont boldFont = painter.font(); - boldFont.setBold(true); - painter.setFont(boldFont); - painter.setPen(Qt::blue); // Optional: change color for current line number - } else { - // Use normal font for other line numbers - painter.setFont(QFont()); - painter.setPen(Qt::black); - } - - // Draw the line number - painter.drawText(-5, top, lineNumberArea->width(), fontMetrics().height(), - Qt::AlignRight | Qt::AlignVCenter, number); - - // Check if the block has wrapped lines - QTextLayout *layout = block.layout(); - for (int i = 0; i < layout->lineCount(); ++i) { - QTextLine line = layout->lineAt(i); - int lineTop = top + static_cast(line.y()); - int lineBottom = lineTop + static_cast(line.height()); - - // If the line is within the visible area and it's not the first line, draw a return symbol - if (i > 0 && lineTop >= event->rect().top() && lineBottom <= event->rect().bottom()) { - painter.setPen(Qt::black); // Set color to black for the return symbol - painter.drawText(-5, lineTop, lineNumberArea->width(), fontMetrics().height(), - Qt::AlignRight | Qt::AlignVCenter, "↩"); - } - } - } - - block = block.next(); - top = bottom; - bottom = top + static_cast(blockBoundingRect(block).height()); - ++blockNumber; - } -} diff --git a/CodeEditor.h b/CodeEditor.h deleted file mode 100644 index c1735d6..0000000 --- a/CodeEditor.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef CODEEDITOR_H -#define CODEEDITOR_H - -#include - -class QPaintEvent; -class QResizeEvent; -class QSize; -class QWidget; - -class LineNumberArea; - -class CodeEditor : public QPlainTextEdit -{ - Q_OBJECT - -public: - CodeEditor(QWidget *parent = nullptr); - - void lineNumberAreaPaintEvent(QPaintEvent *event); - int lineNumberAreaWidth(); - -protected: - void resizeEvent(QResizeEvent *event) override; - -private slots: - void updateLineNumberAreaWidth(int newBlockCount); - void highlightCurrentLine(); - void updateLineNumberArea(const QRect &rect, int dy); - -private: - QWidget *lineNumberArea; -}; - -class LineNumberArea : public QWidget -{ -public: - LineNumberArea(CodeEditor *editor) : QWidget(editor), codeEditor(editor) {} - - QSize sizeHint() const override - { - return QSize(codeEditor->lineNumberAreaWidth(), 0); - } - -protected: - void paintEvent(QPaintEvent *event) override - { - codeEditor->lineNumberAreaPaintEvent(event); - } - -private: - CodeEditor *codeEditor; -}; - -#endif // CODEEDITOR_H diff --git a/examples/1GBfile.sh b/examples/1GBfile.sh index 2e5a13f..7641cce 100755 --- a/examples/1GBfile.sh +++ b/examples/1GBfile.sh @@ -2,14 +2,15 @@ file="1GB.txt" -# Define the size in bytes (1 GB) -size=$((1 * 1024 * 1024 * 1024)) +# Define the size in byte +s (1 GB) size=$((1 * 1024 * 1024 * 1024)) -# Generate the random file -< /dev/urandom tr -dc 'a-zA-Z0-9 ' | head -c "$size" > "$file" +# Generate the random file < /dev/urandom +tr -dc 'a-zA-Z0-9 ' | head -c "$size" > "$file" echo "Done!" + diff --git a/examples/file-generator.sh b/examples/file-generator.sh new file mode 100755 index 0000000..8694bf4 --- /dev/null +++ b/examples/file-generator.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +file="100MB.txt" + +# Define the size in bytes (10 MB) +size=$((100 * 1024 * 1024)) + +# Pre-generate random data and then split it into lines +< /dev/urandom tr -dc 'a-zA-Z0-9 ' | head -c "$size" | awk -v min=40 -v max=400 ' +{ + while (length($0) > 0) { + len = int(min + rand() * (max - min + 1)) + print substr($0, 1, len) + $0 = substr($0, len + 1) + } +} +' > "$file" + +echo "Done! The file $file has been created." From b56825cfd1efe183ef3fb4ced6796417d2885a1d Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Wed, 14 Aug 2024 22:54:39 +0330 Subject: [PATCH 2/7] fixed C++ formatting from menu Signed-off-by: Remisa Yousefvand --- CMakeLists.txt.user | 72 ++++++++++++++++++++++----------------------- document.cpp | 6 ++++ document.h | 1 + mainwindow.cpp | 2 +- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 75db15f..2619e48 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -102,14 +102,14 @@ 2 false - -DCMAKE_BUILD_TYPE:STRING=Debug --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_GENERATOR:STRING=Ninja --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_GENERATOR:STRING=Ninja 0 /data/Code/Qt/Notepad--/build/Desktop-Debug @@ -159,14 +159,14 @@ 2 false - -DCMAKE_BUILD_TYPE:STRING=Release --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_GENERATOR:STRING=Ninja --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_GENERATOR:STRING=Ninja /data/Code/Qt/Notepad--/build/Desktop-Release @@ -215,14 +215,14 @@ 2 false - -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_GENERATOR:STRING=Ninja --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_GENERATOR:STRING=Ninja /data/Code/Qt/Notepad--/build/Desktop-RelWithDebInfo @@ -269,14 +269,14 @@ 2 false - -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_GENERATOR:STRING=Ninja --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_GENERATOR:STRING=Ninja 0 /data/Code/Qt/Notepad--/build/Desktop-Profile @@ -324,14 +324,14 @@ 2 false - -DCMAKE_BUILD_TYPE:STRING=MinSizeRel --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_GENERATOR:STRING=Ninja --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_GENERATOR:STRING=Ninja /data/Code/Qt/Notepad--/build/Desktop-MinSizeRel diff --git a/document.cpp b/document.cpp index 6185e6e..beeb87d 100644 --- a/document.cpp +++ b/document.cpp @@ -181,3 +181,9 @@ void Document::applySyntaxHighlighter() { syntaxHighlighter = new CppSyntaxHighlighter(editor->document()); } } + +void Document::applyCppFormatting() { + // Create a new CppSyntaxHighlighter and apply it to the editor + CppSyntaxHighlighter *highlighter = new CppSyntaxHighlighter(editor->document()); + highlighter->rehighlight(); // Rehighlight the current text in the editor +} diff --git a/document.h b/document.h index f9a5019..b927134 100644 --- a/document.h +++ b/document.h @@ -21,6 +21,7 @@ class Document : public QWidget { void saveFileAs(const QString &newFilePath); bool closeDocument(); void applySyntaxHighlighter(); + void applyCppFormatting(); signals: void saveError(const QString &error); // Signal for save errors diff --git a/mainwindow.cpp b/mainwindow.cpp index 7c06fb2..82f8753 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -104,7 +104,7 @@ void MainWindow::on_action_New_triggered() { void MainWindow::on_actionC_3_triggered() { Document *doc = qobject_cast(ui->documentsTab->currentWidget()); if (doc) { - doc->applySyntaxHighlighter(); // Now this is public + doc->applyCppFormatting(); // Apply C++ formatting to editor text } else { QMessageBox::warning(this, tr("Error"), tr("No document to format.")); } From c94ce470f067245e3d7ca0fd0bed9c8c63ec41fe Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Thu, 15 Aug 2024 19:30:01 +0330 Subject: [PATCH 3/7] go to line... implemented Signed-off-by: Remisa Yousefvand --- CMakeLists.txt.user | 62 ++++++++++++++++++------------------ document.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++-- document.h | 13 ++++++-- mainwindow.cpp | 60 ++++++++++++++++++++++------------- mainwindow.h | 2 ++ mainwindow.ui | 14 ++++++--- 6 files changed, 167 insertions(+), 61 deletions(-) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 2619e48..be91a4b 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -102,14 +102,14 @@ 2 false - -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=Debug --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_BUILD_TYPE:STRING=Debug 0 /data/Code/Qt/Notepad--/build/Desktop-Debug @@ -159,14 +159,14 @@ 2 false - -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=Release --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_BUILD_TYPE:STRING=Release /data/Code/Qt/Notepad--/build/Desktop-Release @@ -215,14 +215,14 @@ 2 false - -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo /data/Code/Qt/Notepad--/build/Desktop-RelWithDebInfo @@ -269,14 +269,14 @@ 2 false - -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo 0 /data/Code/Qt/Notepad--/build/Desktop-Profile @@ -324,14 +324,14 @@ 2 false - -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=MinSizeRel --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel /data/Code/Qt/Notepad--/build/Desktop-MinSizeRel diff --git a/document.cpp b/document.cpp index beeb87d..1577323 100644 --- a/document.cpp +++ b/document.cpp @@ -13,6 +13,7 @@ #include #include #include +#include Document::Document(const QString &filePath, QWidget *parent) : QWidget(parent), m_filePath(filePath), m_fileSize(0), m_startPointer(0), m_endPointer(0), syntaxHighlighter(nullptr) { @@ -34,6 +35,20 @@ Document::Document(const QString &filePath, QWidget *parent) m_currentText.clear(); } +// Setter for Language +void Document::setLanguage(const QString &language) { + m_language = language; + + if (language == "C++") { + applyCppFormatting(); // Automatically apply C++ formatting when language is set to C++ + } +} + +// Getter for Language +QString Document::getLanguage() const { + return m_language; +} + QString Document::filePath() const { return m_filePath; } @@ -124,7 +139,9 @@ void Document::saveFile() { } void Document::saveFileAs(const QString &newFilePath) { - if (newFilePath.isEmpty()) return; + if (newFilePath.isEmpty()) { + return; // User canceled the Save As dialog, do nothing + } m_filePath = newFilePath; saveFile(); } @@ -150,6 +167,11 @@ QByteArray Document::calculateModifiedMD5() { } bool Document::closeDocument() { + // Special case: if the document is empty, allow closing without checking the hash + if (editor->toPlainText().isEmpty() && m_filePath.isEmpty()) { + return true; + } + QByteArray currentHash = calculateModifiedMD5(); if (currentHash != m_originalHash) { @@ -159,7 +181,11 @@ bool Document::closeDocument() { QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (reply == QMessageBox::Save) { - saveFile(); + QString savePath = QFileDialog::getSaveFileName(this, tr("Save File As"), "", tr("Text Files (*.txt);;All Files (*)")); + if (savePath.isEmpty()) { + return false; // User canceled the Save As dialog, don't close the document + } + saveFileAs(savePath); return true; } else if (reply == QMessageBox::Discard) { return true; // Allow closing without saving @@ -177,7 +203,8 @@ void Document::applySyntaxHighlighter() { syntaxHighlighter = nullptr; } - if (m_fileExtension == "cpp" || m_fileExtension == "cxx") { + if (m_fileExtension == "cpp" || m_fileExtension == "cxx" + || m_fileExtension == "CPP" || m_fileExtension == "CXX") { syntaxHighlighter = new CppSyntaxHighlighter(editor->document()); } } @@ -187,3 +214,47 @@ void Document::applyCppFormatting() { CppSyntaxHighlighter *highlighter = new CppSyntaxHighlighter(editor->document()); highlighter->rehighlight(); // Rehighlight the current text in the editor } + +void Document::goToLineNumberInEditor() { + bool ok; + int lineNumber = QInputDialog::getInt(this, tr("Go to Line"), + tr("Line number:"), 1, 1, INT_MAX, 1, &ok); + + if (ok) { + QTextCursor cursor = editor->textCursor(); + cursor.movePosition(QTextCursor::Start); // Move to the start of the editor + + // Move the cursor down to the desired line number + for (int i = 1; i < lineNumber; ++i) { + cursor.movePosition(QTextCursor::Down); + + // Check if the cursor has moved to the end of the document + if (cursor.atEnd()) { + QMessageBox::warning(this, tr("Line Number Out of Bounds"), + tr("The specified line number is outside the bounds of the file.")); + return; // Exit if the line number is out of bounds + } + } + + editor->setTextCursor(cursor); + editor->ensureCursorVisible(); // Ensure the cursor is visible after moving + } +} + +void Document::goToLineNumberInText(QWidget* parent) { + bool ok; + int lineNumber = QInputDialog::getInt(parent, tr("Go to Line"), + tr("Line number:"), 1, 1, INT_MAX, 1, &ok); + if (ok) { + QTextCursor cursor = editor->textCursor(); + cursor.movePosition(QTextCursor::Start); + + int currentLineNumber = 0; + while (currentLineNumber < lineNumber - 1 && !cursor.atEnd()) { + cursor.movePosition(QTextCursor::NextBlock); + ++currentLineNumber; + } + + editor->setTextCursor(cursor); + } +} diff --git a/document.h b/document.h index b927134..c820fe2 100644 --- a/document.h +++ b/document.h @@ -16,12 +16,18 @@ class Document : public QWidget { Document(const QString &filePath, QWidget *parent = nullptr); QString filePath() const; void setFilePath(const QString &path); + void setLanguage(const QString &language); + QString getLanguage() const; void openFile(const QString &filePath); void saveFile(); void saveFileAs(const QString &newFilePath); bool closeDocument(); - void applySyntaxHighlighter(); - void applyCppFormatting(); + //void goToLineNumberInText(int lineNumber); + void goToLineNumberInText(QWidget* parent); // Pass QWidget for the parent window + + + // New method to go to a specific line number + void goToLineNumberInEditor(); signals: void saveError(const QString &error); // Signal for save errors @@ -33,6 +39,8 @@ class Document : public QWidget { void trackChanges(); QByteArray calculateMD5Stream(QFile *file); QByteArray calculateModifiedMD5(); + void applySyntaxHighlighter(); + void applyCppFormatting(); QString m_filePath; QString m_fileExtension; @@ -45,6 +53,7 @@ class Document : public QWidget { QByteArray m_originalHash; QMap m_changedSegments; // Store changed segments QString m_currentText; // Store current text in the editor + QString m_language; // New member to store the language }; #endif // DOCUMENT_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 82f8753..abf852b 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -11,20 +11,17 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); - // Remove the initial empty tab if it exists if (ui->documentsTab->count() > 0) { - ui->documentsTab->removeTab(0); // Remove the first tab + ui->documentsTab->removeTab(0); } - // Create the initial "Untitled Document" tab - Document *firstDoc = new Document("", this); // Pass an empty string for the file path + Document *firstDoc = new Document("", this); ui->documentsTab->addTab(firstDoc, "Untitled Document"); - ui->documentsTab->setCurrentWidget(firstDoc); // Set the first tab as current + ui->documentsTab->setCurrentWidget(firstDoc); - // Open files passed as command line arguments QStringList filePaths = QCoreApplication::arguments(); for (const QString &filePath : filePaths) { - if (filePath != QCoreApplication::applicationFilePath()) { // Skip the application path + if (filePath != QCoreApplication::applicationFilePath()) { openDocument(filePath); } } @@ -35,18 +32,15 @@ MainWindow::~MainWindow() { } void MainWindow::openDocument(const QString &filePath) { - // Check if there is an empty tab to reuse if (ui->documentsTab->count() > 0) { Document *existingDoc = qobject_cast(ui->documentsTab->widget(0)); if (existingDoc && existingDoc->filePath().isEmpty()) { - // Reuse the existing empty tab - existingDoc->openFile(filePath); // Open the file in the existing tab - ui->documentsTab->setTabText(0, QFileInfo(filePath).fileName()); // Update the tab title - return; // Exit as we've reused the tab + existingDoc->openFile(filePath); + ui->documentsTab->setTabText(0, QFileInfo(filePath).fileName()); + return; } } - // If no empty tab exists, create a new document tab Document *newDoc = new Document(filePath, this); ui->documentsTab->addTab(newDoc, QFileInfo(filePath).fileName()); ui->documentsTab->setCurrentWidget(newDoc); @@ -62,7 +56,7 @@ void MainWindow::on_action_Open_triggered() { void MainWindow::on_action_Save_triggered() { Document *doc = qobject_cast(ui->documentsTab->currentWidget()); if (doc) { - doc->saveFile(); // Call saveFile method of Document + doc->saveFile(); } else { QMessageBox::warning(this, tr("Error"), tr("No document to save.")); } @@ -73,7 +67,7 @@ void MainWindow::on_actionSave_As_triggered() { if (doc) { QString filePath = QFileDialog::getSaveFileName(this, tr("Save File As"), "", tr("Text Files (*.txt);;All Files (*)")); if (!filePath.isEmpty()) { - doc->saveFileAs(filePath); // Call saveFileAs method of Document + doc->saveFileAs(filePath); } } else { QMessageBox::warning(this, tr("Error"), tr("No document to save.")); @@ -81,22 +75,19 @@ void MainWindow::on_actionSave_As_triggered() { } void MainWindow::on_documentsTab_tabCloseRequested(int index) { - // Get the current document from the tab Document *doc = qobject_cast(ui->documentsTab->widget(index)); if (doc) { - // Call the closeDocument method to handle the closing logic - bool canClose = doc->closeDocument(); // This method should return true if it's okay to close + bool canClose = doc->closeDocument(); if (canClose) { - // If the document has been closed, remove the tab ui->documentsTab->removeTab(index); } } } void MainWindow::on_action_New_triggered() { - Document *newDoc = new Document("", this); // Pass an empty string for the file path + Document *newDoc = new Document("", this); ui->documentsTab->addTab(newDoc, "Untitled Document"); ui->documentsTab->setCurrentWidget(newDoc); } @@ -104,8 +95,35 @@ void MainWindow::on_action_New_triggered() { void MainWindow::on_actionC_3_triggered() { Document *doc = qobject_cast(ui->documentsTab->currentWidget()); if (doc) { - doc->applyCppFormatting(); // Apply C++ formatting to editor text + doc->setLanguage("C++"); // Set language to C++, which triggers the formatting } else { QMessageBox::warning(this, tr("Error"), tr("No document to format.")); } } + +void MainWindow::on_action_Go_to_line_in_editor_triggered() +{ + Document *doc = qobject_cast(ui->documentsTab->currentWidget()); + if (doc) { + doc->goToLineNumberInEditor (); + } else { + QMessageBox::warning(this, tr("Error"), tr("No document open.")); + } +} + +void MainWindow::on_action_Go_to_line_in_text_triggered() { + Document* doc = qobject_cast(ui->documentsTab->currentWidget()); // If using a tab widget to manage documents + if (doc) { + doc->goToLineNumberInText(this); + } else { + QMessageBox::warning(this, tr("No Document"), tr("There is no document open.")); + } +} + + + + + + + + diff --git a/mainwindow.h b/mainwindow.h index 8d0f8ed..dab332a 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -21,6 +21,8 @@ private slots: void on_documentsTab_tabCloseRequested(int index); void on_action_New_triggered(); void on_actionC_3_triggered(); + void on_action_Go_to_line_in_text_triggered(); + void on_action_Go_to_line_in_editor_triggered(); private: Ui::MainWindow *ui; diff --git a/mainwindow.ui b/mainwindow.ui index 16786dd..7a2eb18 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -105,7 +105,8 @@ - + + @@ -401,7 +402,7 @@ - Find &previoud + Find &previous @@ -409,9 +410,9 @@ &Replace... - + - &Go to line... + &Go to line in editor... @@ -730,6 +731,11 @@ Cython + + + G&o to line in text... + + From fe51732c951930743294e6b9953d5eb5c92386ff Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Thu, 15 Aug 2024 22:52:45 +0330 Subject: [PATCH 4/7] close & close all Signed-off-by: Remisa Yousefvand --- CMakeLists.txt.user | 52 ++++++++++++++++++++++----------------------- mainwindow.cpp | 18 +++++++++++++--- mainwindow.h | 4 ++++ 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index be91a4b..1b8c256 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -102,14 +102,14 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -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 --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} 0 /data/Code/Qt/Notepad--/build/Desktop-Debug @@ -159,14 +159,14 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -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 --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} /data/Code/Qt/Notepad--/build/Desktop-Release @@ -215,14 +215,14 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -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=RelWithDebInfo -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} /data/Code/Qt/Notepad--/build/Desktop-RelWithDebInfo @@ -269,14 +269,14 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -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=RelWithDebInfo -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} 0 /data/Code/Qt/Notepad--/build/Desktop-Profile @@ -324,14 +324,14 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -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=MinSizeRel -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} /data/Code/Qt/Notepad--/build/Desktop-MinSizeRel diff --git a/mainwindow.cpp b/mainwindow.cpp index abf852b..b49925c 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -112,7 +112,7 @@ void MainWindow::on_action_Go_to_line_in_editor_triggered() } void MainWindow::on_action_Go_to_line_in_text_triggered() { - Document* doc = qobject_cast(ui->documentsTab->currentWidget()); // If using a tab widget to manage documents + Document* doc = qobject_cast(ui->documentsTab->currentWidget()); if (doc) { doc->goToLineNumberInText(this); } else { @@ -120,10 +120,22 @@ void MainWindow::on_action_Go_to_line_in_text_triggered() { } } +void MainWindow::on_action_Close_triggered() +{ + int activeTabIndex = ui->documentsTab->currentIndex(); // Get the index of the active tab + if (activeTabIndex != -1) { // Check if there's an active tab + on_documentsTab_tabCloseRequested(activeTabIndex); // Reuse the existing close logic + } +} +void MainWindow::on_actionC_lose_all_triggered() +{ + int tabCount = ui->documentsTab->count(); - - + for (int i = tabCount - 1; i >= 0; --i) { + on_documentsTab_tabCloseRequested(i); + } +} diff --git a/mainwindow.h b/mainwindow.h index dab332a..19230a8 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -24,6 +24,10 @@ private slots: void on_action_Go_to_line_in_text_triggered(); void on_action_Go_to_line_in_editor_triggered(); + void on_action_Close_triggered(); + + void on_actionC_lose_all_triggered(); + private: Ui::MainWindow *ui; void openDocument(const QString &filePath); From 70ab4ff39e3de26e59b538bfb5a402614b2707ba Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Sat, 17 Aug 2024 04:17:37 +0330 Subject: [PATCH 5/7] Language menu completed (except XYZ) Signed-off-by: Remisa Yousefvand --- CMakeLists.txt.user | 62 +-- mainwindow.ui | 958 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 878 insertions(+), 142 deletions(-) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 1b8c256..98fc240 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -102,14 +102,14 @@ 2 false - -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} 0 /data/Code/Qt/Notepad--/build/Desktop-Debug @@ -159,14 +159,14 @@ 2 false - -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} /data/Code/Qt/Notepad--/build/Desktop-Release @@ -215,14 +215,14 @@ 2 false - -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} /data/Code/Qt/Notepad--/build/Desktop-RelWithDebInfo @@ -269,14 +269,14 @@ 2 false - -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} 0 /data/Code/Qt/Notepad--/build/Desktop-Profile @@ -324,14 +324,14 @@ 2 false - -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_BUILD_TYPE:STRING=MinSizeRel -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} /data/Code/Qt/Notepad--/build/Desktop-MinSizeRel diff --git a/mainwindow.ui b/mainwindow.ui index 7a2eb18..9e75a46 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -161,28 +161,252 @@ - - + + + A + + + + + + + + + B + + + + + + + D + + + + + + + + + + + + E + + + + + + + + + + + + + F + + + + + + + + + + G + + + + + + + + + H + + + + + + + + + + + I + + + + + + J + + + + + + + + + + + + + + K + + + + + + L + + + + + + + + + M + + + + + + + + + + + + + + + + N + + + + + + + + O + + + + + + + + + P + + + + + + + + + + + + + + + + + + T + + + + + + + + + + + + + + + + + + R + + + + + + + + + + + S + + + + + + + + + + + + + + + + + + + + + + + W + + + + + + V + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + @@ -508,232 +732,744 @@ C&onvert to... - + + + &Prefrences... + + + + + &Show Menubar + + + + + S&how Toolbar + + + + + Run... + + + + + Modify run commands + + + + + &Open a new window + + + + + &About Notepad-- + + + + + About &Qt + + + + + C + + + + + Clojure + + + + + ClojureScript + + + + + Closure Stylesheets (GSS) + + + + + CMake + + + + + Cobol + + + + + Coffee Script + + + + + Common Lisp + + + + + C++ + + + - A + Crystal - + - B + C# - + + + CSS + + + + + Cypher + + + + + Cython + + + + + G&o to line in text... + + + + + APL + + + + + ASN.1 + + + + + ASP.NET + + + + + Asterisk + + + + + Bash + + + + + Brainfuck + + + D - + + + Dart + + + + + diff + + + + + Django + + + + + Dockerfile + + + + + DTD + + + + + Dylaan + + + + + EBNF + + + + + ECL + + + + + edn + + + + + Eiffel + + + + + Embedded Javascript + + + + + Elm + + + + + Embedded Ruby + + + + + Erlang + + + + + Factor + + + + + FCL + + + + + Forth + + + + + Fortran + + + + + F# + + + + + Gas + + + + + Gherkin + + + + + Go + + + + + Groovy + + + + + HAML + + + + + Haskell + + + + + Haskell (Literate) + + + + + Haxe + + + + + HTML + + + + + HTTP + + + + + IDL + + + + + Jade + + + + + Java + + + + + JavaScript + + + + + Jinja2 + + + + + JSON + + + + + JSON-LD + + + + + JavaServer Pages + + + + + JSX + + + + + Julia + + + + + Kotlin + + + + + LaTeX + + + + + LESS + + + + + Livescript + + + + + Lua + + + + + m4 + + + + + Makefile + + + + + MariaDB + + + + + Markdown (GitHub-flavour) + + + + + Mathematica + + + + + mbox + + + + + mIRC + + + + + Modelica + + + + + mscgen + + + + + msgenny + + + + + MUMPS + + + + + Nginx + + + + + NSIS + + + + + NTriples + + + + + Objective C + + + + + OCaml + + + + + Octave + + + + + Oz + + + + + Pascal + + + + + PEG.js + + + + + Perl + + + + + PGP + + + + + PHP + + + + + Pig + + + + + PLSQL + + + + + PowerShell + + + + + Properties files + + + + + ProtoBuf + + + - E + Pug - + - F + Puppet - + - G + Python - + - H + Text - + - I + Tcl - + - J + Textile - + - K + TiddlyWiki - + - L + Tiki wiki - + - M + TOML - + - N + Tornado - + - O + troff - + - P + TTCN - + - T + TTCN-CFG - + + + Turtle + + + + + Twig + + + + + TypeScript + + + R - + - S + RPM Changes - + - V + RPM Spec - + - W + reStructuredText - + - Y + Ruby - + - Z + Rust - - QAction::MenuRole::NoRole + + + + SAS - + - &Prefrences... + Sass - + - &Show Menubar + Scala - + - S&how Toolbar + Scheme - + - Run... + SCSS - + - Modify run commands + Sieve - + - &Open a new window + Slim - + - &About Notepad-- + Smalltalk - + - About &Qt + Smarty - + - C + Solr - + - Clojure + Soy - + - ClojureScript + SPARQL - + - Closure Stylesheets (GSS) + Spreadsheet - + - CMake + SQL - + - Cobol + Squirrel - + - Coffee Script + sTeX - + - Common Lisp + Swift - + - C++ + SysstemVerilog - + - Crystal + Web IDL - + - C# + VB.NET - + - CSS + VBScript - + - Cypher + Velocity - + - Cython + Verilog - + - G&o to line in text... + VHDL From ce2f5f7a7fadb5bb576bcdbae3ab2904e9ce5022 Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Sun, 25 Aug 2024 03:15:30 +0330 Subject: [PATCH 6/7] Separation of concerns & support of Python Signed-off-by: Remisa Yousefvand --- CMakeLists.txt | 24 ++-- CMakeLists.txt.user | 62 ++++----- cppsyntaxhighlighter.cpp | 88 ------------- document.cpp | 72 +++++------ document.h | 27 ++-- examples/{Notepad--1.cpp => Hello World.cpp} | 2 +- examples/Hello World.py | 1 + examples/Hello World.txt | 1 + examples/Hello World1.txt | 1 - examples/Hello World2.txt | 1 - examples/Hello World3.txt | 1 - examples/Notepad--2.cpp | 6 - examples/Notepad--3.cpp | 6 - languages/cppsyntaxhighlighter.cpp | 117 +++++++++++++++++ .../cppsyntaxhighlighter.h | 3 +- languages/languagemanager.cpp | 24 ++++ languages/languagemanager.h | 14 ++ languages/pythonsyntaxhighlighter.cpp | 121 ++++++++++++++++++ languages/pythonsyntaxhighlighter.h | 32 +++++ mainwindow.cpp | 31 +++-- mainwindow.h | 2 + 21 files changed, 424 insertions(+), 212 deletions(-) delete mode 100644 cppsyntaxhighlighter.cpp rename examples/{Notepad--1.cpp => Hello World.cpp} (59%) create mode 100644 examples/Hello World.py create mode 100644 examples/Hello World.txt delete mode 100644 examples/Hello World1.txt delete mode 100644 examples/Hello World2.txt delete mode 100644 examples/Hello World3.txt delete mode 100644 examples/Notepad--2.cpp delete mode 100644 examples/Notepad--3.cpp create mode 100644 languages/cppsyntaxhighlighter.cpp rename cppsyntaxhighlighter.h => languages/cppsyntaxhighlighter.h (92%) create mode 100644 languages/languagemanager.cpp create mode 100644 languages/languagemanager.h create mode 100644 languages/pythonsyntaxhighlighter.cpp create mode 100644 languages/pythonsyntaxhighlighter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e25acf..6006c99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,11 +16,19 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools) set(TS_FILES Notepad--_en_GB.ts) set(PROJECT_SOURCES - main.cpp - mainwindow.cpp - mainwindow.h - mainwindow.ui - ${TS_FILES} + main.cpp + mainwindow.cpp + mainwindow.h + mainwindow.ui + document.cpp + document.h + languages/cppsyntaxhighlighter.cpp + languages/cppsyntaxhighlighter.h + languages/pythonsyntaxhighlighter.cpp + languages/pythonsyntaxhighlighter.h + languages/languagemanager.cpp + languages/languagemanager.h + ${TS_FILES} ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) @@ -44,9 +52,9 @@ else() else() add_executable(Notepad-- ${PROJECT_SOURCES} - codeeditor.h codeeditor.cpp - document.h document.cpp - cppsyntaxhighlighter.h cppsyntaxhighlighter.cpp + codeeditor.h + codeeditor.cpp + languages/pythonsyntaxhighlighter.h languages/pythonsyntaxhighlighter.cpp ) endif() diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 98fc240..f2668b9 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -102,14 +102,14 @@ 2 false - -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_BUILD_TYPE:STRING=Debug --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} 0 /data/Code/Qt/Notepad--/build/Desktop-Debug @@ -159,14 +159,14 @@ 2 false - -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_BUILD_TYPE:STRING=Release --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} /data/Code/Qt/Notepad--/build/Desktop-Release @@ -215,14 +215,14 @@ 2 false - -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} /data/Code/Qt/Notepad--/build/Desktop-RelWithDebInfo @@ -269,14 +269,14 @@ 2 false - -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} 0 /data/Code/Qt/Notepad--/build/Desktop-Profile @@ -324,14 +324,14 @@ 2 false - -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_BUILD_TYPE:STRING=MinSizeRel --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} /data/Code/Qt/Notepad--/build/Desktop-MinSizeRel diff --git a/cppsyntaxhighlighter.cpp b/cppsyntaxhighlighter.cpp deleted file mode 100644 index ee63123..0000000 --- a/cppsyntaxhighlighter.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "cppsyntaxhighlighter.h" - -CppSyntaxHighlighter::CppSyntaxHighlighter(QTextDocument *parent) - : QSyntaxHighlighter(parent) { - - // Keywords - QStringList keywordPatterns = { - "\\bchar\\b", "\\bclass\\b", "\\bconst\\b", "\\bdouble\\b", "\\benum\\b", - "\\bexplicit\\b", "\\bfriend\\b", "\\binline\\b", "\\bint\\b", "\\blong\\b", - "\\bnamespace\\b", "\\boperator\\b", "\\bprivate\\b", "\\bprotected\\b", "\\bpublic\\b", - "\\bshort\\b", "\\bsignals\\b", "\\bsigned\\b", "\\bslots\\b", "\\bstatic\\b", - "\\bstruct\\b", "\\btemplate\\b", "\\btypedef\\b", "\\btypename\\b", "\\bunion\\b", - "\\bunsigned\\b", "\\bvirtual\\b", "\\bvoid\\b", "\\bvolatile\\b" - }; - - keywordFormat.setForeground(Qt::blue); - for (const QString &pattern : keywordPatterns) { - HighlightingRule rule; - rule.pattern = QRegularExpression(pattern); - rule.format = keywordFormat; - highlightingRules.append(rule); - } - - // Class names - classFormat.setFontWeight(QFont::Bold); - classFormat.setForeground(Qt::darkMagenta); - HighlightingRule classRule; - classRule.pattern = QRegularExpression("\\bQ[A-Za-z]+\\b"); - classRule.format = classFormat; - highlightingRules.append(classRule); - - // Single line comments - singleLineCommentFormat.setForeground(Qt::darkGreen); - HighlightingRule singleLineCommentRule; - singleLineCommentRule.pattern = QRegularExpression("//[^\n]*"); - singleLineCommentRule.format = singleLineCommentFormat; - highlightingRules.append(singleLineCommentRule); - - // Multi-line comments - multiLineCommentFormat.setForeground(Qt::darkGreen); - commentStartExpression = QRegularExpression("/\\*"); - commentEndExpression = QRegularExpression("\\*/"); - - // Quotation marks - quotationFormat.setForeground(Qt::darkRed); - HighlightingRule quotationRule; - quotationRule.pattern = QRegularExpression("\".*\""); - quotationRule.format = quotationFormat; - highlightingRules.append(quotationRule); - - // Function names - functionFormat.setFontItalic(true); - functionFormat.setForeground(Qt::blue); - HighlightingRule functionRule; - functionRule.pattern = QRegularExpression("\\b[A-Za-z0-9_]+(?=\\()"); - functionRule.format = functionFormat; - highlightingRules.append(functionRule); -} - -void CppSyntaxHighlighter::highlightBlock(const QString &text) { - for (const HighlightingRule &rule : qAsConst(highlightingRules)) { - QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); - while (matchIterator.hasNext()) { - QRegularExpressionMatch match = matchIterator.next(); - setFormat(match.capturedStart(), match.capturedLength(), rule.format); - } - } - - setCurrentBlockState(0); - - int startIndex = 0; - if (previousBlockState() != 1) - startIndex = text.indexOf(commentStartExpression); - - while (startIndex >= 0) { - QRegularExpressionMatch match = commentEndExpression.match(text, startIndex); - int endIndex = match.capturedStart(); - int commentLength = 0; - if (endIndex == -1) { - setCurrentBlockState(1); - commentLength = text.length() - startIndex; - } else { - commentLength = endIndex - startIndex + match.capturedLength(); - } - setFormat(startIndex, commentLength, multiLineCommentFormat); - startIndex = text.indexOf(commentStartExpression, startIndex + commentLength); - } -} diff --git a/document.cpp b/document.cpp index 1577323..baacd2c 100644 --- a/document.cpp +++ b/document.cpp @@ -1,19 +1,11 @@ #include "document.h" #include "codeeditor.h" -#include "cppsyntaxhighlighter.h" -#include -#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include +#include Document::Document(const QString &filePath, QWidget *parent) : QWidget(parent), m_filePath(filePath), m_fileSize(0), m_startPointer(0), m_endPointer(0), syntaxHighlighter(nullptr) { @@ -35,28 +27,40 @@ Document::Document(const QString &filePath, QWidget *parent) m_currentText.clear(); } -// Setter for Language -void Document::setLanguage(const QString &language) { - m_language = language; +void Document::setFilePath(const QString &path) { + m_filePath = path; + m_fileExtension = QFileInfo(path).suffix(); + qDebug() << "File opened with extension:" << m_fileExtension; + QString language = LanguageManager::getLanguageFromExtension(m_fileExtension); + qDebug() << "Detected language:" << language; + applySyntaxHighlighter(language); +} - if (language == "C++") { - applyCppFormatting(); // Automatically apply C++ formatting when language is set to C++ - } +QString Document::filePath() const { + return m_filePath; } -// Getter for Language QString Document::getLanguage() const { return m_language; } -QString Document::filePath() const { - return m_filePath; -} +void Document::applySyntaxHighlighter(const QString &language) { + if (syntaxHighlighter) { + delete syntaxHighlighter; + syntaxHighlighter = nullptr; + } -void Document::setFilePath(const QString &path) { - m_filePath = path; - m_fileExtension = QFileInfo(path).suffix(); - applySyntaxHighlighter(); + m_language = language; // Set the current language based on the argument + + // Use LanguageManager to create the appropriate highlighter based on the language directly + syntaxHighlighter = LanguageManager::createHighlighterForExtension(language, editor->document()); + + if (syntaxHighlighter) { + syntaxHighlighter->rehighlight(); // Rehighlight the current text in the editor + qDebug() << "Applied syntax highlighter for language:" << language; + } else { + qDebug() << "No syntax highlighter found for language:" << language; + } } void Document::openFile(const QString &filePath) { @@ -197,24 +201,6 @@ bool Document::closeDocument() { return true; // No unsaved changes, allow closing } -void Document::applySyntaxHighlighter() { - if (syntaxHighlighter) { - delete syntaxHighlighter; - syntaxHighlighter = nullptr; - } - - if (m_fileExtension == "cpp" || m_fileExtension == "cxx" - || m_fileExtension == "CPP" || m_fileExtension == "CXX") { - syntaxHighlighter = new CppSyntaxHighlighter(editor->document()); - } -} - -void Document::applyCppFormatting() { - // Create a new CppSyntaxHighlighter and apply it to the editor - CppSyntaxHighlighter *highlighter = new CppSyntaxHighlighter(editor->document()); - highlighter->rehighlight(); // Rehighlight the current text in the editor -} - void Document::goToLineNumberInEditor() { bool ok; int lineNumber = QInputDialog::getInt(this, tr("Go to Line"), diff --git a/document.h b/document.h index c820fe2..d0601b7 100644 --- a/document.h +++ b/document.h @@ -5,9 +5,10 @@ #include #include #include +#include +#include "languages/languagemanager.h" -class CodeEditor; // Forward declaration -class CppSyntaxHighlighter; // Forward declaration +class CodeEditor; class Document : public QWidget { Q_OBJECT @@ -16,22 +17,18 @@ class Document : public QWidget { Document(const QString &filePath, QWidget *parent = nullptr); QString filePath() const; void setFilePath(const QString &path); - void setLanguage(const QString &language); QString getLanguage() const; void openFile(const QString &filePath); void saveFile(); void saveFileAs(const QString &newFilePath); bool closeDocument(); - //void goToLineNumberInText(int lineNumber); - void goToLineNumberInText(QWidget* parent); // Pass QWidget for the parent window - - - // New method to go to a specific line number + void goToLineNumberInText(QWidget* parent); void goToLineNumberInEditor(); + void applySyntaxHighlighter(const QString &language); signals: - void saveError(const QString &error); // Signal for save errors - void saveCompleted(); // Signal for successful save + void saveError(const QString &error); + void saveCompleted(); private: void loadContent(); @@ -39,21 +36,19 @@ class Document : public QWidget { void trackChanges(); QByteArray calculateMD5Stream(QFile *file); QByteArray calculateModifiedMD5(); - void applySyntaxHighlighter(); - void applyCppFormatting(); QString m_filePath; QString m_fileExtension; QFile m_file; CodeEditor *editor; - CppSyntaxHighlighter *syntaxHighlighter; + QSyntaxHighlighter *syntaxHighlighter; qint64 m_fileSize; qint64 m_startPointer; qint64 m_endPointer; QByteArray m_originalHash; - QMap m_changedSegments; // Store changed segments - QString m_currentText; // Store current text in the editor - QString m_language; // New member to store the language + QMap m_changedSegments; + QString m_currentText; + QString m_language; }; #endif // DOCUMENT_H diff --git a/examples/Notepad--1.cpp b/examples/Hello World.cpp similarity index 59% rename from examples/Notepad--1.cpp rename to examples/Hello World.cpp index 7cff662..7867d62 100644 --- a/examples/Notepad--1.cpp +++ b/examples/Hello World.cpp @@ -1,6 +1,6 @@ #include int main() { - std::cout << "Hello World1!"; + std::cout << "Hello World!"; return 0; } diff --git a/examples/Hello World.py b/examples/Hello World.py new file mode 100644 index 0000000..f301245 --- /dev/null +++ b/examples/Hello World.py @@ -0,0 +1 @@ +print("Hello World!") diff --git a/examples/Hello World.txt b/examples/Hello World.txt new file mode 100644 index 0000000..557db03 --- /dev/null +++ b/examples/Hello World.txt @@ -0,0 +1 @@ +Hello World diff --git a/examples/Hello World1.txt b/examples/Hello World1.txt deleted file mode 100644 index d111384..0000000 --- a/examples/Hello World1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World1 diff --git a/examples/Hello World2.txt b/examples/Hello World2.txt deleted file mode 100644 index b2b6f00..0000000 --- a/examples/Hello World2.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World2 diff --git a/examples/Hello World3.txt b/examples/Hello World3.txt deleted file mode 100644 index f64861f..0000000 --- a/examples/Hello World3.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World3 diff --git a/examples/Notepad--2.cpp b/examples/Notepad--2.cpp deleted file mode 100644 index 3dcafa5..0000000 --- a/examples/Notepad--2.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() { - std::cout << "Hello World2!"; - return 0; -} diff --git a/examples/Notepad--3.cpp b/examples/Notepad--3.cpp deleted file mode 100644 index 8de1be3..0000000 --- a/examples/Notepad--3.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() { - std::cout << "Hello World3!"; - return 0; -} diff --git a/languages/cppsyntaxhighlighter.cpp b/languages/cppsyntaxhighlighter.cpp new file mode 100644 index 0000000..9938676 --- /dev/null +++ b/languages/cppsyntaxhighlighter.cpp @@ -0,0 +1,117 @@ +#include "cppsyntaxhighlighter.h" + +CppSyntaxHighlighter::CppSyntaxHighlighter(QTextDocument *parent) + : QSyntaxHighlighter(parent) { + + // Define keyword formats + keywordFormat.setForeground(Qt::blue); + keywordFormat.setFontWeight(QFont::Bold); + + typeFormat.setForeground(Qt::darkMagenta); + typeFormat.setFontWeight(QFont::Bold); + + preprocessorFormat.setForeground(Qt::darkYellow); + preprocessorFormat.setFontWeight(QFont::Bold); + + // List of C++ keywords + QStringList keywordPatterns = { + "\\balignas\\b", "\\balignof\\b", "\\band\\b", "\\band_eq\\b", "\\basm\\b", "\\batomic_cancel\\b", + "\\batomic_commit\\b", "\\batomic_noexcept\\b", "\\bauto\\b", "\\bbreak\\b", "\\bcase\\b", "\\bcatch\\b", + "\\bchar\\b", "\\bchar8_t\\b", "\\bchar16_t\\b", "\\bchar32_t\\b", "\\bclass\\b", "\\bcompl\\b", + "\\bconcept\\b", "\\bconst\\b", "\\bconsteval\\b", "\\bconstexpr\\b", "\\bconstinit\\b", "\\bconst_cast\\b", + "\\bcontinue\\b", "\\bco_await\\b", "\\bco_return\\b", "\\bco_yield\\b", "\\bdecltype\\b", "\\bdefault\\b", + "\\bdelete\\b", "\\bdo\\b", "\\bdouble\\b", "\\bdynamic_cast\\b", "\\belse\\b", "\\benum\\b", "\\bexplicit\\b", + "\\bexport\\b", "\\bextern\\b", "\\bfalse\\b", "\\bfloat\\b", "\\bfor\\b", "\\bfriend\\b", "\\bgoto\\b", + "\\bif\\b", "\\binline\\b", "\\bint\\b", "\\blong\\b", "\\bmutable\\b", "\\bnamespace\\b", "\\bnew\\b", + "\\bnoexcept\\b", "\\bnot\\b", "\\bnot_eq\\b", "\\bnullptr\\b", "\\boperator\\b", "\\bor\\b", "\\bor_eq\\b", + "\\bprivate\\b", "\\bprotected\\b", "\\bpublic\\b", "\\bregister\\b", "\\breinterpret_cast\\b", "\\brequires\\b", + "\\breturn\\b", "\\bshort\\b", "\\bsigned\\b", "\\bsizeof\\b", "\\bstatic\\b", "\\bstatic_assert\\b", + "\\bstatic_cast\\b", "\\bstruct\\b", "\\bswitch\\b", "\\bsynchronized\\b", "\\btemplate\\b", "\\bthis\\b", + "\\bthread_local\\b", "\\bthrow\\b", "\\btrue\\b", "\\btry\\b", "\\btypedef\\b", "\\btypeid\\b", + "\\btypename\\b", "\\bunion\\b", "\\bunsigned\\b", "\\busing\\b", "\\bvirtual\\b", "\\bvoid\\b", "\\bvolatile\\b", + "\\bwchar_t\\b", "\\bwhile\\b", "\\bxor\\b", "\\bxor_eq\\b" + }; + + for (const QString &pattern : keywordPatterns) { + HighlightingRule rule; + rule.pattern = QRegularExpression(pattern); + rule.format = keywordFormat; + highlightingRules.append(rule); + } + + // List of C++ types + QStringList typePatterns = { + "\\bbool\\b", "\\bchar\\b", "\\bchar16_t\\b", "\\bchar32_t\\b", "\\bdouble\\b", "\\bfloat\\b", + "\\bint\\b", "\\blong\\b", "\\bshort\\b", "\\bsigned\\b", "\\bunsigned\\b", "\\bvoid\\b", "\\bwchar_t\\b" + }; + + for (const QString &pattern : typePatterns) { + HighlightingRule rule; + rule.pattern = QRegularExpression(pattern); + rule.format = typeFormat; + highlightingRules.append(rule); + } + + // Preprocessor directives + HighlightingRule preprocessorRule; + preprocessorRule.pattern = QRegularExpression("^#\\s*[a-zA-Z_]+"); + preprocessorRule.format = preprocessorFormat; + highlightingRules.append(preprocessorRule); + + // Single line comments + singleLineCommentFormat.setForeground(Qt::darkGreen); + HighlightingRule singleLineCommentRule; + singleLineCommentRule.pattern = QRegularExpression("//[^\n]*"); + singleLineCommentRule.format = singleLineCommentFormat; + highlightingRules.append(singleLineCommentRule); + + // Multi-line comments + multiLineCommentFormat.setForeground(Qt::darkGreen); + commentStartExpression = QRegularExpression("/\\*"); + commentEndExpression = QRegularExpression("\\*/"); + + // Quotation marks + quotationFormat.setForeground(Qt::darkRed); + HighlightingRule quotationRule; + quotationRule.pattern = QRegularExpression("\".*\""); + quotationRule.format = quotationFormat; + highlightingRules.append(quotationRule); + + // Function names + functionFormat.setFontItalic(true); + functionFormat.setForeground(Qt::blue); + HighlightingRule functionRule; + functionRule.pattern = QRegularExpression("\\b[A-Za-z_][A-Za-z0-9_]*(?=\\()"); + functionRule.format = functionFormat; + highlightingRules.append(functionRule); +} + +void CppSyntaxHighlighter::highlightBlock(const QString &text) { + for (const HighlightingRule &rule : qAsConst(highlightingRules)) { + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); + while (matchIterator.hasNext()) { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), rule.format); + } + } + + setCurrentBlockState(0); + + int startIndex = 0; + if (previousBlockState() != 1) + startIndex = text.indexOf(commentStartExpression); + + while (startIndex >= 0) { + QRegularExpressionMatch match = commentEndExpression.match(text, startIndex); + int endIndex = match.capturedStart(); + int commentLength = 0; + if (endIndex == -1) { + setCurrentBlockState(1); + commentLength = text.length() - startIndex; + } else { + commentLength = endIndex - startIndex + match.capturedLength(); + } + setFormat(startIndex, commentLength, multiLineCommentFormat); + startIndex = text.indexOf(commentStartExpression, startIndex + commentLength); + } +} diff --git a/cppsyntaxhighlighter.h b/languages/cppsyntaxhighlighter.h similarity index 92% rename from cppsyntaxhighlighter.h rename to languages/cppsyntaxhighlighter.h index d07a5d6..1d052ed 100644 --- a/cppsyntaxhighlighter.h +++ b/languages/cppsyntaxhighlighter.h @@ -22,7 +22,8 @@ class CppSyntaxHighlighter : public QSyntaxHighlighter { QVector highlightingRules; QTextCharFormat keywordFormat; - QTextCharFormat classFormat; + QTextCharFormat typeFormat; + QTextCharFormat preprocessorFormat; QTextCharFormat singleLineCommentFormat; QTextCharFormat multiLineCommentFormat; QTextCharFormat quotationFormat; diff --git a/languages/languagemanager.cpp b/languages/languagemanager.cpp new file mode 100644 index 0000000..32bb164 --- /dev/null +++ b/languages/languagemanager.cpp @@ -0,0 +1,24 @@ +#include "languagemanager.h" +#include "cppsyntaxhighlighter.h" +#include "pythonsyntaxhighlighter.h" + +QSyntaxHighlighter* LanguageManager::createHighlighterForExtension(const QString &identifier, QTextDocument *document) { + if (identifier == "C++" || identifier == "cpp" || identifier == "cxx" || identifier == "h" || identifier == "hpp") { + return new CppSyntaxHighlighter(document); + } else if (identifier == "Python" || identifier == "py") { + return new PythonSyntaxHighlighter(document); + } + + // Add more language mappings here as needed + + return nullptr; // Return nullptr if no matching highlighter is found +} + +QString LanguageManager::getLanguageFromExtension(const QString &extension) { + if (extension == "cpp" || extension == "cxx" || extension == "h" || extension == "hpp") { + return "C++"; + } else if (extension == "py") { + return "Python"; + } + return "Unknown"; +} diff --git a/languages/languagemanager.h b/languages/languagemanager.h new file mode 100644 index 0000000..8a1ab85 --- /dev/null +++ b/languages/languagemanager.h @@ -0,0 +1,14 @@ +#ifndef LANGUAGEMANAGER_H +#define LANGUAGEMANAGER_H + +#include +#include +#include + +class LanguageManager { +public: + static QSyntaxHighlighter* createHighlighterForExtension(const QString &extension, QTextDocument *document); + static QString getLanguageFromExtension(const QString &extension); +}; + +#endif // LANGUAGEMANAGER_H diff --git a/languages/pythonsyntaxhighlighter.cpp b/languages/pythonsyntaxhighlighter.cpp new file mode 100644 index 0000000..7737152 --- /dev/null +++ b/languages/pythonsyntaxhighlighter.cpp @@ -0,0 +1,121 @@ +#include "pythonsyntaxhighlighter.h" + +PythonSyntaxHighlighter::PythonSyntaxHighlighter(QTextDocument *parent) + : QSyntaxHighlighter(parent) { + + // Define the formats + keywordFormat.setForeground(Qt::blue); + keywordFormat.setFontWeight(QFont::Bold); + + classFormat.setFontWeight(QFont::Bold); + classFormat.setForeground(Qt::darkMagenta); + + singleLineCommentFormat.setForeground(Qt::darkGreen); + + quotationFormat.setForeground(Qt::darkRed); + + functionFormat.setFontItalic(true); + functionFormat.setForeground(Qt::blue); + + // Define the keyword lists + keywords = QStringList() << "and" << "as" << "assert" << "break" << "class" << "continue" + << "def" << "del" << "elif" << "else" << "except" << "False" + << "finally" << "for" << "from" << "global" << "if" << "import" + << "in" << "is" << "lambda" << "None" << "nonlocal" << "not" + << "or" << "pass" << "raise" << "return" << "True" << "try" + << "while" << "with" << "yield"; + + builtins = QStringList() << "abs" << "dict" << "help" << "min" << "setattr" + << "all" << "dir" << "hex" << "next" << "slice" + << "any" << "divmod" << "id" << "object" << "sorted" + << "ascii" << "enumerate" << "input" << "oct" << "staticmethod" + << "bin" << "eval" << "int" << "open" << "str" + << "bool" << "exec" << "isinstance" << "ord" << "sum" + << "bytearray" << "filter" << "issubclass" << "pow" << "super" + << "bytes" << "float" << "iter" << "print" << "tuple" + << "callable" << "format" << "len" << "property" << "type" + << "chr" << "frozenset" << "list" << "range" << "vars" + << "classmethod" << "getattr" << "locals" << "repr" << "zip" + << "compile" << "globals" << "map" << "reversed" << "__import__" + << "complex" << "hasattr" << "max" << "round" << "delattr" + << "hash" << "memoryview" << "set"; + + operators = QStringList() << "=" << "==" << "!=" << "<" << "<=" << ">" << ">=" << "+" << "-" + << "*" << "/" << "//" << "%" << "**" << "<<" << ">>" << "&" + << "|" << "^" << "~"; + + braces = QStringList() << "{" << "}" << "(" << ")" << "[" << "]"; +} + +void PythonSyntaxHighlighter::highlightBlock(const QString &text) { + // Highlight keywords + for (const QString &keyword : keywords) { + int index = text.indexOf(keyword); + while (index >= 0) { + int length = keyword.length(); + setFormat(index, length, keywordFormat); + index = text.indexOf(keyword, index + length); + } + } + + // Highlight built-ins + for (const QString &builtin : builtins) { + int index = text.indexOf(builtin); + while (index >= 0) { + int length = builtin.length(); + setFormat(index, length, functionFormat); + index = text.indexOf(builtin, index + length); + } + } + + // Highlight comments + int commentIndex = text.indexOf("#"); + if (commentIndex >= 0) { + setFormat(commentIndex, text.length() - commentIndex, singleLineCommentFormat); + } + + // Highlight strings + int startIndex = 0; + while (startIndex >= 0) { + int singleQuoteIndex = text.indexOf("'", startIndex); + int doubleQuoteIndex = text.indexOf("\"", startIndex); + if (singleQuoteIndex >= 0 && (singleQuoteIndex < doubleQuoteIndex || doubleQuoteIndex < 0)) { + highlightMultiLineString(text, "'", singleQuoteIndex); + startIndex = singleQuoteIndex + 1; + } else if (doubleQuoteIndex >= 0) { + highlightMultiLineString(text, "\"", doubleQuoteIndex); + startIndex = doubleQuoteIndex + 1; + } else { + break; + } + } + + // Highlight operators and braces + for (const QString &op : operators) { + int index = text.indexOf(op); + while (index >= 0) { + setFormat(index, op.length(), keywordFormat); + index = text.indexOf(op, index + op.length()); + } + } + + for (const QString &brace : braces) { + int index = text.indexOf(brace); + while (index >= 0) { + setFormat(index, 1, keywordFormat); + index = text.indexOf(brace, index + 1); + } + } +} + +void PythonSyntaxHighlighter::highlightMultiLineString(const QString &text, const QString &delimiter, int startIndex) { + int endIndex = text.indexOf(delimiter, startIndex + 1); + int length; + if (endIndex == -1) { + setCurrentBlockState(1); + length = text.length() - startIndex; + } else { + length = endIndex - startIndex + 1; + } + setFormat(startIndex, length, quotationFormat); +} diff --git a/languages/pythonsyntaxhighlighter.h b/languages/pythonsyntaxhighlighter.h new file mode 100644 index 0000000..47d6f9b --- /dev/null +++ b/languages/pythonsyntaxhighlighter.h @@ -0,0 +1,32 @@ +#ifndef PYTHONSYNTAXHIGHLIGHTER_H +#define PYTHONSYNTAXHIGHLIGHTER_H + +#include +#include +#include + +class PythonSyntaxHighlighter : public QSyntaxHighlighter { + Q_OBJECT + +public: + explicit PythonSyntaxHighlighter(QTextDocument *parent = nullptr); + +protected: + void highlightBlock(const QString &text) override; + +private: + QTextCharFormat keywordFormat; + QTextCharFormat classFormat; + QTextCharFormat singleLineCommentFormat; + QTextCharFormat quotationFormat; + QTextCharFormat functionFormat; + + QStringList keywords; + QStringList builtins; + QStringList operators; + QStringList braces; + + void highlightMultiLineString(const QString &text, const QString &delimiter, int startIndex); +}; + +#endif // PYTHONSYNTAXHIGHLIGHTER_H diff --git a/mainwindow.cpp b/mainwindow.cpp index b49925c..3abec0f 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,6 +1,7 @@ #include "mainwindow.h" #include "ui_mainwindow.h" #include "document.h" +#include #include #include #include @@ -92,15 +93,6 @@ void MainWindow::on_action_New_triggered() { ui->documentsTab->setCurrentWidget(newDoc); } -void MainWindow::on_actionC_3_triggered() { - Document *doc = qobject_cast(ui->documentsTab->currentWidget()); - if (doc) { - doc->setLanguage("C++"); // Set language to C++, which triggers the formatting - } else { - QMessageBox::warning(this, tr("Error"), tr("No document to format.")); - } -} - void MainWindow::on_action_Go_to_line_in_editor_triggered() { Document *doc = qobject_cast(ui->documentsTab->currentWidget()); @@ -139,3 +131,24 @@ void MainWindow::on_actionC_lose_all_triggered() } } +void MainWindow::on_actionC_3_triggered() { + Document *doc = qobject_cast(ui->documentsTab->currentWidget()); + if (doc) { + qDebug() << "Menu action triggered for C++ syntax highlighting"; + doc->applySyntaxHighlighter("C++"); + } else { + QMessageBox::warning(this, tr("Error"), tr("No document to format.")); + } +} + +void MainWindow::on_actionPython_triggered() +{ + Document *doc = qobject_cast(ui->documentsTab->currentWidget()); + if (doc) { + qDebug() << "Menu action triggered for Python syntax highlighting"; + doc->applySyntaxHighlighter("Python"); + } else { + QMessageBox::warning(this, tr("Error"), tr("No document to format.")); + } +} + diff --git a/mainwindow.h b/mainwindow.h index 19230a8..0c3eae6 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -28,6 +28,8 @@ private slots: void on_actionC_lose_all_triggered(); + void on_actionPython_triggered(); + private: Ui::MainWindow *ui; void openDocument(const QString &filePath); From e828ba9dee16d6c25f3184e5e8913d9d4a19ab9a Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Sun, 25 Aug 2024 16:57:29 +0330 Subject: [PATCH 7/7] added LICENSE & improved working with files Signed-off-by: Remisa Yousefvand --- CMakeLists.txt.user | 72 +++++++++--------- LICENSE | 174 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + assets/lgplv3.png | Bin 0 -> 3343 bytes document.cpp | 113 ++++++++++++++++------------ examples/1GBfile.sh | 13 +--- 6 files changed, 282 insertions(+), 92 deletions(-) create mode 100644 LICENSE create mode 100644 assets/lgplv3.png diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index f2668b9..14bb7a7 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -102,14 +102,14 @@ 2 false - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_BUILD_TYPE:STRING=Debug --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} 0 /data/Code/Qt/Notepad--/build/Desktop-Debug @@ -159,14 +159,14 @@ 2 false - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_BUILD_TYPE:STRING=Release --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} /data/Code/Qt/Notepad--/build/Desktop-Release @@ -215,14 +215,14 @@ 2 false - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} /data/Code/Qt/Notepad--/build/Desktop-RelWithDebInfo @@ -269,14 +269,14 @@ 2 false - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} 0 /data/Code/Qt/Notepad--/build/Desktop-Profile @@ -324,14 +324,14 @@ 2 false - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_BUILD_TYPE:STRING=MinSizeRel --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} + -DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} /data/Code/Qt/Notepad--/build/Desktop-MinSizeRel diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0852004 --- /dev/null +++ b/LICENSE @@ -0,0 +1,174 @@ + GNU LESSER GENERAL PUBLIC LICENSE + + The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. + Contact: http://www.qt.io/licensing/ + + You may use, distribute and copy the Qt Toolkit under the terms of + GNU Lesser General Public License version 3, which is displayed below. + This license makes reference to the version 3 of the GNU General + Public License, which you can find in the LICENSE file. + +------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies of this +licensedocument, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + + As used herein, “this License” refers to version 3 of the GNU Lesser +General Public License, and the “GNU GPL” refers to version 3 of the +GNU General Public License. + + “The Library” refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An “Application” is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A “Combined Work” is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the “Linked +Version”. + + The “Minimal Corresponding Source” for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The “Corresponding Application Code” for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort + to ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this + license document. + +4. Combined Works. + + You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of +the Library contained in the Combined Work and reverse engineering for +debugging such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this + license document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of + this License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with + the Library. A suitable mechanism is one that (a) uses at run + time a copy of the Library already present on the user's + computer system, and (b) will operate properly with a modified + version of the Library that is interface-compatible with the + Linked Version. + + e) Provide Installation Information, but only if you would + otherwise be required to provide such information under section 6 + of the GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the Application + with a modified version of the Linked Version. (If you use option + 4d0, the Installation Information must accompany the Minimal + Corresponding Source and Corresponding Application Code. If you + use option 4d1, you must provide the Installation Information in + the manner specified by section 6 of the GNU GPL for conveying + Corresponding Source.) + +5. Combined Libraries. + + You may place library facilities that are a work based on the Library +side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities, conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of + it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +as you received it specifies that a certain numbered version of the +GNU Lesser General Public License “or any later version” applies to +it, you have the option of following the terms and conditions either +of that published version or of any later version published by the +Free Software Foundation. If the Library as you received it does not +specify a version number of the GNU Lesser General Public License, +you may choose any version of the GNU Lesser General Public License +ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the Library. diff --git a/README.md b/README.md index f156221..85d252b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Notepad-- +![gui](assets/lgplv3.png) + A simple light text editor. Notepadqq was my choice editor. Unfortunately it doesn't maintain anymore. I tried to help but there was old PRs and plenty of unanswered issues. The project was a mix of C++/Qt/Javascript/HTML,CSS,Python... It is a while I didn't code in C++ and my knowledge of Qt is a little. All that said this is a **toy** project, at least for a while. The -- (minus minus) indicates that this is a minimalistic project. I will design GUI just like Notepadqq so there is no new GUI learning. For now I just release for Linux which has Qt6 installed (dynamic compile). diff --git a/assets/lgplv3.png b/assets/lgplv3.png new file mode 100644 index 0000000000000000000000000000000000000000..012f011becd9969943d83a032a46afcd4379c5a6 GIT binary patch literal 3343 zcmV+q4e;`bP)4bM zJ)E`ny6)dz>%Fb@<%-2(xe`b~BG<6mB?zquj}qn)wh=N3F~WJmCc^WC^8YK7n79NO zf$|XA5|%OID11v;Pnb@aK$t?)cz|3KJGBzcff zQA56(gbg5Gogie|mLNzVEV%SSa&G@l6OIwiv$W%cu|$kQ0amlJgp-5}Qz8{3Tucxo z5IPXnHddxrIGblkmM}JgqP{W3!kvbJ<1?l*cy4GG zkw|G}0|~7OpL&q2K^*K-m0=c`X=G=@SIRq9k>xeDFcB?8d*cX843I9$J;CZ6EAl#r ztaB3Tn=aD(YsPcL@Hrc}KzIr(^kR=^b`Z*H-fscIb%e^g=Uj+XfbbDkrRt_+n#MYI zNaQ_k!8lfw)t3jFkV)D4qA$x?UOSPu%&^XSqMTzV>Lt>3f^`Oa?zT7*Nv-G&2wh<_ zGA0sCJzYS+GeSJ5Wk{ykkd=BFyHlw0Pgr9MH7_s>Q@`eDG5lY|&>!7_=Iy>9}cFk!srxhsgI{w7QohDwQA21M!yB2D?fbRQxW zWkRUJLqahBI^x90?c=wG;%>%3N!bLwm<(*68xw~6O(i7-c*Sap*KBMs%gUj`VngY`Kv3zJ%l=1lI69rFp#@M zd+%7NbDXGih+(;hMY)McpCQtJV^G%(E^|3Cz!*-#K9$Vmws=5oZKVTRyi*7VlmH%- zOx#KNX+R;=#8$$|ndIV23WIhb?O=^WImgTXfJmPmRH;C@u7>^i3a*;mkOkvKBxQ6> z3F$(asls@Jl4*;^9`v`U)>~0uO^@f^Ld2pMUKP(vW2K2otQ@xaS(*IIiCaU|x6`1$ zS}t>$YEbU5(;keH@gR}$GxT^D~-wIBDnSx0_E9=gL+A{_kiC^_ULC-jj=Kh z419iQAj)-M+GbJ+IkC1!Uw3HAe4%_}cy3snh;*3Cy&;K|9|s8L2O-n#UUGo)iCGv} zUjsA4UY8f2s*&p!Scnp6h=Tx8w9R@Rb&uBw+qEoev~HNs#fk`IY6}6peGoEn2kvo^ z_mG9b-6ZPVZdk6HMy~sv$m@jd!UW3UdB~Es+1z7J@9=oOEAorOU1F0&$6buE1z`M~ z0Wo4D{;g|3rq>B)2nB_j}A~K5U&{ zPGQ>u_ZBBy2oC2CkTJdNWU~xcrDp=!nS_`9F_9Pb>sce}OE(Pw)5vw-aR;UF_=go# zON7)m2Wqy_IYKqh8>j7UG5mPHQZ_UZX5uy8mKq`zBOD~`(H(?jSH?!_}-I>y2{Y;Wta0tHc${^YYNO~a~`u6@pBz}>_- ztNcO^i8|P}n!^e@$QAOB8jt^=h<%(X>g!|0VR~87P%CEB5Qf!wVS+9$oCwqjM4II* zQ@IRyvL%PslCO6NNI=-8*16d8RbA`Z=V(EPFzy) zF`;M}GJV7v9Iwd>-kT1aenNe~~xc za1x#q<+^woE1AbXEZ+5rHZ?)Ii~DIe5063mmsv=p*Cfe3h*X2HAFEQ`K<`=%Zm`#u z6oE{AS)FYx)w#$mF5Qw}YgEWS@x!PCSo&SuI4NSIvVugP%j0AkA~hqNAbdk;5_k?Y zLhX8}vQe>$AC81dUm(QGDgc##o}tG-EZT%5(;T<$9IMh+sWD+Z@xC%=u-}%(h}0Rv zwvv%<3^fNDp*G%{#OKgtOt4dP9DA2|HtNx$JpuZ~!J|?SGV8ul9=dxFFdmv*CJttl zHzZLqVGPv&O>PGT0+UGywFyK=WoD!-??I+97TY_7`ceZpZc7o~0g+zu^0|c}Q6pc|bbT?fE3U{OS&fA|b*^@)CyQAf;0Mn_IicBBYmHsr$Dw zA=`#!ygRPJ=>%EhWzDmlV8&RCBT{>EAel}|&CZ8ZB`~g8P=uD_qf%oWPPk7+O}H6E z0}$zE!WL|6OVoXoR&PZKaW&3K7%+Ene-v&+xfL%~eU(iJkFe0$C9v5HaIsJyLqFCs zf6+qr|3)|vdIE7pDL9YTh56zdB7Y1FbEgsHw;wl!)J35FX5=+Qy;GrWb;D`h4=j_) z`c*a|SECWQ{zj?&UE|UYUPhCk=iLx8TMgI7s29-~aoMYJ#ml=$8w)o~MZ^TPcX7mC zaQtg8cf%I57TATC;n=8}ArLG-@D$>8^0Kr) zxL9Woqpp$6I$ViG6|}@r@9E4c-2wMG#Sp*K7U%ucDpUqm=M3DgQXGU^jMFvuq1+2d zcluV-GMTz%6NyrBfbt>?kv-zxCSKedK_U>vQKzHA``;Xf#jQAzdH@d1iP!?~adDj1 z0-+D$;!ayibc#o+!}N9a!|k`qY8$hFrR%`?9JY!}heDFcqtf zg9Y&3f6eYiI*QwE?^i!6m}7shF7cy%S#JL+g}aU>!nJXck;Wm8T6ty>9)m+R_th}A Z{{kwc4yr0Vl(YZ<002ovPDHLkV1jf3FPs1X literal 0 HcmV?d00001 diff --git a/document.cpp b/document.cpp index baacd2c..c89c10c 100644 --- a/document.cpp +++ b/document.cpp @@ -1,11 +1,14 @@ #include "document.h" #include "codeeditor.h" +#include "languages/languagemanager.h" #include #include #include #include #include #include +#include +#include Document::Document(const QString &filePath, QWidget *parent) : QWidget(parent), m_filePath(filePath), m_fileSize(0), m_startPointer(0), m_endPointer(0), syntaxHighlighter(nullptr) { @@ -73,24 +76,24 @@ void Document::openFile(const QString &filePath) { setFilePath(filePath); m_fileSize = m_file.size(); - m_startPointer = 0; - m_endPointer = qMin(m_fileSize, m_startPointer + 1024 * 1024); // Load first 1MB - loadContent(); + // Load the entire file content for simplicity + QByteArray content = m_file.readAll(); + editor->setPlainText(QString::fromUtf8(content)); + editor->moveCursor(QTextCursor::Start); // Calculate the original hash of the file asynchronously QtConcurrent::run([this]() { m_originalHash = calculateMD5Stream(&m_file); + qDebug() << "Original MD5 calculated:" << m_originalHash.toHex(); }); -} -void Document::loadContent() { - if (!m_file.isOpen()) return; + m_file.close(); +} - m_file.seek(m_startPointer); - QByteArray content = m_file.read(m_endPointer - m_startPointer); - editor->setPlainText(QString::fromUtf8(content)); - editor->moveCursor(QTextCursor::Start); +void Document::trackChanges() { + // Basic change tracking (full document, for simplicity) + m_currentText = editor->toPlainText(); } void Document::updatePointers() { @@ -113,9 +116,33 @@ void Document::updatePointers() { } } -void Document::trackChanges() { - m_currentText = editor->toPlainText(); - m_changedSegments[m_startPointer] = m_currentText; +void Document::loadContent() { + if (!m_file.isOpen()) { + qDebug() << "File is not open, cannot load content."; + return; + } + + // Calculate the size of the portion to read + qint64 bytesToRead = m_endPointer - m_startPointer; + + // Ensure the reading is within bounds + if (m_startPointer < 0 || m_startPointer >= m_fileSize || bytesToRead <= 0) { + qDebug() << "Invalid pointers or no data to read."; + return; + } + + m_file.seek(m_startPointer); // Seek to the start pointer + + QByteArray content = m_file.read(bytesToRead); + if (content.isEmpty()) { + qDebug() << "No content read from the file."; + return; + } + + editor->setPlainText(QString::fromUtf8(content)); // Set content to the editor + editor->moveCursor(QTextCursor::Start); // Move cursor to the start of the document + + qDebug() << "File content loaded successfully. Start pointer:" << m_startPointer << ", End pointer:" << m_endPointer; } void Document::saveFile() { @@ -130,16 +157,15 @@ void Document::saveFile() { return; } - // Use QTextStream for writing QTextStream out(&file); - out << editor->toPlainText(); // Write the entire content of the editor to the file - - // After saving, calculate the new hash asynchronously - QtConcurrent::run([this]() { - m_originalHash = calculateMD5Stream(&m_file); - }); + out << editor->toPlainText(); file.close(); + + // Recalculate and store the MD5 hash of the saved file + m_originalHash = calculateMD5Stream(&file); + + qDebug() << "File saved. New MD5:" << m_originalHash.toHex(); } void Document::saveFileAs(const QString &newFilePath) { @@ -152,31 +178,34 @@ void Document::saveFileAs(const QString &newFilePath) { QByteArray Document::calculateMD5Stream(QFile *file) { QCryptographicHash hash(QCryptographicHash::Md5); - file->seek(0); + if (!file->isOpen()) { + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << "Failed to open file for MD5 calculation:" << file->errorString(); + return QByteArray(); + } + } + + file->seek(0); // Ensure we start from the beginning of the file - QByteArray buffer; + // Read the entire file content and update the hash while (!file->atEnd()) { - buffer = file->read(1024 * 1024); // Read in chunks + QByteArray buffer = file->read(1024 * 1024); // Read in chunks (1MB here) hash.addData(buffer); } - return hash.result(); + file->close(); // Close the file if it was opened here + return hash.result(); // Return the calculated MD5 hash } QByteArray Document::calculateModifiedMD5() { - QString currentContent = editor->toPlainText(); - QCryptographicHash hash(QCryptographicHash::Md5); - hash.addData(currentContent.toUtf8()); - return hash.result(); + QFile file(m_filePath); + return calculateMD5Stream(&file); } bool Document::closeDocument() { - // Special case: if the document is empty, allow closing without checking the hash - if (editor->toPlainText().isEmpty() && m_filePath.isEmpty()) { - return true; - } - QByteArray currentHash = calculateModifiedMD5(); + qDebug() << "Original MD5:" << m_originalHash.toHex(); + qDebug() << "Current MD5:" << currentHash.toHex(); if (currentHash != m_originalHash) { QMessageBox::StandardButton reply; @@ -185,20 +214,16 @@ bool Document::closeDocument() { QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (reply == QMessageBox::Save) { - QString savePath = QFileDialog::getSaveFileName(this, tr("Save File As"), "", tr("Text Files (*.txt);;All Files (*)")); - if (savePath.isEmpty()) { - return false; // User canceled the Save As dialog, don't close the document - } - saveFileAs(savePath); + saveFile(); return true; } else if (reply == QMessageBox::Discard) { - return true; // Allow closing without saving + return true; } else { - return false; // Cancel closing + return false; } } - return true; // No unsaved changes, allow closing + return true; } void Document::goToLineNumberInEditor() { @@ -210,20 +235,18 @@ void Document::goToLineNumberInEditor() { QTextCursor cursor = editor->textCursor(); cursor.movePosition(QTextCursor::Start); // Move to the start of the editor - // Move the cursor down to the desired line number for (int i = 1; i < lineNumber; ++i) { cursor.movePosition(QTextCursor::Down); - // Check if the cursor has moved to the end of the document if (cursor.atEnd()) { QMessageBox::warning(this, tr("Line Number Out of Bounds"), tr("The specified line number is outside the bounds of the file.")); - return; // Exit if the line number is out of bounds + return; } } editor->setTextCursor(cursor); - editor->ensureCursorVisible(); // Ensure the cursor is visible after moving + editor->ensureCursorVisible(); } } diff --git a/examples/1GBfile.sh b/examples/1GBfile.sh index 7641cce..69bf450 100755 --- a/examples/1GBfile.sh +++ b/examples/1GBfile.sh @@ -1,16 +1,7 @@ #!/usr/bin/env bash -file="1GB.txt" +output_file="1GB.txt" -# Define the size in byte -s (1 GB) size=$((1 * 1024 * 1024 * 1024)) - -# Generate the random file < /dev/urandom -tr -dc 'a-zA-Z0-9 ' | head -c "$size" > "$file" +base64 /dev/urandom | head -c 1073741824 > "$output_file" echo "Done!" - - - - -