Skip to content

Commit

Permalink
* Various bug fixes
Browse files Browse the repository at this point in the history
* Hook file will be automatically copied every time the application starts
* Stability improvements when executing code in the game. Whenever DCS needs to run code, there's a chance it will pause for a fraction of a second. Ideally the server runs in a separate thread, but I don't have the energy to research how to make a compiled C++ DLL right now to do that. Have to look into the Olympus guys' code maybe. Anyway, never eat yellow snow.
  • Loading branch information
nielsvaes committed Mar 15, 2024
1 parent 4e6f432 commit ed3524d
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 65 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.4.4
* Various bug fixes
* Hook file will be automatically copied every time the application starts
* Stability improvements when executing code in the game. Whenever DCS needs to run code, there's a chance it will pause for a fraction of a second. Ideally the server runs in a separate thread, but I don't have the energy to research how to make a compiled C++ DLL right now to do that. Have to look into the Olympus guys' code maybe. Anyway, never eat yellow snow.

## 1.4.3
* Keeping indentation when pressing enter.
* Backspace will remove any leading 4 x space to jump back an indentation level
Expand Down
2 changes: 1 addition & 1 deletion dcs-code-injector-hook.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ local function init()
local code_injector_client = DCSCI.server:accept()

if code_injector_client then
code_injector_client:settimeout(0)
code_injector_client:settimeout(0.005)

local chunk, err, partial
local response = ""
Expand Down
2 changes: 1 addition & 1 deletion dcs_code_injector/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os

VERSION = "1.4.3"
VERSION = "1.4.4"
ICON = os.path.join(os.path.dirname(__file__), "ui", "icons", "icon.png")
165 changes: 120 additions & 45 deletions dcs_code_injector/code_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@


class CodeTextEdit(QPlainTextEdit):
execute_code = Signal(str)
def __init__(self):
"""
Constructor for the CodeTextEdit class.
Expand Down Expand Up @@ -157,10 +158,11 @@ def update_line_number_area_width(self):

def update_line_number_area(self, rect, dy):
"""
Updates the line number area when the document is scrolled or the editor is resized.
:param rect:
:param dy:
:return:
Parameters:
rect (QRect): The rectangle in the viewport that needs to be updated.
dy (int): The amount of vertical scroll. If non-zero, the line number area is scrolled accordingly.
"""
if dy:
self.line_number_area.scroll(0, dy)
Expand Down Expand Up @@ -260,14 +262,29 @@ def update_keywords(self):
list(set(self.completer.model().stringList() + [function_signature])))

def set_font(self, font):
"""
Sets the font used in the text editor.
Parameters:
font (str): The name of the font to be set.
"""
self.font = font
EZSettings().set(sk.code_font, font)

def set_font_size(self, font_size):
"""
Sets the font size used in the text editor.
Parameters:
font_size (int): The size of the font to be set.
"""
self.font_size = font_size
EZSettings().set(sk.code_font_size, font_size)

def update_font(self):
"""
Applies the current font and font size settings to the text editor.
"""
self.setStyleSheet(f"font: {self.font_size}pt '{self.font}';")

def __insert_code(self, text, move_back_pos):
Expand All @@ -287,64 +304,88 @@ def __insert_code(self, text, move_back_pos):
self.insertPlainText(selected_text)

def check_cursor_position(self):
"""
Checks if the cursor has moved to a new block (line) and updates the autocompletion keywords if necessary.
"""
cursor = self.textCursor()
block_number = cursor.blockNumber()
if block_number != self.previous_block_number:
self.previous_block_number = block_number
self.update_keywords()

def mousePressEvent(self, event):
"""
Overrides the mouse press event to check the cursor position when the mouse is clicked.
Parameters:
event (QMouseEvent): The mouse event.
"""
super().mousePressEvent(event)
self.check_cursor_position()

def keyPressEvent(self, event: QKeyEvent) -> None:
if self.completer.popup().isVisible() and event.key() in [
Qt.Key.Key_Enter,
Qt.Key.Key_Return,
Qt.Key.Key_Up,
Qt.Key.Key_Down,
Qt.Key.Key_Tab,
Qt.Key.Key_Backtab,
]:
self.completer.popup().close()
event.ignore()
return
"""
Overrides the key press event to add custom behavior for certain key combinations.
if event.key() == Qt.Key_Slash and event.modifiers() == Qt.ControlModifier:
self.handle_control_slash()
elif event.key() == Qt.Key_Up and event.modifiers() == Qt.ControlModifier:
self.handle_control_up()
elif event.key() == Qt.Key_Down and event.modifiers() == Qt.ControlModifier:
self.handle_control_down()
elif event.key() == Qt.Key_P and event.modifiers() == Qt.ControlModifier:
self.handle_control_p()
elif event.key() == Qt.Key_Tab:
self.handle_tab()
elif event.key() == Qt.Key_Backtab:
self.handle_backtab()
elif event.key() in (Qt.Key_Up, Qt.Key_Down):
super().keyPressEvent(event)
self.check_cursor_position()
elif event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
cursor = self.textCursor()
current_line = cursor.block().text()
indentation = re.match(r"\s*", current_line).group() # Capture leading whitespace
super().keyPressEvent(event) # Call the parent method to insert the newline
self.insertPlainText(indentation) # Insert the captured indentation
self.check_cursor_position()
elif event.key() == Qt.Key_Backspace:
cursor = self.textCursor()
text_up_to_cursor = self.toPlainText()[:cursor.position()]
if text_up_to_cursor.endswith(' '): # Check if the cursor is preceded by 4 spaces
cursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 4)
cursor.removeSelectedText()
return # Prevent calling super().keyPressEvent(event) to avoid deleting an extra character
Parameters:
event (QKeyEvent): The key event.
"""
if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return and event.modifiers() == Qt.ControlModifier:
text = self.textCursor().selection().toPlainText()
if text == "":
text = self.toPlainText()
self.execute_code.emit(text)
else:
if self.completer.popup().isVisible() and event.key() in [
Qt.Key.Key_Enter,
Qt.Key.Key_Return,
Qt.Key.Key_Up,
Qt.Key.Key_Down,
Qt.Key.Key_Tab,
Qt.Key.Key_Backtab,
]:
self.completer.popup().close()
event.ignore()
return

if event.key() == Qt.Key_Slash and event.modifiers() == Qt.ControlModifier:
self.handle_control_slash()
elif event.key() == Qt.Key_Up and event.modifiers() == Qt.ControlModifier:
self.handle_control_up()
elif event.key() == Qt.Key_Down and event.modifiers() == Qt.ControlModifier:
self.handle_control_down()
elif event.key() == Qt.Key_P and event.modifiers() == Qt.ControlModifier:
self.handle_control_p()
elif event.key() == Qt.Key_Tab:
self.handle_tab()
elif event.key() == Qt.Key_Backtab:
self.handle_backtab()
elif event.key() in (Qt.Key_Up, Qt.Key_Down):
super().keyPressEvent(event)
self.check_cursor_position()
elif event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter and not event.modifiers() == Qt.ControlModifier:
cursor = self.textCursor()
current_line = cursor.block().text()
indentation = re.match(r"\s*", current_line).group() # Capture leading whitespace
super().keyPressEvent(event) # Call the parent method to insert the newline
self.insertPlainText(indentation) # Insert the captured indentation
self.check_cursor_position()
elif event.key() == Qt.Key_Backspace:
cursor = self.textCursor()
text_up_to_cursor = self.toPlainText()[:cursor.position()]
if text_up_to_cursor.endswith(' '): # Check if the cursor is preceded by 4 spaces
cursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 4)
cursor.removeSelectedText()
return # Prevent calling super().keyPressEvent(event) to avoid deleting an extra character
else:
super().keyPressEvent(event)
else:
super().keyPressEvent(event)
else:
super().keyPressEvent(event)

def handle_control_slash(self):
"""
Toggles commenting on the selected lines. Adds or removes '-- ' at the start of each selected line.
"""
cursor = self.textCursor()
selected_text = cursor.selection().toPlainText()
lines = selected_text.split("\n")
Expand All @@ -359,18 +400,40 @@ def handle_control_slash(self):
# replace the selected text with the commented lines
cursor.insertText("\n".join(commented_lines))

def update_document_size(self):
"""
Updates the document size based on the current font size, affecting the overall layout and appearance.
"""

self.setStyleSheet(f"font: {self.font_size}pt 'Courier New';")

def handle_control_up(self):
"""
Increases the font size of the text editor by one point.
"""
self.font_size += 1
self.update_document_size()

def handle_control_down(self):
"""
Decreases the font size of the text editor by one point.
"""
self.font_size -= 1
self.update_document_size()

def handle_control_p(self):
"""
Inserts a predefined piece of code at the current cursor position. This is a placeholder for custom functionality.
"""
self.__insert_code("BASE:I()", -1)

def handle_special_characters(self, event):
"""
Handles the automatic insertion of paired special characters (e.g., quotes, parentheses).
Parameters:
event (QKeyEvent): The key event containing the special character to be handled.
"""
cursor = self.textCursor()
cursor.movePosition(QTextCursor.MoveOperation.Right, QTextCursor.KeepAnchor)
if cursor.selectedText() == event.text():
Expand All @@ -390,6 +453,9 @@ def handle_special_characters(self, event):
self.__insert_code(")" * 2, -1)

def handle_tab(self):
"""
Handles the Tab key press for indentation. If text is selected, indents the selection; otherwise, inserts spaces.
"""
cursor = self.textCursor()
start = cursor.selectionStart()
end = cursor.selectionEnd()
Expand All @@ -415,6 +481,9 @@ def handle_tab(self):
self.setTextCursor(cursor)

def handle_backtab(self):
"""
Handles the Shift+Tab key press for unindentation. If text is selected, unindents the selection.
"""
cursor = self.textCursor()
start = cursor.selectionStart()
end = cursor.selectionEnd()
Expand Down Expand Up @@ -444,6 +513,12 @@ def handle_backtab(self):
self.setTextCursor(cursor)

def resizeEvent(self, event):
"""
Handles the resize event of the text editor to adjust the line number area accordingly.
Parameters:
event (QResizeEvent): The resize event.
"""
super().resizeEvent(event)

content_rect = self.contentsRect()
Expand Down
20 changes: 3 additions & 17 deletions dcs_code_injector/dcs_code_injector_window.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
from PySide6.QtCore import Qt

import os
import json
Expand Down Expand Up @@ -73,13 +72,11 @@ def __init__(self):
self.timer.start()

self.back_up_settings_file()
self.copy_hook_file()

self.show()
self.init_done = True

# def update_code_views_font(self):
# for i in range(self.tab_widget.count()):
# self.tab_widget.widget(i).update_font()

def read_log(self):
"""
Expand Down Expand Up @@ -213,6 +210,7 @@ def add_new_tab(self, name=None, code=None):

code_text_edit = CodeTextEdit()
code_text_edit.textChanged.connect(self.save_code)
code_text_edit.execute_code.connect(self.send_code)
self.tab_widget.insertTab(self.tab_widget.count() - 1, code_text_edit, "UNNAMED")

self.tab_widget.setCurrentIndex(self.tab_widget.count() - 2)
Expand Down Expand Up @@ -291,6 +289,7 @@ def add_text_to_log(self, complete_text):
self.txt_log.verticalScrollBar().setValue(self.txt_log.verticalScrollBar().maximum())

def send_code(self, code):
self.add_code_to_log(code)
self.statusbar.showMessage("Trying to send data...")
self.stop_button = QPushButton("Stop")
self.statusbar.addPermanentWidget(self.stop_button)
Expand Down Expand Up @@ -397,19 +396,6 @@ def show_settings():
dlg = SettingsDialog()
dlg.exec_()

def keyPressEvent(self, event: QKeyEvent) -> None:
"""
Handles key press events.
:param event: <QKeyEvent> the key press event
"""

if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return and event.modifiers() == Qt.ControlModifier:
text = self.tab_widget.currentWidget().textCursor().selection().toPlainText()
if text == "":
text = self.tab_widget.currentWidget().toPlainText()
self.send_code(text)

def closeEvent(self, event):
"""
Handles the close event of the window, saves the window's position and size before closing
Expand Down
2 changes: 1 addition & 1 deletion dcs_code_injector/hook_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
local code_injector_client = DCSCI.server:accept()
if code_injector_client then
code_injector_client:settimeout(0)
code_injector_client:settimeout(0.005)
local chunk, err, partial
local response = ""
Expand Down

0 comments on commit ed3524d

Please sign in to comment.