Skip to content

Commit

Permalink
add options to disable copy & paste
Browse files Browse the repository at this point in the history
  • Loading branch information
MyreMylar committed May 2, 2024
1 parent 3c29557 commit 32858dc
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 101 deletions.
23 changes: 18 additions & 5 deletions pygame_gui/core/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def __linux_paste():
stdout, _ = process.communicate()
return stdout.decode('utf-8')

else:
elif PLATFORM == 'DARWIN':
def __mac_copy(data: str):
with subprocess.Popen('pbcopy',
env={'LANG': 'en_US.UTF-8'},
Expand All @@ -185,10 +185,19 @@ def __mac_paste():
return subprocess.check_output(
'pbpaste', env={'LANG': 'en_US.UTF-8'}).decode('utf-8')

else:
def __unknown_copy(data: str):

Check warning on line 189 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L189

Added line #L189 was not covered by tests
# copy not supported on this platform
pass

Check warning on line 191 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L191

Added line #L191 was not covered by tests

def __unknown_paste():

Check warning on line 193 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L193

Added line #L193 was not covered by tests
# paste not supported on this platform
return ""

Check warning on line 195 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L195

Added line #L195 was not covered by tests


def clipboard_copy(data: str):
"""
Hopefully cross platform, copy to a clipboard.
Hopefully cross-platform, copy to a clipboard.
:return: A platform specific copy function.
Expand All @@ -201,13 +210,15 @@ def clipboard_copy(data: str):
__windows_copy(data)
elif current_platform == 'LINUX':
__linux_copy(data)
else:
elif current_platform == 'DARWIN':

Check warning on line 213 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L213

Added line #L213 was not covered by tests
__mac_copy(data)
else:
__unknown_copy(data)

Check warning on line 216 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L216

Added line #L216 was not covered by tests


def clipboard_paste():
"""
Hopefully cross platform, paste from a clipboard.
Hopefully cross-platform, paste from a clipboard.
:return: A platform specific paste function.
Expand All @@ -220,8 +231,10 @@ def clipboard_paste():
return __windows_paste()
elif current_platform == 'LINUX':
return __linux_paste()
else:
elif current_platform == 'DARWIN':

Check warning on line 234 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L234

Added line #L234 was not covered by tests
return __mac_paste()
else:
return __unknown_paste()

Check warning on line 237 in pygame_gui/core/utility.py

View check run for this annotation

Codecov / codecov/patch

pygame_gui/core/utility.py#L237

Added line #L237 was not covered by tests


def create_resource_path(relative_path: Union[str, Path]):
Expand Down
6 changes: 5 additions & 1 deletion pygame_gui/elements/ui_text_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ def __init__(self,
self.vertical_cursor_movement = False
self.last_horiz_cursor_index = 0

self.copy_text_enabled = True
self.paste_text_enabled = False

self.rebuild_from_changed_theme_data()

@property
Expand Down Expand Up @@ -922,7 +925,8 @@ def _do_copy(self):
if self.text_box_layout is not None and abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
clipboard_copy(self.text_box_layout.plain_text[low_end:high_end])
if self.ui_manager.copy_text_enabled and self.copy_text_enabled:
clipboard_copy(self.text_box_layout.plain_text[low_end:high_end])

def _calculate_double_click_word_selection(self):
"""
Expand Down
72 changes: 38 additions & 34 deletions pygame_gui/elements/ui_text_entry_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def __init__(self,
self.cursor_blink_delay_after_moving = 1.0
self.blink_cursor_time_acc = 0.0
self.blink_cursor_time = 0.4
self.paste_text_enabled = True

self.cursor_on = False

Expand Down Expand Up @@ -333,17 +334,19 @@ def _process_cut_event(self, event: Event) -> bool:
return consumed_event

def _do_cut(self):
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
clipboard_copy(self.html_text[low_end:high_end])
self.text_box_layout.delete_selected_text()
self.edit_position = low_end
self.html_text = self.html_text[:low_end] + self.html_text[high_end:]
self.text_box_layout.set_cursor_position(self.edit_position)
self.select_range = [0, 0]
self.redraw_from_text_block()
self.cursor_has_moved_recently = True
if self.ui_manager.copy_text_enabled and self.copy_text_enabled:
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])

clipboard_copy(self.html_text[low_end:high_end])
self.text_box_layout.delete_selected_text()
self.edit_position = low_end
self.html_text = self.html_text[:low_end] + self.html_text[high_end:]
self.text_box_layout.set_cursor_position(self.edit_position)
self.select_range = [0, 0]
self.redraw_from_text_block()
self.cursor_has_moved_recently = True

def _process_paste_event(self, event: Event) -> bool:
"""
Expand All @@ -362,30 +365,31 @@ def _process_paste_event(self, event: Event) -> bool:
return consumed_event

def _do_paste(self):
paste = clipboard_paste()
if paste is not None:
new_text = self.convert_all_line_endings_to_unix(clipboard_paste())
if self.ui_manager.paste_text_enabled and self.paste_text_enabled:
paste = clipboard_paste()
if paste is not None:
new_text = self.convert_all_line_endings_to_unix(clipboard_paste())

if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
self.html_text = self.html_text[:low_end] + new_text + self.html_text[high_end:]
self.set_text(self.html_text)
self.edit_position = low_end + len(new_text)
self.text_box_layout.set_cursor_position(self.edit_position)
self.redraw_from_text_block()
self.select_range = [0, 0]
self.cursor_has_moved_recently = True
elif len(new_text) > 0:
self.html_text = (self.html_text[:self.edit_position] +
new_text +
self.html_text[self.edit_position:])
original_edit_pos = self.edit_position
self.set_text(self.html_text)
self.edit_position = original_edit_pos + len(new_text)
self.text_box_layout.set_cursor_position(self.edit_position)
self.redraw_from_text_block()
self.cursor_has_moved_recently = True
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
self.html_text = self.html_text[:low_end] + new_text + self.html_text[high_end:]
self.set_text(self.html_text)
self.edit_position = low_end + len(new_text)
self.text_box_layout.set_cursor_position(self.edit_position)
self.redraw_from_text_block()
self.select_range = [0, 0]
self.cursor_has_moved_recently = True
elif len(new_text) > 0:
self.html_text = (self.html_text[:self.edit_position] +
new_text +
self.html_text[self.edit_position:])
original_edit_pos = self.edit_position
self.set_text(self.html_text)
self.edit_position = original_edit_pos + len(new_text)
self.text_box_layout.set_cursor_position(self.edit_position)
self.redraw_from_text_block()
self.cursor_has_moved_recently = True

def redraw_from_text_block(self):
self.text_box_layout.fit_layout_rect_height_to_rows()
Expand Down
128 changes: 67 additions & 61 deletions pygame_gui/elements/ui_text_entry_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ def __init__(self,
self.forbidden_characters: Optional[List[str]] = None
self.length_limit: Optional[int] = None

self.copy_text_enabled = True
self.paste_text_enabled = True

self.rebuild_from_changed_theme_data()

@property
Expand Down Expand Up @@ -780,20 +783,21 @@ def _process_cut_event(self, event: Event) -> bool:
return consumed_event

def _do_cut(self):
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
clipboard_copy(self.text[low_end:high_end])
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.delete_selected_text()
self.drawable_shape.apply_active_text_changes()
self.edit_position = low_end
self.text = self.text[:low_end] + self.text[high_end:]
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.set_cursor_position(self.edit_position)
self.drawable_shape.apply_active_text_changes()
self.select_range = [0, 0]
self.cursor_has_moved_recently = True
if self.ui_manager.copy_text_enabled and self.copy_text_enabled:
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
clipboard_copy(self.text[low_end:high_end])
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.delete_selected_text()
self.drawable_shape.apply_active_text_changes()
self.edit_position = low_end
self.text = self.text[:low_end] + self.text[high_end:]
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.set_cursor_position(self.edit_position)
self.drawable_shape.apply_active_text_changes()
self.select_range = [0, 0]
self.cursor_has_moved_recently = True

def _process_copy_event(self, event: Event) -> bool:
"""
Expand All @@ -817,7 +821,8 @@ def _do_copy(self):
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
clipboard_copy(self.text[low_end:high_end])
if self.ui_manager.copy_text_enabled and self.copy_text_enabled:
clipboard_copy(self.text[low_end:high_end])

def _process_paste_event(self, event: pygame.event.Event) -> bool:
"""
Expand All @@ -837,52 +842,53 @@ def _process_paste_event(self, event: pygame.event.Event) -> bool:
return consumed_event

def _do_paste(self):
new_text = clipboard_paste()
if self.validate_text_string(new_text):
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
final_text = self.text[:low_end] + new_text + self.text[high_end:]
within_length_limit = True
if self.length_limit is not None and len(final_text) > self.length_limit:
within_length_limit = False
if within_length_limit:
self.text = final_text
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.delete_selected_text()
self.drawable_shape.apply_active_text_changes()
display_new_text = new_text
if self.is_text_hidden:
display_new_text = self.hidden_text_char * len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.insert_text(display_new_text, low_end)
self.edit_position = low_end + len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.set_cursor_position(
self.edit_position)
self.drawable_shape.apply_active_text_changes()
self.select_range = [0, 0]
self.cursor_has_moved_recently = True
elif len(new_text) > 0:
final_text = (self.text[:self.edit_position] +
new_text +
self.text[self.edit_position:])
within_length_limit = True
if self.length_limit is not None and len(final_text) > self.length_limit:
within_length_limit = False
if within_length_limit:
self.text = final_text
display_new_text = new_text
if self.is_text_hidden:
display_new_text = self.hidden_text_char * len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.insert_text(display_new_text, self.edit_position)
self.edit_position += len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.set_cursor_position(
self.edit_position)
self.drawable_shape.apply_active_text_changes()
self.cursor_has_moved_recently = True
if self.ui_manager.paste_text_enabled and self.paste_text_enabled:
new_text = clipboard_paste()
if self.validate_text_string(new_text):
if abs(self.select_range[0] - self.select_range[1]) > 0:
low_end = min(self.select_range[0], self.select_range[1])
high_end = max(self.select_range[0], self.select_range[1])
final_text = self.text[:low_end] + new_text + self.text[high_end:]
within_length_limit = True
if self.length_limit is not None and len(final_text) > self.length_limit:
within_length_limit = False
if within_length_limit:
self.text = final_text
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.delete_selected_text()
self.drawable_shape.apply_active_text_changes()
display_new_text = new_text
if self.is_text_hidden:
display_new_text = self.hidden_text_char * len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.insert_text(display_new_text, low_end)
self.edit_position = low_end + len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.set_cursor_position(
self.edit_position)
self.drawable_shape.apply_active_text_changes()
self.select_range = [0, 0]
self.cursor_has_moved_recently = True
elif len(new_text) > 0:
final_text = (self.text[:self.edit_position] +
new_text +
self.text[self.edit_position:])
within_length_limit = True
if self.length_limit is not None and len(final_text) > self.length_limit:
within_length_limit = False
if within_length_limit:
self.text = final_text
display_new_text = new_text
if self.is_text_hidden:
display_new_text = self.hidden_text_char * len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.insert_text(display_new_text, self.edit_position)
self.edit_position += len(new_text)
if self.drawable_shape is not None:
self.drawable_shape.text_box_layout.set_cursor_position(
self.edit_position)
self.drawable_shape.apply_active_text_changes()
self.cursor_has_moved_recently = True

def _process_mouse_button_event(self, event: pygame.event.Event) -> bool:
"""
Expand Down
3 changes: 3 additions & 0 deletions pygame_gui/ui_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ def __init__(self,
self.text_hovered = False
self.hovering_any_ui_element = False

self.copy_text_enabled = True
self.paste_text_enabled = True

if auto_load:
self.resource_loader.start()
# If we are using a blocking loader this will only return when loading is complete
Expand Down

0 comments on commit 32858dc

Please sign in to comment.