From 7fa2c2209d1daad542ff584bbbacc641950e2c69 Mon Sep 17 00:00:00 2001 From: apakhomov Date: Tue, 29 Dec 2020 15:06:26 +0300 Subject: [PATCH] TextEditer Version 2.0 --- LABA3-4.pro | 33 ----- LABA3-4.pro.user | 357 ++++++++++++++++++++++++++++++++++++++++++++ color.xml | 2 +- dialog.cpp | 14 +- dialog.h | 4 + dialog.ui | 3 + highlighter.cpp | 64 +------- highlighter.h | 35 +++-- linenumberarea.cpp | 97 ++++++++++++ linenumberarea.h | 58 ++++++++ mainwindow.cpp | 363 +++++++++++++++++++++++++++++++++++---------- mainwindow.h | 21 ++- mainwindow.ui | 3 + 13 files changed, 861 insertions(+), 193 deletions(-) delete mode 100644 LABA3-4.pro create mode 100644 LABA3-4.pro.user create mode 100644 linenumberarea.cpp create mode 100644 linenumberarea.h diff --git a/LABA3-4.pro b/LABA3-4.pro deleted file mode 100644 index 2bafca5..0000000 --- a/LABA3-4.pro +++ /dev/null @@ -1,33 +0,0 @@ -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets xml - -CONFIG += c++11 - -# You can make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - dialog.cpp \ - highlighter.cpp \ - main.cpp \ - mainwindow.cpp - -HEADERS += \ - dialog.h \ - highlighter.h \ - mainwindow.h - -FORMS += \ - dialog.ui \ - mainwindow.ui - -# Default rules for deployment. -qnx: target.path = /tmp/$${TARGET}/bin -else: unix:!android: target.path = /opt/$${TARGET}/bin -!isEmpty(target.path): INSTALLS += target - -RESOURCES += \ - Recources.qrc \ - Recources.qrc diff --git a/LABA3-4.pro.user b/LABA3-4.pro.user new file mode 100644 index 0000000..8718737 --- /dev/null +++ b/LABA3-4.pro.user @@ -0,0 +1,357 @@ + + + + + + EnvironmentId + {0e34fe76-b21e-4404-a6bd-1fc9584f0dea} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + true + true + true + true + + + 0 + true + + -fno-delayed-template-parsing + + true + Builtin.Questionable + + true + Builtin.DefaultTidyAndClazy + 4 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop Qt 5.15.1 MinGW 64-bit + Desktop Qt 5.15.1 MinGW 64-bit + qt.qt5.5151.win64_mingw81_kit + 0 + 0 + 0 + + true + 0 + C:\build-LABA3-4-Desktop_Qt_5_15_1_MinGW_64_bit-Debug + C:/build-LABA3-4-Desktop_Qt_5_15_1_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + + false + + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Сборка + Сборка + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Очистка + Очистка + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Отладка + Qt4ProjectManager.Qt4BuildConfiguration + 2 + 2 + 2 + + + true + 2 + C:\build-LABA3-4-Desktop_Qt_5_15_1_MinGW_64_bit-Release + C:/build-LABA3-4-Desktop_Qt_5_15_1_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + + false + + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Сборка + Сборка + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Очистка + Очистка + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Выпуск + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 2 + + + true + 0 + C:\build-LABA3-4-Desktop_Qt_5_15_1_MinGW_64_bit-Profile + C:/build-LABA3-4-Desktop_Qt_5_15_1_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + + false + + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Сборка + Сборка + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Очистка + Очистка + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Профилирование + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 0 + + 3 + + + 0 + Развёртывание + Развёртывание + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:C:/LABA3-4/LABA3-4.pro + C:/LABA3-4/LABA3-4.pro + + false + + false + true + true + false + false + true + + C:/build-LABA3-4-Desktop_Qt_5_15_1_MinGW_64_bit-Debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/color.xml b/color.xml index 45a3d6e..cce2170 100644 --- a/color.xml +++ b/color.xml @@ -1,7 +1,7 @@ - + diff --git a/dialog.cpp b/dialog.cpp index 212f34a..bdef0fc 100644 --- a/dialog.cpp +++ b/dialog.cpp @@ -17,11 +17,21 @@ Dialog::~Dialog() void Dialog::fillTable(const QVector& fileDirs , const QStringList & fileNames) { + for(int i =0; i < fileDirs.count() ; i++) { ui->tableWidget->insertRow(i); - ui->tableWidget->setItem(i,0,new QTableWidgetItem(fileNames[i])); - ui->tableWidget->setItem(i,1,new QTableWidgetItem(fileDirs[i].path())); + ui->tableWidget->setItem(i,0,new QTableWidgetItem(fileNames[i],Qt::DisplayRole)); + ui->tableWidget->setItem(i,1,new QTableWidgetItem(fileDirs[i].path(),Qt::DisplayRole)); + } + + ui->tableWidget->verticalHeader()->setStretchLastSection(true); } + + + void Dialog::closeEvent(QCloseEvent* event) + { + emit done(-1); + } diff --git a/dialog.h b/dialog.h index 895437d..9ff3d1a 100644 --- a/dialog.h +++ b/dialog.h @@ -22,6 +22,10 @@ public: void fillTable(const QVector& , const QStringList &); +private slots: + + void closeEvent(QCloseEvent* event) override; + private: Ui::Dialog *ui; }; diff --git a/dialog.ui b/dialog.ui index 0b2ae11..a0d3d9f 100644 --- a/dialog.ui +++ b/dialog.ui @@ -22,6 +22,9 @@ 0 + + QAbstractItemView::NoEditTriggers + diff --git a/highlighter.cpp b/highlighter.cpp index 22922f3..7b74790 100644 --- a/highlighter.cpp +++ b/highlighter.cpp @@ -1,68 +1,14 @@ #include "highlighter.h" #include -Highlighter::Highlighter(QTextDocument *parent) +Highlighter::Highlighter(QTextDocument *parent ,QVector rules) : QSyntaxHighlighter(parent) { - QFile file(":xml/color.xml" ); //!!! Это нужно считывать в основмном окне, т.к. там эти данные нужны. - //!!! Сюда надо передавать контейнер. - - if(file.open(QFile::ReadOnly | QFile::Text)) - { - - HighlightingRule rule; - - QTextCharFormat format; - - QRegularExpression pattern; - - xmlStream.setDevice(&file); - - while(!xmlStream.atEnd() && !xmlStream.hasError()) - { - xmlStream.readNext(); - - - if( xmlStream.isStartElement() ) - { - - if ( xmlStream.name() == "pattern" ) - { - - QRegularExpression reg(xmlStream.attributes().at(0).value().toString()); - - rule.pattern = reg; - qDebug()< #include @@ -12,34 +13,40 @@ #include #include +struct HighlightingRule +{ + QRegularExpression pattern; + QTextCharFormat format; +}; class Highlighter : public QSyntaxHighlighter { Q_OBJECT +private: + + + QVector highlightingRules; + + QRegularExpression commentStartExpression; + QRegularExpression commentEndExpression; + + QTextCharFormat multiLineCommentFormat; + + public: - Highlighter(QTextDocument *parent); + Highlighter(QTextDocument *parent,QVector highlightingRules); QXmlStreamReader xmlStream; + QString fileExs; + protected: void highlightBlock(const QString &text) override; - private: - struct HighlightingRule - { - QRegularExpression pattern; - QTextCharFormat format; - }; - - QVector highlightingRules; - - QRegularExpression commentStartExpression; - QRegularExpression commentEndExpression; - - QTextCharFormat multiLineCommentFormat; + friend class MainWindow; }; diff --git a/linenumberarea.cpp b/linenumberarea.cpp new file mode 100644 index 0000000..22c75c6 --- /dev/null +++ b/linenumberarea.cpp @@ -0,0 +1,97 @@ +#include "linenumberarea.h" + + + +CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) +{ + lineNumberArea = new LineNumberArea(this); + + 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; + } + + int space = 3 + 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 = qRound(blockBoundingGeometry(block).translated(contentOffset()).top()); + int bottom = top + qRound(blockBoundingRect(block).height()); + + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + painter.setPen(Qt::black); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + qRound(blockBoundingRect(block).height()); + ++blockNumber; + } +} diff --git a/linenumberarea.h b/linenumberarea.h new file mode 100644 index 0000000..b115bb5 --- /dev/null +++ b/linenumberarea.h @@ -0,0 +1,58 @@ +#ifndef LINENUMBERAREA_H +#define LINENUMBERAREA_H + +#include +#include +#include"mainwindow.h" + +class CodeEditor; +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 // LINENUMBERAREA_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 6688703..af58cc7 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -17,7 +17,7 @@ MainWindow::MainWindow(QWidget *parent) //!!! Под Linux нет такого каталога. Посмотрите методы Qt, возвращающие стандартные каталоги на любой платформе. - fileSystem.setRootPath("C:\\"); + fileSystem.setRootPath(QDir::rootPath()); ui->treeView->setModel(&fileSystem); @@ -38,12 +38,11 @@ MainWindow::MainWindow(QWidget *parent) this->setWindowTitle("Текстовый редактор"); - connect(ui->fileTreeAct,SIGNAL(toggled(bool)),this, SLOT(on_fileTreeAct(bool))); connect(ui->activeFilesAct,SIGNAL(toggled(bool)),this, SLOT(on_activeFilesAct(bool))); - bar = new QToolBar(); ///!!! Не указан родительский объект + bar = new QToolBar(this); bar->addAction(ui->newAct); bar->addAction(ui->openAct); @@ -52,7 +51,6 @@ MainWindow::MainWindow(QWidget *parent) addToolBar(Qt::TopToolBarArea,bar); - }; MainWindow::~MainWindow() @@ -60,6 +58,49 @@ MainWindow::~MainWindow() delete ui; } +void MainWindow::closeEvent(QCloseEvent* closeEvent) +{ + if(!on_exitAct_triggered()) + closeEvent->ignore(); +} + + +bool MainWindow::on_exitAct_triggered() +{ + Dialog* dial = new Dialog(this); + + dial->setWindowTitle("Хотите сохранить файлы перед выход ?"); + + dial->fillTable(fileDirs,fileNames); + + + int mode = dial->exec(); + + if(mode == QDialog::Accepted) + { + on_saveAllAct_triggered(); + qApp->quit(); + return true; + } + else if(mode == QDialog::Rejected ) + { + qApp->quit(); + return true; + } + else if (mode == -1) + { + return false; + } + + +} + + +void MainWindow::on_tabWidget_tabCloseRequested(int index) +{ + on_closeAct_triggered(); +} + void MainWindow::on_newAct_triggered() { @@ -70,7 +111,7 @@ void MainWindow::on_newAct_triggered() fileNames.push_back(nameFile); strList.setStringList(fileNames); fileDirs.push_back(QDir::current()); - QPlainTextEdit* textEd = new QPlainTextEdit(); + QPlainTextEdit* textEd = new QPlainTextEdit(this); ui->tabWidget->addTab(textEd,nameFile); if(ui->tabWidget->currentIndex() == -1) { @@ -80,6 +121,7 @@ void MainWindow::on_newAct_triggered() ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1 ); } + connect(textEd,SIGNAL(textChanged()),this , SLOT(tabModification())); } @@ -145,72 +187,16 @@ void MainWindow::on_closeAllAct_triggered() } } -void MainWindow::on_exitAct_triggered() -{ - Dialog* dial = new Dialog; ///!!! Не указан родительский объект - - dial->setWindowTitle("Хотите сохранить файлы перед выход ?"); - - dial->fillTable(fileDirs,fileNames); - - int mode = dial->exec(); - - if(mode == QDialog::Accepted) - { - on_saveAllAct_triggered(); - qApp->quit(); - } - if(mode == QDialog::Rejected) - { - qApp->quit(); - } - -} - void MainWindow::on_openAct_triggered() { //!!! А если пользователь python в файл добавит? Там свои расширения... - - QString openFileName = QFileDialog::getOpenFileName(this,"Выбрать файл для открытия","C:\\", - "Все файлы (*.txt *.h *.cpp *.pro *.pdf) ;; " - "C++ файлы (*.h *.cpp *.pro);; Текстовые .txt ;; PDF файлы *.pdf"); - - QFile file(openFileName); - - - if(!file.open(QIODevice::ReadOnly)) - { - QErrorMessage * msg = new QErrorMessage(); - msg->showMessage("Файл с данным расширением не открывается"); - return; - } - - QPlainTextEdit* textEd = new QPlainTextEdit; - - QFileInfo fileInfo (file); - - ///!!! Жесткая зависимость от расширений. Проверять надо с теми расширениями, которые приведены в файле настроек - - if(fileInfo.completeSuffix() == "h" || fileInfo.completeSuffix() == "cpp" || fileInfo.completeSuffix() == "pro" || fileInfo.completeSuffix() == "ui" ) - { - Highlighter* highlighter = new Highlighter(textEd->document()); - } - - textEd->setPlainText(file.readAll()); - - ui->tabWidget->addTab(textEd,fileInfo.baseName() + "." + fileInfo.completeSuffix()); - fileNames.push_back(QString (fileInfo.baseName() + "." + fileInfo.completeSuffix()) ); + QString openFileName = QFileDialog::getOpenFileName(this,"Выбрать файл для открытия",QDir::rootPath()) ; - fileDirs.push_back(fileInfo.path()); + loadFileData(openFileName); - strList.setStringList(fileNames); - - ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1 ); - - file.close(); } @@ -221,13 +207,13 @@ void MainWindow::on_saveAct_triggered() QPlainTextEdit* textEd = qobject_cast (ui->tabWidget->currentWidget()); if( textEd==nullptr ) { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка сохранения файла"); return; } - QFile file(ui->tabWidget->tabText(ui->tabWidget->currentIndex())); + QFile file(fileNames.at(ui->tabWidget->currentIndex())); QTextStream text(&file); if(file.open(QIODevice::WriteOnly )) { @@ -235,7 +221,7 @@ void MainWindow::on_saveAct_triggered() } else { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка сохранения файла"); return; } @@ -247,14 +233,12 @@ void MainWindow::on_saveAsAct_triggered() { ///!!! Жесткая зависимость от расширений - QString saveFileName = QFileDialog::getSaveFileName(this,"Выбрать файл для сохранения","C:\\", - "Все файлы (*.txt *.cpp *.h);; Текстовый файлы *.txt ;;" - " C++ файлы (*.h *.cpp)"); + QString saveFileName = QFileDialog::getSaveFileName(this,"Выбрать файл для сохранения",QDir::rootPath()); QPlainTextEdit* textEd = qobject_cast (ui->tabWidget->currentWidget()); if( textEd==nullptr ) { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка сохранения файла"); return; } @@ -267,7 +251,7 @@ void MainWindow::on_saveAsAct_triggered() } else { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка сохранения файла"); return; @@ -306,7 +290,7 @@ void MainWindow::on_listView_clicked(const QModelIndex &index) { if(!index.isValid()) { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Возникла ошибка в обозревателе открытых документов"); return; } @@ -344,11 +328,13 @@ void MainWindow::on_cutAct_triggered() QPlainTextEdit* textEd = qobject_cast (ui->tabWidget->currentWidget()); if(textEd == nullptr) { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка вырезки"); return; } + connect(textEd,SIGNAL(textChanged()),this , SLOT(tabModification())); + textEd->cut(); } @@ -357,7 +343,7 @@ void MainWindow::on_copyAct_triggered() QPlainTextEdit* textEd = qobject_cast (ui->tabWidget->currentWidget()); if(textEd == nullptr) { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка копирования"); return; } @@ -370,11 +356,14 @@ void MainWindow::on_insertAct_triggered() QPlainTextEdit* textEd = qobject_cast (ui->tabWidget->currentWidget()); if(textEd == nullptr) { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка вставки"); return; // } + connect(textEd,SIGNAL(textChanged()),this , SLOT(tabModification())); + + textEd->paste(); } @@ -383,11 +372,14 @@ void MainWindow::on_deleteAct_triggered() QPlainTextEdit* textEd = qobject_cast (ui->tabWidget->currentWidget()); if(textEd == nullptr) { - QErrorMessage * msg = new QErrorMessage(); + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка удаления"); return; // } + + connect(textEd,SIGNAL(textChanged()),this , SLOT(tabModification())); + textEd->textCursor().removeSelectedText(); } @@ -396,19 +388,20 @@ void MainWindow::on_highlightAct_triggered() QPlainTextEdit* textEd = qobject_cast (ui->tabWidget->currentWidget()); if(textEd == nullptr) { - QErrorMessage * msg = new QErrorMessage(); ///!!! Не указан родительский объект + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Ошибка выделить все"); - return; // + return; } textEd->selectAll(); } +/* void MainWindow::on_treeView_clicked(const QModelIndex &index) { if(!index.isValid()) { - QErrorMessage* msg = new QErrorMessage; ///!!! Не указан родительский объект + QErrorMessage* msg = new QErrorMessage(this); msg->showMessage("Oшибка открытия файла"); } QString path = fileSystem.filePath(index); @@ -431,13 +424,13 @@ void MainWindow::on_treeView_clicked(const QModelIndex &index) } else { - QErrorMessage * msg = new QErrorMessage(); ///!!! Не указан родительский объект + QErrorMessage * msg = new QErrorMessage(this); msg->showMessage("Файл с данным расширением не открывается"); return; } - QPlainTextEdit* textEd = new QPlainTextEdit; ///!!! Не указан родительский объект + QPlainTextEdit* textEd = new QPlainTextEdit(this); QFileInfo fileInfo (file); @@ -460,6 +453,56 @@ void MainWindow::on_treeView_clicked(const QModelIndex &index) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1 ); file.close(); + + connect(textEd,SIGNAL(textChanged()),this , SLOT(tabModification())); + + } + else + { + return; + // кликнул на папку , выходишь + } +} +*/ + + void MainWindow::tabModification() + { + int index = ui->tabWidget->currentIndex(); + + if(! ui->tabWidget->tabText(index).contains("*")) + { + ui->tabWidget->setTabText(index, ui->tabWidget->tabText(index) + "*"); + } + else + { + QPlainTextEdit* textEd = qobject_cast(ui->tabWidget->widget(index) ) ; + + if( textEd == nullptr ) + { + + QErrorMessage * msg = new QErrorMessage(this); + msg->showMessage("Ошибка исправления вкладки виджета "); + return; // + } + + disconnect(textEd,SIGNAL(textChanged()),this , SLOT(tabModification())); + + } + + + } + +void MainWindow::on_treeView_doubleClicked(const QModelIndex &index) +{ + if(!index.isValid()) + { + QErrorMessage* msg = new QErrorMessage(this); + msg->showMessage("Oшибка открытия файла"); + } + QString path = fileSystem.filePath(index); + if(path.contains('.')) + { + loadFileData(path); } else { @@ -468,4 +511,162 @@ void MainWindow::on_treeView_clicked(const QModelIndex &index) } } + void MainWindow::loadFileData(const QString& path) + { + QFile file(path); + if(!file.open(QIODevice::ReadOnly)) + { + QErrorMessage * msg = new QErrorMessage(this); + msg->showMessage("Файл с данным расширением не открывается"); + return; + } + + QFileInfo fileInfo (file); + + + QPlainTextEdit* textEd ; + CodeEditor* codeEditor; + + QVector highlightingRule = loadXmlFile(path); + + //!!! Зависимость от расширений + if(!highlightingRule.isEmpty()) + { + + codeEditor = new CodeEditor(this); + + Highlighter* highLighter = new Highlighter (codeEditor->document(),highlightingRule); + + codeEditor->setPlainText(file.readAll()); + + ui->tabWidget->addTab(codeEditor,fileInfo.baseName() + "." + fileInfo.completeSuffix()); + + connect(codeEditor,SIGNAL(textChanged()),this , SLOT(tabModification())); + + } + else + { + textEd = new QPlainTextEdit(this); + + textEd->setPlainText(file.readAll()); + + ui->tabWidget->addTab(textEd,fileInfo.baseName() + "." + fileInfo.completeSuffix()); + + connect(textEd,SIGNAL(textChanged()),this , SLOT(tabModification())); + } + + + + fileNames.push_back(QString (fileInfo.baseName() + "." + fileInfo.completeSuffix()) ); + + fileDirs.push_back(fileInfo.path()); + + strList.setStringList(fileNames); + + ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1 ); + + file.close(); + } + + + QVector MainWindow::loadXmlFile(const QString &path) + { + + QFile file(":xml/color.xml" ); //!!! Это нужно считывать в основмном окне, т.к. там эти данные нужны. + //!!! Сюда надо передавать контейнер. + + QFileInfo fileInfo(path); + + QVector highlightingRules; + + if(file.open(QFile::ReadOnly | QFile::Text)) + { + QXmlStreamReader xmlStream; + + HighlightingRule rule; + + QTextCharFormat format; + + QRegularExpression pattern; + + xmlStream.setDevice(&file); + + while(!xmlStream.atEnd() && !xmlStream.hasError()) + { + xmlStream.readNext(); + + + if( xmlStream.isStartElement() ) + { + if(xmlStream.name() == "syntax") + { + QXmlStreamAttribute attr = xmlStream.attributes().at(2); + + QString exstensions = attr.value().toString(); + + QStringList Exstensionlist = exstensions.split(" "); + + + bool isCodeInFile = false; + + for ( auto exstension : Exstensionlist ) + { + + + if(fileInfo.completeSuffix() == exstension) + { + isCodeInFile = true; + } + + } + + if(!isCodeInFile) + { + return highlightingRules;; + } + + + } + + if ( xmlStream.name() == "pattern" ) + { + + QRegularExpression reg(xmlStream.attributes().at(0).value().toString()); + + rule.pattern = reg; + qDebug()< #include #include @@ -11,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -33,8 +35,16 @@ #include #include #include +#include +#include +#include +#include +#include +#include +struct HighlightingRule; + QT_BEGIN_NAMESPACE @@ -61,7 +71,9 @@ protected: QToolBar * bar; + void loadFileData(const QString &); + QVector loadXmlFile(const QString &); public: @@ -78,7 +90,7 @@ private slots: void on_closeAct_triggered(); void on_closeAllAct_triggered(); void on_openAct_triggered(); - void on_exitAct_triggered(); + bool on_exitAct_triggered(); void on_saveAct_triggered(); void on_saveAsAct_triggered(); void on_saveAllAct_triggered(); @@ -86,7 +98,7 @@ private slots: void on_fileTreeDock_visibilityChanged(bool visible); void on_activeFilesDock_visibilityChanged(bool visible); void on_listView_clicked(const QModelIndex &index); - void on_treeView_clicked(const QModelIndex &index); + // void on_treeView_clicked(const QModelIndex &index); void on_activeFilesAct(bool visible); void on_fileTreeAct(bool visible); @@ -97,9 +109,12 @@ private slots: void on_deleteAct_triggered(); void on_highlightAct_triggered(); + void tabModification(); + void on_tabWidget_tabCloseRequested(int index); + void on_treeView_doubleClicked(const QModelIndex &index); - + void closeEvent(QCloseEvent * closeEvent) override; }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 5efa33c..39864c2 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -20,6 +20,9 @@ -1 + + true + -- GitLab