pygpt-net 2.6.67__py3-none-any.whl → 2.7.0__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.
- pygpt_net/CHANGELOG.txt +12 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/assistant/assistant.py +13 -8
- pygpt_net/controller/assistant/batch.py +29 -15
- pygpt_net/controller/assistant/files.py +19 -14
- pygpt_net/controller/assistant/store.py +63 -41
- pygpt_net/controller/attachment/attachment.py +45 -35
- pygpt_net/controller/chat/attachment.py +50 -39
- pygpt_net/controller/config/field/dictionary.py +26 -14
- pygpt_net/controller/ctx/common.py +27 -17
- pygpt_net/controller/ctx/ctx.py +182 -101
- pygpt_net/controller/files/files.py +101 -41
- pygpt_net/controller/idx/indexer.py +87 -31
- pygpt_net/controller/kernel/kernel.py +13 -2
- pygpt_net/controller/mode/mode.py +3 -3
- pygpt_net/controller/model/editor.py +70 -15
- pygpt_net/controller/model/importer.py +153 -54
- pygpt_net/controller/painter/painter.py +2 -2
- pygpt_net/controller/presets/experts.py +68 -15
- pygpt_net/controller/presets/presets.py +72 -36
- pygpt_net/controller/settings/profile.py +76 -35
- pygpt_net/controller/settings/workdir.py +70 -39
- pygpt_net/core/assistants/files.py +20 -18
- pygpt_net/core/filesystem/actions.py +111 -10
- pygpt_net/core/filesystem/filesystem.py +2 -1
- pygpt_net/core/idx/idx.py +12 -11
- pygpt_net/core/idx/worker.py +13 -1
- pygpt_net/core/models/models.py +4 -4
- pygpt_net/core/profile/profile.py +13 -3
- pygpt_net/data/config/config.json +3 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/css/style.dark.css +39 -1
- pygpt_net/data/css/style.light.css +39 -1
- pygpt_net/data/locale/locale.de.ini +3 -1
- pygpt_net/data/locale/locale.en.ini +3 -1
- pygpt_net/data/locale/locale.es.ini +3 -1
- pygpt_net/data/locale/locale.fr.ini +3 -1
- pygpt_net/data/locale/locale.it.ini +3 -1
- pygpt_net/data/locale/locale.pl.ini +4 -2
- pygpt_net/data/locale/locale.uk.ini +3 -1
- pygpt_net/data/locale/locale.zh.ini +3 -1
- pygpt_net/provider/api/openai/__init__.py +4 -2
- pygpt_net/provider/core/config/patch.py +9 -1
- pygpt_net/tools/image_viewer/tool.py +17 -0
- pygpt_net/tools/text_editor/tool.py +9 -0
- pygpt_net/ui/__init__.py +2 -2
- pygpt_net/ui/layout/ctx/ctx_list.py +16 -6
- pygpt_net/ui/main.py +3 -1
- pygpt_net/ui/widget/calendar/select.py +3 -3
- pygpt_net/ui/widget/filesystem/explorer.py +1082 -142
- pygpt_net/ui/widget/lists/assistant.py +185 -24
- pygpt_net/ui/widget/lists/assistant_store.py +245 -42
- pygpt_net/ui/widget/lists/attachment.py +230 -47
- pygpt_net/ui/widget/lists/attachment_ctx.py +189 -33
- pygpt_net/ui/widget/lists/base_list_combo.py +2 -2
- pygpt_net/ui/widget/lists/context.py +1253 -70
- pygpt_net/ui/widget/lists/experts.py +110 -8
- pygpt_net/ui/widget/lists/model_editor.py +217 -14
- pygpt_net/ui/widget/lists/model_importer.py +125 -6
- pygpt_net/ui/widget/lists/preset.py +460 -71
- pygpt_net/ui/widget/lists/profile.py +149 -27
- pygpt_net/ui/widget/lists/uploaded.py +230 -38
- pygpt_net/ui/widget/option/combo.py +1046 -32
- pygpt_net/ui/widget/option/dictionary.py +35 -7
- {pygpt_net-2.6.67.dist-info → pygpt_net-2.7.0.dist-info}/METADATA +14 -57
- {pygpt_net-2.6.67.dist-info → pygpt_net-2.7.0.dist-info}/RECORD +69 -69
- {pygpt_net-2.6.67.dist-info → pygpt_net-2.7.0.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.67.dist-info → pygpt_net-2.7.0.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.67.dist-info → pygpt_net-2.7.0.dist-info}/entry_points.txt +0 -0
pygpt_net/controller/ctx/ctx.py
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
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.
|
|
9
|
+
# Updated Date: 2025.12.27 21:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
|
-
from typing import Optional, List
|
|
12
|
+
from typing import Optional, List, Union
|
|
13
13
|
|
|
14
14
|
from PySide6.QtCore import QModelIndex, QTimer
|
|
15
15
|
from PySide6.QtGui import QStandardItem
|
|
@@ -273,7 +273,7 @@ class Ctx:
|
|
|
273
273
|
self.update()
|
|
274
274
|
index = self.get_child_index_by_id(id)
|
|
275
275
|
if index.isValid():
|
|
276
|
-
self.window.ui.nodes['ctx.list'].
|
|
276
|
+
self.window.ui.nodes['ctx.list'].force_scroll_to_current()
|
|
277
277
|
|
|
278
278
|
def unselect(self):
|
|
279
279
|
"""Unselect ctx"""
|
|
@@ -319,7 +319,7 @@ class Ctx:
|
|
|
319
319
|
def new(
|
|
320
320
|
self,
|
|
321
321
|
force: bool = False,
|
|
322
|
-
group_id: Optional[int] = None
|
|
322
|
+
group_id: Optional[Union[int, list]] = None
|
|
323
323
|
):
|
|
324
324
|
"""
|
|
325
325
|
Create new ctx
|
|
@@ -330,6 +330,15 @@ class Ctx:
|
|
|
330
330
|
if not force and self.context_change_locked():
|
|
331
331
|
return
|
|
332
332
|
|
|
333
|
+
# if multiple group IDs provided, pick the first valid
|
|
334
|
+
if isinstance(group_id, list):
|
|
335
|
+
valid_group_id = None
|
|
336
|
+
for gid in group_id:
|
|
337
|
+
if self.window.core.ctx.has_group(gid):
|
|
338
|
+
valid_group_id = gid
|
|
339
|
+
break
|
|
340
|
+
group_id = valid_group_id
|
|
341
|
+
|
|
333
342
|
if group_id is None:
|
|
334
343
|
if self.group_id is not None and self.group_id > 0:
|
|
335
344
|
group_id = self.group_id
|
|
@@ -596,13 +605,13 @@ class Ctx:
|
|
|
596
605
|
|
|
597
606
|
def delete(
|
|
598
607
|
self,
|
|
599
|
-
id: int,
|
|
608
|
+
id: Union[int, list],
|
|
600
609
|
force: bool = False
|
|
601
610
|
):
|
|
602
611
|
"""
|
|
603
612
|
Delete ctx by idx
|
|
604
613
|
|
|
605
|
-
:param id: context meta idx on list
|
|
614
|
+
:param id: context meta idx on list or list of idxs
|
|
606
615
|
:param force: force delete
|
|
607
616
|
"""
|
|
608
617
|
if not force:
|
|
@@ -612,26 +621,31 @@ class Ctx:
|
|
|
612
621
|
msg=trans('ctx.delete.confirm'),
|
|
613
622
|
)
|
|
614
623
|
return
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
self.
|
|
630
|
-
|
|
631
|
-
self.window.
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
624
|
+
updated = False
|
|
625
|
+
ids = id if isinstance(id, list) else [id]
|
|
626
|
+
for id in ids:
|
|
627
|
+
try:
|
|
628
|
+
self.delete_meta_from_idx(id)
|
|
629
|
+
except Exception as e:
|
|
630
|
+
self.window.core.debug.log(e)
|
|
631
|
+
print("Error deleting ctx data from indexes", e)
|
|
632
|
+
|
|
633
|
+
if self.window.core.ctx.get_current() == id:
|
|
634
|
+
items = self.window.core.ctx.all() # TODO: get by meta id(s)
|
|
635
|
+
self.window.core.history.remove_items(items)
|
|
636
|
+
self.window.core.attachments.context.delete_by_meta_id(id)
|
|
637
|
+
self.window.core.ctx.remove(id)
|
|
638
|
+
self.remove_selected(id)
|
|
639
|
+
|
|
640
|
+
if self.window.core.ctx.get_current() == id:
|
|
641
|
+
self.window.core.ctx.clear_current()
|
|
642
|
+
event = RenderEvent(RenderEvent.CLEAR_OUTPUT)
|
|
643
|
+
self.window.dispatch(event)
|
|
644
|
+
updated = True
|
|
645
|
+
|
|
646
|
+
if updated:
|
|
647
|
+
self.update_and_restore()
|
|
648
|
+
self.window.controller.ui.tabs.update_title_current("...")
|
|
635
649
|
|
|
636
650
|
def delete_meta_from_idx(self, id: int):
|
|
637
651
|
"""
|
|
@@ -738,13 +752,18 @@ class Ctx:
|
|
|
738
752
|
if self.window.core.ctx.count_meta() == 0:
|
|
739
753
|
self.new()
|
|
740
754
|
|
|
741
|
-
def rename(self, id: int):
|
|
755
|
+
def rename(self, id: Union[int, list]):
|
|
742
756
|
"""
|
|
743
757
|
Ctx name rename by id (show dialog)
|
|
744
758
|
|
|
745
|
-
:param id: context id
|
|
759
|
+
:param id: context id or list of ids
|
|
746
760
|
"""
|
|
747
|
-
|
|
761
|
+
first_id = id
|
|
762
|
+
if isinstance(id, list):
|
|
763
|
+
if len(id) == 0:
|
|
764
|
+
return
|
|
765
|
+
first_id = id[0]
|
|
766
|
+
meta = self.window.core.ctx.get_meta_by_id(first_id)
|
|
748
767
|
self.window.ui.dialog['rename'].id = 'ctx'
|
|
749
768
|
self.window.ui.dialog['rename'].input.setText(meta.name)
|
|
750
769
|
self.window.ui.dialog['rename'].current = id
|
|
@@ -752,19 +771,24 @@ class Ctx:
|
|
|
752
771
|
|
|
753
772
|
def set_important(
|
|
754
773
|
self,
|
|
755
|
-
id: int,
|
|
774
|
+
id: Union[int, list],
|
|
756
775
|
value: bool = True
|
|
757
776
|
):
|
|
758
777
|
"""
|
|
759
778
|
Set as important
|
|
760
779
|
|
|
761
|
-
:param id: context idx
|
|
780
|
+
:param id: context idx or list of idxs
|
|
762
781
|
:param value: important value
|
|
763
782
|
"""
|
|
764
|
-
|
|
765
|
-
if
|
|
766
|
-
|
|
767
|
-
self.window.core.ctx.
|
|
783
|
+
updated = False
|
|
784
|
+
ids = id if isinstance(id, list) else [id]
|
|
785
|
+
for id in ids:
|
|
786
|
+
meta = self.window.core.ctx.get_meta_by_id(id)
|
|
787
|
+
if meta is not None:
|
|
788
|
+
meta.important = value
|
|
789
|
+
self.window.core.ctx.save(id)
|
|
790
|
+
updated = True
|
|
791
|
+
if updated:
|
|
768
792
|
self.update_and_restore()
|
|
769
793
|
|
|
770
794
|
def is_important(self, idx: int) -> bool:
|
|
@@ -782,19 +806,25 @@ class Ctx:
|
|
|
782
806
|
|
|
783
807
|
def set_label(
|
|
784
808
|
self,
|
|
785
|
-
id: int,
|
|
809
|
+
id: Union[int, list],
|
|
786
810
|
label_id: int
|
|
787
811
|
):
|
|
788
812
|
"""
|
|
789
813
|
Set color label for ctx by idx
|
|
790
814
|
|
|
791
|
-
:param id: context idx
|
|
815
|
+
:param id: context idx or list of idxs
|
|
792
816
|
:param label_id: label id
|
|
793
817
|
"""
|
|
794
|
-
|
|
795
|
-
if
|
|
796
|
-
|
|
797
|
-
self.window.core.ctx.
|
|
818
|
+
updated = False
|
|
819
|
+
ids = id if isinstance(id, list) else [id]
|
|
820
|
+
for id in ids:
|
|
821
|
+
meta = self.window.core.ctx.get_meta_by_id(id)
|
|
822
|
+
if meta is not None:
|
|
823
|
+
meta.label = label_id
|
|
824
|
+
self.window.core.ctx.save(id)
|
|
825
|
+
updated = True
|
|
826
|
+
|
|
827
|
+
if updated:
|
|
798
828
|
QTimer.singleShot(
|
|
799
829
|
10,
|
|
800
830
|
lambda: self.update_and_restore()
|
|
@@ -808,7 +838,7 @@ class Ctx:
|
|
|
808
838
|
|
|
809
839
|
def update_name(
|
|
810
840
|
self,
|
|
811
|
-
id: int,
|
|
841
|
+
id: Union[int, list],
|
|
812
842
|
name: str,
|
|
813
843
|
close: bool = True,
|
|
814
844
|
refresh: bool = True
|
|
@@ -816,16 +846,22 @@ class Ctx:
|
|
|
816
846
|
"""
|
|
817
847
|
Update ctx name
|
|
818
848
|
|
|
819
|
-
:param id: context id
|
|
849
|
+
:param id: context id or list of ids
|
|
820
850
|
:param name: context name
|
|
821
851
|
:param close: close rename dialog
|
|
822
852
|
:param refresh: refresh ctx list
|
|
823
853
|
"""
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
854
|
+
ctx_id = id
|
|
855
|
+
if not isinstance(id, list):
|
|
856
|
+
ctx_id = [id]
|
|
857
|
+
|
|
858
|
+
for id in ctx_id:
|
|
859
|
+
if id not in self.window.core.ctx.get_meta():
|
|
860
|
+
continue
|
|
861
|
+
self.window.core.ctx.meta[id].name = name
|
|
862
|
+
self.window.core.ctx.set_initialized()
|
|
863
|
+
self.window.core.ctx.save(id)
|
|
864
|
+
|
|
829
865
|
if close:
|
|
830
866
|
self.window.ui.dialog['rename'].close()
|
|
831
867
|
|
|
@@ -834,10 +870,13 @@ class Ctx:
|
|
|
834
870
|
else:
|
|
835
871
|
self.update(reload=True, all=False, no_scroll=True)
|
|
836
872
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
873
|
+
for id in ctx_id:
|
|
874
|
+
if id not in self.window.core.ctx.get_meta():
|
|
875
|
+
continue
|
|
876
|
+
meta = self.window.core.ctx.get_meta_by_id(id)
|
|
877
|
+
if meta is not None:
|
|
878
|
+
if id == self.window.core.ctx.get_current():
|
|
879
|
+
self.window.controller.ui.tabs.update_title_current(meta.name)
|
|
841
880
|
|
|
842
881
|
def update_name_current(self, name: str):
|
|
843
882
|
"""
|
|
@@ -934,7 +973,11 @@ class Ctx:
|
|
|
934
973
|
index = self.get_child_index_by_id(id)
|
|
935
974
|
nodes = self.window.ui.nodes
|
|
936
975
|
nodes['ctx.list'].unlocked = True
|
|
976
|
+
if not index.isValid():
|
|
977
|
+
nodes['ctx.list'].unlocked = False
|
|
978
|
+
return
|
|
937
979
|
nodes['ctx.list'].setCurrentIndex(index)
|
|
980
|
+
nodes['ctx.list'].force_scroll_to_current()
|
|
938
981
|
nodes['ctx.list'].unlocked = False
|
|
939
982
|
|
|
940
983
|
def find_index_by_id(
|
|
@@ -1067,37 +1110,47 @@ class Ctx:
|
|
|
1067
1110
|
|
|
1068
1111
|
def move_to_group(
|
|
1069
1112
|
self,
|
|
1070
|
-
meta_id: int,
|
|
1113
|
+
meta_id: Union[int, list],
|
|
1071
1114
|
group_id: int,
|
|
1072
1115
|
update: bool = True
|
|
1073
1116
|
):
|
|
1074
1117
|
"""
|
|
1075
1118
|
Move ctx to group
|
|
1076
1119
|
|
|
1077
|
-
:param meta_id: int
|
|
1120
|
+
:param meta_id: int or list of int
|
|
1078
1121
|
:param group_id: int
|
|
1079
1122
|
:param update: update ctx list
|
|
1080
1123
|
"""
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1124
|
+
updated = False
|
|
1125
|
+
ids = meta_id if isinstance(meta_id, list) else [meta_id]
|
|
1126
|
+
for meta_id in ids:
|
|
1127
|
+
self.window.core.ctx.update_meta_group_id(meta_id, group_id)
|
|
1128
|
+
self.group_id = group_id
|
|
1129
|
+
updated = True
|
|
1130
|
+
|
|
1131
|
+
if updated and update:
|
|
1084
1132
|
QTimer.singleShot(
|
|
1085
1133
|
10,
|
|
1086
1134
|
lambda: self.update_and_restore()
|
|
1087
1135
|
)
|
|
1088
1136
|
|
|
1089
|
-
def remove_from_group(self, meta_id):
|
|
1137
|
+
def remove_from_group(self, meta_id: Union[int, list]):
|
|
1090
1138
|
"""
|
|
1091
1139
|
Remove ctx from group
|
|
1092
1140
|
|
|
1093
|
-
:param meta_id: int
|
|
1141
|
+
:param meta_id: int or list of int
|
|
1094
1142
|
"""
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1143
|
+
updated = False
|
|
1144
|
+
ids = meta_id if isinstance(meta_id, list) else [meta_id]
|
|
1145
|
+
for meta_id in ids:
|
|
1146
|
+
self.window.core.ctx.update_meta_group_id(meta_id, None)
|
|
1147
|
+
updated = True
|
|
1148
|
+
if updated:
|
|
1149
|
+
self.group_id = None
|
|
1150
|
+
QTimer.singleShot(
|
|
1151
|
+
10,
|
|
1152
|
+
lambda: self.update_and_restore()
|
|
1153
|
+
)
|
|
1101
1154
|
|
|
1102
1155
|
def new_group(
|
|
1103
1156
|
self,
|
|
@@ -1117,13 +1170,13 @@ class Ctx:
|
|
|
1117
1170
|
def create_group(
|
|
1118
1171
|
self,
|
|
1119
1172
|
name: Optional[str] = None,
|
|
1120
|
-
meta_id: Optional[int] = None
|
|
1173
|
+
meta_id: Optional[Union[int, list]] = None
|
|
1121
1174
|
):
|
|
1122
1175
|
"""
|
|
1123
1176
|
Make directory
|
|
1124
1177
|
|
|
1125
1178
|
:param name: name of directory
|
|
1126
|
-
:param meta_id: int
|
|
1179
|
+
:param meta_id: int or list of int
|
|
1127
1180
|
"""
|
|
1128
1181
|
if name is None:
|
|
1129
1182
|
self.window.update_status(
|
|
@@ -1133,53 +1186,69 @@ class Ctx:
|
|
|
1133
1186
|
group = self.window.core.ctx.make_group(name)
|
|
1134
1187
|
id = self.window.core.ctx.insert_group(group)
|
|
1135
1188
|
if id is not None:
|
|
1136
|
-
if meta_id is not None
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1189
|
+
ids = meta_id if isinstance(meta_id, list) else [meta_id] if meta_id is not None else []
|
|
1190
|
+
for meta_id in ids:
|
|
1191
|
+
if meta_id is not None:
|
|
1192
|
+
self.move_to_group(meta_id, id, update=False)
|
|
1193
|
+
|
|
1194
|
+
self.update()
|
|
1195
|
+
self.window.update_status(
|
|
1196
|
+
"Group '{}' created.".format(name)
|
|
1197
|
+
)
|
|
1198
|
+
self.window.ui.dialog['create'].close()
|
|
1199
|
+
# self.select_group(id)
|
|
1200
|
+
self.group_id = id
|
|
1145
1201
|
|
|
1146
1202
|
def rename_group(
|
|
1147
1203
|
self,
|
|
1148
|
-
id: int,
|
|
1204
|
+
id: Union[int, list],
|
|
1149
1205
|
force: bool = False
|
|
1150
1206
|
):
|
|
1151
1207
|
"""
|
|
1152
1208
|
Rename group
|
|
1153
1209
|
|
|
1154
|
-
:param id: group ID
|
|
1210
|
+
:param id: group ID or list of IDs
|
|
1155
1211
|
:param force: force rename
|
|
1156
1212
|
"""
|
|
1213
|
+
ids = id if isinstance(id, list) else [id]
|
|
1157
1214
|
if not force:
|
|
1158
|
-
|
|
1159
|
-
|
|
1215
|
+
is_group = False
|
|
1216
|
+
name = ""
|
|
1217
|
+
for tmp_id in ids:
|
|
1218
|
+
group = self.window.core.ctx.get_group_by_id(tmp_id)
|
|
1219
|
+
if group is not None:
|
|
1220
|
+
is_group = True
|
|
1221
|
+
name = group.name
|
|
1222
|
+
break
|
|
1223
|
+
if not is_group:
|
|
1160
1224
|
return
|
|
1161
1225
|
self.window.ui.dialog['rename'].id = 'ctx.group'
|
|
1162
|
-
self.window.ui.dialog['rename'].input.setText(
|
|
1226
|
+
self.window.ui.dialog['rename'].input.setText(name)
|
|
1163
1227
|
self.window.ui.dialog['rename'].current = id
|
|
1164
1228
|
self.window.ui.dialog['rename'].show()
|
|
1165
1229
|
|
|
1166
1230
|
def update_group_name(
|
|
1167
1231
|
self,
|
|
1168
|
-
id: int,
|
|
1232
|
+
id: Union[int, list],
|
|
1169
1233
|
name: str,
|
|
1170
1234
|
close: bool = True
|
|
1171
1235
|
):
|
|
1172
1236
|
"""
|
|
1173
1237
|
Update group name
|
|
1174
1238
|
|
|
1175
|
-
:param id: group ID
|
|
1239
|
+
:param id: group ID or list of IDs
|
|
1176
1240
|
:param name: group name
|
|
1177
1241
|
:param close: close rename dialog
|
|
1178
1242
|
"""
|
|
1179
|
-
|
|
1180
|
-
if
|
|
1181
|
-
|
|
1182
|
-
self.window.core.ctx.
|
|
1243
|
+
updated = False
|
|
1244
|
+
ids = id if isinstance(id, list) else [id]
|
|
1245
|
+
for id in ids:
|
|
1246
|
+
group = self.window.core.ctx.get_group_by_id(id)
|
|
1247
|
+
if group is not None:
|
|
1248
|
+
group.name = name
|
|
1249
|
+
self.window.core.ctx.update_group(group)
|
|
1250
|
+
updated = True
|
|
1251
|
+
if updated:
|
|
1183
1252
|
if close:
|
|
1184
1253
|
self.window.ui.dialog['rename'].close()
|
|
1185
1254
|
self.update_and_restore()
|
|
@@ -1207,17 +1276,18 @@ class Ctx:
|
|
|
1207
1276
|
nodes = self.window.ui.nodes
|
|
1208
1277
|
nodes['ctx.list'].unlocked = True
|
|
1209
1278
|
nodes['ctx.list'].setCurrentIndex(index)
|
|
1279
|
+
nodes['ctx.list'].force_scroll_to_current()
|
|
1210
1280
|
nodes['ctx.list'].unlocked = False
|
|
1211
1281
|
|
|
1212
1282
|
def delete_group(
|
|
1213
1283
|
self,
|
|
1214
|
-
id: int,
|
|
1284
|
+
id: Union[int, list],
|
|
1215
1285
|
force: bool = False
|
|
1216
1286
|
):
|
|
1217
1287
|
"""
|
|
1218
1288
|
Delete group only
|
|
1219
1289
|
|
|
1220
|
-
:param id: group ID
|
|
1290
|
+
:param id: group ID or list of IDs
|
|
1221
1291
|
:param force: force delete
|
|
1222
1292
|
"""
|
|
1223
1293
|
if not force:
|
|
@@ -1227,22 +1297,28 @@ class Ctx:
|
|
|
1227
1297
|
msg=trans('confirm.ctx.delete')
|
|
1228
1298
|
)
|
|
1229
1299
|
return
|
|
1230
|
-
|
|
1231
|
-
if
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1300
|
+
updated = False
|
|
1301
|
+
ids = id if isinstance(id, list) else [id]
|
|
1302
|
+
for id in ids:
|
|
1303
|
+
group = self.window.core.ctx.get_group_by_id(id)
|
|
1304
|
+
if group is not None:
|
|
1305
|
+
self.window.core.ctx.remove_group(group, all=False)
|
|
1306
|
+
if self.group_id == id:
|
|
1307
|
+
self.group_id = None
|
|
1308
|
+
updated = True
|
|
1309
|
+
|
|
1310
|
+
if updated:
|
|
1235
1311
|
self.update_and_restore()
|
|
1236
1312
|
|
|
1237
1313
|
def delete_group_all(
|
|
1238
1314
|
self,
|
|
1239
|
-
id: int,
|
|
1315
|
+
id: Union[int, list],
|
|
1240
1316
|
force: bool = False
|
|
1241
1317
|
):
|
|
1242
1318
|
"""
|
|
1243
1319
|
Delete group with all items
|
|
1244
1320
|
|
|
1245
|
-
:param id: group ID
|
|
1321
|
+
:param id: group ID or list of IDs
|
|
1246
1322
|
:param force: force delete
|
|
1247
1323
|
"""
|
|
1248
1324
|
if not force:
|
|
@@ -1252,11 +1328,16 @@ class Ctx:
|
|
|
1252
1328
|
msg=trans('confirm.ctx.delete.all')
|
|
1253
1329
|
)
|
|
1254
1330
|
return
|
|
1255
|
-
|
|
1256
|
-
if
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1331
|
+
updated = False
|
|
1332
|
+
ids = id if isinstance(id, list) else [id]
|
|
1333
|
+
for id in ids:
|
|
1334
|
+
group = self.window.core.ctx.get_group_by_id(id)
|
|
1335
|
+
if group is not None:
|
|
1336
|
+
self.window.core.ctx.remove_group(group, all=True)
|
|
1337
|
+
if self.group_id == id:
|
|
1338
|
+
self.group_id = None
|
|
1339
|
+
updated = True
|
|
1340
|
+
if updated:
|
|
1260
1341
|
self.update_and_restore()
|
|
1261
1342
|
|
|
1262
1343
|
def prepare_summary(self, ctx: CtxItem) -> bool:
|