Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
ada2d1c7cf |
21 changed files with 148 additions and 230 deletions
30
README.md
30
README.md
|
@ -6,32 +6,24 @@ So I just made one.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
| Feature | Description | State |
|
| Feature | Description | State |
|
||||||
|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|
|
|-----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|
|
||||||
| Editing of basic image formats /<br>"Syntax Highlighting" | If you have a very simple black/white image format<br/>where single bits control the color,<br/>the editor can highlight the enabled bits. | <input type="checkbox" disabled checked /> Implemented |
|
| Editing of basic image formats /<br>"Syntax Highlighting" | If u have a very simple black/white image format<br/>where single bits control the color,<br/>the editor can highlight the enabled bits. | <input type="checkbox" disabled checked /> Implemented |
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
This program was made for Linux. It may work on Windows or Mac too, but it was not tested on these systems.\
|
This program was made for Linux.\
|
||||||
Before you can install the editor, you first have to install the requirements. That can be done using:
|
It may work on Windows or Mac too, but it was not tested on these systems.\
|
||||||
|
To be able to use this program, you have to clone the repository,\
|
||||||
```bash
|
install the requirements and make the file called "main.py" executable.\
|
||||||
sudo apt install pyqt6-dev-tools xcb libxcb-cursor0
|
|
||||||
```
|
|
||||||
|
|
||||||
And to install the editor, you just have to clone the repository and install it using pip.\
|
|
||||||
You can do that using these commands:
|
You can do that using these commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://teapot.informationsanarchistik.de/Wobbl/Bread_Editor.git
|
git clone https://teapot.informationsanarchistik.de/Wobbl/Bread_Editor.git
|
||||||
cd Bread_Editor
|
cd Bread_Editor
|
||||||
pip install .
|
pip install -r requirements.txt
|
||||||
|
chmod +x main.py
|
||||||
```
|
```
|
||||||
|
|
||||||
If you have already set up git for ssh, you can also clone the repository like this:
|
Now you can execute the program using `./main.py`.
|
||||||
|
You can also create a desktop shortcut to the file.
|
||||||
```bash
|
|
||||||
git clone git git@teapot.informationsanarchistik.de:Wobbl/Bread_Editor.git
|
|
||||||
```
|
|
||||||
|
|
||||||
You can now start the editor by typing in the terminal: `bread_editor`
|
|
30
binary_text_edit.py
Normal file
30
binary_text_edit.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from PyQt6.QtWidgets import QPlainTextEdit
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryTextEdit(QPlainTextEdit): # rewrite QPlainTextEdit.keyPressEvent because it has no .setValidator()
|
||||||
|
def keyPressEvent(self, event):
|
||||||
|
allowed_keys = {"", "0", "1"}
|
||||||
|
|
||||||
|
if event.text() in allowed_keys:
|
||||||
|
cursor = self.textCursor()
|
||||||
|
pos = cursor.position()
|
||||||
|
text = self.toPlainText()
|
||||||
|
text_length = len(text)
|
||||||
|
|
||||||
|
if not (pos + 1) % 9 == 0 or event.text() in {"", None}: # dont overwrite the separator character
|
||||||
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
|
# skip over the separator character when the cursor is before it.
|
||||||
|
if (pos + 2) % 9 == 0 and not event.text() in {"", None}:
|
||||||
|
if pos == text_length: # append to the input if the cursor is at the end
|
||||||
|
self.insertPlainText(" ")
|
||||||
|
cursor = self.textCursor()
|
||||||
|
cursor.setPosition(pos + 2)
|
||||||
|
|
||||||
|
cursor.setPosition(pos + 2)
|
||||||
|
self.setTextCursor(cursor)
|
||||||
|
|
||||||
|
else:
|
||||||
|
event.ignore()
|
|
@ -1 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
|
@ -1,50 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
from PyQt6.QtWidgets import QPlainTextEdit
|
|
||||||
from PyQt6.QtCore import Qt
|
|
||||||
|
|
||||||
|
|
||||||
class BinaryTextEdit(QPlainTextEdit): # rewrite QPlainTextEdit.keyPressEvent because it has no .setValidator()
|
|
||||||
def keyPressEvent(self, event):
|
|
||||||
allowed_keys = {"", "0", "1"}
|
|
||||||
|
|
||||||
if event.text() in allowed_keys:
|
|
||||||
cursor = self.textCursor()
|
|
||||||
position = cursor.position()
|
|
||||||
text = self.toPlainText()
|
|
||||||
text_length = len(text)
|
|
||||||
|
|
||||||
if not (position + 1) % 9 == 0 or event.text() in {"", None}: # dont overwrite the separator character
|
|
||||||
super().keyPressEvent(event)
|
|
||||||
|
|
||||||
# skip over the separator character when the cursor is right before it.
|
|
||||||
if (position + 2) % 9 == 0 and not event.text() in {"", None}:
|
|
||||||
if position == text_length - 1: # append to the input if the cursor is at the end
|
|
||||||
self.insertPlainText(" 00000000")
|
|
||||||
|
|
||||||
cursor.setPosition(position + 2)
|
|
||||||
self.setTextCursor(cursor)
|
|
||||||
|
|
||||||
elif event.key() == Qt.Key.Key_Backspace or event.key() == Qt.Key.Key_Delete:
|
|
||||||
# delete last byte when backspace or delete is pressed
|
|
||||||
text = self.toPlainText()
|
|
||||||
|
|
||||||
if len(text) >= 9:
|
|
||||||
cursor = self.textCursor()
|
|
||||||
position = cursor.position()
|
|
||||||
|
|
||||||
text = text[:-9] # delete last byte
|
|
||||||
|
|
||||||
self.setPlainText(text)
|
|
||||||
|
|
||||||
# calculate the new cursor position (by subtracting 9, we set the position to the same bit but one byte
|
|
||||||
# before and by floor dividing this by 9 we get the "byte index" and when we multiply this by 9, we get
|
|
||||||
# the character position of the first bit in that byte.)
|
|
||||||
position = (position - 9) // 9 * 9
|
|
||||||
|
|
||||||
cursor.setPosition(position)
|
|
||||||
|
|
||||||
self.setTextCursor(cursor)
|
|
||||||
|
|
||||||
else:
|
|
||||||
event.ignore()
|
|
|
@ -1 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
|
@ -1 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
def convert_ui():
|
|
||||||
working_dir = os.getcwd()
|
|
||||||
|
|
||||||
if not working_dir.split('/')[
|
|
||||||
-1] == "raw_ui": # cd into the right directory if this gets executed from somewhere else
|
|
||||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
|
|
||||||
for ui_file, script_out in paths.items():
|
|
||||||
os.system(f"pyuic6 {ui_file} {params} ../{script_out}")
|
|
||||||
|
|
||||||
os.chdir(working_dir) # switch back to the working directory from which the script was executed
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": # dont ask for debug on setup
|
|
||||||
input_debug = input("Do you want to debug the gui scripts? (Make gui scripts executable.) (y/n): ")
|
|
||||||
|
|
||||||
debug = input_debug == "y"
|
|
||||||
|
|
||||||
convert_ui()
|
|
||||||
|
|
||||||
else:
|
|
||||||
debug = False
|
|
||||||
|
|
||||||
params = "-o"
|
|
||||||
|
|
||||||
if debug:
|
|
||||||
params = "-xo"
|
|
||||||
|
|
||||||
paths = {
|
|
||||||
"main_window.ui": "main_window.py"
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
from PyQt6.QtWidgets import QApplication, QMainWindow
|
|
||||||
from bread_editor.gui.main_window import Ui_MainWindow
|
|
||||||
|
|
||||||
|
|
||||||
class GUI:
|
|
||||||
def __init__(self, app):
|
|
||||||
self.app = app
|
|
||||||
|
|
||||||
self.qt_app = QApplication([])
|
|
||||||
self.QTMainWindow = QMainWindow()
|
|
||||||
|
|
||||||
self.main_window = Ui_MainWindow()
|
|
||||||
|
|
||||||
self.setup_gui()
|
|
||||||
self.connect_gui()
|
|
||||||
|
|
||||||
def setup_gui(self):
|
|
||||||
self.main_window.setupUi(self.QTMainWindow)
|
|
||||||
self.main_window.settingsDock.hide()
|
|
||||||
|
|
||||||
def post_setup(self):
|
|
||||||
self.main_window.bitsAreSquaresSetting.blockSignals(True)
|
|
||||||
self.main_window.bitsAreSquaresSetting.setChecked(self.app.settings.square_bits)
|
|
||||||
self.main_window.bitsAreSquaresSetting.blockSignals(False)
|
|
||||||
|
|
||||||
self.main_window.highlightOnesSetting.setChecked(self.app.settings.highlight_ones)
|
|
||||||
|
|
||||||
self.app.utils.update_style_in_all_bit_editors()
|
|
||||||
|
|
||||||
def connect_gui(self):
|
|
||||||
self.main_window.openFile.triggered.connect(self.app.file_actions.open_files)
|
|
||||||
self.main_window.newFile.triggered.connect(lambda: self.app.file_actions.create_file())
|
|
||||||
self.main_window.saveFile.triggered.connect(self.app.file_actions.save_current_file)
|
|
||||||
self.main_window.saveFileAs.triggered.connect(self.app.file_actions.save_current_file_as)
|
|
||||||
|
|
||||||
self.main_window.menuSettings.triggered.connect(self.main_window.settingsDock.show)
|
|
||||||
|
|
||||||
self.main_window.bitsAreSquaresSetting.stateChanged.connect(self.app.utils.update_style_in_all_bit_editors)
|
|
||||||
self.main_window.highlightOnesSetting.stateChanged.connect(self.app.utils.update_style_in_all_bit_editors)
|
|
||||||
|
|
||||||
self.main_window.openFileTabs.tabCloseRequested.connect(self.app.file_actions.close_current_file)
|
|
||||||
self.QTMainWindow.closeEvent = self.app.utils.on_close
|
|
15
connect_gui.py
Normal file
15
connect_gui.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
def connect_gui(app):
|
||||||
|
app.gui.main_window.openFile.triggered.connect(app.file_actions.open_files)
|
||||||
|
app.gui.main_window.newFile.triggered.connect(app.file_actions.create_file)
|
||||||
|
app.gui.main_window.saveFile.triggered.connect(app.file_actions.save_current_file)
|
||||||
|
app.gui.main_window.saveFileAs.triggered.connect(app.file_actions.save_current_file_as)
|
||||||
|
|
||||||
|
app.gui.main_window.menuSettings.triggered.connect(app.gui.main_window.settingsDock.show)
|
||||||
|
|
||||||
|
app.gui.main_window.bitsAreSquaresSetting.stateChanged.connect(app.utils.update_style_in_all_bit_editors)
|
||||||
|
app.gui.main_window.highlightOnesSetting.stateChanged.connect(app.utils.update_style_in_all_bit_editors)
|
||||||
|
|
||||||
|
app.gui.main_window.openFileTabs.tabCloseRequested.connect(app.file_actions.close_current_file)
|
||||||
|
app.gui.QTMainWindow.closeEvent = app.utils.on_close
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
from PyQt6.QtWidgets import QWidget, QVBoxLayout
|
from PyQt6.QtWidgets import QWidget, QVBoxLayout
|
||||||
from PyQt6.QtGui import QFont, QTextCharFormat, QColor
|
from PyQt6.QtGui import QFont, QTextCharFormat, QColor
|
||||||
from bread_editor.binary_text_edit import BinaryTextEdit
|
from binary_text_edit import BinaryTextEdit
|
||||||
from bread_editor.highlighting import Higlighter
|
from highlighting import Higlighter
|
||||||
|
|
||||||
|
|
||||||
class BitEditor:
|
class BitEditor:
|
||||||
|
@ -55,11 +55,6 @@ class BitEditor:
|
||||||
self.font.setLetterSpacing(QFont.SpacingType.PercentageSpacing, spacing)
|
self.font.setLetterSpacing(QFont.SpacingType.PercentageSpacing, spacing)
|
||||||
self.input.setFont(self.font)
|
self.input.setFont(self.font)
|
||||||
|
|
||||||
self.cursor_width = self.input.fontMetrics().averageCharWidth()
|
|
||||||
|
|
||||||
# set the cursor with to match the letter spacing
|
|
||||||
self.input.setCursorWidth(self.cursor_width + 1) # + 1 because else it somehow draws a 1px wide vertical line
|
|
||||||
|
|
||||||
highlight_ones = self.app.settings.highlight_ones
|
highlight_ones = self.app.settings.highlight_ones
|
||||||
|
|
||||||
highlighter_document = self.input.document() if highlight_ones else None
|
highlighter_document = self.input.document() if highlight_ones else None
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from PyQt6.QtWidgets import QFileDialog
|
from PyQt6.QtWidgets import QFileDialog, QTabWidget
|
||||||
from bread_editor.editor import BitEditor
|
from editor import BitEditor
|
||||||
|
|
||||||
MAX_FILE_SIZE = 262144 # 2^18
|
MAX_FILE_SIZE = 262144 # 2^18
|
||||||
|
|
||||||
|
@ -20,12 +20,15 @@ class FileActions:
|
||||||
dialog.setViewMode(QFileDialog.ViewMode.List)
|
dialog.setViewMode(QFileDialog.ViewMode.List)
|
||||||
|
|
||||||
if dialog.exec():
|
if dialog.exec():
|
||||||
self.open_multiple_files(dialog.selectedFiles())
|
for file_path in dialog.selectedFiles():
|
||||||
|
if not file_path in self.app.open_files: # dont open file twice
|
||||||
|
if os.path.getsize(file_path) > MAX_FILE_SIZE:
|
||||||
|
self.app.utils.ftb_popup.exec()
|
||||||
|
return
|
||||||
|
|
||||||
def create_file(self, content: bytes=(0).to_bytes(1, "big")):
|
self.app.open_files[file_path] = File(self.app, file_path, file_path.split("/")[-1])
|
||||||
# open a dialog where the user can choose a new filepath and create an empty file at that path
|
|
||||||
# bytes=(0).to_bytes(1) creates a byte with only zeros in it
|
|
||||||
|
|
||||||
|
def create_file(self, content: bin=b""):
|
||||||
file_path, extension = QFileDialog.getSaveFileName(
|
file_path, extension = QFileDialog.getSaveFileName(
|
||||||
caption="New File",
|
caption="New File",
|
||||||
directory=self.app.utils.home_path,
|
directory=self.app.utils.home_path,
|
||||||
|
@ -79,16 +82,6 @@ class FileActions:
|
||||||
for file_path in self.app.open_files:
|
for file_path in self.app.open_files:
|
||||||
self.app.open_files[file_path].save()
|
self.app.open_files[file_path].save()
|
||||||
|
|
||||||
def open_multiple_files(self, file_paths):
|
|
||||||
for file_path in file_paths:
|
|
||||||
if not file_path in self.app.open_files and os.path.isfile(file_path):
|
|
||||||
if os.path.getsize(file_path) > MAX_FILE_SIZE:
|
|
||||||
self.app.utils.ftb_popup.exec()
|
|
||||||
return
|
|
||||||
|
|
||||||
file = File(self.app, file_path, file_path.split("/")[-1])
|
|
||||||
self.app.open_files[file_path] = file
|
|
||||||
|
|
||||||
|
|
||||||
class File:
|
class File:
|
||||||
def __init__(self, app, path, name):
|
def __init__(self, app, path, name):
|
23
gui/raw_ui/ui_to_py.py
Normal file
23
gui/raw_ui/ui_to_py.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
working_dir = os.getcwd()
|
||||||
|
|
||||||
|
if not working_dir.split('/')[-1] == "raw_ui": # cd into the right directory if this gets executed from somewhere else
|
||||||
|
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
input_debug = input("Do you want to debug the gui scripts? (Make gui scripts executable.) (y/n): ")
|
||||||
|
|
||||||
|
debug = input_debug == "y"
|
||||||
|
|
||||||
|
params = "-o"
|
||||||
|
if debug:
|
||||||
|
params = "-xo"
|
||||||
|
|
||||||
|
paths = {
|
||||||
|
"main_window.ui": "main_window.py"
|
||||||
|
}
|
||||||
|
|
||||||
|
for ui_file, script_out in paths.items():
|
||||||
|
os.system(f"pyuic6 {ui_file} {params} ../{script_out}")
|
|
@ -3,11 +3,11 @@
|
||||||
import sys
|
import sys
|
||||||
from PyQt6.QtCore import QTimer
|
from PyQt6.QtCore import QTimer
|
||||||
from wobbl_tools.data_file import load_dataclass_json
|
from wobbl_tools.data_file import load_dataclass_json
|
||||||
from bread_editor.utils import Utils
|
from utils import Utils
|
||||||
from bread_editor.file import File, FileActions
|
from file import File, FileActions
|
||||||
from bread_editor.ui import GUI
|
from ui import GUI
|
||||||
from bread_editor.settings import Settings
|
from settings import Settings
|
||||||
from bread_editor.ipc import IPC
|
from ipc import IPC
|
||||||
|
|
||||||
|
|
||||||
class BreadEditor:
|
class BreadEditor:
|
||||||
|
@ -24,6 +24,7 @@ class BreadEditor:
|
||||||
|
|
||||||
self.gui = GUI(self)
|
self.gui = GUI(self)
|
||||||
|
|
||||||
|
self.gui.connect_gui(self)
|
||||||
self.open_files: dict[str, File] = {}
|
self.open_files: dict[str, File] = {}
|
||||||
self.open_files_queue = []
|
self.open_files_queue = []
|
||||||
|
|
||||||
|
@ -37,19 +38,14 @@ class BreadEditor:
|
||||||
|
|
||||||
self.gui.post_setup()
|
self.gui.post_setup()
|
||||||
|
|
||||||
self.utils.popup_init()
|
|
||||||
|
|
||||||
self.utils.on_start()
|
self.utils.on_start()
|
||||||
|
|
||||||
|
self.utils.popup_init()
|
||||||
|
|
||||||
self.gui.QTMainWindow.show()
|
self.gui.QTMainWindow.show()
|
||||||
sys.exit(self.gui.qt_app.exec())
|
sys.exit(self.gui.qt_app.exec())
|
||||||
|
|
||||||
|
|
||||||
def start_from_command_line():
|
|
||||||
editor = BreadEditor()
|
|
||||||
editor.run()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
editor = BreadEditor()
|
editor = BreadEditor()
|
||||||
editor.run()
|
editor.run()
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import List
|
from typing import List
|
||||||
from bread_editor.utils import Utils
|
from utils import Utils
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
30
setup.py
30
setup.py
|
@ -1,30 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import setuptools
|
|
||||||
from bread_editor.gui.raw_ui import ui_to_py
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
ui_to_py.convert_ui() # convert the .ui files to .py files before setup
|
|
||||||
|
|
||||||
this_directory = Path(__file__).parent # use readme file as long description
|
|
||||||
long_description = (this_directory / "README.md").read_text()
|
|
||||||
|
|
||||||
setuptools.setup(
|
|
||||||
name="Bread Editor",
|
|
||||||
version="0.0",
|
|
||||||
description="A binary editor with that you can edit single bits.",
|
|
||||||
long_description=long_description,
|
|
||||||
long_description_content_type="text/markdown",
|
|
||||||
url="https://teapot.informationsanarchistik.de/Wobbl/Bread_Editor",
|
|
||||||
author="The Wobbler",
|
|
||||||
author_email="emil@i21k.de",
|
|
||||||
packages=["bread_editor", "bread_editor.gui"],
|
|
||||||
package_data={"": ["*.ui", "*.txt"]},
|
|
||||||
install_requires=[
|
|
||||||
"PyQt6",
|
|
||||||
"wobbl_tools @ git+https://teapot.informationsanarchistik.de/Wobbl/wobbl_tools@main#egg=wobbl_tools"
|
|
||||||
],
|
|
||||||
entry_points={
|
|
||||||
"console_scripts": ["bread_editor=bread_editor.main:start_from_command_line"],
|
|
||||||
}
|
|
||||||
)
|
|
33
ui.py
Normal file
33
ui.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from PyQt6.QtWidgets import QApplication, QMainWindow
|
||||||
|
from PyQt6.QtGui import QFont
|
||||||
|
from gui.main_window import Ui_MainWindow
|
||||||
|
from connect_gui import connect_gui
|
||||||
|
|
||||||
|
|
||||||
|
class GUI:
|
||||||
|
def __init__(self, app):
|
||||||
|
self.app = app
|
||||||
|
|
||||||
|
self.qt_app = QApplication([])
|
||||||
|
self.QTMainWindow = QMainWindow()
|
||||||
|
|
||||||
|
self.main_window = Ui_MainWindow()
|
||||||
|
|
||||||
|
self.setup_gui()
|
||||||
|
|
||||||
|
self.connect_gui = connect_gui
|
||||||
|
|
||||||
|
def setup_gui(self):
|
||||||
|
self.main_window.setupUi(self.QTMainWindow)
|
||||||
|
self.main_window.settingsDock.hide()
|
||||||
|
|
||||||
|
def post_setup(self):
|
||||||
|
self.main_window.bitsAreSquaresSetting.blockSignals(True)
|
||||||
|
self.main_window.bitsAreSquaresSetting.setChecked(self.app.settings.square_bits)
|
||||||
|
self.main_window.bitsAreSquaresSetting.blockSignals(False)
|
||||||
|
|
||||||
|
self.main_window.highlightOnesSetting.setChecked(self.app.settings.highlight_ones)
|
||||||
|
|
||||||
|
self.app.utils.update_style_in_all_bit_editors()
|
|
@ -4,6 +4,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from PyQt6.QtWidgets import QMessageBox
|
from PyQt6.QtWidgets import QMessageBox
|
||||||
|
from file import File
|
||||||
|
|
||||||
|
|
||||||
class Utils:
|
class Utils:
|
||||||
|
@ -32,7 +33,7 @@ class Utils:
|
||||||
"https://teapot.informationsanarchistik.de/Wobbl/Bread_Editor"
|
"https://teapot.informationsanarchistik.de/Wobbl/Bread_Editor"
|
||||||
)
|
)
|
||||||
|
|
||||||
def unsaved_changes_popup(self): # show popup and simplify return values
|
def unsaved_changes_popup(self):
|
||||||
button = self.usc_popup.exec()
|
button = self.usc_popup.exec()
|
||||||
|
|
||||||
match button:
|
match button:
|
||||||
|
@ -68,14 +69,14 @@ class Utils:
|
||||||
def on_close(self, event):
|
def on_close(self, event):
|
||||||
changes = False
|
changes = False
|
||||||
|
|
||||||
for file_path in self.app.open_files: # check for files that have unsaved changes
|
for file_path in self.app.open_files:
|
||||||
file = self.app.open_files[file_path]
|
file = self.app.open_files[file_path]
|
||||||
|
|
||||||
if file.bit_editor.not_saved:
|
if file.bit_editor.not_saved:
|
||||||
changes = True
|
changes = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if changes: # show a popup that informs the user that there are unsaved changes and ask them what to do
|
if changes:
|
||||||
save_or_not = self.unsaved_changes_popup()
|
save_or_not = self.unsaved_changes_popup()
|
||||||
|
|
||||||
match save_or_not:
|
match save_or_not:
|
||||||
|
@ -93,7 +94,8 @@ class Utils:
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
# get paths of open files and save them to the settings to reopen them automatically on next start
|
print("Bye!")
|
||||||
|
|
||||||
file_keys = self.app.open_files.keys()
|
file_keys = self.app.open_files.keys()
|
||||||
open_files = []
|
open_files = []
|
||||||
|
|
||||||
|
@ -104,10 +106,7 @@ class Utils:
|
||||||
|
|
||||||
self.app.settings.save(f"{self.editor_path}/settings.json")
|
self.app.settings.save(f"{self.editor_path}/settings.json")
|
||||||
|
|
||||||
print("Bye!")
|
|
||||||
|
|
||||||
def update_style_in_all_bit_editors(self):
|
def update_style_in_all_bit_editors(self):
|
||||||
# update the highlighting and character spacing when a setting has changed
|
|
||||||
self.app.settings.highlight_ones = self.app.gui.main_window.highlightOnesSetting.isChecked()
|
self.app.settings.highlight_ones = self.app.gui.main_window.highlightOnesSetting.isChecked()
|
||||||
self.app.settings.square_bits = self.app.gui.main_window.bitsAreSquaresSetting.isChecked()
|
self.app.settings.square_bits = self.app.gui.main_window.bitsAreSquaresSetting.isChecked()
|
||||||
|
|
||||||
|
@ -117,18 +116,23 @@ class Utils:
|
||||||
editor.update_style()
|
editor.update_style()
|
||||||
|
|
||||||
def on_start(self):
|
def on_start(self):
|
||||||
# either open the lastly opened files or open the files specified by the parameters
|
|
||||||
if len(sys.argv) == 1: # if no parameters were passed to the editor
|
if len(sys.argv) == 1: # if no parameters were passed to the editor
|
||||||
file_paths = self.app.settings.last_opened_files
|
self.load_files(self.app.settings.last_opened_files)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
file_paths = sys.argv[1:]
|
file_paths = sys.argv[1:]
|
||||||
|
|
||||||
self.app.file_actions.open_multiple_files(file_paths)
|
self.load_files(file_paths)
|
||||||
|
|
||||||
|
def load_files(self, file_paths):
|
||||||
|
for file_path in file_paths:
|
||||||
|
if not file_path in self.app.open_files and os.path.isfile(file_path):
|
||||||
|
file = File(self.app, file_path, file_path.split("/")[-1])
|
||||||
|
self.app.open_files[file_path] = file
|
||||||
|
|
||||||
def check_file_queue(self):
|
def check_file_queue(self):
|
||||||
if not self.app.open_files_queue == []: # check for file paths in the queue that the ipc server put there
|
if not len(self.app.open_files_queue) == 0:
|
||||||
filenames = self.app.open_files_queue
|
filenames = self.app.open_files_queue
|
||||||
self.app.open_files_queue = []
|
self.app.open_files_queue = []
|
||||||
|
|
||||||
self.app.file_actions.open_multiple_files(filenames)
|
self.load_files(filenames)
|
Loading…
Add table
Reference in a new issue