8 changed files with 382 additions and 40 deletions
@ -0,0 +1,159 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2024 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
__all__ = ['ttkCrossOpen', 'ttkCrossSave', 'ttkCrossSaveAs', 'TTkEncoding', 'ttkConnectDragOpen', 'ttkEmitDragOpen', 'ttkEmitFileOpen'] |
||||
|
||||
import os |
||||
import importlib.util |
||||
import json |
||||
|
||||
from TermTk import pyTTkSlot, pyTTkSignal |
||||
from TermTk import TTkLog |
||||
from TermTk import TTkMessageBox, TTkFileDialogPicker, TTkHelper, TTkString, TTkK, TTkColor |
||||
|
||||
ttkCrossOpen = None |
||||
ttkCrossSave = None |
||||
ttkCrossSaveAs = None |
||||
ttkEmitDragOpen = None |
||||
ttkEmitFileOpen = None |
||||
ttkConnectDragOpen = None |
||||
|
||||
class TTkEncoding(str): |
||||
TEXT = "text" |
||||
TEXT_PLAIN = "text/plain" |
||||
TEXT_PLAIN_UTF8 = "text/plain;charset=utf-8" |
||||
APPLICATION = 'application' |
||||
APPLICATION_JSON = 'application/json' |
||||
IMAGE = 'image' |
||||
IMAGE_PNG = 'image/png' |
||||
IMAGE_SVG = 'image/svg+xml' |
||||
IMAGE_JPG = 'image/jpeg' |
||||
|
||||
if importlib.util.find_spec('pyodideProxy'): |
||||
TTkLog.info("Using 'pyodideProxy' as clipboard manager") |
||||
import pyodideProxy |
||||
ttkDragOpen = {} |
||||
ttkFileOpen = pyTTkSignal(dict) |
||||
|
||||
def _open(path, encoding, filter, cb=None): |
||||
if not cb: return |
||||
ttkFileOpen.connect(cb) |
||||
pyodideProxy.openFile(encoding) |
||||
|
||||
def _save(filePath, content, encoding, filter=None): |
||||
pyodideProxy.saveFile(os.path.basename(filePath), content, encoding) |
||||
|
||||
def _connectDragOpen(encoding, cb): |
||||
if not encoding in ttkDragOpen: |
||||
ttkDragOpen[encoding] = pyTTkSignal(dict) |
||||
return ttkDragOpen[encoding].connect(cb) |
||||
|
||||
def _emitDragOpen(encoding, data): |
||||
for do in [ttkDragOpen[e] for e in ttkDragOpen if encoding.startswith(e)]: |
||||
do.emit(data) |
||||
|
||||
def _emitFileOpen(encoding, data): |
||||
ttkFileOpen.emit(data) |
||||
ttkFileOpen.clear() |
||||
|
||||
ttkCrossOpen = _open |
||||
ttkCrossSave = _save |
||||
ttkCrossSaveAs = _save |
||||
ttkEmitDragOpen = _emitDragOpen |
||||
ttkEmitFileOpen = _emitFileOpen |
||||
ttkConnectDragOpen = _connectDragOpen |
||||
|
||||
else: |
||||
def _crossDecoder_text(fileName) : |
||||
with open(fileName) as fp: |
||||
return fp.read() |
||||
def _crossDecoder_json(fileName) : |
||||
with open(fileName) as fp: |
||||
# return json.load(fp) |
||||
return fp.read() |
||||
def _crossDecoder_image(fileName): |
||||
return None |
||||
|
||||
_crossDecoder = { |
||||
TTkEncoding.TEXT : _crossDecoder_text , |
||||
TTkEncoding.TEXT_PLAIN : _crossDecoder_text , |
||||
TTkEncoding.TEXT_PLAIN_UTF8 : _crossDecoder_text , |
||||
TTkEncoding.APPLICATION : _crossDecoder_json , |
||||
TTkEncoding.APPLICATION_JSON : _crossDecoder_json , |
||||
TTkEncoding.IMAGE : _crossDecoder_image , |
||||
TTkEncoding.IMAGE_PNG : _crossDecoder_image , |
||||
TTkEncoding.IMAGE_SVG : _crossDecoder_image , |
||||
TTkEncoding.IMAGE_JPG : _crossDecoder_image , |
||||
} |
||||
|
||||
def _open(path, encoding, filter, cb=None): |
||||
if not cb: return |
||||
def __openFile(fileName): |
||||
_decoder = _crossDecoder.get(encoding,lambda _:None) |
||||
content = _decoder(fileName) |
||||
cb({'name':fileName, 'data':content}) |
||||
filePicker = TTkFileDialogPicker(pos = (3,3), size=(100,30), caption="Open", path=path, fileMode=TTkK.FileMode.ExistingFile ,filter=filter) |
||||
filePicker.pathPicked.connect(__openFile) |
||||
TTkHelper.overlay(None, filePicker, 5, 5, True) |
||||
|
||||
def _save(filePath, content, encoding): |
||||
TTkLog.info(f"Saving to: {filePath}") |
||||
with open(filePath,'w') as fp: |
||||
fp.write(content) |
||||
|
||||
def _saveAs(filePath, content, encoding, filter, cb=None): |
||||
if not cb: return |
||||
def _approveFile(fileName): |
||||
if os.path.exists(fileName): |
||||
@pyTTkSlot(TTkMessageBox.StandardButton) |
||||
def _cb(btn): |
||||
if btn == TTkMessageBox.StandardButton.Save: |
||||
ttkCrossSave(fileName,content,encoding) |
||||
elif btn == TTkMessageBox.StandardButton.Cancel: |
||||
return |
||||
if cb: |
||||
cb() |
||||
messageBox = TTkMessageBox( |
||||
text= ( |
||||
TTkString( f'A file named "{os.path.basename(fileName)}" already exists.\nDo you want to replace it?', TTkColor.BOLD) + |
||||
TTkString( f'\n\nReplacing it will overwrite its contents.') ), |
||||
icon=TTkMessageBox.Icon.Warning, |
||||
standardButtons=TTkMessageBox.StandardButton.Discard|TTkMessageBox.StandardButton.Save|TTkMessageBox.StandardButton.Cancel) |
||||
messageBox.buttonSelected.connect(_cb) |
||||
TTkHelper.overlay(None, messageBox, 5, 5, True) |
||||
else: |
||||
ttkCrossSave(fileName,content,encoding) |
||||
filePicker = TTkFileDialogPicker( |
||||
size=(100,30), path=filePath, |
||||
acceptMode=TTkK.AcceptMode.AcceptSave, |
||||
caption="Save As...", |
||||
fileMode=TTkK.FileMode.AnyFile , |
||||
filter=filter) |
||||
filePicker.pathPicked.connect(_approveFile) |
||||
TTkHelper.overlay(None, filePicker, 5, 5, True) |
||||
|
||||
ttkCrossOpen = _open |
||||
ttkCrossSave = _save |
||||
ttkCrossSaveAs = _saveAs |
||||
ttkEmitDragOpen = lambda a:None |
||||
ttkEmitFileOpen = lambda a:None |
||||
ttkConnectDragOpen = lambda a,b:None |
||||
Loading…
Reference in new issue