pygpt-net 2.6.33__py3-none-any.whl → 2.6.34__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. pygpt_net/CHANGELOG.txt +7 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/controller/assistant/batch.py +14 -4
  4. pygpt_net/controller/assistant/files.py +1 -0
  5. pygpt_net/controller/assistant/store.py +195 -1
  6. pygpt_net/controller/camera/camera.py +1 -1
  7. pygpt_net/controller/chat/common.py +50 -46
  8. pygpt_net/controller/config/placeholder.py +95 -75
  9. pygpt_net/controller/dialogs/confirm.py +3 -1
  10. pygpt_net/controller/media/media.py +11 -3
  11. pygpt_net/controller/painter/common.py +231 -13
  12. pygpt_net/core/assistants/files.py +18 -0
  13. pygpt_net/core/camera/camera.py +31 -402
  14. pygpt_net/core/camera/worker.py +430 -0
  15. pygpt_net/core/filesystem/url.py +3 -0
  16. pygpt_net/core/render/web/body.py +65 -9
  17. pygpt_net/core/text/utils.py +3 -0
  18. pygpt_net/data/config/config.json +3 -3
  19. pygpt_net/data/config/models.json +3 -3
  20. pygpt_net/data/config/settings.json +10 -5
  21. pygpt_net/data/locale/locale.de.ini +8 -7
  22. pygpt_net/data/locale/locale.en.ini +9 -6
  23. pygpt_net/data/locale/locale.es.ini +8 -7
  24. pygpt_net/data/locale/locale.fr.ini +8 -7
  25. pygpt_net/data/locale/locale.it.ini +8 -7
  26. pygpt_net/data/locale/locale.pl.ini +8 -7
  27. pygpt_net/data/locale/locale.uk.ini +8 -7
  28. pygpt_net/data/locale/locale.zh.ini +8 -7
  29. pygpt_net/item/assistant.py +13 -1
  30. pygpt_net/provider/api/google/__init__.py +32 -23
  31. pygpt_net/provider/api/openai/store.py +45 -1
  32. pygpt_net/provider/llms/google.py +4 -0
  33. pygpt_net/ui/dialog/assistant_store.py +213 -203
  34. pygpt_net/ui/layout/chat/input.py +3 -3
  35. pygpt_net/ui/widget/draw/painter.py +16 -1
  36. pygpt_net/ui/widget/option/combo.py +5 -1
  37. pygpt_net/ui/widget/textarea/input.py +273 -3
  38. {pygpt_net-2.6.33.dist-info → pygpt_net-2.6.34.dist-info}/METADATA +9 -2
  39. {pygpt_net-2.6.33.dist-info → pygpt_net-2.6.34.dist-info}/RECORD +42 -41
  40. {pygpt_net-2.6.33.dist-info → pygpt_net-2.6.34.dist-info}/LICENSE +0 -0
  41. {pygpt_net-2.6.33.dist-info → pygpt_net-2.6.34.dist-info}/WHEEL +0 -0
  42. {pygpt_net-2.6.33.dist-info → pygpt_net-2.6.34.dist-info}/entry_points.txt +0 -0
pygpt_net/CHANGELOG.txt CHANGED
@@ -1,3 +1,10 @@
1
+ 2.6.34 (2025-09-03)
2
+
3
+ - Added auto-resizing for input.
4
+ - Added file management to the OpenAI Vector Stores tool.
5
+ - Implemented removal of script tags when exporting HTML.
6
+ - Enabled maintaining custom resolution in Painter.
7
+
1
8
  2.6.33 (2025-09-02)
2
9
 
3
10
  - Added a "crop" option, auto-resize canvas, and layer support to Painter.
pygpt_net/__init__.py CHANGED
@@ -6,15 +6,15 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.09.02 00:00:00 #
9
+ # Updated Date: 2025.09.03 00:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  __author__ = "Marcin Szczygliński"
13
13
  __copyright__ = "Copyright 2025, Marcin Szczygliński"
14
14
  __credits__ = ["Marcin Szczygliński"]
15
15
  __license__ = "MIT"
16
- __version__ = "2.6.33"
17
- __build__ = "2025-09-02"
16
+ __version__ = "2.6.34"
17
+ __build__ = "2025-09-03"
18
18
  __maintainer__ = "Marcin Szczygliński"
19
19
  __github__ = "https://github.com/szczyglis-dev/py-gpt"
20
20
  __report__ = "https://github.com/szczyglis-dev/py-gpt/issues"
@@ -6,11 +6,12 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.08.24 23:00:00 #
9
+ # Updated Date: 2025.09.02 22:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, Any
13
13
 
14
+ from PySide6.QtCore import QTimer
14
15
  from PySide6.QtWidgets import QFileDialog, QApplication
15
16
 
16
17
  from pygpt_net.utils import trans
@@ -526,6 +527,15 @@ class Batch:
526
527
  msg=msg,
527
528
  )
528
529
 
530
+ def refresh_delayed(self, ms: int = 1000):
531
+ """
532
+ Refresh UI after delay
533
+
534
+ :param ms: milliseconds to wait
535
+ """
536
+ self.window.update_status("Refreshing status...")
537
+ QTimer.singleShot(ms, lambda: self.window.controller.assistant.store.refresh_status())
538
+
529
539
  def upload(self, force: bool = False):
530
540
  """
531
541
  Upload files to vector store
@@ -548,10 +558,10 @@ class Batch:
548
558
 
549
559
  :param num: number of uploaded files
550
560
  """
551
- self.window.controller.assistant.files.update()
552
- self.window.controller.assistant.store.refresh_status()
561
+ self.window.controller.assistant.files.update()
553
562
  self.window.update_status("OK. Uploaded files: " + str(num) + ".")
554
563
  self.window.ui.dialogs.alert("OK. Uploaded files: " + str(num) + ".")
564
+ self.refresh_delayed(1500)
555
565
 
556
566
  def handle_uploaded_files_failed(self, error: Any):
557
567
  """
@@ -562,7 +572,7 @@ class Batch:
562
572
  self.window.core.debug.log(error)
563
573
  print("Error uploading files")
564
574
  self.window.controller.assistant.files.update()
565
- self.window.controller.assistant.store.refresh_status()
575
+ self.refresh_delayed(1500)
566
576
  self.window.update_status("Error uploading files.")
567
577
  self.window.ui.dialogs.alert(error)
568
578
 
@@ -31,6 +31,7 @@ class Files:
31
31
  def update(self):
32
32
  """Update assistants files list"""
33
33
  self.update_list()
34
+ self.window.controller.assistant.store.update_files_list()
34
35
 
35
36
  def select(self, idx: int):
36
37
  """
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.08.24 23:00:00 #
9
+ # Updated Date: 2025.09.02 22:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import copy
@@ -14,6 +14,8 @@ import json
14
14
  from typing import Optional
15
15
 
16
16
  from PySide6.QtWidgets import QApplication
17
+ from PySide6.QtGui import QStandardItem
18
+ from PySide6.QtCore import Qt, QTimer
17
19
 
18
20
  from pygpt_net.item.assistant import AssistantStoreItem
19
21
  from pygpt_net.utils import trans
@@ -57,6 +59,8 @@ class VectorStore:
57
59
  "value": "",
58
60
  },
59
61
  }
62
+ # Mapping of current files list rows to file IDs
63
+ self._files_row_to_id = []
60
64
 
61
65
  def get_options(self) -> dict:
62
66
  """
@@ -147,6 +151,8 @@ class VectorStore:
147
151
  self.current = None # reset if not exists
148
152
  self.window.controller.config.load_options(self.id, options)
149
153
 
154
+ self.update_files_list()
155
+
150
156
  def refresh_status(self):
151
157
  """Reload store status"""
152
158
  if self.current is not None: # TODO: reset on profile reload
@@ -157,6 +163,7 @@ class VectorStore:
157
163
  self.refresh_store(store)
158
164
  self.window.update_status(trans('status.assistant.saved'))
159
165
  self.update() # update stores list in assistant dialog
166
+ self.update_files_list()
160
167
 
161
168
  def refresh_store(
162
169
  self,
@@ -200,6 +207,8 @@ class VectorStore:
200
207
  self.refresh_store(store)
201
208
  self.window.update_status(trans('status.assistant.saved'))
202
209
  self.update()
210
+ if self.current == store_id:
211
+ self.update_files_list()
203
212
 
204
213
  def update_current(self):
205
214
  """Update current store"""
@@ -220,6 +229,13 @@ class VectorStore:
220
229
  option["value"] = store.expire_days
221
230
  self.window.controller.config.apply(self.id, "expire_days", option)
222
231
 
232
+ def save_btn(self):
233
+ """Save vector store editor and close dialog"""
234
+ self.window.update_status("Saving...")
235
+ self.save()
236
+ self.refresh_status()
237
+ self.window.update_status("Saved.")
238
+
223
239
  def save(self, persist: bool = True):
224
240
  """
225
241
  Save vector store editor
@@ -258,6 +274,7 @@ class VectorStore:
258
274
  self.update() # update stores list in assistant dialog
259
275
  self.window.update_status(trans("info.settings.saved"))
260
276
  self.restore_selection()
277
+ self.update_files_list()
261
278
 
262
279
  def reload_items(self):
263
280
  """Reload list items"""
@@ -281,6 +298,7 @@ class VectorStore:
281
298
  self.save(persist=False)
282
299
  self.current = self.get_by_tab_idx(idx)
283
300
  self.init()
301
+ self.update_files_list()
284
302
 
285
303
  def new(self):
286
304
  """Create new vector store"""
@@ -305,6 +323,7 @@ class VectorStore:
305
323
  self.init()
306
324
  self.restore_selection()
307
325
  self.refresh_by_store_id(store.id)
326
+ self.update_files_list()
308
327
 
309
328
  def delete_by_idx(
310
329
  self,
@@ -357,6 +376,7 @@ class VectorStore:
357
376
  self.update() # update stores list in assistant dialog
358
377
  self.init()
359
378
  self.restore_selection()
379
+ self.update_files_list()
360
380
  else:
361
381
  self.window.update_status(trans('status.error'))
362
382
  except Exception as e:
@@ -469,6 +489,7 @@ class VectorStore:
469
489
  """Update vector store editor"""
470
490
  self.reload_items()
471
491
  self.window.controller.assistant.editor.update_store_list() # update stores list in assistant dialog
492
+ self.update_files_list()
472
493
 
473
494
  def set_hide_thread(self, state: bool):
474
495
  """
@@ -478,3 +499,176 @@ class VectorStore:
478
499
  """
479
500
  self.window.core.config.set("assistant.store.hide_threads", state)
480
501
  self.update()
502
+
503
+ # ==================== Files ====================
504
+
505
+ def update_files_list(self):
506
+ """
507
+ Update files list view for the current store based on local DB.
508
+ This method does not hit the API; it reflects local state.
509
+ """
510
+ model_id = 'assistant.store.files.list'
511
+ if 'assistant.store.files.list' not in self.window.ui.models:
512
+ return # files panel not initialized yet
513
+ model = self.window.ui.models[model_id]
514
+ try:
515
+ model.removeRows(0, model.rowCount())
516
+ except Exception:
517
+ pass
518
+
519
+ self._files_row_to_id = []
520
+
521
+ if self.current is None:
522
+ return
523
+
524
+ files_db = self.window.core.assistants.files
525
+ if files_db is None:
526
+ return
527
+
528
+ # Resolve store files collection from DB
529
+ try:
530
+ store_files = files_db.get_by_store_or_thread(self.current, None) or {}
531
+ except Exception as e:
532
+ self.window.core.debug.log(e)
533
+ store_files = {}
534
+
535
+ i = 0
536
+ for file_id, file_obj in store_files.items():
537
+ if isinstance(file_obj, dict):
538
+ data = file_obj
539
+ else:
540
+ data = {}
541
+ for key in ('id', 'file_id', 'name', 'filename', 'bytes', 'size', 'usage_bytes', 'status'):
542
+ try:
543
+ if hasattr(file_obj, key):
544
+ data[key] = getattr(file_obj, key)
545
+ except Exception:
546
+ pass
547
+ if not data and hasattr(file_obj, 'to_dict'):
548
+ try:
549
+ data = file_obj.to_dict()
550
+ except Exception:
551
+ data = {}
552
+
553
+ # Choose display name
554
+ name = data.get('filename') or data.get('name') or file_id
555
+ # Choose size
556
+ size_val = None
557
+ for k in ('bytes', 'size', 'usage_bytes'):
558
+ if data.get(k) is not None:
559
+ size_val = data.get(k)
560
+ break
561
+
562
+ # Human-readable size if possible
563
+ size_txt = ""
564
+ try:
565
+ if size_val:
566
+ size_txt = self.window.core.filesystem.sizeof_fmt(int(size_val))
567
+ except Exception:
568
+ pass
569
+
570
+ extra = []
571
+ if size_txt:
572
+ extra.append(size_txt)
573
+ if data.get('status'):
574
+ extra.append(str(data.get('status')))
575
+ label = name
576
+ if extra:
577
+ label += " ({})".format(", ".join(extra))
578
+
579
+ item = QStandardItem(label)
580
+ item.setEditable(False)
581
+ item.setData(file_id, Qt.UserRole)
582
+ model.setItem(i, 0, item)
583
+ self._files_row_to_id.append(data['file_id'] if 'file_id' in data else file_id)
584
+ i += 1
585
+
586
+ def delete_file_by_idx(self, idx: int, force: bool = False):
587
+ """
588
+ Delete a single file from the current store by row index in files list.
589
+ This uses API to remove the file from a remote store, then triggers async re-import
590
+ of files for the current store to keep the local DB in sync.
591
+
592
+ :param idx: row index in files list
593
+ :param force: force delete without confirmation
594
+ """
595
+ if self.current is None:
596
+ self.window.ui.dialogs.alert("Please select vector store first.")
597
+ return
598
+
599
+ if not force:
600
+ self.window.ui.dialogs.confirm(
601
+ type='assistant.file.delete',
602
+ id=idx,
603
+ msg=trans('confirm.assistant.store.file.delete'),
604
+ )
605
+ return
606
+
607
+ model_id = 'assistant.store.files.list'
608
+ if model_id not in self.window.ui.models:
609
+ return
610
+ if idx < 0 or idx >= len(self._files_row_to_id):
611
+ return
612
+
613
+ file_id = self._files_row_to_id[idx]
614
+ if not file_id:
615
+ return
616
+
617
+ # Update UI state
618
+ self.window.update_status(trans('status.sending'))
619
+ QApplication.processEvents()
620
+
621
+ try:
622
+ api = self.window.core.api.openai.store
623
+ removed = False
624
+
625
+ # Prefer store-scoped removal if available
626
+ if hasattr(api, 'remove_store_file'):
627
+ try:
628
+ api.remove_store_file(self.current, file_id)
629
+ removed = True
630
+ except Exception as e:
631
+ self.window.core.debug.log(e)
632
+
633
+ # Fallback: remove by file_id only
634
+ if not removed and hasattr(api, 'remove_file'):
635
+ try:
636
+ api.remove_file(file_id)
637
+ removed = True
638
+ except Exception as e:
639
+ self.window.core.debug.log(e)
640
+
641
+ if not removed:
642
+ raise RuntimeError("Remove file API not available.")
643
+
644
+ # Remove from local DB
645
+ try:
646
+ self.window.core.assistants.files.delete_by_file_id(file_id)
647
+ except Exception as e:
648
+ self.window.core.debug.log(e)
649
+
650
+ # Optimistic UI update: remove row from the model immediately
651
+ try:
652
+ self.window.ui.models[model_id].removeRow(idx)
653
+ # also update index map
654
+ try:
655
+ del self._files_row_to_id[idx]
656
+ except Exception:
657
+ pass
658
+ except Exception:
659
+ pass
660
+
661
+ # Trigger re-import for the current store to refresh local DB and UI elsewhere
662
+ try:
663
+ self.window.update_status("Refreshing status...")
664
+ QTimer.singleShot(1000, lambda: self.window.controller.assistant.store.refresh_status())
665
+ except Exception as e:
666
+ self.window.core.debug.log(e)
667
+
668
+ self.window.update_status(trans('status.deleted'))
669
+
670
+ except Exception as e:
671
+ self.window.update_status(trans('status.error'))
672
+ self.window.ui.dialogs.alert("Failed to delete file: {}".format(e))
673
+ self.window.core.debug.log(e)
674
+ self.update_files_list()
@@ -18,7 +18,7 @@ from PySide6.QtCore import Slot, QObject
18
18
  from PySide6.QtGui import QImage, QPixmap, Qt
19
19
 
20
20
  from pygpt_net.core.events import AppEvent, KernelEvent
21
- from pygpt_net.core.camera import CaptureWorker
21
+ from pygpt_net.core.camera.worker import CaptureWorker
22
22
  from pygpt_net.core.types import MODE_ASSISTANT
23
23
  from pygpt_net.utils import trans
24
24
 
@@ -10,7 +10,6 @@
10
10
  # ================================================== #
11
11
 
12
12
  import os
13
- from typing import Any
14
13
 
15
14
  from PySide6.QtGui import QTextCursor
16
15
  from PySide6.QtWidgets import QFileDialog, QApplication
@@ -34,42 +33,45 @@ class Common:
34
33
 
35
34
  def setup(self):
36
35
  """Set up UI"""
36
+ nodes = self.window.ui.nodes
37
+ config = self.window.core.config
38
+
37
39
  # stream mode
38
- if self.window.core.config.get('stream'):
39
- self.window.ui.nodes['input.stream'].setChecked(True)
40
+ if config.get('stream'):
41
+ nodes['input.stream'].setChecked(True)
40
42
  else:
41
- self.window.ui.nodes['input.stream'].setChecked(False)
43
+ nodes['input.stream'].setChecked(False)
42
44
 
43
45
  # send clear
44
- if self.window.core.config.get('send_clear'):
45
- self.window.ui.nodes['input.send_clear'].setChecked(True)
46
+ if config.get('send_clear'):
47
+ nodes['input.send_clear'].setChecked(True)
46
48
  else:
47
- self.window.ui.nodes['input.send_clear'].setChecked(False)
49
+ nodes['input.send_clear'].setChecked(False)
48
50
 
49
51
  # send with enter/shift/disabled
50
- mode = self.window.core.config.get('send_mode')
52
+ mode = config.get('send_mode')
51
53
  if mode == 2:
52
- self.window.ui.nodes['input.send_shift_enter'].setChecked(True)
53
- self.window.ui.nodes['input.send_enter'].setChecked(False)
54
- self.window.ui.nodes['input.send_none'].setChecked(False)
54
+ nodes['input.send_shift_enter'].setChecked(True)
55
+ nodes['input.send_enter'].setChecked(False)
56
+ nodes['input.send_none'].setChecked(False)
55
57
  elif mode == 1:
56
- self.window.ui.nodes['input.send_enter'].setChecked(True)
57
- self.window.ui.nodes['input.send_shift_enter'].setChecked(False)
58
- self.window.ui.nodes['input.send_none'].setChecked(False)
58
+ nodes['input.send_enter'].setChecked(True)
59
+ nodes['input.send_shift_enter'].setChecked(False)
60
+ nodes['input.send_none'].setChecked(False)
59
61
  elif mode == 0:
60
- self.window.ui.nodes['input.send_enter'].setChecked(False)
61
- self.window.ui.nodes['input.send_shift_enter'].setChecked(False)
62
- self.window.ui.nodes['input.send_none'].setChecked(True)
62
+ nodes['input.send_enter'].setChecked(False)
63
+ nodes['input.send_shift_enter'].setChecked(False)
64
+ nodes['input.send_none'].setChecked(True)
63
65
 
64
66
  # cmd enabled
65
- if self.window.core.config.get('cmd'):
66
- self.window.ui.nodes['cmd.enabled'].setChecked(True)
67
+ if config.get('cmd'):
68
+ nodes['cmd.enabled'].setChecked(True)
67
69
  else:
68
- self.window.ui.nodes['cmd.enabled'].setChecked(False)
70
+ nodes['cmd.enabled'].setChecked(False)
69
71
 
70
72
  # output timestamps
71
- is_timestamp = self.window.core.config.get('output_timestamp')
72
- self.window.ui.nodes['output.timestamp'].setChecked(is_timestamp)
73
+ is_timestamp = config.get('output_timestamp')
74
+ nodes['output.timestamp'].setChecked(is_timestamp)
73
75
  if is_timestamp:
74
76
  data = {
75
77
  "initialized": self.initialized,
@@ -78,22 +80,22 @@ class Common:
78
80
  self.window.dispatch(event)
79
81
 
80
82
  # raw (plain) output
81
- plain = self.window.core.config.get('render.plain')
82
- self.window.ui.nodes['output.raw'].setChecked(plain)
83
+ plain = config.get('render.plain')
84
+ nodes['output.raw'].setChecked(plain)
83
85
  if plain:
84
- self.window.ui.nodes['output.timestamp'].setVisible(True)
85
- for pid in self.window.ui.nodes['output']:
86
+ nodes['output.timestamp'].setVisible(True)
87
+ for pid in nodes['output']:
86
88
  try:
87
- self.window.ui.nodes['output'][pid].setVisible(False)
88
- self.window.ui.nodes['output_plain'][pid].setVisible(True)
89
+ nodes['output'][pid].setVisible(False)
90
+ nodes['output_plain'][pid].setVisible(True)
89
91
  except Exception as e:
90
92
  pass
91
93
  else:
92
- self.window.ui.nodes['output.timestamp'].setVisible(False)
93
- for pid in self.window.ui.nodes['output']:
94
+ nodes['output.timestamp'].setVisible(False)
95
+ for pid in nodes['output']:
94
96
  try:
95
- self.window.ui.nodes['output'][pid].setVisible(True)
96
- self.window.ui.nodes['output_plain'][pid].setVisible(False)
97
+ nodes['output'][pid].setVisible(True)
98
+ nodes['output_plain'][pid].setVisible(False)
97
99
  except Exception as e:
98
100
  pass
99
101
 
@@ -101,7 +103,7 @@ class Common:
101
103
  self.window.dispatch(event) # switch renderer if needed
102
104
 
103
105
  # set focus to input
104
- self.window.ui.nodes['input'].setFocus()
106
+ nodes['input'].setFocus()
105
107
  self.initialized = True
106
108
 
107
109
  def append_to_input(
@@ -115,8 +117,9 @@ class Common:
115
117
  :param text: text to append
116
118
  :param separator: text separator
117
119
  """
118
- prev_text = self.window.ui.nodes['input'].toPlainText()
119
- cur = self.window.ui.nodes['input'].textCursor()
120
+ node = self.window.ui.nodes['input']
121
+ prev_text = node.toPlainText()
122
+ cur = node.textCursor()
120
123
  cur.movePosition(QTextCursor.End)
121
124
  text = str(text).strip()
122
125
  if prev_text.strip() != "":
@@ -128,8 +131,8 @@ class Common:
128
131
  if sep: # New line if LF
129
132
  cur.insertBlock()
130
133
  cur.movePosition(QTextCursor.End) # Move cursor to end of text
131
- self.window.ui.nodes['input'].setTextCursor(cur) # Update visible cursor
132
- self.window.ui.nodes['input'].setFocus() # Set focus to input
134
+ node.setTextCursor(cur) # Update visible cursor
135
+ node.setFocus() # Set focus to input
133
136
 
134
137
  # update tokens counter
135
138
  self.window.controller.ui.update_tokens()
@@ -176,18 +179,19 @@ class Common:
176
179
 
177
180
  :param value: True if enabled
178
181
  """
182
+ nodes = self.window.ui.nodes
179
183
  if value == 0:
180
- self.window.ui.nodes['input.send_none'].setChecked(True)
181
- self.window.ui.nodes['input.send_shift_enter'].setChecked(False)
182
- self.window.ui.nodes['input.send_enter'].setChecked(False)
184
+ nodes['input.send_none'].setChecked(True)
185
+ nodes['input.send_shift_enter'].setChecked(False)
186
+ nodes['input.send_enter'].setChecked(False)
183
187
  elif value == 1:
184
- self.window.ui.nodes['input.send_enter'].setChecked(True)
185
- self.window.ui.nodes['input.send_shift_enter'].setChecked(False)
186
- self.window.ui.nodes['input.send_none'].setChecked(False)
188
+ nodes['input.send_enter'].setChecked(True)
189
+ nodes['input.send_shift_enter'].setChecked(False)
190
+ nodes['input.send_none'].setChecked(False)
187
191
  elif value == 2:
188
- self.window.ui.nodes['input.send_shift_enter'].setChecked(True)
189
- self.window.ui.nodes['input.send_enter'].setChecked(False)
190
- self.window.ui.nodes['input.send_none'].setChecked(False)
192
+ nodes['input.send_shift_enter'].setChecked(True)
193
+ nodes['input.send_enter'].setChecked(False)
194
+ nodes['input.send_none'].setChecked(False)
191
195
  self.window.core.config.set('send_mode', value)
192
196
 
193
197
  def focus_input(self):