ttkode 0.3.2a2__tar.gz → 0.4.0a2__tar.gz
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.
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/PKG-INFO +2 -2
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/pyproject.toml +1 -1
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/__init__.py +1 -1
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/__main__.py +1 -5
- ttkode-0.4.0a2/ttkode/app/__init__.py +27 -0
- ttkode-0.3.2a2/ttkode/app/__init__.py → ttkode-0.4.0a2/ttkode/app/state.py +4 -4
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/app/ttkode.py +172 -27
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/proxy.py +17 -13
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode.egg-info/PKG-INFO +2 -2
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode.egg-info/SOURCES.txt +1 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode.egg-info/requires.txt +1 -1
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/README.md +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/setup.cfg +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/app/about.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/app/activitybar.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/app/cfg.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/app/options.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/helper.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/plugin.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/plugins/_010/__init__.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/plugins/_010/findwidget.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/plugins/_010_findplugin.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/plugins/_020_debugplugin.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/plugins/testplugin.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode/plugins/testplugin1.py +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode.egg-info/dependency_links.txt +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode.egg-info/entry_points.txt +0 -0
- {ttkode-0.3.2a2 → ttkode-0.4.0a2}/ttkode.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ttkode
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0a2
|
|
4
4
|
Summary: Terminal ToolKit Studio Code editor
|
|
5
5
|
Author-email: Eugenio Parodi <ceccopierangiolieugenio@googlemail.com>
|
|
6
6
|
License: MIT
|
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Terminals
|
|
|
19
19
|
Classifier: Topic :: Software Development :: User Interfaces
|
|
20
20
|
Requires-Python: >=3.9
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
|
-
Requires-Dist: pyTermTk>=0.
|
|
22
|
+
Requires-Dist: pyTermTk>=0.43.0-a.0
|
|
23
23
|
Requires-Dist: appdirs
|
|
24
24
|
Requires-Dist: copykitten
|
|
25
25
|
Requires-Dist: pygments
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
|
|
25
|
-
__version__:str = '0.
|
|
25
|
+
__version__:str = '0.4.0-a.2'
|
|
26
26
|
|
|
27
27
|
from .plugin import TTkodePlugin, TTkodePluginActivity
|
|
28
28
|
from .proxy import TTKodeViewerProxy, ttkodeProxy
|
|
@@ -33,7 +33,6 @@ from TermTk import TTkLog
|
|
|
33
33
|
|
|
34
34
|
from ttkode import TTkodeHelper
|
|
35
35
|
from ttkode import ttkodeProxy
|
|
36
|
-
from ttkode.app.ttkode import TTKode
|
|
37
36
|
from ttkode.app.cfg import TTKodeCfg
|
|
38
37
|
|
|
39
38
|
|
|
@@ -62,10 +61,7 @@ def main():
|
|
|
62
61
|
|
|
63
62
|
TTkodeHelper._loadPlugins()
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
ttkodeProxy.setTTKode(ttkode)
|
|
67
|
-
|
|
68
|
-
root = TTk( layout=ttkode,
|
|
64
|
+
root = TTk( layout=ttkodeProxy.ttkode(),
|
|
69
65
|
title="TTkode",
|
|
70
66
|
mouseTrack=True,
|
|
71
67
|
sigmask=(
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
# MIT License
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
# copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
# SOFTWARE.
|
|
23
|
+
|
|
24
|
+
from .cfg import *
|
|
25
|
+
from .state import TTKodeState
|
|
26
|
+
# from .glbl import *
|
|
27
|
+
from .ttkode import TTKode, TTKodeWidget
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
# MIT License
|
|
3
2
|
#
|
|
4
3
|
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
|
|
@@ -21,6 +20,7 @@
|
|
|
21
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
21
|
# SOFTWARE.
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
__all__ = ['TTKodeState']
|
|
24
|
+
|
|
25
|
+
class TTKodeState():
|
|
26
|
+
pass
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
|
|
23
|
-
__all__ = ['TTKode']
|
|
23
|
+
__all__ = ['TTKode', 'TTKodeWidget']
|
|
24
24
|
|
|
25
25
|
import os
|
|
26
26
|
from typing import List,Tuple,Optional,Any
|
|
@@ -31,6 +31,10 @@ from TermTk.TTkWidgets.tabwidget import _TTkNewTabWidgetDragData
|
|
|
31
31
|
from .about import About
|
|
32
32
|
from .activitybar import TTKodeActivityBar
|
|
33
33
|
|
|
34
|
+
class TTKodeWidget():
|
|
35
|
+
def closeRequested(self, tab:ttk.TTkTabWidget, num:int):
|
|
36
|
+
raise NotImplementedError()
|
|
37
|
+
|
|
34
38
|
class TTKodeFileWidgetItem(ttk.TTkTreeWidgetItem):
|
|
35
39
|
__slots__ = ('_path', '_lineNumber')
|
|
36
40
|
def __init__(self, *args, path:str, lineNumber:int=0, **kwargs) -> None:
|
|
@@ -45,16 +49,24 @@ class TTKodeFileWidgetItem(ttk.TTkTreeWidgetItem):
|
|
|
45
49
|
class _TextDocument(ttk.TextDocumentHighlight):
|
|
46
50
|
__slots__ = ('_filePath', '_tabText',
|
|
47
51
|
'fileChangedStatus', '_changedStatus', '_savedSnapshot')
|
|
48
|
-
def __init__(self, filePath:str="",
|
|
52
|
+
def __init__(self, filePath:str="", **kwargs):
|
|
49
53
|
self.fileChangedStatus:ttk.pyTTkSignal = ttk.pyTTkSignal(bool, _TextDocument)
|
|
50
54
|
self._filePath:str = filePath
|
|
51
|
-
self._tabText = tabText
|
|
52
55
|
self._changedStatus:bool = False
|
|
56
|
+
self._genTabText()
|
|
53
57
|
super().__init__(**kwargs)
|
|
54
58
|
self._savedSnapshot = self.snapshootId()
|
|
55
59
|
self.guessLexerFromFilename(filePath)
|
|
56
60
|
self.contentsChanged.connect(self._handleContentChanged)
|
|
57
61
|
|
|
62
|
+
def _genTabText(self):
|
|
63
|
+
self._tabText = (
|
|
64
|
+
ttk.TTkString(ttk.TTkCfg.theme.fileIcon.getIcon(self._filePath),ttk.TTkCfg.theme.fileIconColor) +
|
|
65
|
+
ttk.TTkColor.RST + " " + os.path.basename(self._filePath) )
|
|
66
|
+
|
|
67
|
+
def isChanged(self) -> bool:
|
|
68
|
+
return self._changedStatus
|
|
69
|
+
|
|
58
70
|
def getTabButtonStyle(self) -> dict:
|
|
59
71
|
if self._changedStatus:
|
|
60
72
|
return {'default':{'closeGlyph':' ● '}}
|
|
@@ -70,17 +82,67 @@ class _TextDocument(ttk.TextDocumentHighlight):
|
|
|
70
82
|
ttk.TTkLog.debug(f"{self.isUndoAvailable()=} == {self._changedStatus=}")
|
|
71
83
|
self.fileChangedStatus.emit(self._changedStatus, self)
|
|
72
84
|
|
|
73
|
-
def save(self):
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
def save(self) -> None:
|
|
86
|
+
try:
|
|
87
|
+
with open(self._filePath, 'w') as f:
|
|
88
|
+
f.write(self.toPlainText())
|
|
89
|
+
self._changedStatus = False
|
|
90
|
+
self._savedSnapshot = self.snapshootId()
|
|
91
|
+
self.fileChangedStatus.emit(self._changedStatus, self)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
ttk.TTkLog.error(f"Error saving file: {e}")
|
|
94
|
+
|
|
95
|
+
def saveToFile(self, fileName:str) -> None:
|
|
96
|
+
self._filePath = fileName
|
|
97
|
+
self._genTabText()
|
|
98
|
+
self.save()
|
|
99
|
+
class _TextEdit(ttk.TTkTextEdit, TTKodeWidget):
|
|
100
|
+
__slots__ = ('docFocussed')
|
|
80
101
|
def __init__(self, **kwargs):
|
|
102
|
+
self.docFocussed = ttk.pyTTkSignal(_TextDocument)
|
|
81
103
|
super().__init__(**kwargs)
|
|
82
104
|
self.cursorPositionChanged.connect(self._positionChanged)
|
|
83
|
-
|
|
105
|
+
self.textEditView().focusChanged.connect(self._handleFocusChanged)
|
|
106
|
+
|
|
107
|
+
@ttk.pyTTkSlot(bool)
|
|
108
|
+
def _handleFocusChanged(self, focus:bool) -> None:
|
|
109
|
+
if focus:
|
|
110
|
+
self.docFocussed.emit(self.document())
|
|
111
|
+
|
|
112
|
+
def closeRequested(self, tab:ttk.TTkTabWidget, num:int):
|
|
113
|
+
from ttkode import ttkodeProxy
|
|
114
|
+
doc = self.document()
|
|
115
|
+
docs = [wid.document() for wid in ttkodeProxy.iterWidgets(_TextEdit) if wid is not self]
|
|
116
|
+
if not doc.isChanged() or doc in docs:
|
|
117
|
+
ttkodeProxy.closeTab(self)
|
|
118
|
+
else:
|
|
119
|
+
pass
|
|
120
|
+
# Do you want to save the changes you made to ""?
|
|
121
|
+
# Your saves will be lost if you don't save them.
|
|
122
|
+
# Save, Don't Save, Cancel
|
|
123
|
+
messageBox = ttk.TTkMessageBox(
|
|
124
|
+
title="🚨 Close? 🚨",
|
|
125
|
+
text=ttk.TTkString(f"Do you want to save the change\nyou made to {os.path.basename(doc._filePath)}?\n\nYour saves will be lost\nif you don't save them."),
|
|
126
|
+
icon=ttk.TTkMessageBox.Icon.Warning,
|
|
127
|
+
standardButtons=
|
|
128
|
+
ttk.TTkMessageBox.StandardButton.Discard|
|
|
129
|
+
ttk.TTkMessageBox.StandardButton.Save|
|
|
130
|
+
ttk.TTkMessageBox.StandardButton.Cancel)
|
|
131
|
+
|
|
132
|
+
@ttk.pyTTkSlot(ttk.TTkMessageBox.StandardButton)
|
|
133
|
+
def _cb(btn):
|
|
134
|
+
if btn == ttk.TTkMessageBox.StandardButton.Save:
|
|
135
|
+
doc.save()
|
|
136
|
+
self.textEditView().focusChanged.clear()
|
|
137
|
+
ttkodeProxy.closeTab(self)
|
|
138
|
+
if btn == ttk.TTkMessageBox.StandardButton.Discard:
|
|
139
|
+
self.textEditView().focusChanged.clear()
|
|
140
|
+
ttkodeProxy.closeTab(self)
|
|
141
|
+
elif btn == ttk.TTkMessageBox.StandardButton.Cancel:
|
|
142
|
+
return
|
|
143
|
+
messageBox.buttonSelected.clear()
|
|
144
|
+
messageBox.buttonSelected.connect(_cb)
|
|
145
|
+
ttk.TTkHelper.overlay(None, messageBox, 5, 5, True)
|
|
84
146
|
|
|
85
147
|
@ttk.pyTTkSlot(ttk.TTkTextCursor)
|
|
86
148
|
def _positionChanged(self, cursor:ttk.TTkTextCursor):
|
|
@@ -106,8 +168,10 @@ class _TextEdit(ttk.TTkTextEdit):
|
|
|
106
168
|
tedit.textCursor().setPosition(line=linenum,pos=0)
|
|
107
169
|
|
|
108
170
|
class TTKode(ttk.TTkGridLayout):
|
|
109
|
-
__slots__ = ('_kodeTab', '_activityBar')
|
|
171
|
+
__slots__ = ('_kodeTab', '_activityBar', '_lastDoc')
|
|
172
|
+
_lastDoc:Optional[_TextDocument]
|
|
110
173
|
def __init__(self, **kwargs):
|
|
174
|
+
self._lastDoc = None
|
|
111
175
|
super().__init__(**kwargs)
|
|
112
176
|
|
|
113
177
|
appTemplate = ttk.TTkAppTemplate(border=False)
|
|
@@ -119,15 +183,17 @@ class TTKode(ttk.TTkGridLayout):
|
|
|
119
183
|
appTemplate.setMenuBar(appMenuBar:=ttk.TTkMenuBarLayout(), ttk.TTkAppTemplate.MAIN)
|
|
120
184
|
fileMenu = appMenuBar.addMenu("&File")
|
|
121
185
|
fileMenu.addMenu("Open").menuButtonClicked.connect(self._showFileDialog)
|
|
186
|
+
fileMenu.addMenu("&Save").menuButtonClicked.connect(self.saveLastDoc)
|
|
187
|
+
fileMenu.addMenu("Save &As...").menuButtonClicked.connect(self.saveLastDocAs)
|
|
122
188
|
fileMenu.addMenu("Close") # .menuButtonClicked.connect(self._closeFile)
|
|
123
|
-
fileMenu.addMenu("Exit").menuButtonClicked.connect(
|
|
189
|
+
fileMenu.addMenu("Exit").menuButtonClicked.connect(self._quit)
|
|
124
190
|
|
|
125
191
|
def _showAbout(btn):
|
|
126
192
|
ttk.TTkHelper.overlay(None, About(), 30,10)
|
|
127
193
|
def _showAboutTTk(btn):
|
|
128
194
|
ttk.TTkHelper.overlay(None, ttk.TTkAbout(), 30,10)
|
|
129
195
|
|
|
130
|
-
appMenuBar.addMenu("&Quit", alignment=ttk.TTkK.RIGHT_ALIGN).menuButtonClicked.connect(
|
|
196
|
+
appMenuBar.addMenu("&Quit", alignment=ttk.TTkK.RIGHT_ALIGN).menuButtonClicked.connect(self._quit)
|
|
131
197
|
helpMenu = appMenuBar.addMenu("&Help", alignment=ttk.TTkK.RIGHT_ALIGN)
|
|
132
198
|
helpMenu.addMenu("About ...").menuButtonClicked.connect(_showAbout)
|
|
133
199
|
helpMenu.addMenu("About ttk").menuButtonClicked.connect(_showAboutTTk)
|
|
@@ -159,11 +225,88 @@ class TTKode(ttk.TTkGridLayout):
|
|
|
159
225
|
|
|
160
226
|
fileTree.fileActivated.connect(lambda x: self._openFile(x.path()))
|
|
161
227
|
self._kodeTab.tabAdded.connect(self._tabAdded)
|
|
228
|
+
self._kodeTab.kodeTabCloseRequested.connect(self._handleTabCloseRequested)
|
|
229
|
+
|
|
230
|
+
ttk.TTkShortcut(ttk.TTkK.CTRL | ttk.TTkK.Key_S).activated.connect(self.saveLastDoc)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@ttk.pyTTkSlot(_TextDocument)
|
|
234
|
+
def _handleDocFocussed(self, doc:_TextDocument):
|
|
235
|
+
self._lastDoc = doc
|
|
236
|
+
|
|
237
|
+
@ttk.pyTTkSlot()
|
|
238
|
+
def _quit(self):
|
|
239
|
+
from ttkode import ttkodeProxy
|
|
240
|
+
docs = set(os.path.basename(wid.document()._filePath) for wid in ttkodeProxy.iterWidgets(_TextEdit) if wid.document().isChanged())
|
|
241
|
+
if docs:
|
|
242
|
+
messageBox = ttk.TTkMessageBox(
|
|
243
|
+
title="🚨 Quit? 🚨",
|
|
244
|
+
text=ttk.TTkString("Do you want to quit?\nThere are still unsaved documents,\nif you quit those changes will be lost" + ''.join([f"\n - {_d}" for _d in docs])),
|
|
245
|
+
icon=ttk.TTkMessageBox.Icon.Warning,
|
|
246
|
+
standardButtons=
|
|
247
|
+
ttk.TTkMessageBox.StandardButton.Ok|
|
|
248
|
+
ttk.TTkMessageBox.StandardButton.Cancel)
|
|
249
|
+
@ttk.pyTTkSlot(ttk.TTkMessageBox.StandardButton)
|
|
250
|
+
def _cb(btn):
|
|
251
|
+
if btn == ttk.TTkMessageBox.StandardButton.Ok:
|
|
252
|
+
ttk.TTkHelper.quit()
|
|
253
|
+
elif btn == ttk.TTkMessageBox.StandardButton.Cancel:
|
|
254
|
+
return
|
|
255
|
+
messageBox.buttonSelected.clear()
|
|
256
|
+
messageBox.buttonSelected.connect(_cb)
|
|
257
|
+
ttk.TTkHelper.overlay(None, messageBox, 5, 5, True)
|
|
258
|
+
else:
|
|
259
|
+
ttk.TTkHelper.quit()
|
|
260
|
+
|
|
261
|
+
@ttk.pyTTkSlot()
|
|
262
|
+
def saveLastDoc(self):
|
|
263
|
+
if self._lastDoc:
|
|
264
|
+
self._lastDoc.save()
|
|
265
|
+
|
|
266
|
+
@ttk.pyTTkSlot()
|
|
267
|
+
def saveLastDocAs(self):
|
|
268
|
+
if not self._lastDoc:
|
|
269
|
+
return
|
|
270
|
+
def _approveFile(fileName):
|
|
271
|
+
if os.path.exists(fileName):
|
|
272
|
+
@ttk.pyTTkSlot(ttk.TTkMessageBox.StandardButton)
|
|
273
|
+
def _cb(btn):
|
|
274
|
+
if btn == ttk.TTkMessageBox.StandardButton.Save:
|
|
275
|
+
self._lastDoc.saveToFile(fileName)
|
|
276
|
+
elif btn == ttk.TTkMessageBox.StandardButton.Cancel:
|
|
277
|
+
return
|
|
278
|
+
messageBox = ttk.TTkMessageBox(
|
|
279
|
+
text= (
|
|
280
|
+
ttk.TTkString( f'A file named "{os.path.basename(fileName)}" already exists.\nDo you want to replace it?', ttk.TTkColor.BOLD) +
|
|
281
|
+
ttk.TTkString( f'\n\nReplacing it will overwrite its contents.') ),
|
|
282
|
+
icon=ttk.TTkMessageBox.Icon.Warning,
|
|
283
|
+
standardButtons=
|
|
284
|
+
ttk.TTkMessageBox.StandardButton.Discard|
|
|
285
|
+
ttk.TTkMessageBox.StandardButton.Save|
|
|
286
|
+
ttk.TTkMessageBox.StandardButton.Cancel)
|
|
287
|
+
messageBox.buttonSelected.connect(_cb)
|
|
288
|
+
ttk.TTkHelper.overlay(None, messageBox, 5, 5, True)
|
|
289
|
+
else:
|
|
290
|
+
self._lastDoc.saveToFile(fileName)
|
|
291
|
+
filePicker = ttk.TTkFileDialogPicker(
|
|
292
|
+
pos = (3,3), size=(80,30),
|
|
293
|
+
acceptMode=ttk.TTkK.AcceptMode.AcceptSave,
|
|
294
|
+
caption="Save As...",
|
|
295
|
+
path=self._lastDoc._filePath,
|
|
296
|
+
fileMode=ttk.TTkK.FileMode.AnyFile ,
|
|
297
|
+
filter="All Files (*)")
|
|
298
|
+
filePicker.pathPicked.connect(_approveFile)
|
|
299
|
+
ttk.TTkHelper.overlay(None, filePicker, 5, 5, True)
|
|
300
|
+
|
|
301
|
+
@ttk.pyTTkSlot(ttk.TTkTabWidget, int)
|
|
302
|
+
def _handleTabCloseRequested(self, tab:ttk.TTkTabWidget, num:int):
|
|
303
|
+
# tab.removeTab(num)
|
|
304
|
+
tab.widget(num).closeRequested(tab, num)
|
|
162
305
|
|
|
163
306
|
def _getTabButtonFromWidget(self, widget:ttk.TTkWidget) -> ttk.TTkTabButton:
|
|
164
|
-
for
|
|
165
|
-
if
|
|
166
|
-
return
|
|
307
|
+
for kt, index in self._kodeTab.iterItems():
|
|
308
|
+
if kt.widget(index) == widget:
|
|
309
|
+
return kt.tabButton(index)
|
|
167
310
|
return None
|
|
168
311
|
|
|
169
312
|
ttk.pyTTkSlot(ttk.TTkTabWidget, int)
|
|
@@ -180,26 +323,26 @@ class TTKode(ttk.TTkGridLayout):
|
|
|
180
323
|
ttk.TTkHelper.overlay(None, filePicker, 20, 5, True)
|
|
181
324
|
|
|
182
325
|
def _getDocument(self, filePath) -> Tuple[_TextDocument, Optional[_TextEdit]]:
|
|
183
|
-
for
|
|
184
|
-
if issubclass(type(
|
|
185
|
-
doc =
|
|
326
|
+
for kt, index in self._kodeTab.iterItems():
|
|
327
|
+
if issubclass(type(wid:=kt.widget(index)), _TextEdit):
|
|
328
|
+
doc = wid.document()
|
|
186
329
|
if issubclass(type(doc), _TextDocument):
|
|
187
330
|
if filePath == doc._filePath:
|
|
188
|
-
return doc,
|
|
331
|
+
return doc, wid
|
|
189
332
|
with open(filePath, 'r') as f:
|
|
190
333
|
content = f.read()
|
|
191
|
-
|
|
192
|
-
td = _TextDocument(text=content, filePath=filePath, tabText=tabText)
|
|
334
|
+
td = _TextDocument(text=content, filePath=filePath)
|
|
193
335
|
td.fileChangedStatus.connect(self._handleFileChangedStatus)
|
|
194
336
|
return td, None
|
|
195
337
|
|
|
196
338
|
ttk.pyTTkSlot(bool, _TextDocument)
|
|
197
339
|
def _handleFileChangedStatus(self, status:bool, doc:_TextDocument) -> None:
|
|
198
340
|
# ttk.TTkLog.debug(f"Status ({status}) -> {doc._filePath}")
|
|
199
|
-
for
|
|
200
|
-
if issubclass(type(
|
|
201
|
-
if doc ==
|
|
202
|
-
|
|
341
|
+
for kt, index in self._kodeTab.iterItems():
|
|
342
|
+
if issubclass(type(wid:=kt.widget(index)), _TextEdit):
|
|
343
|
+
if doc == wid.document():
|
|
344
|
+
kt.tabButton(index).mergeStyle(doc.getTabButtonStyle())
|
|
345
|
+
kt.tabButton(index).setText(doc._tabText)
|
|
203
346
|
|
|
204
347
|
def _openFile(self, filePath, line:int=0, pos:int=0):
|
|
205
348
|
filePath = os.path.realpath(filePath)
|
|
@@ -208,6 +351,7 @@ class TTKode(ttk.TTkGridLayout):
|
|
|
208
351
|
self._kodeTab.setCurrentWidget(tedit)
|
|
209
352
|
else:
|
|
210
353
|
tedit = _TextEdit(document=doc, readOnly=False, lineNumber=True)
|
|
354
|
+
tedit.docFocussed.connect(self._handleDocFocussed)
|
|
211
355
|
self._kodeTab.addTab(tedit, doc._tabText)
|
|
212
356
|
self._kodeTab.setCurrentWidget(tedit)
|
|
213
357
|
tedit.goToLine(line)
|
|
@@ -230,6 +374,7 @@ class TTKode(ttk.TTkGridLayout):
|
|
|
230
374
|
if filePath:
|
|
231
375
|
doc, _ = self._getDocument(filePath=filePath)
|
|
232
376
|
tedit = _TextEdit(document=doc, readOnly=False, lineNumber=True)
|
|
377
|
+
tedit.docFocussed.connect(self._handleDocFocussed)
|
|
233
378
|
tedit.goToLine(linenum)
|
|
234
379
|
newData = _TTkNewTabWidgetDragData(
|
|
235
380
|
widget=tedit,
|
|
@@ -26,7 +26,7 @@ from typing import Optional, Callable, Any
|
|
|
26
26
|
|
|
27
27
|
import TermTk as ttk
|
|
28
28
|
|
|
29
|
-
from ttkode.app.ttkode import TTKode
|
|
29
|
+
from ttkode.app.ttkode import TTKode, TTKodeWidget
|
|
30
30
|
|
|
31
31
|
class TTKodeViewerProxy():
|
|
32
32
|
__slots__ = ('_fileName')
|
|
@@ -41,26 +41,30 @@ class TTKodeProxy():
|
|
|
41
41
|
'_ttkode',
|
|
42
42
|
# Signals
|
|
43
43
|
)
|
|
44
|
-
_ttkode:
|
|
45
|
-
_openFileCb:
|
|
46
|
-
def __init__(self) -> None:
|
|
47
|
-
self._openFileCb = None
|
|
48
|
-
self._ttkode = None
|
|
49
|
-
|
|
50
|
-
def setTTKode(self, ttkode:TTKode) -> None:
|
|
44
|
+
_ttkode:TTKode
|
|
45
|
+
_openFileCb:Callable[[Any, int, int], Any]
|
|
46
|
+
def __init__(self, ttkode:TTKode) -> None:
|
|
51
47
|
self._ttkode = ttkode
|
|
52
48
|
self._openFileCb = ttkode._openFile
|
|
53
49
|
|
|
54
50
|
def ttkode(self) -> TTKode:
|
|
55
|
-
if not self._ttkode:
|
|
56
|
-
raise Exception("TTkode uninitialized")
|
|
57
51
|
return self._ttkode
|
|
58
52
|
|
|
53
|
+
def iterWidgets(self, widType=TTKodeWidget):
|
|
54
|
+
for kt, index in self._ttkode._kodeTab.iterItems():
|
|
55
|
+
if issubclass(type(wid:=kt.widget(index)), widType):
|
|
56
|
+
yield wid
|
|
57
|
+
|
|
58
|
+
@ttk.pyTTkSlot(TTKodeWidget)
|
|
59
|
+
def closeTab(self, widget:TTKodeWidget) -> None:
|
|
60
|
+
for kt, index in self._ttkode._kodeTab.iterItems():
|
|
61
|
+
if kt.widget(index)==widget:
|
|
62
|
+
kt.removeTab(index)
|
|
63
|
+
|
|
59
64
|
def setOpenFile(self, cb):
|
|
60
65
|
self._openFileCb = cb
|
|
61
66
|
|
|
62
67
|
def openFile(self, fileName:str, line:int=0, pos:int=0):
|
|
63
|
-
|
|
64
|
-
return self._openFileCb(fileName, line, pos)
|
|
68
|
+
return self._openFileCb(fileName, line, pos)
|
|
65
69
|
|
|
66
|
-
ttkodeProxy:TTKodeProxy = TTKodeProxy()
|
|
70
|
+
ttkodeProxy:TTKodeProxy = TTKodeProxy(ttkode=TTKode())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ttkode
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0a2
|
|
4
4
|
Summary: Terminal ToolKit Studio Code editor
|
|
5
5
|
Author-email: Eugenio Parodi <ceccopierangiolieugenio@googlemail.com>
|
|
6
6
|
License: MIT
|
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Terminals
|
|
|
19
19
|
Classifier: Topic :: Software Development :: User Interfaces
|
|
20
20
|
Requires-Python: >=3.9
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
|
-
Requires-Dist: pyTermTk>=0.
|
|
22
|
+
Requires-Dist: pyTermTk>=0.43.0-a.0
|
|
23
23
|
Requires-Dist: appdirs
|
|
24
24
|
Requires-Dist: copykitten
|
|
25
25
|
Requires-Dist: pygments
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|