From e21c45b4442697255327335e484d9e20c29f51d0 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Mon, 13 Sep 2021 14:22:07 +0700 Subject: [PATCH 01/50] chore: set "cmake.configureOnOpen" to true --- .vscode/settings.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..473059c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": true, +} \ No newline at end of file From 863f2713cc62490c2f0e350e12044cfe66c5c8e1 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Mon, 13 Sep 2021 14:22:39 +0700 Subject: [PATCH 02/50] chore: Change compiler to GCC As we use GCC obviously. --- .vscode/c_cpp_properties.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..56f828e --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,19 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/usr/include/qt/QtWidgets", + "/usr/include/qt" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "c++14", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file From 9db81886ef23f915c82a8ba0cd5cdf13d2911f50 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Mon, 13 Sep 2021 14:24:44 +0700 Subject: [PATCH 03/50] chore: Add gitignore for CMake files --- .gitignore | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21299f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +# +# Stolen from https://github.com/kigster/cmake-project-template/blob/master/.gitignore +# + +# Compiled Object files +**/.DS_Store +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +**/cmake-build-debug +**/CMakeCache.txt +**/cmake_install.cmake +**/install_manifest.txt +**/CMakeFiles/ +**/CTestTestfile.cmake +**/Makefile +**/*.cbp +**/CMakeScripts +**/compile_commands.json + +include/divisible/* + + +## Local + +.idea/*.xml + +build/**/* + +include/* +lib/* +bin/* +test/test_runner + From bf51d4dd9f253d24e92d1f1101e0f3e2452f8f9a Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Mon, 13 Sep 2021 14:32:06 +0700 Subject: [PATCH 04/50] feat: Add the needed boilerplate code needed to run the program This moves ui/echidna.ui and src/resources.qrs to src/echidna.ui and src/resources.qrs respectively. I couldn't find any way to have these files on a separate ui folder, as CMake's AUTOUIC feature will only look for .ui files in the importing code's directory. I have compiled and ran this and the UI feels great. I mean I have the Dracula theme configured on my machine, not sure what will it looked like without it. Next up we will work on our Monaco replacement. Will discuss on whether making it a Qt Designer plugin or not. --- CMakeLists.txt | 32 ++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 0 {ui => src}/echidna.ui | 8 ++++---- src/editor.cpp | 31 +++++++++++++++++++++++++++++++ src/editor.h | 24 ++++++++++++++++++++++++ src/main.cpp | 14 ++++++++++++++ src/resources.qrc | 5 +++++ 7 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt rename {ui => src}/echidna.ui (97%) create mode 100644 src/editor.cpp create mode 100644 src/editor.h create mode 100644 src/main.cpp create mode 100644 src/resources.qrc diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5407626 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,32 @@ +CMake_Minimum_Required(VERSION 3.1.0) + +Project(echidna VERSION 0.0 LANGUAGES CXX) + +Set(CMAKE_CXX_STANDARD 11) +Set(CMAKE_CXX_STANDARD_REQUIRED ON) + +Set(CMAKE_AUTOMOC ON) +Set(CMAKE_AUTORCC ON) +Set(CMAKE_AUTOUIC ON) + + + +Find_Package(Qt5 COMPONENTS Widgets REQUIRED) + +add_subdirectory(src) + +file(GLOB SOURCES src/*.cpp) +file(GLOB HEADERS src/*.h) + +Add_Executable(echidna + ${SOURCES} + ${HEADERS} + src/echidna.ui + src/resources.qrc +) + + + +Target_Link_Libraries(echidna Qt5::Widgets) + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/ui/echidna.ui b/src/echidna.ui similarity index 97% rename from ui/echidna.ui rename to src/echidna.ui index 43d2a85..6ff9ab8 100644 --- a/ui/echidna.ui +++ b/src/echidna.ui @@ -1,7 +1,7 @@ - MainWindow - + EchidnaEditor + 0 @@ -11,9 +11,9 @@ - MainWindow + Echidna Editor - + diff --git a/src/editor.cpp b/src/editor.cpp new file mode 100644 index 0000000..2a69a9b --- /dev/null +++ b/src/editor.cpp @@ -0,0 +1,31 @@ +#include "editor.h" +#include + +EchidnaEditor::EchidnaEditor(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::EchidnaEditor) +{ + +ui->setupUi(this); +this->setCentralWidget(ui->centralWidget); + + + +} + +EchidnaEditor::~EchidnaEditor(){ + delete ui; +} + + +/** + * undefined reference to `vtable for EchidnaEditor' + * + * / + + +/* + +undefined reference to `vtable for EchidnaEditor' + +*/ \ No newline at end of file diff --git a/src/editor.h b/src/editor.h new file mode 100644 index 0000000..a355ca2 --- /dev/null +++ b/src/editor.h @@ -0,0 +1,24 @@ +#include + +namespace Ui { +class EchidnaEditor; +} + + +class EchidnaEditor : public QMainWindow +{ + Q_OBJECT + +public: + explicit EchidnaEditor(QWidget *parent = nullptr); + ~EchidnaEditor(); + +private slots: + void addFolderIntoWorkspace(){ + + } + +private: + Ui::EchidnaEditor *ui; + +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..cbaed37 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,14 @@ +#include +#include "editor.h" + +int main(int argc, char *argv[]){ + + QApplication EchidnaEditorApp(argc, argv); + + EchidnaEditor Editor; + + Editor.show(); + + EchidnaEditorApp.exec(); + +} \ No newline at end of file diff --git a/src/resources.qrc b/src/resources.qrc new file mode 100644 index 0000000..d601a4b --- /dev/null +++ b/src/resources.qrc @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From aa9ab4216b82de2e851d93b2de2a06e476b83034 Mon Sep 17 00:00:00 2001 From: FortressValkriye Date: Mon, 13 Sep 2021 14:44:12 +0700 Subject: [PATCH 05/50] chore: Remove uneeded comments As VS Code does not properly display long error messages. I had to copy and paste the error messages to somewhere. And I forgot to not commit them. Bruh. --- src/editor.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/editor.cpp b/src/editor.cpp index 2a69a9b..13faa5b 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -16,16 +16,3 @@ this->setCentralWidget(ui->centralWidget); EchidnaEditor::~EchidnaEditor(){ delete ui; } - - -/** - * undefined reference to `vtable for EchidnaEditor' - * - * / - - -/* - -undefined reference to `vtable for EchidnaEditor' - -*/ \ No newline at end of file From 1586a798d983f57e75c0faba3410a3c63627e1a9 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Mon, 13 Sep 2021 20:01:46 +0700 Subject: [PATCH 06/50] ref(echidna.ui): Rename tabWidget to activityTab --- src/echidna.ui | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/echidna.ui b/src/echidna.ui index 6ff9ab8..cc597fd 100644 --- a/src/echidna.ui +++ b/src/echidna.ui @@ -60,7 +60,7 @@ - + 0 @@ -75,7 +75,6 @@ width: 48px; height: 48px; } - From 628bfd13ac7cfa410b9c15d4728e2e5e8307cdcd Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 15 Oct 2021 13:36:26 +0700 Subject: [PATCH 07/50] feat: add some Qt C++ codes Just archived code to be removed immediately. --- src/met/core-editor.cpp | 75 +++++++++++++++++++++++++++++++++++++++++ src/met/core-editor.h | 58 +++++++++++++++++++++++++++++++ src/met/editor.cpp | 64 +++++++++++++++++++++++++++++++++++ src/met/editor.h | 39 +++++++++++++++++++++ src/met/main.cpp | 14 ++++++++ 5 files changed, 250 insertions(+) create mode 100644 src/met/core-editor.cpp create mode 100644 src/met/core-editor.h create mode 100644 src/met/editor.cpp create mode 100644 src/met/editor.h create mode 100644 src/met/main.cpp diff --git a/src/met/core-editor.cpp b/src/met/core-editor.cpp new file mode 100644 index 0000000..74108f3 --- /dev/null +++ b/src/met/core-editor.cpp @@ -0,0 +1,75 @@ +#include "core-editor.h" + +EchidnaCoreEditor::EchidnaCoreEditor(QWidget *parent) : QPlainTextEdit(parent) { + LineNumberArea *lineNumber = new LineNumberArea(this); + + QObject::connect(this, &EchidnaCoreEditor::cursorPositionChanged, &EchidnaCoreEditor::highlightCurrentLine); + QObject::connect(this, &EchidnaCoreEditor::updateRequest, &EchidnaCoreEditor::updateLineNumberArea); + QObject::connect(this, &EchidnaCoreEditor::blockCountChanged, &EchidnaCoreEditor::updateLineNumberAreaWidth); + + this->highlightCurrentLine(); + this->updateLineNumberAreaWidth(0); +} + +EchidnaCoreEditor::~EchidnaCoreEditor(){ + +} + +int EchidnaCoreEditor::lineNumberAreaWidth(){ + +} + + +void EchidnaCoreEditor::lineNumberAreaPaintEvent(QPaintEvent *event){ + +} + +void EchidnaCoreEditor::resizeEvent(QResizeEvent *e){ + + QPlainTextEdit::resizeEvent(e); + + QRect contentsRect = this->contentsRect(); + + +} + + /** + * + * This function implements the functionaly that highlight the current line your cursor is currently on. + * + * TODO: Implement support for multi-line editing. + * + */ +void EchidnaCoreEditor::highlightCurrentLine(){ + + if(this->isReadOnly()){ + return; + } else { + QList selections; + + QTextEdit::ExtraSelection selection; + + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + + QBrush selectionFormatBrush = selection.format.foreground(); + + + } + +} + + + +/* + +the method `set_menubar` exists for reference `&components::echidna_editor::imp::EchidnaEditor`, but its trait bounds were not satisfied + +method cannot be called on `&components::echidna_editor::imp::EchidnaEditor` due to unsatisfied trait bounds + +note: the following trait bounds were not satisfied: + `components::echidna_editor::imp::EchidnaEditor: glib::IsA` + which is required by `components::echidna_editor::imp::EchidnaEditor: gtk4::prelude::GtkApplicationExt` + `&components::echidna_editor::imp::EchidnaEditor: glib::IsA` + which is required by `&components::echidna_editor::imp::EchidnaEditor: gtk4::prelude::GtkApplicationExt` + +*/ diff --git a/src/met/core-editor.h b/src/met/core-editor.h new file mode 100644 index 0000000..f27dab1 --- /dev/null +++ b/src/met/core-editor.h @@ -0,0 +1,58 @@ + +/* + + Echidna Core Text Editor. This is the Monaco replacement for Echidna. + + A lot of the code are ~~stolen~~ inspired from [Qt's Code Editor example](https://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html), with added features to replicate the Visual Studio Code experience. + +*/ + +#include + +class LineNumberArea : public QWidget +{ + +public: + LineNumberArea(EchidnaCoreEditor *editor) : QWidget(editor), coreEditor(editor) + { + } + + QSize sizeHint() const override + { + return QSize(coreEditor->lineNumberAreaWidth(), 0); + } + +protected: + void paintEvent(QPaintEvent *event) override + { + coreEditor->lineNumberAreaPaintEvent(event); + } + + EchidnaCoreEditor *coreEditor; +}; + +class EchidnaCoreEditor : public QPlainTextEdit +{ + Q_OBJECT + +public: + EchidnaCoreEditor(QWidget *parent = nullptr); + ~EchidnaCoreEditor(); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); +protected: + void resizeEvent(QResizeEvent *event) override; + +private slots: + void highlightCurrentLine(); + void updateLineNumberAreaWidth(int newBlockCount); + void updateLineNumberArea(const QRect &rect, int dy); + + + LineNumberArea *lineNumber; +}; + + + + diff --git a/src/met/editor.cpp b/src/met/editor.cpp new file mode 100644 index 0000000..bacc01c --- /dev/null +++ b/src/met/editor.cpp @@ -0,0 +1,64 @@ +#include "editor.h" +#include +#include +#include +#include + +EchidnaEditor::EchidnaEditor(QWidget *parent) : QMainWindow(parent), + ui(new Ui::EchidnaEditor) +{ + + ui->setupUi(this); + this->setCentralWidget(ui->centralWidget); + + QObject::connect(this, &EchidnaEditor::newFileOpened, &EchidnaEditor::handleNewFileOpened); +} + +EchidnaEditor::~EchidnaEditor() +{ + delete ui; +}; + +void EchidnaEditor::actionOpenFolder() +{ + QString dir = QFileDialog::getExistingDirectory(this, + "Add a Folder to Workspace", + QDir::homePath(), + QFileDialog::ShowDirsOnly); + + + std::vector::iterator foundExistingOpenedFolders = std::find_if(this->folders->begin(), this->folders->end(), + [&](QFileSystemModel *iterator) + { + return iterator->rootPath() == dir; + }); + if (this->folders->end() != foundExistingOpenedFolders) + { + } + else + { + QFileSystemModel *model = new QFileSystemModel; + model->setRootPath(dir); + + } + + +} + +void EchidnaEditor::actionOpenFile(){ + QStringList files = QFileDialog::getOpenFileNames(this, + "Open Files", + QDir::homePath() + ); + + for(int i = 0; i < files.size(); ++i){ + emit this->newFileOpened(files.at(i)); + } +} +void EchidnaEditor::handleNewFileOpened(QString filename){ + + QFile file(filename); + + + +} \ No newline at end of file diff --git a/src/met/editor.h b/src/met/editor.h new file mode 100644 index 0000000..7aecf04 --- /dev/null +++ b/src/met/editor.h @@ -0,0 +1,39 @@ +#include +#include +#include +namespace Ui +{ + class EchidnaEditor; +} + +class EchidnaEditor : public QMainWindow +{ + Q_OBJECT + +public: + explicit EchidnaEditor(QWidget *parent = nullptr); + ~EchidnaEditor(); + +private slots: + + void actionOpenFolder(); + void actionAddFolderToWorkspace(QString folder); + void actionOpenFile(); + void handleNewFileOpened(QString file); + +signals: + + void newFileOpened(QString file); + void newFolderOpened(); +private: + Ui::EchidnaEditor *ui; + std::vector *folders; + std::vector *files; +}; + + + + + + + diff --git a/src/met/main.cpp b/src/met/main.cpp new file mode 100644 index 0000000..cbaed37 --- /dev/null +++ b/src/met/main.cpp @@ -0,0 +1,14 @@ +#include +#include "editor.h" + +int main(int argc, char *argv[]){ + + QApplication EchidnaEditorApp(argc, argv); + + EchidnaEditor Editor; + + Editor.show(); + + EchidnaEditorApp.exec(); + +} \ No newline at end of file From 4e87067cc4366d1075fcbd7712f2370cef98e87b Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 15 Oct 2021 13:38:29 +0700 Subject: [PATCH 08/50] feat: remove C++/Qt code We are migrating to Rust rn. --- .vscode/c_cpp_properties.json | 19 --- .vscode/settings.json | 3 - CMakeLists.txt | 32 ----- src/CMakeLists.txt | 0 src/echidna.ui | 237 ---------------------------------- src/editor.cpp | 18 --- src/editor.h | 24 ---- src/main.cpp | 14 -- src/met/core-editor.cpp | 75 ----------- src/met/core-editor.h | 58 --------- src/met/editor.cpp | 64 --------- src/met/editor.h | 39 ------ src/met/main.cpp | 14 -- src/resources.qrc | 5 - 14 files changed, 602 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json delete mode 100644 .vscode/settings.json delete mode 100644 CMakeLists.txt delete mode 100644 src/CMakeLists.txt delete mode 100644 src/echidna.ui delete mode 100644 src/editor.cpp delete mode 100644 src/editor.h delete mode 100644 src/main.cpp delete mode 100644 src/met/core-editor.cpp delete mode 100644 src/met/core-editor.h delete mode 100644 src/met/editor.cpp delete mode 100644 src/met/editor.h delete mode 100644 src/met/main.cpp delete mode 100644 src/resources.qrc diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 56f828e..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**", - "/usr/include/qt/QtWidgets", - "/usr/include/qt" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c17", - "cppStandard": "c++14", - "intelliSenseMode": "linux-gcc-x64", - "configurationProvider": "ms-vscode.cmake-tools" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 473059c..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "cmake.configureOnOpen": true, -} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 5407626..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -CMake_Minimum_Required(VERSION 3.1.0) - -Project(echidna VERSION 0.0 LANGUAGES CXX) - -Set(CMAKE_CXX_STANDARD 11) -Set(CMAKE_CXX_STANDARD_REQUIRED ON) - -Set(CMAKE_AUTOMOC ON) -Set(CMAKE_AUTORCC ON) -Set(CMAKE_AUTOUIC ON) - - - -Find_Package(Qt5 COMPONENTS Widgets REQUIRED) - -add_subdirectory(src) - -file(GLOB SOURCES src/*.cpp) -file(GLOB HEADERS src/*.h) - -Add_Executable(echidna - ${SOURCES} - ${HEADERS} - src/echidna.ui - src/resources.qrc -) - - - -Target_Link_Libraries(echidna Qt5::Widgets) - - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/echidna.ui b/src/echidna.ui deleted file mode 100644 index cc597fd..0000000 --- a/src/echidna.ui +++ /dev/null @@ -1,237 +0,0 @@ - - - EchidnaEditor - - - - 0 - 0 - 770 - 559 - - - - Echidna Editor - - - - - - 0 - 490 - 801 - 21 - - - - background-color: #191A21 - - - - - - 270 - 290 - 531 - 201 - - - - 2 - - - - Problems - - - - - Output - - - - - Terminal - - - - - Debug Console - - - - - - - 0 - 0 - 271 - 491 - - - - QTabBar::tab { -width: 48px; -height: 48px; - -} - - - - QTabWidget::West - - - 0 - - - - Tab 1 - - - - - Tab 2 - - - - - - - - 0 - 0 - 770 - 25 - - - - - Edit - - - - - - - Selection - - - - - View - - - - Tabs - - - - - - - - - - - Go - - - - - Run - - - - - Terminal - - - - - Help - - - - - File - - - - New - - - - - - - - - - - - - - - - - - - - - New File - - - - - Undo - - - - - Redo - - - - - Problems - - - - - Output - - - - - Debug Console - - - - - Terminal - - - - - File - - - - - Open - - - - - Window - - - - - Save - - - - - - diff --git a/src/editor.cpp b/src/editor.cpp deleted file mode 100644 index 13faa5b..0000000 --- a/src/editor.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "editor.h" -#include - -EchidnaEditor::EchidnaEditor(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::EchidnaEditor) -{ - -ui->setupUi(this); -this->setCentralWidget(ui->centralWidget); - - - -} - -EchidnaEditor::~EchidnaEditor(){ - delete ui; -} diff --git a/src/editor.h b/src/editor.h deleted file mode 100644 index a355ca2..0000000 --- a/src/editor.h +++ /dev/null @@ -1,24 +0,0 @@ -#include - -namespace Ui { -class EchidnaEditor; -} - - -class EchidnaEditor : public QMainWindow -{ - Q_OBJECT - -public: - explicit EchidnaEditor(QWidget *parent = nullptr); - ~EchidnaEditor(); - -private slots: - void addFolderIntoWorkspace(){ - - } - -private: - Ui::EchidnaEditor *ui; - -}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index cbaed37..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include "editor.h" - -int main(int argc, char *argv[]){ - - QApplication EchidnaEditorApp(argc, argv); - - EchidnaEditor Editor; - - Editor.show(); - - EchidnaEditorApp.exec(); - -} \ No newline at end of file diff --git a/src/met/core-editor.cpp b/src/met/core-editor.cpp deleted file mode 100644 index 74108f3..0000000 --- a/src/met/core-editor.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "core-editor.h" - -EchidnaCoreEditor::EchidnaCoreEditor(QWidget *parent) : QPlainTextEdit(parent) { - LineNumberArea *lineNumber = new LineNumberArea(this); - - QObject::connect(this, &EchidnaCoreEditor::cursorPositionChanged, &EchidnaCoreEditor::highlightCurrentLine); - QObject::connect(this, &EchidnaCoreEditor::updateRequest, &EchidnaCoreEditor::updateLineNumberArea); - QObject::connect(this, &EchidnaCoreEditor::blockCountChanged, &EchidnaCoreEditor::updateLineNumberAreaWidth); - - this->highlightCurrentLine(); - this->updateLineNumberAreaWidth(0); -} - -EchidnaCoreEditor::~EchidnaCoreEditor(){ - -} - -int EchidnaCoreEditor::lineNumberAreaWidth(){ - -} - - -void EchidnaCoreEditor::lineNumberAreaPaintEvent(QPaintEvent *event){ - -} - -void EchidnaCoreEditor::resizeEvent(QResizeEvent *e){ - - QPlainTextEdit::resizeEvent(e); - - QRect contentsRect = this->contentsRect(); - - -} - - /** - * - * This function implements the functionaly that highlight the current line your cursor is currently on. - * - * TODO: Implement support for multi-line editing. - * - */ -void EchidnaCoreEditor::highlightCurrentLine(){ - - if(this->isReadOnly()){ - return; - } else { - QList selections; - - QTextEdit::ExtraSelection selection; - - selection.format.setProperty(QTextFormat::FullWidthSelection, true); - - QBrush selectionFormatBrush = selection.format.foreground(); - - - } - -} - - - -/* - -the method `set_menubar` exists for reference `&components::echidna_editor::imp::EchidnaEditor`, but its trait bounds were not satisfied - -method cannot be called on `&components::echidna_editor::imp::EchidnaEditor` due to unsatisfied trait bounds - -note: the following trait bounds were not satisfied: - `components::echidna_editor::imp::EchidnaEditor: glib::IsA` - which is required by `components::echidna_editor::imp::EchidnaEditor: gtk4::prelude::GtkApplicationExt` - `&components::echidna_editor::imp::EchidnaEditor: glib::IsA` - which is required by `&components::echidna_editor::imp::EchidnaEditor: gtk4::prelude::GtkApplicationExt` - -*/ diff --git a/src/met/core-editor.h b/src/met/core-editor.h deleted file mode 100644 index f27dab1..0000000 --- a/src/met/core-editor.h +++ /dev/null @@ -1,58 +0,0 @@ - -/* - - Echidna Core Text Editor. This is the Monaco replacement for Echidna. - - A lot of the code are ~~stolen~~ inspired from [Qt's Code Editor example](https://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html), with added features to replicate the Visual Studio Code experience. - -*/ - -#include - -class LineNumberArea : public QWidget -{ - -public: - LineNumberArea(EchidnaCoreEditor *editor) : QWidget(editor), coreEditor(editor) - { - } - - QSize sizeHint() const override - { - return QSize(coreEditor->lineNumberAreaWidth(), 0); - } - -protected: - void paintEvent(QPaintEvent *event) override - { - coreEditor->lineNumberAreaPaintEvent(event); - } - - EchidnaCoreEditor *coreEditor; -}; - -class EchidnaCoreEditor : public QPlainTextEdit -{ - Q_OBJECT - -public: - EchidnaCoreEditor(QWidget *parent = nullptr); - ~EchidnaCoreEditor(); - - void lineNumberAreaPaintEvent(QPaintEvent *event); - int lineNumberAreaWidth(); -protected: - void resizeEvent(QResizeEvent *event) override; - -private slots: - void highlightCurrentLine(); - void updateLineNumberAreaWidth(int newBlockCount); - void updateLineNumberArea(const QRect &rect, int dy); - - - LineNumberArea *lineNumber; -}; - - - - diff --git a/src/met/editor.cpp b/src/met/editor.cpp deleted file mode 100644 index bacc01c..0000000 --- a/src/met/editor.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "editor.h" -#include -#include -#include -#include - -EchidnaEditor::EchidnaEditor(QWidget *parent) : QMainWindow(parent), - ui(new Ui::EchidnaEditor) -{ - - ui->setupUi(this); - this->setCentralWidget(ui->centralWidget); - - QObject::connect(this, &EchidnaEditor::newFileOpened, &EchidnaEditor::handleNewFileOpened); -} - -EchidnaEditor::~EchidnaEditor() -{ - delete ui; -}; - -void EchidnaEditor::actionOpenFolder() -{ - QString dir = QFileDialog::getExistingDirectory(this, - "Add a Folder to Workspace", - QDir::homePath(), - QFileDialog::ShowDirsOnly); - - - std::vector::iterator foundExistingOpenedFolders = std::find_if(this->folders->begin(), this->folders->end(), - [&](QFileSystemModel *iterator) - { - return iterator->rootPath() == dir; - }); - if (this->folders->end() != foundExistingOpenedFolders) - { - } - else - { - QFileSystemModel *model = new QFileSystemModel; - model->setRootPath(dir); - - } - - -} - -void EchidnaEditor::actionOpenFile(){ - QStringList files = QFileDialog::getOpenFileNames(this, - "Open Files", - QDir::homePath() - ); - - for(int i = 0; i < files.size(); ++i){ - emit this->newFileOpened(files.at(i)); - } -} -void EchidnaEditor::handleNewFileOpened(QString filename){ - - QFile file(filename); - - - -} \ No newline at end of file diff --git a/src/met/editor.h b/src/met/editor.h deleted file mode 100644 index 7aecf04..0000000 --- a/src/met/editor.h +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include -namespace Ui -{ - class EchidnaEditor; -} - -class EchidnaEditor : public QMainWindow -{ - Q_OBJECT - -public: - explicit EchidnaEditor(QWidget *parent = nullptr); - ~EchidnaEditor(); - -private slots: - - void actionOpenFolder(); - void actionAddFolderToWorkspace(QString folder); - void actionOpenFile(); - void handleNewFileOpened(QString file); - -signals: - - void newFileOpened(QString file); - void newFolderOpened(); -private: - Ui::EchidnaEditor *ui; - std::vector *folders; - std::vector *files; -}; - - - - - - - diff --git a/src/met/main.cpp b/src/met/main.cpp deleted file mode 100644 index cbaed37..0000000 --- a/src/met/main.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include "editor.h" - -int main(int argc, char *argv[]){ - - QApplication EchidnaEditorApp(argc, argv); - - EchidnaEditor Editor; - - Editor.show(); - - EchidnaEditorApp.exec(); - -} \ No newline at end of file diff --git a/src/resources.qrc b/src/resources.qrc deleted file mode 100644 index d601a4b..0000000 --- a/src/resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file From c88f019285314a0bfdec4983d0d1b693954741c4 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 15 Oct 2021 13:39:13 +0700 Subject: [PATCH 09/50] feat: add untracked Qt files To be removed immediately as we are moving to GTK. --- ui/echidna-qt.ui | 253 +++++++++++++++++++++++++++++++++++++++++++++++ ui/resources.qrc | 5 + 2 files changed, 258 insertions(+) create mode 100644 ui/echidna-qt.ui create mode 100644 ui/resources.qrc diff --git a/ui/echidna-qt.ui b/ui/echidna-qt.ui new file mode 100644 index 0000000..59efb30 --- /dev/null +++ b/ui/echidna-qt.ui @@ -0,0 +1,253 @@ + + + EchidnaEditor + + + + 0 + 0 + 770 + 559 + + + + Echidna Editor + + + + + + 0 + 490 + 801 + 21 + + + + background-color: #191A21 + + + + + + 270 + 290 + 531 + 201 + + + + 2 + + + + Problems + + + + + Output + + + + + Terminal + + + + + Debug Console + + + + + + + 0 + 0 + 271 + 491 + + + + QTabBar::tab { +width: 48px; +height: 48px; + +} + + + + QTabWidget::West + + + 0 + + + + Tab 1 + + + + + Tab 2 + + + + + + + + 0 + 0 + 770 + 25 + + + + + Selection + + + + + View + + + + Tabs + + + + + + + + + + + Go + + + + + Run + + + + + Terminal + + + + + Help + + + + + + File + + + + New + + + + + + + Open + + + + + + + + + + + + + + + + + + + + + New File + + + + + Undo + + + + + Redo + + + + + Problems + + + + + Output + + + + + Debug Console + + + + + Terminal + + + + + File + + + + + Window + + + + + Save + + + + + File + + + + + Folder + + + + + Add Folder to Workspace + + + + + GitHub Repository + + + + + + diff --git a/ui/resources.qrc b/ui/resources.qrc new file mode 100644 index 0000000..d601a4b --- /dev/null +++ b/ui/resources.qrc @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From 737027151a93edf69311c8fda9730822184c4427 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 15 Oct 2021 13:40:06 +0700 Subject: [PATCH 10/50] feat: remove some Qt files --- ui/echidna-qt.ui | 253 ----------------------------------------------- ui/resources.qrc | 5 - 2 files changed, 258 deletions(-) delete mode 100644 ui/echidna-qt.ui delete mode 100644 ui/resources.qrc diff --git a/ui/echidna-qt.ui b/ui/echidna-qt.ui deleted file mode 100644 index 59efb30..0000000 --- a/ui/echidna-qt.ui +++ /dev/null @@ -1,253 +0,0 @@ - - - EchidnaEditor - - - - 0 - 0 - 770 - 559 - - - - Echidna Editor - - - - - - 0 - 490 - 801 - 21 - - - - background-color: #191A21 - - - - - - 270 - 290 - 531 - 201 - - - - 2 - - - - Problems - - - - - Output - - - - - Terminal - - - - - Debug Console - - - - - - - 0 - 0 - 271 - 491 - - - - QTabBar::tab { -width: 48px; -height: 48px; - -} - - - - QTabWidget::West - - - 0 - - - - Tab 1 - - - - - Tab 2 - - - - - - - - 0 - 0 - 770 - 25 - - - - - Selection - - - - - View - - - - Tabs - - - - - - - - - - - Go - - - - - Run - - - - - Terminal - - - - - Help - - - - - - File - - - - New - - - - - - - Open - - - - - - - - - - - - - - - - - - - - - New File - - - - - Undo - - - - - Redo - - - - - Problems - - - - - Output - - - - - Debug Console - - - - - Terminal - - - - - File - - - - - Window - - - - - Save - - - - - File - - - - - Folder - - - - - Add Folder to Workspace - - - - - GitHub Repository - - - - - - diff --git a/ui/resources.qrc b/ui/resources.qrc deleted file mode 100644 index d601a4b..0000000 --- a/ui/resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file From 3408ad2830e013161a8a8166a4df3d0e50d34bf0 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Mon, 18 Oct 2021 15:02:41 +0700 Subject: [PATCH 11/50] refactor: rewrite in Rust --- .gitignore | 5 + Cargo.lock | 772 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 15 + LICENSE | 386 ++++++++++++++++++++- README.md | 2 +- src/app/imp.rs | 216 ++++++++++++ src/app/mod.rs | 53 +++ src/app/workspace.rs | 182 ++++++++++ src/components/mod.rs | 5 + src/main.rs | 16 + src/metadata.rs | 1 + ui/menu.ui | 70 ++++ ui/window.ui | 42 +++ 13 files changed, 1747 insertions(+), 18 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/app/imp.rs create mode 100644 src/app/mod.rs create mode 100644 src/app/workspace.rs create mode 100644 src/components/mod.rs create mode 100644 src/main.rs create mode 100644 src/metadata.rs create mode 100644 ui/menu.ui create mode 100644 ui/window.ui diff --git a/.gitignore b/.gitignore index 21299f5..4ca0eac 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,8 @@ lib/* bin/* test/test_runner + + +# Added by cargo + +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fe5ac16 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,772 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cairo-rs" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9164355c892b026d6257e696dde5f3cb39beb3718297f0f161b562fe2ee3ab86" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80" +dependencies = [ + "glib-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "cfg-expr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571" +dependencies = [ + "smallvec", +] + +[[package]] +name = "echidna" +version = "0.1.0" +dependencies = [ + "gdk4", + "gio", + "glib", + "gtk4", + "relative-path", + "serde", + "serde_json", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "futures-channel" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" + +[[package]] +name = "futures-executor" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" + +[[package]] +name = "futures-task" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" + +[[package]] +name = "futures-util" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +dependencies = [ + "autocfg", + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gdk4" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c0f7f98ad25b81ac9462f74a091b0e4c0983ed1e74d19a38230c772b4dcef81" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262a79666b42e1884577f11a050439a964b95dec55343ac6ace7930e1415fa18" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps 4.0.0", +] + +[[package]] +name = "gio" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a29d8062af72045518271a2cd98b4e1617ce43f5b4223ad0fb9a0eff8f718c" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", + "winapi", +] + +[[package]] +name = "glib" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a930b7208e6e0ab839eea5f65ac2b82109f729621430d47fe905e2e09d33f4" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +dependencies = [ + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gobject-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +dependencies = [ + "glib-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "graphene-rs" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1460a39f06e491e6112f27e71e51435c833ba370723224dd1743dfd1f201f19" +dependencies = [ + "glib", + "graphene-sys", + "libc", +] + +[[package]] +name = "graphene-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d23fb7a9547e5f072a7e0cd49cd648fedeb786d122b106217511980cbb8962" +dependencies = [ + "glib-sys", + "libc", + "pkg-config", + "system-deps 3.2.0", +] + +[[package]] +name = "gsk4" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20b71f2e2cc699c2e0fbfa22899eeaffd84f9c1dc01e9263deac8664eec22dc0" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30468aff80e4faadf22f9ba164ea17511a69a9995d7a13827a13424ef47b2472" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps 4.0.0", +] + +[[package]] +name = "gtk4" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "906f9308d15789d96a736881582181d710ae0937197119df459f3d2b46ef6776" +dependencies = [ + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "once_cell", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0d008cdf23214c697482415dd20f666bdf3cc9f5e803b017223c17c5b59a6e" +dependencies = [ + "anyhow", + "heck", + "itertools", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06be0a6322aa77dd372f726e97efbcbb192d9a824a414a8874f238effd7747c" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps 4.0.0", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "libc" +version = "0.2.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "pango" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc88307d9797976ea62722ff2ec5de3fae279c6e20100ed3f49ca1a4bf3f96" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "relative-path" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9629de8974fd69c97684736786b807edd3da456d3e3f95341dd9d4cbd8f5ad6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "strum" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "system-deps" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +dependencies = [ + "anyhow", + "cfg-expr 0.8.1", + "heck", + "itertools", + "pkg-config", + "strum", + "strum_macros", + "thiserror", + "toml", + "version-compare", +] + +[[package]] +name = "system-deps" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c1889ab44c2a423ba9ba4d64cd04989b25c0280ca7ade813f05368418722a04" +dependencies = [ + "cfg-expr 0.9.0", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "thiserror" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..46e8d7d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "echidna" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +gtk = { version = "0.3.0", package = "gtk4" } +gio = { version = "0.14.6", package = "gio" } +glib = "0.14.5" +serde_json = "1.0.68" +serde = { version = "1.0.130", features = ["derive"] } +relative-path = "1.5.0" +gdk = { version = "0.3.0", package = "gdk4"} \ No newline at end of file diff --git a/LICENSE b/LICENSE index ddd20a0..ee6256c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,373 @@ -MIT License +Mozilla Public License Version 2.0 +================================== -Copyright (c) 2021 Operation Codebreaker +1. Definitions +-------------- -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at https://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/README.md b/README.md index de73fb3..fb14e5d 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Codebreaker \ No newline at end of file +# Echidna Code Editor diff --git a/src/app/imp.rs b/src/app/imp.rs new file mode 100644 index 0000000..1ca28f6 --- /dev/null +++ b/src/app/imp.rs @@ -0,0 +1,216 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + + + +use gtk::subclass::prelude::*; +use gtk::prelude::*; +use gtk::{ + ApplicationWindow, + Application, + FileChooserDialog, + FileChooserAction, + AboutDialog, + ResponseType +}; +use gio::{ + MenuModel, + SimpleAction, + Cancellable +}; +//use super::workspace; +use glib::clone; + +#[derive(Debug, Default)] +pub struct EchidnaEditor { + pub name: &'static str, + pub app_id: &'static str +} + + + + + +#[glib::object_subclass] +impl ObjectSubclass for EchidnaEditor { + const NAME: &'static str = "EchidnaEditorApplication"; + type Type = super::EchidnaEditor; + type ParentType = Application; + + fn new() -> Self { + Self { + name: "Echidna Code Editor", + app_id: "land.echidna.editor" + } + } +} + + + +impl EchidnaEditor { + + /* + Open a file and put it in an editor and the opened files bar. + + - Open a file chooser dialog. + - Connect a signal to it and get the file choosen. + - Read th file's information and + - TODO: if it's a plain text, + - TODO: Load the file's content + - TODO: Create an editor + - TODO: Set the editor's content to the file's content. + - TODO: Somehow keep track of what file belongs to what editor/opened file bar widget. + - TODO: If the user enables Autosave, listen to the editor's changes and automatically save the editor's content. + - TODO: Close the editor and the tab widget when the file is closed (triggered by the X button on them). + + Perhaps some of the last points should not be implemented in this function but rather in another function that keeps track of every files. + */ + fn action_open_file(window: ApplicationWindow, app: &Self, action: &SimpleAction, variant: Option<&glib::Variant>){ + + let dialog: FileChooserDialog = FileChooserDialog::new(Some("Open a file"), + Some(&window), + FileChooserAction::Open, + &[("Cancel", ResponseType::Cancel), + ("Open", ResponseType::Accept) ]); + + + dialog.set_visible(true); + + + + // TODO: Somehow inserts self to this function. + // This function sets the callback function as 'static, which for some reasons ban cloning self into it. Idk why. + dialog.connect_response(clone!(@weak window => + move |dialog, response| { + + if response == ResponseType::Accept { + + let file_option = dialog.file(); + + match file_option { + Some(file) => { + dialog.destroy(); + Self::open_file(file); + + }, + None => { + + }, + } + } else if response == ResponseType::Cancel { + dialog.destroy(); + + } })); + + } + + fn open_file(file: gio::File){ + let cancellable = Cancellable::new(); + let filepath = file.path(); + let file_info_result = file.query_info( + "*", + gio::FileQueryInfoFlags::NONE, + Some(&cancellable)); + + match file_info_result { + Ok(info) => { + match info.content_type() { + Some(content_type) => { + println!("Opened {} and found its content type is {}.", "file", content_type.to_string()); + let content_cancellable = Cancellable::new(); + let file_content = file.load_contents(Some(&content_cancellable)); + match file_content { + Ok(content) => { + let (int_vec, text_option) = content; + println!("The int vector of {:?} is {:?}", filepath, int_vec); + match text_option { + Some(text) => println!("Opened {:?} and its content is:\n{}", filepath, text.as_str()), + None => println!("No value for {:?}.", filepath), + } + } + Err(e) => println!("Could not open {:?} because:\n{:#?}", filepath, e), + } + }, + None => println!("It does not seem like {:?} has a type", filepath), + + } + + }, + Err(e) => println!("Could not retrieve file information for {:?} because:\n{}", filepath, e), + } + + + } + + +} + +impl ObjectImpl for EchidnaEditor { + + + +} + +impl ApplicationImpl for EchidnaEditor { + + fn activate(&self, app: &Self::Type){ + + let builder = gtk::Builder::from_string(include_str!("../../ui/window.ui")); + let window: ApplicationWindow = builder + .object("window") + .expect("Could not get object 'window' from builder."); + + let menubuilder = gtk::Builder::from_string(include_str!("../../ui/menu.ui")); + let menubar: MenuModel = menubuilder + .object("menu") + .expect("Could not get object 'menu' from builder."); + + app.set_menubar(Some(&menubar)); + + let act_exit: SimpleAction = SimpleAction::new("exit", None); + app.add_action(&act_exit); + + act_exit.connect_activate(clone!(@weak app => + move |_action, _value| { + app.quit(); + } + )); + + + let act_about: SimpleAction = SimpleAction::new("about", None); + app.add_action(&act_about); + act_about.connect_activate( |_action, _value| { + + let about_dialog: AboutDialog = AboutDialog::new(); + + + about_dialog.set_license_type(gtk::License::Mpl20); + about_dialog.set_program_name(Some("Echidna Code Editor")); + about_dialog.set_website(Some("https://gitlab.com/EchidnaHQ/Echidna")); + about_dialog.set_authors(&["FortressValkriye"]); + about_dialog.set_copyright(Some("Made with by ❤️ Echidna contributors")); + about_dialog.set_visible(true); + }); + + + let action_open_file: SimpleAction = SimpleAction::new("open-file", None); + + window.add_action(&action_open_file); + action_open_file.connect_activate(clone!(@weak window, @weak app => + move |action, variant| { + Self::action_open_file(window, Self::from_instance(&app), action, variant); + })); + window.set_application(Some(app)); + + window.present(); + + } + + + + +} + +impl GtkApplicationImpl for EchidnaEditor {} + diff --git a/src/app/mod.rs b/src/app/mod.rs new file mode 100644 index 0000000..56420dd --- /dev/null +++ b/src/app/mod.rs @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +pub mod imp; +pub mod workspace; + +use glib::wrapper; + + + +wrapper! { + pub struct EchidnaEditor(ObjectSubclass) @extends gio::Application, gtk::Application, @implements gio::ActionGroup, gio::ActionMap; +} + +impl Default for EchidnaEditor { + fn default() -> Self { + Self::new("land.echidna.editor") + + } + + +} + + +impl EchidnaEditor { + + + pub fn new( + app_id: &'static str) -> Self { + + let object = glib::Object::new(&[ + ("application-id", &app_id), + ("flags", &gio::ApplicationFlags::empty()) + ]); + + match object { + Ok(o) => o, + Err(e) => panic!("Error in making EchidnaApplication {}", e), + } + + + } + + + + + + + + +} + diff --git a/src/app/workspace.rs b/src/app/workspace.rs new file mode 100644 index 0000000..47b53f3 --- /dev/null +++ b/src/app/workspace.rs @@ -0,0 +1,182 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + + use std::path::Path; + use serde::{Deserialize, Serialize}; + use relative_path::RelativePath; + use gio::Cancellable; + use gio::{ + SimpleAction, + File, + FileQueryInfoFlags, + FileType +}; + use gtk::prelude::*; + use glib::clone; + use gtk::{ + ApplicationWindow, + FileChooserDialog, + FileChooserAction, + ResponseType, + TreeStore, +}; +use glib::types::Type; + +#[derive(Deserialize, Serialize)] +struct MonacoFolder { + path: String +} + +#[derive(Deserialize, Serialize)] +struct MonacoWorkspace { + folders: Vec +} + + pub fn action_open_workspace( + window: ApplicationWindow, + app: super::imp::EchidnaEditor, + _action: &SimpleAction, + _variant: Option<&glib::Variant>, + ) { + let dialog: FileChooserDialog = FileChooserDialog::new( + Some("Open a file"), + Some(&window), + FileChooserAction::Open, + &[ + ("Cancel", ResponseType::Cancel), + ("Open", ResponseType::Accept), + ], + ); + + dialog.set_visible(true); + + // TODO: Somehow inserts self to this function. + // This function sets the callback function as 'static, which for some reasons ban cloning self into it. Idk why. + dialog.connect_response(clone!(@weak window => + move |dialog, response| { + + if response == ResponseType::Accept { + + let file_option = dialog.file(); + + match file_option { + Some(file) => { + dialog.destroy(); + open_workspace(file); + }, + None => { + + }, + } + } else if response == ResponseType::Cancel { + dialog.destroy(); + + } })); + } +/** + * __Open Workspace__ + * + * Basically, this is just the same as Open Folder, but it's many folders. + * + * - Open a FileChooserDialog, set to only view .code-workspace files. + * - If the user pressed cancel, destroy the dialog. If the user opened a .code-workspace file: + * - Get the workspace file, load and parse its content, .code-workspace files are in JSON with comments. But JSON only should be fine, for now. + * - Iterate over folders listed in the workspace file. + * - Find the absolute path of the folder: Relative to the workspace file. + * - Create a GFile instance of that path, and call open_folder(file: File) and pass the GFile instance to it. + * + */ +pub fn open_workspace(file: File){ + let cancellable = Cancellable::new(); + let filepath_raw = &file.path().expect("Could not get the file path of the file."); + let filepath = Path::new(&filepath_raw); + let file_info_result = file.query_info( + "*", + gio::FileQueryInfoFlags::NONE, + Some(&cancellable)); + + match file_info_result { + Ok(info) => { + match info.content_type() { + Some(content_type) => { + println!("Opened {} and found its content type is {}.", "file", content_type.to_string()); + let content_cancellable = Cancellable::new(); + let file_content = file.load_contents(Some(&content_cancellable)); + match file_content { + Ok(content) => { + let (int_vec, _byte_string) = content; + + match serde_json::from_slice::(&int_vec) { + Ok(workspace) => for folder in workspace.folders { + let path = RelativePath::new(&folder.path); + + let folder = File::for_path(path.to_path(filepath)); + + // Do something with the folder, perhaps lists its child and . + open_folder(folder); + }, + Err(e) => println!("Could not parse {:#?} because of:\n{}", filepath, e), + } + } + Err(e) => println!("Could not open {:?} because:\n{}", filepath, e), + } + }, + None => println!("It does not seem like {:?} has a type", filepath), + + } + + }, + Err(e) => println!("Could not retrieve file information for {:?} because:\n{}", filepath, e), + } + + } + + + +/** + * + * + */ +fn recursive_add_files_into_tree_store(parent_file: File, tree: TreeStore){ + let child_enumerate_cancellable = Cancellable::new(); + let child_files = parent_file.enumerate_children("*", FileQueryInfoFlags::NONE, Some(&child_enumerate_cancellable)); + let filepath = &parent_file.path().expect("Could not get the file path of the file."); + match child_files { + Ok(files) => { + for file_iter in files { + match file_iter { + Ok(file_info) => { + let file = parent_file.child(file_info.name()); + let tree_iter = tree.append(None); + tree.set_value(&tree_iter, 2, &file_info.name().to_str().to_value()); + + if file_info.file_type() == FileType::Directory { + recursive_add_files_into_tree_store(file, tree); + + } + + }, + Err(e) => println!("Could not get information on file because of:\n{}", e) + } + + } + + }, + Err(e) => println!("Could not look up the children files of {:?} because:\n{:#?}", filepath, e) + } +} + +/* + Loads a folder into the tree view. + + - Create a new tree + - Enumerate over child files of 'file'. (PS: In the Unix family of OS-es, directories are files too) + */ +pub fn open_folder(file: File){ + let tree = TreeStore::new(&[gdk::Texture::static_type(), Type::STRING]); + recursive_add_files_into_tree_store(file, tree); + + + + } \ No newline at end of file diff --git a/src/components/mod.rs b/src/components/mod.rs new file mode 100644 index 0000000..7a10ed2 --- /dev/null +++ b/src/components/mod.rs @@ -0,0 +1,5 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +pub mod app; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5bb4936 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +mod app; + +use gtk::prelude::ApplicationExtManual; +use app::EchidnaEditor; + +fn main() { + let app = EchidnaEditor::new( + "land.echidna.editor", + ); + + std::process::exit(app.run()); +} \ No newline at end of file diff --git a/src/metadata.rs b/src/metadata.rs new file mode 100644 index 0000000..77c261f --- /dev/null +++ b/src/metadata.rs @@ -0,0 +1 @@ +"Echidna Code Editor"; diff --git a/ui/menu.ui b/ui/menu.ui new file mode 100644 index 0000000..8bc48f3 --- /dev/null +++ b/ui/menu.ui @@ -0,0 +1,70 @@ + + + + + + File +
+ + New File + win.new-file + + + New Window app.new-window + +
+
+ + Open File win.open-file + + + Open Folder + win.open-folder + + + Open Workspace + win.open-workspace + +
+
+ + Add Folder to Workspace + win.add-folder-to-workspace + + + Save Workspace As + win.save-workspace + + + Duplicate Workspace + win.duplicate-workspace + +
+
+ + Save + win.save + + + Save All + win.save-all + +
+
+ + Exit + app.exit + +
+
+ + Help +
+ + About + app.about + +
+
+
+
diff --git a/ui/window.ui b/ui/window.ui new file mode 100644 index 0000000..586b8c4 --- /dev/null +++ b/ui/window.ui @@ -0,0 +1,42 @@ + + + + + + + vertical + + + 1 + + + + + + + + + 1 + + + + + + + + + + 10 + 10 + 10 + 10 + 6 + 6 + + + + + + + + From 6dcbc7117d1b66a594fb4a9a48367bf387fc8112 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Wed, 20 Oct 2021 11:53:45 +0700 Subject: [PATCH 12/50] feat: set default title, width, and height for window --- ui/window.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/window.ui b/ui/window.ui index 586b8c4..87a5dbc 100644 --- a/ui/window.ui +++ b/ui/window.ui @@ -2,6 +2,9 @@ + Echidna Code Editor + 800 + 600 vertical From 9b56dd086bd8e69f217d7708f9646b50144106f8 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 09:24:00 +0700 Subject: [PATCH 13/50] chore: remove metadata.rs --- src/metadata.rs | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/metadata.rs diff --git a/src/metadata.rs b/src/metadata.rs deleted file mode 100644 index 77c261f..0000000 --- a/src/metadata.rs +++ /dev/null @@ -1 +0,0 @@ -"Echidna Code Editor"; From 6adbdd38f29812b1b882108080ba61d16a357696 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 09:44:49 +0700 Subject: [PATCH 14/50] refactor: move menubar code to menubar.rs --- src/app/menubar.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/app/menubar.rs diff --git a/src/app/menubar.rs b/src/app/menubar.rs new file mode 100644 index 0000000..eba4474 --- /dev/null +++ b/src/app/menubar.rs @@ -0,0 +1,86 @@ +use super::imp::EchidnaEditor; +use super::imp::EchidnaEditorExt; +use gio::{MenuModel, SimpleAction}; +use glib::clone; +use gtk::prelude::*; +use gtk::AboutDialog; + +pub trait MenubarImplementedEditor { + fn setup_menubar( + &self, + app: &super::EchidnaEditor, + window: gtk::ApplicationWindow, + builder: gtk::Builder, + ); +} + +impl MenubarImplementedEditor for EchidnaEditor { + fn setup_menubar( + &self, + app: &super::EchidnaEditor, + window: gtk::ApplicationWindow, + builder: gtk::Builder, + ) { + let menubuilder = gtk::Builder::from_string(include_str!("../../ui/menu.ui")); + let menubar: MenuModel = menubuilder + .object("menu") + .expect("Could not get object 'menu' from builder."); + app.set_menubar(Some(&menubar)); + window.set_show_menubar(true); + let act_exit: SimpleAction = SimpleAction::new("exit", None); + app.add_action(&act_exit); + + act_exit.connect_activate(clone!(@weak app => + move |_action, _value| { + app.quit(); + } + )); + + let act_about: SimpleAction = SimpleAction::new("about", None); + app.add_action(&act_about); + act_about.connect_activate(|_action, _value| { + let about_dialog: AboutDialog = AboutDialog::new(); + + about_dialog.set_license_type(gtk::License::Mpl20); + about_dialog.set_program_name(Some("Echidna Code Editor")); + about_dialog.set_website(Some("https://gitlab.com/EchidnaHQ/Echidna")); + about_dialog.set_authors(&["FortressValkriye"]); + about_dialog.set_copyright(Some("Made with by ❤️ Echidna contributors")); + about_dialog.set_visible(true); + }); + + let notebook: gtk::Notebook = builder + .object("echidna-notebook") + .expect("Could not get 'echidna-notebook' from builder."); + //app.notebook = Some(Rc::new(RefCell::new(notebook))); + let act_exit: SimpleAction = SimpleAction::new("exit", None); + app.add_action(&act_exit); + + act_exit.connect_activate(clone!(@weak app => + move |_action, _value| { + app.quit(); + } + )); + + let act_about: SimpleAction = SimpleAction::new("about", None); + app.add_action(&act_about); + act_about.connect_activate(|_action, _value| { + let about_dialog: AboutDialog = AboutDialog::new(); + + about_dialog.set_license_type(gtk::License::Mpl20); + about_dialog.set_program_name(Some("Echidna Code Editor")); + about_dialog.set_website(Some("https://gitlab.com/EchidnaHQ/Echidna")); + about_dialog.set_authors(&["FortressValkriye"]); + about_dialog.set_copyright(Some("Made with by ❤️ Echidna contributors")); + about_dialog.set_visible(true); + }); + + let action_open_file: SimpleAction = SimpleAction::new("open-file", None); + + window.add_action(&action_open_file); + action_open_file.connect_activate(clone!(@weak window, @weak app, @weak notebook => + move |action, variant| { + Self::action_open_file(window, app, action, variant, notebook); + })); + } +} From d4670be8b4c30b6fccaf8b3913d9bcc65fd68bd8 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:12:41 +0700 Subject: [PATCH 15/50] chore: add a GtkNotebook to window.ui --- ui/window.ui | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/ui/window.ui b/ui/window.ui index 87a5dbc..f45375e 100644 --- a/ui/window.ui +++ b/ui/window.ui @@ -1,8 +1,8 @@ - + - Echidna Code Editor + Echidna Code Editor 800 600 @@ -12,18 +12,30 @@ 1 - + - + - + + + + + Hello from Echidna! + + + + + Welcome + + @@ -35,11 +47,9 @@ 10 6 6 - - - + \ No newline at end of file From c3e76bccb24427db15499beaa84d6864f4c1b0e6 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:13:14 +0700 Subject: [PATCH 16/50] feat: import menubar from app/mod.rs --- src/app/mod.rs | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index 56420dd..b98bcfb 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -3,51 +3,30 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ pub mod imp; +pub mod menubar; pub mod workspace; - use glib::wrapper; - - wrapper! { pub struct EchidnaEditor(ObjectSubclass) @extends gio::Application, gtk::Application, @implements gio::ActionGroup, gio::ActionMap; } impl Default for EchidnaEditor { fn default() -> Self { - Self::new("land.echidna.editor") - + Self::new("land.echidna.editor") } - - } - impl EchidnaEditor { - - - pub fn new( - app_id: &'static str) -> Self { - - let object = glib::Object::new(&[ + pub fn new(app_id: &'static str) -> Self { + let object = glib::Object::new(&[ ("application-id", &app_id), - ("flags", &gio::ApplicationFlags::empty()) + ("flags", &gio::ApplicationFlags::empty()), ]); - match object { - Ok(o) => o, - Err(e) => panic!("Error in making EchidnaApplication {}", e), - } - - + match object { + Ok(o) => o, + Err(e) => panic!("Error in making EchidnaApplication {}", e), + } } - - - - - - - - } - From c62d8ae5862a840b7f90b41b324f068a9ec7cf6b Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:13:32 +0700 Subject: [PATCH 17/50] deps: add sourceview5 to deps --- Cargo.lock | 35 +++++++++++++++++++++++++++++++++++ Cargo.toml | 3 ++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index fe5ac16..22d9c21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,7 @@ dependencies = [ "relative-path", "serde", "serde_json", + "sourceview5", ] [[package]] @@ -630,6 +631,40 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +[[package]] +name = "sourceview5" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2f8375300de56f43ef03876a8c6ede4be89ea994b76e0f07e080aeb43c6dc3" +dependencies = [ + "bitflags", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "gtk4", + "libc", + "pango", + "sourceview5-sys", +] + +[[package]] +name = "sourceview5-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be3031333cb0f2300aa9e57a25b82f9c9c915dce25b81ac703fbe9a4e6e8986" +dependencies = [ + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk4-sys", + "libc", + "pango-sys", + "system-deps 4.0.0", +] + [[package]] name = "strum" version = "0.21.0" diff --git a/Cargo.toml b/Cargo.toml index 46e8d7d..0516f82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ glib = "0.14.5" serde_json = "1.0.68" serde = { version = "1.0.130", features = ["derive"] } relative-path = "1.5.0" -gdk = { version = "0.3.0", package = "gdk4"} \ No newline at end of file +gdk = { version = "0.3.0", package = "gdk4"} +sourceview = { package = "sourceview5", version = "0.3.0"} \ No newline at end of file From 3c7a4b3bbc63d356ef2f9a28ea6d9ee1a7b70a1c Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:18:53 +0700 Subject: [PATCH 18/50] chore(ui): add more menus to menu.ui --- ui/menu.ui | 179 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 137 insertions(+), 42 deletions(-) diff --git a/ui/menu.ui b/ui/menu.ui index 8bc48f3..6f66721 100644 --- a/ui/menu.ui +++ b/ui/menu.ui @@ -1,6 +1,6 @@ - + File @@ -10,61 +10,156 @@ win.new-file - New Window app.new-window + New Window + app.new-window
- Open File win.open-file - + Open File + win.open-file + Open Folder win.open-folder - - Open Workspace - win.open-workspace - -
-
- - Add Folder to Workspace - win.add-folder-to-workspace - - - Save Workspace As - win.save-workspace - - - Duplicate Workspace - win.duplicate-workspace - -
-
- - Save - win.save - - - Save All - win.save-all - -
-
- - Exit - app.exit - -
+ + Open Workspace + win.open-workspace + + +
+ + Add Folder to Workspace + win.add-folder-to-workspace + + + Save Workspace As + win.save-workspace + + + Duplicate Workspace + win.duplicate-workspace + +
+
+ + Save + win.save + + + Save All + win.save-all + +
+
+ + Close Window + + +
+
+ + Exit + app.exit + +
+
+ + Edit +
+ + Undo + win.undo + + + Redo + win.redo + +
+
+ + Cut + win.cut + +
+
+ + Selection +
+ + Select All + win.select-all + +
+
+ + View +
+ + Open Command Palette + +
+
+ + Go +
+ + Switch Editor + win.switch-editor + +
+
+ + Run +
+ + Start Debugging + win.start-debugging + +
+
+ + Terminal +
+ + New Terminal + win.new-terminal + +
Help +
+ + Get Started + window.get-started + + + Show All Commands + win.show-all-commands + + + Documentation + app.open-docs + +
+
+ + View License + +
+
+ + Search Feature Requests + +
About app.about
-
-
-
+ + + \ No newline at end of file From d9c91f3431714164dd4b9dff894ccb41a554d971 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:30:49 +0700 Subject: [PATCH 19/50] refactor: replace menubar code from imp.rs with MenubarImplementedEditor::setup_menubar() --- src/app/imp.rs | 79 ++++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 54 deletions(-) diff --git a/src/app/imp.rs b/src/app/imp.rs index 1ca28f6..b1877a4 100644 --- a/src/app/imp.rs +++ b/src/app/imp.rs @@ -2,18 +2,23 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - - +use std::str::from_utf8; +use sourceview::{View, Buffer, LanguageManager, }; +use sourceview::prelude::*; use gtk::subclass::prelude::*; use gtk::prelude::*; +use std::rc::Rc; +use super::menubar::MenubarImplementedEditor; use gtk::{ ApplicationWindow, Application, FileChooserDialog, FileChooserAction, - AboutDialog, - ResponseType + ResponseType, + Label + }; + use gio::{ MenuModel, SimpleAction, @@ -153,62 +158,28 @@ impl ObjectImpl for EchidnaEditor { } impl ApplicationImpl for EchidnaEditor { - + fn activate(&self, app: &Self::Type){ - let builder = gtk::Builder::from_string(include_str!("../../ui/window.ui")); - let window: ApplicationWindow = builder - .object("window") - .expect("Could not get object 'window' from builder."); - - let menubuilder = gtk::Builder::from_string(include_str!("../../ui/menu.ui")); - let menubar: MenuModel = menubuilder - .object("menu") - .expect("Could not get object 'menu' from builder."); - - app.set_menubar(Some(&menubar)); - - let act_exit: SimpleAction = SimpleAction::new("exit", None); - app.add_action(&act_exit); - - act_exit.connect_activate(clone!(@weak app => - move |_action, _value| { - app.quit(); - } - )); - - - let act_about: SimpleAction = SimpleAction::new("about", None); - app.add_action(&act_about); - act_about.connect_activate( |_action, _value| { - - let about_dialog: AboutDialog = AboutDialog::new(); - - - about_dialog.set_license_type(gtk::License::Mpl20); - about_dialog.set_program_name(Some("Echidna Code Editor")); - about_dialog.set_website(Some("https://gitlab.com/EchidnaHQ/Echidna")); - about_dialog.set_authors(&["FortressValkriye"]); - about_dialog.set_copyright(Some("Made with by ❤️ Echidna contributors")); - about_dialog.set_visible(true); - }); - + let builder = gtk::Builder::from_string(include_str!("../../ui/window.ui")); + let window: ApplicationWindow = builder + .object("window") + .expect("Could not get object 'window' from builder."); - let action_open_file: SimpleAction = SimpleAction::new("open-file", None); + let menubuilder = gtk::Builder::from_string(include_str!("../../ui/menu.ui")); + let menubar: MenuModel = menubuilder + .object("menu") + .expect("Could not get object 'menu' from builder."); - window.add_action(&action_open_file); - action_open_file.connect_activate(clone!(@weak window, @weak app => - move |action, variant| { - Self::action_open_file(window, Self::from_instance(&app), action, variant); - })); - window.set_application(Some(app)); + self.setup_menubar(app, window, builder); + let notebook: gtk::Notebook = builder + .object("echidna-notebook") + .expect("Could not get 'echidna-notebook' from builder."); + window.set_application(Some(app)); - window.present(); + window.present(); - } - - - + } } From e4e226fe81558499eab934aa1750fb24ea2efa6e Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:35:14 +0700 Subject: [PATCH 20/50] refactor: put all our own imp::EchidnaEditor methods into EchidnaEditorExt trait --- src/app/imp.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/app/imp.rs b/src/app/imp.rs index b1877a4..0edfecf 100644 --- a/src/app/imp.rs +++ b/src/app/imp.rs @@ -33,7 +33,10 @@ pub struct EchidnaEditor { pub app_id: &'static str } - +pub trait EchidnaEditorExt { + fn action_open_file(window: ApplicationWindow, app: super::EchidnaEditor, action: &SimpleAction, variant: Option<&glib::Variant>, notebook: gtk::Notebook); + fn open_file(notebook: >k::Notebook, file: gio::File); +} @@ -47,13 +50,13 @@ impl ObjectSubclass for EchidnaEditor { Self { name: "Echidna Code Editor", app_id: "land.echidna.editor" - } + } } } -impl EchidnaEditor { +impl EchidnaEditorExt for EchidnaEditor { /* Open a file and put it in an editor and the opened files bar. @@ -71,7 +74,7 @@ impl EchidnaEditor { Perhaps some of the last points should not be implemented in this function but rather in another function that keeps track of every files. */ - fn action_open_file(window: ApplicationWindow, app: &Self, action: &SimpleAction, variant: Option<&glib::Variant>){ + fn action_open_file(window: ApplicationWindow, app: super::EchidnaEditor, _action: &SimpleAction, variant: Option<&glib::Variant>, notebook: gtk::Notebook){ let dialog: FileChooserDialog = FileChooserDialog::new(Some("Open a file"), Some(&window), @@ -110,7 +113,7 @@ impl EchidnaEditor { } - fn open_file(file: gio::File){ + fn open_file(notebook: >k::Notebook, file: gio::File){ let cancellable = Cancellable::new(); let filepath = file.path(); let file_info_result = file.query_info( From 5a610f7be5e64b48274e088fcf02b4b953e8bcdb Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:36:07 +0700 Subject: [PATCH 21/50] refactor: put all workspace-related functions to WorkspaceImplementedEditor trait --- src/app/workspace.rs | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/app/workspace.rs b/src/app/workspace.rs index 47b53f3..e0d92e2 100644 --- a/src/app/workspace.rs +++ b/src/app/workspace.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + use glib::subclass::types::ObjectSubclassExt; + use super::imp::EchidnaEditor; use std::path::Path; use serde::{Deserialize, Serialize}; use relative_path::RelativePath; @@ -32,10 +34,27 @@ struct MonacoFolder { struct MonacoWorkspace { folders: Vec } + +trait WorkspaceImplementedEditor { + fn action_open_workspace( + &self, + window: ApplicationWindow, + app: super::EchidnaEditor, + _action: &SimpleAction, + _variant: Option<&glib::Variant>, + ); + + fn open_workspace(&self, file: File); + fn recursive_add_files_into_tree_store(&self, parent_file: File, tree: &TreeStore); + fn open_folder(&self, file: File); +} + +impl WorkspaceImplementedEditor for EchidnaEditor { - pub fn action_open_workspace( - window: ApplicationWindow, - app: super::imp::EchidnaEditor, + fn action_open_workspace( + &self, + window: ApplicationWindow, + app: super::EchidnaEditor, _action: &SimpleAction, _variant: Option<&glib::Variant>, ) { @@ -53,7 +72,7 @@ struct MonacoWorkspace { // TODO: Somehow inserts self to this function. // This function sets the callback function as 'static, which for some reasons ban cloning self into it. Idk why. - dialog.connect_response(clone!(@weak window => + dialog.connect_response(clone!(@weak window, @weak app => move |dialog, response| { if response == ResponseType::Accept { @@ -63,7 +82,7 @@ struct MonacoWorkspace { match file_option { Some(file) => { dialog.destroy(); - open_workspace(file); + Self::from_instance(&app).open_workspace(file); }, None => { @@ -87,7 +106,7 @@ struct MonacoWorkspace { * - Create a GFile instance of that path, and call open_folder(file: File) and pass the GFile instance to it. * */ -pub fn open_workspace(file: File){ +fn open_workspace(&self, file: File){ let cancellable = Cancellable::new(); let filepath_raw = &file.path().expect("Could not get the file path of the file."); let filepath = Path::new(&filepath_raw); @@ -114,7 +133,7 @@ pub fn open_workspace(file: File){ let folder = File::for_path(path.to_path(filepath)); // Do something with the folder, perhaps lists its child and . - open_folder(folder); + self.open_folder(folder); }, Err(e) => println!("Could not parse {:#?} because of:\n{}", filepath, e), } @@ -138,7 +157,7 @@ pub fn open_workspace(file: File){ * * */ -fn recursive_add_files_into_tree_store(parent_file: File, tree: TreeStore){ +fn recursive_add_files_into_tree_store(&self, parent_file: File, tree: &TreeStore){ let child_enumerate_cancellable = Cancellable::new(); let child_files = parent_file.enumerate_children("*", FileQueryInfoFlags::NONE, Some(&child_enumerate_cancellable)); let filepath = &parent_file.path().expect("Could not get the file path of the file."); @@ -152,7 +171,7 @@ fn recursive_add_files_into_tree_store(parent_file: File, tree: TreeStore){ tree.set_value(&tree_iter, 2, &file_info.name().to_str().to_value()); if file_info.file_type() == FileType::Directory { - recursive_add_files_into_tree_store(file, tree); + self.recursive_add_files_into_tree_store(file, tree); } @@ -173,10 +192,11 @@ fn recursive_add_files_into_tree_store(parent_file: File, tree: TreeStore){ - Create a new tree - Enumerate over child files of 'file'. (PS: In the Unix family of OS-es, directories are files too) */ -pub fn open_folder(file: File){ +fn open_folder(&self, file: File){ let tree = TreeStore::new(&[gdk::Texture::static_type(), Type::STRING]); - recursive_add_files_into_tree_store(file, tree); + self.recursive_add_files_into_tree_store(file, &tree); - } \ No newline at end of file + } +} \ No newline at end of file From 78fd55310481cda87bea03176adc497417fa9fea Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:36:47 +0700 Subject: [PATCH 22/50] feat: implement opening a file to a new editor --- src/app/imp.rs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/app/imp.rs b/src/app/imp.rs index 0edfecf..4b1e99c 100644 --- a/src/app/imp.rs +++ b/src/app/imp.rs @@ -89,7 +89,7 @@ impl EchidnaEditorExt for EchidnaEditor { // TODO: Somehow inserts self to this function. // This function sets the callback function as 'static, which for some reasons ban cloning self into it. Idk why. - dialog.connect_response(clone!(@weak window => + dialog.connect_response(clone!( @weak app, @weak window, => move |dialog, response| { if response == ResponseType::Accept { @@ -98,8 +98,9 @@ impl EchidnaEditorExt for EchidnaEditor { match file_option { Some(file) => { - dialog.destroy(); - Self::open_file(file); + dialog.destroy(); + + Self::open_file(¬ebook, file); }, None => { @@ -115,12 +116,11 @@ impl EchidnaEditorExt for EchidnaEditor { fn open_file(notebook: >k::Notebook, file: gio::File){ let cancellable = Cancellable::new(); - let filepath = file.path(); + let filepath = file.path().expect("No filepath"); let file_info_result = file.query_info( "*", gio::FileQueryInfoFlags::NONE, Some(&cancellable)); - match file_info_result { Ok(info) => { match info.content_type() { @@ -130,12 +130,23 @@ impl EchidnaEditorExt for EchidnaEditor { let file_content = file.load_contents(Some(&content_cancellable)); match file_content { Ok(content) => { - let (int_vec, text_option) = content; - println!("The int vector of {:?} is {:?}", filepath, int_vec); - match text_option { - Some(text) => println!("Opened {:?} and its content is:\n{}", filepath, text.as_str()), - None => println!("No value for {:?}.", filepath), + let (int_vec, _text_option) = content; + let language_manager = LanguageManager::new(); + let language = language_manager.guess_language(Some(&info.name().to_str().expect("Could not open the file because its name is not supported by Unicode.")), None); + + let buffer = Buffer::new(None); + buffer.set_text(from_utf8(&int_vec).expect(format!("Could not parse the contents of {:?} as it's unsupported by UTF-8", filepath).as_str())); + match language { + Some(lang) => buffer.set_language(Some(&lang)), + None => {} } + + let sourceview = View::with_buffer(&buffer); + + notebook.prepend_page(&sourceview, + Some(&Label::new(Some(&info.name().to_str() + .expect("Could not parse file's name"))))); + } Err(e) => println!("Could not open {:?} because:\n{:#?}", filepath, e), } From 67a1f0057ea7c55966501940465ddccb72fe86d6 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 10:37:12 +0700 Subject: [PATCH 23/50] chore(clippy): set "clippy::style" rule to deny --- clippy.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 clippy.toml diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..171c603 --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +"clippy::style" = "deny" \ No newline at end of file From d38ad0627c4f8b40e558204120c3cfb67d9ce149 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 13:16:13 +0700 Subject: [PATCH 24/50] feat: implement win.close action --- src/app/menubar.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/app/menubar.rs b/src/app/menubar.rs index eba4474..98dc3a9 100644 --- a/src/app/menubar.rs +++ b/src/app/menubar.rs @@ -9,8 +9,8 @@ pub trait MenubarImplementedEditor { fn setup_menubar( &self, app: &super::EchidnaEditor, - window: gtk::ApplicationWindow, - builder: gtk::Builder, + window: >k::ApplicationWindow, + builder: >k::Builder, ); } @@ -18,8 +18,8 @@ impl MenubarImplementedEditor for EchidnaEditor { fn setup_menubar( &self, app: &super::EchidnaEditor, - window: gtk::ApplicationWindow, - builder: gtk::Builder, + window: >k::ApplicationWindow, + builder: >k::Builder, ) { let menubuilder = gtk::Builder::from_string(include_str!("../../ui/menu.ui")); let menubar: MenuModel = menubuilder @@ -75,6 +75,17 @@ impl MenubarImplementedEditor for EchidnaEditor { about_dialog.set_visible(true); }); + + let act_window_close = SimpleAction::new("close", None); + + window.add_action(&act_window_close); + + act_window_close.connect_activate(clone!(@weak window => + move | _action, _variant | { + window.close(); + } + )); + let action_open_file: SimpleAction = SimpleAction::new("open-file", None); window.add_action(&action_open_file); From 1e1da03c76da63d9a87dcac6c1c2f3d4650d98c2 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 19:19:23 +0700 Subject: [PATCH 25/50] feat: implement app.report-issue and app.search-feature-requests actions --- Cargo.lock | 118 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 17 ++++--- src/app/menubar.rs | 16 +++++- 3 files changed, 142 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22d9c21..d08c660 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bumpalo" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" + [[package]] name = "cairo-rs" version = "0.14.7" @@ -62,6 +68,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "echidna" version = "0.1.0" @@ -74,6 +86,7 @@ dependencies = [ "serde", "serde_json", "sourceview5", + "webbrowser", ] [[package]] @@ -424,12 +437,36 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + [[package]] name = "memoffset" version = "0.6.4" @@ -784,6 +821,87 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecad156490d6b620308ed411cfee90d280b3cbd13e189ea0d3fada8acc89158a" +dependencies = [ + "web-sys", + "widestring", + "winapi", +] + +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 0516f82..1343bdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,12 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -gtk = { version = "0.3.0", package = "gtk4" } -gio = { version = "0.14.6", package = "gio" } -glib = "0.14.5" -serde_json = "1.0.68" -serde = { version = "1.0.130", features = ["derive"] } -relative-path = "1.5.0" -gdk = { version = "0.3.0", package = "gdk4"} -sourceview = { package = "sourceview5", version = "0.3.0"} \ No newline at end of file +gtk = { version = "^0.3.0", package = "gtk4" } +gio = { version = "^0.14.6", package = "gio" } +glib = "^0.14.5" +serde_json = "^1.0.68" +serde = { version = "^1.0.130", features = ["derive"] } +relative-path = "^1.5.0" +gdk = { version = "^0.3.0", package = "gdk4"} +sourceview = { package = "sourceview5", version = "^0.3.0"} +webbrowser = { version = "^0.5.5" } \ No newline at end of file diff --git a/src/app/menubar.rs b/src/app/menubar.rs index 98dc3a9..9682342 100644 --- a/src/app/menubar.rs +++ b/src/app/menubar.rs @@ -75,12 +75,26 @@ impl MenubarImplementedEditor for EchidnaEditor { about_dialog.set_visible(true); }); + let act_report_issue = SimpleAction::new("report-issue", None); + + app.add_action(&act_report_issue); + + act_report_issue.connect_activate(|_action, _variant| { + webbrowser::open("https://github.com/EchidnaHQ/Echidna/issues/new"); + }); + let act_search_feature_requests = SimpleAction::new("search-feature-requests", None); + + app.add_action(&act_search_feature_requests); + + act_search_feature_requests.connect_activate(|_action, _variant| { + webbrowser::open("https://github.com/EchidnaHQ/Echidna/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement"); + }); let act_window_close = SimpleAction::new("close", None); window.add_action(&act_window_close); - act_window_close.connect_activate(clone!(@weak window => + act_window_close.connect_activate(clone!(@weak window => move | _action, _variant | { window.close(); } From 842044ddde31948cbd965530d134f4f1d7bc76c2 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 19:20:38 +0700 Subject: [PATCH 26/50] chore(ui): add win.close to menu.ui --- ui/menu.ui | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/menu.ui b/ui/menu.ui index 6f66721..ffb3dcc 100644 --- a/ui/menu.ui +++ b/ui/menu.ui @@ -55,7 +55,7 @@
Close Window - + win.close
@@ -147,11 +147,17 @@
View License + app.view-license
Search Feature Requests + app.search-feature-requests + + + Report Issue + app.report-issue
From 48c87b9214e7d2f832096f415d937c672f281780 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 19:21:31 +0700 Subject: [PATCH 27/50] refactor: remove unecessarily getting the notebook in imp.rs --- src/app/imp.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/app/imp.rs b/src/app/imp.rs index 4b1e99c..d4643f8 100644 --- a/src/app/imp.rs +++ b/src/app/imp.rs @@ -7,7 +7,6 @@ use sourceview::{View, Buffer, LanguageManager, }; use sourceview::prelude::*; use gtk::subclass::prelude::*; use gtk::prelude::*; -use std::rc::Rc; use super::menubar::MenubarImplementedEditor; use gtk::{ ApplicationWindow, @@ -185,10 +184,8 @@ impl ApplicationImpl for EchidnaEditor { .object("menu") .expect("Could not get object 'menu' from builder."); - self.setup_menubar(app, window, builder); - let notebook: gtk::Notebook = builder - .object("echidna-notebook") - .expect("Could not get 'echidna-notebook' from builder."); + self.setup_menubar(app, &window, &builder.clone()); + window.set_application(Some(app)); window.present(); From b68e93c3d40c92fbfc27c72547ae07b3679650e9 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Fri, 22 Oct 2021 20:04:40 +0700 Subject: [PATCH 28/50] refactor: change repo url in about dialog to the GitHub one --- src/app/menubar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/menubar.rs b/src/app/menubar.rs index 9682342..e8da0fb 100644 --- a/src/app/menubar.rs +++ b/src/app/menubar.rs @@ -69,7 +69,7 @@ impl MenubarImplementedEditor for EchidnaEditor { about_dialog.set_license_type(gtk::License::Mpl20); about_dialog.set_program_name(Some("Echidna Code Editor")); - about_dialog.set_website(Some("https://gitlab.com/EchidnaHQ/Echidna")); + about_dialog.set_website(Some("https://github.com/EchidnaHQ/Echidna")); about_dialog.set_authors(&["FortressValkriye"]); about_dialog.set_copyright(Some("Made with by ❤️ Echidna contributors")); about_dialog.set_visible(true); From 385f2dda32f47db53ce213f147e88bf730a29eb0 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Sun, 24 Oct 2021 14:20:53 +0700 Subject: [PATCH 29/50] refactor: move all traits to EchidnaWindow struct Before, all the traits are implemented for EchidnaApplication. This is added to better support using the app with many windows open. EchidnaApplication may be obsolete now, but I'm not removing it for now. --- src/app/imp.rs | 198 -------------------- src/components/app/imp.rs | 60 ++++++ src/{ => components}/app/mod.rs | 4 +- src/components/mod.rs | 1 + src/components/window/file.rs | 134 +++++++++++++ src/components/window/imp.rs | 37 ++++ src/{app => components/window}/menubar.rs | 48 ++--- src/components/window/mod.rs | 36 ++++ src/components/window/sidebar.rs | 9 + src/components/window/window.ui | 55 ++++++ src/{app => components/window}/workspace.rs | 0 src/main.rs | 11 +- 12 files changed, 359 insertions(+), 234 deletions(-) delete mode 100644 src/app/imp.rs create mode 100644 src/components/app/imp.rs rename src/{ => components}/app/mod.rs (96%) create mode 100644 src/components/window/file.rs create mode 100644 src/components/window/imp.rs rename src/{app => components/window}/menubar.rs (75%) create mode 100644 src/components/window/mod.rs create mode 100644 src/components/window/sidebar.rs create mode 100644 src/components/window/window.ui rename src/{app => components/window}/workspace.rs (100%) diff --git a/src/app/imp.rs b/src/app/imp.rs deleted file mode 100644 index d4643f8..0000000 --- a/src/app/imp.rs +++ /dev/null @@ -1,198 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use std::str::from_utf8; -use sourceview::{View, Buffer, LanguageManager, }; -use sourceview::prelude::*; -use gtk::subclass::prelude::*; -use gtk::prelude::*; -use super::menubar::MenubarImplementedEditor; -use gtk::{ - ApplicationWindow, - Application, - FileChooserDialog, - FileChooserAction, - ResponseType, - Label - -}; - -use gio::{ - MenuModel, - SimpleAction, - Cancellable -}; -//use super::workspace; -use glib::clone; - -#[derive(Debug, Default)] -pub struct EchidnaEditor { - pub name: &'static str, - pub app_id: &'static str -} - -pub trait EchidnaEditorExt { - fn action_open_file(window: ApplicationWindow, app: super::EchidnaEditor, action: &SimpleAction, variant: Option<&glib::Variant>, notebook: gtk::Notebook); - fn open_file(notebook: >k::Notebook, file: gio::File); -} - - - -#[glib::object_subclass] -impl ObjectSubclass for EchidnaEditor { - const NAME: &'static str = "EchidnaEditorApplication"; - type Type = super::EchidnaEditor; - type ParentType = Application; - - fn new() -> Self { - Self { - name: "Echidna Code Editor", - app_id: "land.echidna.editor" - } - } -} - - - -impl EchidnaEditorExt for EchidnaEditor { - - /* - Open a file and put it in an editor and the opened files bar. - - - Open a file chooser dialog. - - Connect a signal to it and get the file choosen. - - Read th file's information and - - TODO: if it's a plain text, - - TODO: Load the file's content - - TODO: Create an editor - - TODO: Set the editor's content to the file's content. - - TODO: Somehow keep track of what file belongs to what editor/opened file bar widget. - - TODO: If the user enables Autosave, listen to the editor's changes and automatically save the editor's content. - - TODO: Close the editor and the tab widget when the file is closed (triggered by the X button on them). - - Perhaps some of the last points should not be implemented in this function but rather in another function that keeps track of every files. - */ - fn action_open_file(window: ApplicationWindow, app: super::EchidnaEditor, _action: &SimpleAction, variant: Option<&glib::Variant>, notebook: gtk::Notebook){ - - let dialog: FileChooserDialog = FileChooserDialog::new(Some("Open a file"), - Some(&window), - FileChooserAction::Open, - &[("Cancel", ResponseType::Cancel), - ("Open", ResponseType::Accept) ]); - - - dialog.set_visible(true); - - - - // TODO: Somehow inserts self to this function. - // This function sets the callback function as 'static, which for some reasons ban cloning self into it. Idk why. - dialog.connect_response(clone!( @weak app, @weak window, => - move |dialog, response| { - - if response == ResponseType::Accept { - - let file_option = dialog.file(); - - match file_option { - Some(file) => { - dialog.destroy(); - - Self::open_file(¬ebook, file); - - }, - None => { - - }, - } - } else if response == ResponseType::Cancel { - dialog.destroy(); - - } })); - - } - - fn open_file(notebook: >k::Notebook, file: gio::File){ - let cancellable = Cancellable::new(); - let filepath = file.path().expect("No filepath"); - let file_info_result = file.query_info( - "*", - gio::FileQueryInfoFlags::NONE, - Some(&cancellable)); - match file_info_result { - Ok(info) => { - match info.content_type() { - Some(content_type) => { - println!("Opened {} and found its content type is {}.", "file", content_type.to_string()); - let content_cancellable = Cancellable::new(); - let file_content = file.load_contents(Some(&content_cancellable)); - match file_content { - Ok(content) => { - let (int_vec, _text_option) = content; - let language_manager = LanguageManager::new(); - let language = language_manager.guess_language(Some(&info.name().to_str().expect("Could not open the file because its name is not supported by Unicode.")), None); - - let buffer = Buffer::new(None); - buffer.set_text(from_utf8(&int_vec).expect(format!("Could not parse the contents of {:?} as it's unsupported by UTF-8", filepath).as_str())); - match language { - Some(lang) => buffer.set_language(Some(&lang)), - None => {} - } - - let sourceview = View::with_buffer(&buffer); - - notebook.prepend_page(&sourceview, - Some(&Label::new(Some(&info.name().to_str() - .expect("Could not parse file's name"))))); - - } - Err(e) => println!("Could not open {:?} because:\n{:#?}", filepath, e), - } - }, - None => println!("It does not seem like {:?} has a type", filepath), - - } - - }, - Err(e) => println!("Could not retrieve file information for {:?} because:\n{}", filepath, e), - } - - - } - - -} - -impl ObjectImpl for EchidnaEditor { - - - -} - -impl ApplicationImpl for EchidnaEditor { - - fn activate(&self, app: &Self::Type){ - - let builder = gtk::Builder::from_string(include_str!("../../ui/window.ui")); - let window: ApplicationWindow = builder - .object("window") - .expect("Could not get object 'window' from builder."); - - let menubuilder = gtk::Builder::from_string(include_str!("../../ui/menu.ui")); - let menubar: MenuModel = menubuilder - .object("menu") - .expect("Could not get object 'menu' from builder."); - - self.setup_menubar(app, &window, &builder.clone()); - - window.set_application(Some(app)); - - window.present(); - - } - -} - -impl GtkApplicationImpl for EchidnaEditor {} - diff --git a/src/components/app/imp.rs b/src/components/app/imp.rs new file mode 100644 index 0000000..9dd1c98 --- /dev/null +++ b/src/components/app/imp.rs @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use super::super::window::EchidnaWindow; +use super::super::window::menubar::MenubarImplementedEditor; + +use gtk::subclass::prelude::*; +use gtk::prelude::*; + +use gtk::{ + Application, +}; + +#[derive(Debug, Default)] +pub struct EchidnaEditor { + pub name: &'static str, + pub app_id: &'static str +} + + + + +#[glib::object_subclass] +impl ObjectSubclass for EchidnaEditor { + const NAME: &'static str = "EchidnaEditorApplication"; + type Type = super::EchidnaEditor; + type ParentType = Application; + + fn new() -> Self { + Self { + name: "Echidna Code Editor", + app_id: "land.echidna.editor" + } + } +} + + +impl ObjectImpl for EchidnaEditor { + + + +} + +impl ApplicationImpl for EchidnaEditor { + + fn activate(&self, app: &Self::Type){ + + let window = EchidnaWindow::new(app); + + window.setup_menubar(); + window.set_application(Some(app)); + + window.present(); + + } + +} + +impl GtkApplicationImpl for EchidnaEditor {} + diff --git a/src/app/mod.rs b/src/components/app/mod.rs similarity index 96% rename from src/app/mod.rs rename to src/components/app/mod.rs index b98bcfb..8b3c9c1 100644 --- a/src/app/mod.rs +++ b/src/components/app/mod.rs @@ -3,12 +3,12 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ pub mod imp; -pub mod menubar; -pub mod workspace; + use glib::wrapper; wrapper! { pub struct EchidnaEditor(ObjectSubclass) @extends gio::Application, gtk::Application, @implements gio::ActionGroup, gio::ActionMap; + } impl Default for EchidnaEditor { diff --git a/src/components/mod.rs b/src/components/mod.rs index 7a10ed2..24e9074 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -3,3 +3,4 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ pub mod app; +pub mod window; diff --git a/src/components/window/file.rs b/src/components/window/file.rs new file mode 100644 index 0000000..b043344 --- /dev/null +++ b/src/components/window/file.rs @@ -0,0 +1,134 @@ + +use glib::{ + clone +}; +use sourceview::{ + View, + Buffer, + LanguageManager, + prelude::* +}; +use gio::{ + Cancellable + +}; +use gtk::{ + FileChooserDialog, + FileChooserAction, + ResponseType, + Label, + prelude::*, + subclass::prelude::* +}; + +pub trait FileImplementedEditor { + fn action_open_file/*>*/(window: Self); + fn open_file(notebook: >k::Notebook, file: gio::File); +} + +impl FileImplementedEditor for super::EchidnaWindow { + /* + Open a file and put it in an editor and the opened files bar. + + - Open a file chooser dialog. + - Connect a signal to it and get the file choosen. + - Read th file's information and + - TODO: if it's a plain text, + - TODO: Load the file's content + - TODO: Create an editor + - TODO: Set the editor's content to the file's content. + - TODO: Somehow keep track of what file belongs to what editor/opened file bar widget. + - TODO: If the user enables Autosave, listen to the editor's changes and automatically save the editor's content. + - TODO: Close the editor and the tab widget when the file is closed (triggered by the X button on them). + + Perhaps some of the last points should not be implemented in this function but rather in another function that keeps track of every files. + */ + fn action_open_file/*>*/(window: Self){ + + let dialog: FileChooserDialog = FileChooserDialog::new(Some("Open a file"), + Some(&window), + FileChooserAction::Open, + &[("Cancel", ResponseType::Cancel), + ("Open", ResponseType::Accept) ]); + + + dialog.set_visible(true); + + + + // TODO: Somehow inserts self to this function. + // This function sets the callback function as 'static, which for some reasons ban cloning self into it. Idk why. + dialog.connect_response(clone!( @weak window, => + move |dialog, response| { + + if response == ResponseType::Accept { + + let file_option = dialog.file(); + + match file_option { + Some(file) => { + dialog.destroy(); + + Self::open_file(&super::imp::EchidnaWindow::from_instance(&window).notebook, file); + + }, + None => { + + }, + } + } else if response == ResponseType::Cancel { + dialog.destroy(); + + } })); + + } + + fn open_file(notebook: >k::Notebook, file: gio::File){ + let cancellable = Cancellable::new(); + let filepath = file.path().expect("No filepath"); + let file_info_result = file.query_info( + "*", + gio::FileQueryInfoFlags::NONE, + Some(&cancellable)); + match file_info_result { + Ok(info) => { + match info.content_type() { + Some(content_type) => { + println!("Opened {} and found its content type is {}.", "file", content_type.to_string()); + let content_cancellable = Cancellable::new(); + let file_content = file.load_contents(Some(&content_cancellable)); + match file_content { + Ok(content) => { + let (int_vec, _text_option) = content; + let language_manager = LanguageManager::new(); + let language = language_manager.guess_language(Some(&info.name().to_str().expect("Could not open the file because its name is not supported by Unicode.")), None); + + let buffer = Buffer::new(None); + buffer.set_text(std::str::from_utf8(&int_vec).expect(format!("Could not parse the contents of {:?} as it's unsupported by UTF-8", filepath).as_str())); + match language { + Some(lang) => buffer.set_language(Some(&lang)), + None => {} + } + + let sourceview = View::with_buffer(&buffer); + + notebook.prepend_page(&sourceview, + Some(&Label::new(Some(&info.name().to_str() + .expect("Could not parse file's name"))))); + + } + Err(e) => println!("Could not open {:?} because:\n{:#?}", filepath, e), + } + }, + None => println!("It does not seem like {:?} has a type", filepath), + + } + + }, + Err(e) => println!("Could not retrieve file information for {:?} because:\n{}", filepath, e), + } + + + } + +} \ No newline at end of file diff --git a/src/components/window/imp.rs b/src/components/window/imp.rs new file mode 100644 index 0000000..38344b2 --- /dev/null +++ b/src/components/window/imp.rs @@ -0,0 +1,37 @@ + +use gtk::prelude::*; +use gtk::subclass::prelude::*; +use gtk::CompositeTemplate; + +#[derive(Debug, Default, CompositeTemplate)] +#[template(file = "./window.ui")] +pub struct EchidnaWindow { + #[template_child] + pub notebook: TemplateChild, +} + +#[glib::object_subclass] +impl ObjectSubclass for EchidnaWindow { + const NAME: &'static str = "EchidnaWindow"; + type Type = super::EchidnaWindow; + type ParentType = gtk::ApplicationWindow; + + + fn class_init(class: &mut Self::Class) { + Self::bind_template(class); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } +} + +impl ObjectImpl for EchidnaWindow {} + +impl WidgetImpl for EchidnaWindow {} + +impl WindowImpl for EchidnaWindow {} + +impl ApplicationWindowImpl for EchidnaWindow {} + +impl BuildableImpl for EchidnaWindow {} diff --git a/src/app/menubar.rs b/src/components/window/menubar.rs similarity index 75% rename from src/app/menubar.rs rename to src/components/window/menubar.rs index e8da0fb..7cb1924 100644 --- a/src/app/menubar.rs +++ b/src/components/window/menubar.rs @@ -1,32 +1,25 @@ -use super::imp::EchidnaEditor; -use super::imp::EchidnaEditorExt; +use super::file::FileImplementedEditor; +use super::EchidnaWindow; use gio::{MenuModel, SimpleAction}; use glib::clone; use gtk::prelude::*; use gtk::AboutDialog; pub trait MenubarImplementedEditor { - fn setup_menubar( - &self, - app: &super::EchidnaEditor, - window: >k::ApplicationWindow, - builder: >k::Builder, - ); + fn setup_menubar(&self); } -impl MenubarImplementedEditor for EchidnaEditor { - fn setup_menubar( - &self, - app: &super::EchidnaEditor, - window: >k::ApplicationWindow, - builder: >k::Builder, - ) { - let menubuilder = gtk::Builder::from_string(include_str!("../../ui/menu.ui")); +impl MenubarImplementedEditor for EchidnaWindow { + fn setup_menubar(&self) { + let app = &self + .application() + .expect("&self does not have an application set."); + let menubuilder = gtk::Builder::from_string(include_str!("../../../ui/menu.ui")); let menubar: MenuModel = menubuilder .object("menu") .expect("Could not get object 'menu' from builder."); app.set_menubar(Some(&menubar)); - window.set_show_menubar(true); + &self.set_show_menubar(true); let act_exit: SimpleAction = SimpleAction::new("exit", None); app.add_action(&act_exit); @@ -49,9 +42,6 @@ impl MenubarImplementedEditor for EchidnaEditor { about_dialog.set_visible(true); }); - let notebook: gtk::Notebook = builder - .object("echidna-notebook") - .expect("Could not get 'echidna-notebook' from builder."); //app.notebook = Some(Rc::new(RefCell::new(notebook))); let act_exit: SimpleAction = SimpleAction::new("exit", None); app.add_action(&act_exit); @@ -92,20 +82,22 @@ impl MenubarImplementedEditor for EchidnaEditor { let act_window_close = SimpleAction::new("close", None); - window.add_action(&act_window_close); + &self.add_action(&act_window_close); + + { + let window = self.clone(); - act_window_close.connect_activate(clone!(@weak window => - move | _action, _variant | { + act_window_close.connect_activate(move |_action, _variant| { window.close(); - } - )); + }); + } let action_open_file: SimpleAction = SimpleAction::new("open-file", None); - window.add_action(&action_open_file); - action_open_file.connect_activate(clone!(@weak window, @weak app, @weak notebook => + &self.add_action(&action_open_file); + action_open_file.connect_activate(clone!(@weak self as window => move |action, variant| { - Self::action_open_file(window, app, action, variant, notebook); + Self::action_open_file(window); })); } } diff --git a/src/components/window/mod.rs b/src/components/window/mod.rs new file mode 100644 index 0000000..bff0d6f --- /dev/null +++ b/src/components/window/mod.rs @@ -0,0 +1,36 @@ +mod file; + +mod imp; +pub mod menubar; + +use glib::{ + + + object::IsA, + +}; + +glib::wrapper! { + pub struct EchidnaWindow(ObjectSubclass) + @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, + @implements gio::ActionGroup, gio::ActionMap, gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager; +} + +impl EchidnaWindow { + pub fn new>(application: &P) -> Self { + + let object = glib::Object::new(&[ + ("application", &application) + ]); + + match object { + Ok(o) => o, + Err(e) => panic!("Error in making EchidnaApplication {}", e), + } + } + + + + +} + diff --git a/src/components/window/sidebar.rs b/src/components/window/sidebar.rs new file mode 100644 index 0000000..4014aed --- /dev/null +++ b/src/components/window/sidebar.rs @@ -0,0 +1,9 @@ +trait SidebarImplementedEditor { + fn setup_sidebar(); +} + +impl SidebarImplementedEditor for super::imp::EchidnaEditor { + fn setup_sidebar(){ + + } +} \ No newline at end of file diff --git a/src/components/window/window.ui b/src/components/window/window.ui new file mode 100644 index 0000000..f8ec6b6 --- /dev/null +++ b/src/components/window/window.ui @@ -0,0 +1,55 @@ + + + + + \ No newline at end of file diff --git a/src/app/workspace.rs b/src/components/window/workspace.rs similarity index 100% rename from src/app/workspace.rs rename to src/components/window/workspace.rs diff --git a/src/main.rs b/src/main.rs index 5bb4936..01d237c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,15 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -mod app; +mod components; -use gtk::prelude::ApplicationExtManual; use app::EchidnaEditor; +use components::app; +use gtk::prelude::ApplicationExtManual; fn main() { - let app = EchidnaEditor::new( - "land.echidna.editor", - ); + let app = EchidnaEditor::new("land.echidna.editor"); std::process::exit(app.run()); -} \ No newline at end of file +} From 52d5b5e4868520b0b6cd2f7b00fcefa8bd328c17 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Sun, 24 Oct 2021 16:42:15 +0700 Subject: [PATCH 30/50] style: add missing license headers The MPL is a file-based license, rather than a codebase-based license. Each files need to be marked as MPL. If we don't do mark them, they may cause confusion. --- src/components/window/file.rs | 3 +++ src/components/window/imp.rs | 5 ++++- src/components/window/menubar.rs | 4 ++++ src/components/window/mod.rs | 4 ++++ src/components/window/sidebar.rs | 4 ++++ src/components/window/window.ui | 3 +++ 6 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/components/window/file.rs b/src/components/window/file.rs index b043344..0f25a3e 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -1,3 +1,6 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use glib::{ clone diff --git a/src/components/window/imp.rs b/src/components/window/imp.rs index 38344b2..891f66b 100644 --- a/src/components/window/imp.rs +++ b/src/components/window/imp.rs @@ -1,4 +1,7 @@ - +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + use gtk::prelude::*; use gtk::subclass::prelude::*; use gtk::CompositeTemplate; diff --git a/src/components/window/menubar.rs b/src/components/window/menubar.rs index 7cb1924..0e37b41 100644 --- a/src/components/window/menubar.rs +++ b/src/components/window/menubar.rs @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + use super::file::FileImplementedEditor; use super::EchidnaWindow; use gio::{MenuModel, SimpleAction}; diff --git a/src/components/window/mod.rs b/src/components/window/mod.rs index bff0d6f..3b8470a 100644 --- a/src/components/window/mod.rs +++ b/src/components/window/mod.rs @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + mod file; mod imp; diff --git a/src/components/window/sidebar.rs b/src/components/window/sidebar.rs index 4014aed..9932783 100644 --- a/src/components/window/sidebar.rs +++ b/src/components/window/sidebar.rs @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + trait SidebarImplementedEditor { fn setup_sidebar(); } diff --git a/src/components/window/window.ui b/src/components/window/window.ui index f8ec6b6..4f0cf8c 100644 --- a/src/components/window/window.ui +++ b/src/components/window/window.ui @@ -1,4 +1,7 @@ +