Browse Source

feat: allow multiple files to be selected and dragged (#438)

pull/441/head
Pier CeccoPierangioliEugenio 7 months ago committed by GitHub
parent
commit
9fe249c0d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 37
      apps/ttkode/ttkode/app/ttkode.py
  2. 2
      apps/ttkode/ttkode/plugins/_010/findwidget.py
  3. 16
      tests/t.generic/test.stderr.001.py
  4. 63
      tests/t.generic/test.stderr.002.py

37
apps/ttkode/ttkode/app/ttkode.py

@ -198,7 +198,7 @@ class TTKode(ttk.TTkGridLayout):
helpMenu.addMenu("About ...").menuButtonClicked.connect(_showAbout)
helpMenu.addMenu("About ttk").menuButtonClicked.connect(_showAboutTTk)
fileTree = ttk.TTkFileTree(path='.', dragDropMode=ttk.TTkK.DragDropMode.AllowDrag)
fileTree = ttk.TTkFileTree(path='.', dragDropMode=ttk.TTkK.DragDropMode.AllowDrag, selectionMode=ttk.TTkK.SelectionMode.MultiSelection)
self._activityBar = TTKodeActivityBar()
self._activityBar.addActivity(name="Explorer", icon=ttk.TTkString("╔██\n╚═╝"), widget=fileTree, select=True)
@ -344,8 +344,10 @@ class TTKode(ttk.TTkGridLayout):
kt.tabButton(index).mergeStyle(doc.getTabButtonStyle())
kt.tabButton(index).setText(doc._tabText)
def _openFile(self, filePath, line:int=0, pos:int=0):
def _openFile(self, filePath, line:int=0, pos:int=0) -> None:
filePath = os.path.realpath(filePath)
if not os.path.isfile(filePath):
return
doc, tedit = self._getDocument(filePath=filePath)
if tedit:
self._kodeTab.setCurrentWidget(tedit)
@ -359,29 +361,36 @@ class TTKode(ttk.TTkGridLayout):
def _dropEventProxyFile(self, evt:ttk.TTkDnDEvent):
data = evt.data()
filePath = None
filePaths = []
linenums = []
if ( issubclass(type(data), ttk.TTkTreeWidget._DropTreeData) and data.items ):
if issubclass(type(data.items[0]), ttk.TTkFileTreeWidgetItem):
linenum:int = 0
ftwi:ttk.TTkFileTreeWidgetItem = data.items[0]
filePath = os.path.realpath(ftwi.path())
ftwis:List[ttk.TTkFileTreeWidgetItem] = data.items
filePaths = [os.path.realpath(_f.path()) for _f in ftwis]
linenums:List[int] = [0]*len(filePaths)
elif issubclass(type(data.items[0]), TTKodeFileWidgetItem):
kfwi:TTKodeFileWidgetItem = data.items[0]
linenum:int = kfwi.lineNumber()
filePath = os.path.realpath(kfwi.path())
linenums:List[int] = [kfwi.lineNumber()]
filePaths = [os.path.realpath(kfwi.path())]
if filePath:
newData = []
for filePath,linenum in zip(filePaths,linenums) :
if not os.path.isfile(filePath):
continue
doc, _ = self._getDocument(filePath=filePath)
tedit = _TextEdit(document=doc, readOnly=False, lineNumber=True)
tedit.docFocussed.connect(self._handleDocFocussed)
tedit.goToLine(linenum)
newData = _TTkNewTabWidgetDragData(
widget=tedit,
label=doc._tabText,
data=None,
closable=True
newData.append(
_TTkNewTabWidgetDragData(
widget=tedit,
label=doc._tabText,
data=None,
closable=True
)
)
if newData:
newEvt = evt.clone()
newEvt.setData(newData)
return newEvt

2
apps/ttkode/ttkode/plugins/_010/findwidget.py

@ -83,6 +83,8 @@ def _custom_walk(directory:str, patterns:List[str]=[]) -> Generator[Tuple[str, s
full_path = os.path.join(directory, entry)
if _should_ignore(full_path, patterns):
continue
if not os.path.exists(full_path):
continue
if os.path.isdir(full_path):
if entry == '.git':
continue

16
tests/t.generic/test.stderr.001.py

@ -0,0 +1,16 @@
import sys
from io import StringIO
sys.stderr.write('Eugenio')
old_stderr = sys.stderr
sys.stderr = mystderr = StringIO()
sys.stderr.write('Eugenio2')
sys.stderr = old_stderr
print('Err:',mystderr.getvalue())
with open('jkhdkjdhkjdhkjdhd.txt','r') as f:
x = f.read()

63
tests/t.generic/test.stderr.002.py

@ -0,0 +1,63 @@
import sys
import contextlib
class StderrHandler:
def __init__(self, callback=None):
"""
Create a handler for stderr output.
Args:
callback: A function that will be called with each piece of text written to stderr
"""
self.buffer = ""
self.callback = callback
def write(self, text):
self.buffer += text
if self.callback:
self.callback(text)
return len(text)
def flush(self):
# Required to be a proper file-like object
pass
def getvalue(self):
return self.buffer
@contextlib.contextmanager
def redirect_stderr_to_handler(callback=None):
"""Context manager for temporarily redirecting stderr to our handler."""
handler = StderrHandler(callback)
original_stderr = sys.stderr
sys.stderr = handler
try:
yield handler
finally:
sys.stderr = original_stderr
# Example 1: Using the context manager
def my_handler(text):
print(f"Captured stderr: {text!r}")
with redirect_stderr_to_handler(my_handler):
# Any stderr output inside this block will be handled by my_handler
print("This is an error", file=sys.stderr)
raise Exception("This will also be captured")
# Example 2: Manual redirection
handler = StderrHandler(lambda text: print(f"Got: {text}"))
original_stderr = sys.stderr
sys.stderr = handler
try:
# Now stderr is redirected
print("Error message", file=sys.stderr)
finally:
# Always restore the original stderr
sys.stderr = original_stderr
# Get the accumulated output
print(f"Captured content: {handler.getvalue()}")
Loading…
Cancel
Save