libcanvas/Canvas{Ex,Im}portStore.py: cleanup.

assets/tools/MiRCARTReduce.py: fixed (for spoke.)
assets/tools/{MiRCARTTo{Ansi,PngFile},SAUCETo{Ansi,MiRCART}}.py: updated.
lib{canvas/Canvas,gui/Gui{CanvasInterface,Frame}}.py: updated.
lib{{canvas/Canvas{Backend,Journal},Colours},tools/ToolRect}.py: minor cleanup.
roar.py: updated.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2019-09-06 10:29:45 +02:00
parent 80ff03e4b1
commit 997042ad90
15 changed files with 440 additions and 609 deletions

View File

@ -12,8 +12,7 @@ from CanvasImportStore import CanvasImportStore
import sys
def reduce(inPathName):
canvasStore = CanvasImportStore(inPathName)
inMap = canvasStore.outMap.copy(); del canvasStore;
canvasStore = CanvasImportStore(inPathName); inMap = canvasStore.outMap.copy();
with open(inPathName, "w+") as outFile:
for inCurRow in range(len(inMap)):
lastAttribs, lastColours = CanvasImportStore._CellState.CS_NONE, None
@ -28,12 +27,18 @@ def reduce(inPathName):
if lastColours == None \
or (lastColours[0] != inCurCell[:2][0] \
and lastColours[1] != inCurCell[:2][1]):
if (inCurCell[3] in set("0123456789")) and (inCurCell[1] < 10):
print("\u0003{:d},{:02d}{}".format(*inCurCell[:2], inCurCell[3]), end="", file=outFile)
else:
print("\u0003{:d},{:d}{}".format(*inCurCell[:2], inCurCell[3]), end="", file=outFile)
lastColours = inCurCell[:2]
elif lastColours[1] == inCurCell[:2][1] \
and lastColours[0] != inCurCell[:2][0]:
print("\u0003{:d}{}".format(inCurCell[:2][0], inCurCell[3]), end="", file=outFile)
lastColours[0] = inCurCell[:2][0]
elif (lastColours[1] == inCurCell[:2][1]) \
and (lastColours[0] != inCurCell[:2][0]):
if (inCurCell[3] in set("0123456789")) and (inCurCell[0] < 10):
print("\u0003{:02d}{}".format(inCurCell[0], inCurCell[3]), end="", file=outFile)
else:
print("\u0003{:d}{}".format(inCurCell[0], inCurCell[3]), end="", file=outFile)
lastColours[0] = inCurCell[0]
else:
print(inCurCell[3], end="", file=outFile)
print("\n", end="", file=outFile)

View File

@ -18,9 +18,12 @@ def main(*argv):
print("usage: {} <MiRCART input file pathname>".format(sys.argv[0]), file=sys.stderr)
else:
canvasImportStore = CanvasImportStore()
canvasImportStore.importAnsiFile(argv[1])
rc, error = canvasImportStore.importAnsiFile(argv[1])
if rc:
canvasExportStore = CanvasExportStore()
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, sys.stdout)
else
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__":
main(*sys.argv)

View File

@ -27,9 +27,12 @@ def main(*argv):
optdict["-s"] = 11 if not "-s" in optdict else int(optdict["-s"])
for inFile in argv:
canvasImportStore = CanvasImportStore()
canvasImportStore.importTextFile(inFile)
rc, error = canvasImportStore.importTextFile(inFile)
if rc:
canvasExportStore = CanvasExportStore()
canvasExportStore.exportPngFile(canvasImportStore.outMap, os.path.splitext(inFile)[0] + ".png", optdict["-f"], optdict["-s"])
canvasExportStore.exportPngFile(canvasImportStore.outMap, optdict["-f"], optdict["-s"], os.path.splitext(inFile)[0] + ".png")
else:
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__":
main(*sys.argv)

View File

@ -18,10 +18,13 @@ def main(*argv):
print("usage: {} <SAUCE input file pathname> <ANSI output file pathname>".format(sys.argv[0]), file=sys.stderr)
else:
canvasImportStore = CanvasImportStore()
canvasImportStore.importSauceFile(argv[1])
rc, error = canvasImportStore.importSauceFile(argv[1])
if rc:
canvasExportStore = CanvasExportStore()
with open(argv[2], "w", encoding="utf-8") as outFile:
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile)
else:
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__":
main(*sys.argv)

View File

@ -18,10 +18,13 @@ def main(*argv):
print("usage: {} <SAUCE input file pathname> <mIRC art output file pathname>".format(sys.argv[0]), file=sys.stderr)
else:
canvasImportStore = CanvasImportStore()
canvasImportStore.importSauceFile(argv[1])
rc, error = canvasImportStore.importSauceFile(argv[1])
if rc:
canvasExportStore = CanvasExportStore()
with open(argv[2], "w", encoding="utf-8") as outFile:
canvasExportStore.exportTextFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile)
else:
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__":
main(*sys.argv)

View File

@ -43,7 +43,7 @@ class Canvas(wx.Panel):
if commitUndo:
if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas(patchDelta, patch)
self.canvasJournal.updateCurrentDeltas(patch, patchDelta)
self._commitPatch(patch)
# }}}
@ -90,7 +90,7 @@ class Canvas(wx.Panel):
# }}}
# {{{ onPanelPaint(self, event): XXX
def onPanelPaint(self, event):
self.canvasBackend.onPanelPaintEvent(self, event)
self.canvasBackend.onPanelPaintEvent(event, self)
# }}}
# {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX
def onStoreUpdate(self, newCanvasSize, newCanvas=None):
@ -129,7 +129,7 @@ class Canvas(wx.Panel):
undoPatches, redoPatches = ["resize", *oldCanvasSize], ["resize", *newCanvasSize]
if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas(undoPatches, redoPatches)
self.canvasJournal.updateCurrentDeltas(redoPatches, undoPatches)
if deltaCanvasSize[0] < 0:
for numRow in range(oldCanvasSize[1]):
@ -137,7 +137,7 @@ class Canvas(wx.Panel):
for numCol in range((oldCanvasSize[0] + deltaCanvasSize[0]), oldCanvasSize[0]):
if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas([numCol, numRow, *self.canvasMap[numRow][numCol]], [numCol, numRow, 1, 1, 0, " "])
self.canvasJournal.updateCurrentDeltas([numCol, numRow, 1, 1, 0, " "], [numCol, numRow, *self.canvasMap[numRow][numCol]])
del self.canvasMap[numRow][-1:(deltaCanvasSize[0]-1):-1]
else:
for numRow in range(oldCanvasSize[1]):
@ -150,7 +150,7 @@ class Canvas(wx.Panel):
for numCol in range(oldCanvasSize[0] + deltaCanvasSize[0]):
if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas([numCol, numRow, *self.canvasMap[numRow][numCol]], [numCol, numRow, 1, 1, 0, " "])
self.canvasJournal.updateCurrentDeltas([numCol, numRow, 1, 1, 0, " "], [numCol, numRow, *self.canvasMap[numRow][numCol]])
del self.canvasMap[-1:(deltaCanvasSize[1]-1):-1]
else:
for numNewRow in range(oldCanvasSize[1], newCanvasSize[1]):
@ -182,7 +182,7 @@ class Canvas(wx.Panel):
self.canvasBackend = CanvasBackend(defaultCanvasSize, defaultCellSize)
self.canvasJournal = CanvasJournal()
self.canvasExportStore = CanvasExportStore()
self.canvasImportStore = CanvasImportStore(parentCanvas=self)
self.canvasImportStore = CanvasImportStore()
self.canvasInterface = canvasInterface(self, parentFrame)
# Bind event handlers

View File

@ -13,81 +13,59 @@ class CanvasBackend():
# {{{ _drawBrushPatch(self, eventDc, patch): XXX
def _drawBrushPatch(self, eventDc, patch):
absPoint = self._xlatePoint(patch)
brushFg = self._brushes[patch[3]]
brushBg = self._brushes[patch[2]]
pen = self._pens[patch[3]]
brushBg, brushFg, pen = self._brushes[patch[2]], self._brushes[patch[3]], self._pens[patch[3]]
self._setBrushDc(brushBg, brushFg, eventDc, pen)
eventDc.DrawRectangle(*absPoint, *self.cellSize)
# }}}
# {{{ _drawCharPatch(self, eventDc, patch): XXX
def _drawCharPatch(self, eventDc, patch):
absPoint = self._xlatePoint(patch)
brushFg = self._brushes[patch[2]]
brushBg = self._brushes[patch[3]]
pen = self._pens[patch[3]]
fontBitmap = wx.Bitmap(*self.cellSize)
absPoint, fontBitmap = self._xlatePoint(patch), wx.Bitmap(*self.cellSize)
brushBg, brushFg, pen = self._brushes[patch[3]], self._brushes[patch[2]], self._pens[patch[3]]
fontDc = wx.MemoryDC(); fontDc.SelectObject(fontBitmap);
fontDc.SetTextForeground(wx.Colour(Colours[patch[2]][0:4]))
fontDc.SetTextBackground(wx.Colour(Colours[patch[3]][0:4]))
fontDc.SetTextForeground(wx.Colour(Colours[patch[2]][:4]))
fontDc.SetTextBackground(wx.Colour(Colours[patch[3]][:4]))
fontDc.SetBrush(brushBg); fontDc.SetBackground(brushBg); fontDc.SetPen(pen);
fontDc.SetFont(self._font)
fontDc.DrawRectangle(0, 0, *self.cellSize)
fontDc.DrawText(patch[5], 0, 0)
fontDc.DrawRectangle(0, 0, *self.cellSize); fontDc.DrawText(patch[5], 0, 0);
eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0)
# }}}
# {{{ _finiBrushesAndPens(self): XXX
def _finiBrushesAndPens(self):
for brush in self._brushes or []:
brush.Destroy()
self._brushes = None
for pen in self._pens or []:
pen.Destroy()
self._pens = None
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
[brush.Destroy() for brush in self._brushes or []]
[pen.Destroy() for pen in self._pens or []]
self._brushes, self._lastBrushBg, self._lastBrushFg, self._lastPen, self._pens = None, None, None, None, None
# }}}
# {{{ _initBrushesAndPens(self): XXX
def _initBrushesAndPens(self):
self._brushes = [None for x in range(len(Colours))]
self._pens = [None for x in range(len(Colours))]
self._brushes, self._pens = [None for x in range(len(Colours))], [None for x in range(len(Colours))]
for mircColour in range(len(Colours)):
self._brushes[mircColour] = wx.Brush( \
wx.Colour(Colours[mircColour][0:4]), wx.BRUSHSTYLE_SOLID)
self._pens[mircColour] = wx.Pen( \
wx.Colour(Colours[mircColour][0:4]), 1)
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
self._brushes[mircColour] = wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)
self._pens[mircColour] = wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
# }}}
# {{{ _setBrushDc(self, brushBg, brushFg, dc, pen): XXX
def _setBrushDc(self, brushBg, brushFg, dc, pen):
if self._lastBrushBg != brushBg:
dc.SetBackground(brushBg)
self._lastBrushBg = brushBg
dc.SetBackground(brushBg); self._lastBrushBg = brushBg;
if self._lastBrushFg != brushFg:
dc.SetBrush(brushFg)
self._lastBrushFg = brushFg
dc.SetBrush(brushFg); self._lastBrushFg = brushFg;
if self._lastPen != pen:
dc.SetPen(pen)
self._lastPen = pen
dc.SetPen(pen); self._lastPen = pen;
# }}}
# {{{ _xlatePoint(self, patch): XXX
def _xlatePoint(self, patch):
return [a * b for a, b in zip(patch[0:2], self.cellSize)]
return [a * b for a, b in zip(patch[:2], self.cellSize)]
# }}}
# {{{ drawCursorMaskWithJournal(self, canvasJournal, eventDc): XXX
def drawCursorMaskWithJournal(self, canvasJournal, eventDc):
for patch in canvasJournal.popCursor():
self.drawPatch(eventDc, patch)
[self.drawPatch(eventDc, patch) for patch in canvasJournal.popCursor()]
# }}}
# {{{ drawPatch(self, eventDc, patch): XXX
def drawPatch(self, eventDc, patch):
if patch[0] < self.canvasSize[0] \
and patch[0] >= 0 \
and patch[1] < self.canvasSize[1] \
and patch[1] >= 0:
if patch[5] == " ":
self._drawBrushPatch(eventDc, patch)
else:
self._drawCharPatch(eventDc, patch)
if ((patch[0] >= 0) and (patch[0] < self.canvasSize[0])) \
and ((patch[1] >= 0) and (patch[1] < self.canvasSize[1])):
self._drawBrushPatch(eventDc, patch) if patch[5] == " " else self._drawCharPatch(eventDc, patch)
return True
else:
return False
@ -95,11 +73,11 @@ class CanvasBackend():
# {{{ getDeviceContext(self, parentWindow): XXX
def getDeviceContext(self, parentWindow):
eventDc = wx.BufferedDC(wx.ClientDC(parentWindow), self.canvasBitmap)
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
return eventDc
# }}}
# {{{ onPanelPaintEvent(self, panelWindow, panelEvent): XXX
def onPanelPaintEvent(self, panelWindow, panelEvent):
# {{{ onPanelPaintEvent(self, panelEvent, panelWindow): XXX
def onPanelPaintEvent(self, panelEvent, panelWindow):
if self.canvasBitmap != None:
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
# }}}
@ -113,27 +91,19 @@ class CanvasBackend():
if self.canvasBitmap == None:
self.canvasBitmap = wx.Bitmap(winSize)
else:
oldDc = wx.MemoryDC()
oldDc.SelectObject(self.canvasBitmap)
newDc = wx.MemoryDC()
newBitmap = wx.Bitmap(winSize)
newDc.SelectObject(newBitmap)
oldDc = wx.MemoryDC(); oldDc.SelectObject(self.canvasBitmap);
newDc = wx.MemoryDC(); newBitmap = wx.Bitmap(winSize); newDc.SelectObject(newBitmap);
newDc.Blit(0, 0, *self.canvasBitmap.GetSize(), oldDc, 0, 0)
oldDc.SelectObject(wx.NullBitmap)
self.canvasBitmap.Destroy(); self.canvasBitmap = newBitmap;
self.canvasSize = canvasSize; self.cellSize = cellSize;
self._font = wx.Font( \
8, \
wx.FONTFAMILY_TELETYPE, \
wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
self.canvasSize, self.cellSize = canvasSize, cellSize
self._font = wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
# }}}
# {{{ xlateEventPoint(self, event, eventDc): XXX
def xlateEventPoint(self, event, eventDc):
eventPoint = event.GetLogicalPosition(eventDc)
rectX = eventPoint.x - (eventPoint.x % self.cellSize[0])
rectY = eventPoint.y - (eventPoint.y % self.cellSize[1])
mapX = int(rectX / self.cellSize[0] if rectX else 0)
mapY = int(rectY / self.cellSize[1] if rectY else 0)
rectX, rectY = eventPoint.x - (eventPoint.x % self.cellSize[0]), eventPoint.y - (eventPoint.y % self.cellSize[1])
mapX, mapY = int(rectX / self.cellSize[0] if rectX else 0), int(rectY / self.cellSize[1] if rectY else 0)
return (mapX, mapY)
# }}}
@ -149,7 +119,6 @@ class CanvasBackend():
def __init__(self, canvasSize, cellSize):
self._brushes, self._font, self._lastBrush, self._lastPen, self._pens = None, None, None, None, None
self.canvasBitmap, self.cellSize = None, None
self._initBrushesAndPens()
self.reset(canvasSize, cellSize)
self._initBrushesAndPens(); self.reset(canvasSize, cellSize);
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -31,38 +31,19 @@ class CanvasExportStore():
ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
PastebinPostUrl = "https://pastebin.com/api/api_post.php"
# {{{ _drawUnderline(self, curPos, fontSize, imgDraw, fillColour): XXX
def _drawUnderLine(self, curPos, fontSize, imgDraw, fillColour):
# {{{ _drawUnderline(self, curPos, fillColour, fontSize, imgDraw): XXX
def _drawUnderLine(self, curPos, fillColour, fontSize, imgDraw):
imgDraw.line( \
xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \
curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \
fill=fillColour)
# }}}
# {{{ _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName): upload single PNG file to Imgur
def _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName):
with open(pathName, "rb") as requestImage:
requestImageData = requestImage.read()
requestData = { \
"image": base64.b64encode(requestImageData), \
"key": apiKey, \
"name": imgName, \
"title": imgTitle, \
"type": "base64"}
requestHeaders = {"Authorization": "Client-ID " + apiKey}
responseHttp = requests.post(self.ImgurUploadUrl, data=requestData, headers=requestHeaders)
responseDict = json.loads(responseHttp.text)
if responseHttp.status_code == 200:
return [200, responseDict.get("data").get("link")]
else:
return [responseHttp.status_code, ""]
# }}}
# {{{ exportAnsiFile(self, canvasMap, canvasSize, outFile): XXX
def exportAnsiFile(self, canvasMap, canvasSize, outFile):
outBuffer = ""
for inCurRow in range(len(canvasMap)):
lastAttribs = self._CellState.CS_NONE
lastColours = None
lastAttribs, lastColours = self._CellState.CS_NONE, None
for inCurCol in range(len(canvasMap[inCurRow])):
inCurCell = canvasMap[inCurRow][inCurCol]
if lastAttribs != inCurCell[2]:
@ -79,14 +60,32 @@ class CanvasExportStore():
else:
outBuffer += inCurCell[3]
outBuffer += "\u001b[0m\n"
if len(outBuffer):
outFile.write(outBuffer)
return (True, None)
else:
return (False, "empty buffer generated")
# }}}
# {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): XXX
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
tmpPathName = tempfile.mkstemp()
os.close(tmpPathName[0])
canvasBitmap.ConvertToImage().SaveFile(tmpPathName[1], imgType)
imgurResult = self._exportFileToImgur(apiKey, imgName, imgTitle, tmpPathName[1])
with open(tmpPathName[1], "rb") as requestImage:
requestImageData = requestImage.read()
requestData = { \
"image": base64.b64encode(requestImageData), \
"key": apiKey, \
"name": imgName, \
"title": imgTitle, \
"type": "base64"}
requestHeaders = {"Authorization": "Client-ID " + apiKey}
responseHttp = requests.post(self.ImgurUploadUrl, data=requestData, headers=requestHeaders)
responseDict = json.loads(responseHttp.text)
if responseHttp.status_code == 200:
imgurResult = (True, responseHttp.status_code, responseDict.get("data").get("link"))
else:
imgurResult = (False, responseHttp.status_code, responseDict.get("data"))
os.remove(tmpPathName[1])
return imgurResult
# }}}
@ -107,39 +106,32 @@ class CanvasExportStore():
"api_paste_private": pastePrivate}
responseHttp = requests.post(self.PastebinPostUrl, data=requestData)
if responseHttp.status_code == 200:
if responseHttp.text.startswith("http"):
return (True, responseHttp.text)
else:
return (False, responseHttp.text)
return (True if responseHttp.text.startswith("http") else False, responseHttp.text)
else:
return (False, str(responseHttp.status_code))
else:
return (False, "missing requests and/or urllib3 module(s)")
# }}}
# {{{ exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize): XXX
def exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize):
# {{{ exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName): XXX
def exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName):
if havePIL:
inSize = (len(canvasMap[0]), len(canvasMap))
outCurPos = [0, 0]
outFontFilePath, outFontSize = fontFilePath, fontSize
outImgFont = ImageFont.truetype(outFontFilePath, outFontSize)
outImgFontSize = [*outImgFont.getsize(" ")]
outImgFontSize[1] += 3
inSize = (len(canvasMap[0]), len(canvasMap))
outImgFontSize = [*outImgFont.getsize(" ")]; outImgFontSize[1] += 3;
outSize = [a * b for a, b in zip(inSize, outImgFontSize)]
outCurPos = [0, 0]
outImg = Image.new("RGBA", outSize, (*ColourMapNormal[1], 255))
outImgDraw = ImageDraw.Draw(outImg)
outImgDraw.fontmode = "1"
outImgDraw = ImageDraw.Draw(outImg); outImgDraw.fontmode = "1";
for inCurRow in range(len(canvasMap)):
for inCurCol in range(len(canvasMap[inCurRow])):
inCurCell = canvasMap[inCurRow][inCurCol]
outColours = [0, 0]
inCurCell = canvasMap[inCurRow][inCurCol]; outColours = (0, 0);
if inCurCell[2] & self._CellState.CS_BOLD:
if inCurCell[3] != " ":
if inCurCell[3] == "":
outColours[1] = ColourMapNormal[inCurCell[0]]
else:
outColours[0] = ColourMapBold[inCurCell[0]]
outColours[1] = ColourMapNormal[inCurCell[1]]
outColours = (ColourMapBold[inCurCell[0]], ColourMapNormal[inCurCell[1]])
else:
outColours[1] = ColourMapNormal[inCurCell[1]]
else:
@ -147,8 +139,7 @@ class CanvasExportStore():
if inCurCell[3] == "":
outColours[1] = ColourMapNormal[inCurCell[0]]
else:
outColours[0] = ColourMapNormal[inCurCell[0]]
outColours[1] = ColourMapNormal[inCurCell[1]]
outColours = (ColourMapNormal[inCurCell[0]], ColourMapNormal[inCurCell[1]])
else:
outColours[1] = ColourMapNormal[inCurCell[1]]
outImgDraw.rectangle((*outCurPos, outCurPos[0] + outImgFontSize[0], outCurPos[1] + outImgFontSize[1]), fill=(*outColours[1], 255))
@ -158,14 +149,13 @@ class CanvasExportStore():
outImgDraw.text(outCurPos, inCurCell[3], (*outColours[0], 255), outImgFont)
if inCurCell[2] & self._CellState.CS_UNDERLINE:
outColours[0] = ColourMapNormal[inCurCell[0]]
self._drawUnderLine(outCurPos, outImgFontSize, outImgDraw, (*outColours[0], 255))
self._drawUnderLine(outCurPos, (*outColours[0], 255), outImgFontSize, outImgDraw)
outCurPos[0] += outImgFontSize[0];
outCurPos[0] = 0
outCurPos[1] += outImgFontSize[1]
outCurPos[0] = 0; outCurPos[1] += outImgFontSize[1];
outImg.save(outPathName);
return True
return (True, None)
else:
return False
return (False, "missing PIL modules")
# }}}
# {{{ exportTextBuffer(self, canvasMap, canvasSize): XXX
def exportTextBuffer(self, canvasMap, canvasSize):
@ -191,12 +181,15 @@ class CanvasExportStore():
canvasLastColours[0] = canvasColColours[0]
outBuffer += canvasColText
outBuffer += "\n"
return outBuffer
if len(outBuffer):
return (True, outBuffer)
else:
return (False, "empty buffer generated")
# }}}
# {{{ exportTextFile(self, canvasMap, canvasSize, outFile): XXX
def exportTextFile(self, canvasMap, canvasSize, outFile):
outBuffer = self.exportTextBuffer(canvasMap, canvasSize)
outFile.write(outBuffer)
rc, outBuffer = self.exportTextBuffer(canvasMap, canvasSize)
return outFile.write(outBuffer) if rc else (rc, outBuffer)
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -17,271 +17,129 @@ class CanvasImportStore():
CS_ITALIC = 0x02
CS_UNDERLINE = 0x04
# }}}
# {{{ _ParseState(): Parsing loop state
class _ParseState():
PS_CHAR = 1
PS_COLOUR_DIGIT0 = 2
PS_COLOUR_DIGIT1 = 3
# }}}
# {{{ _flipCellStateBit(self, cellState, bit): XXX
def _flipCellStateBit(self, cellState, bit):
# {{{ _flipCellStateBit(self, bit, cellState): XXX
def _flipCellStateBit(self, bit, cellState):
return cellState & ~bit if cellState & bit else cellState | bit
# }}}
# {{{ _parseCharAsColourSpec(self, colourSpec, curColours): XXX
def _parseCharAsColourSpec(self, colourSpec, curColours):
if len(colourSpec) > 0:
colourSpec = colourSpec.split(",")
if len(colourSpec) == 2 \
and len(colourSpec[1]) > 0:
return (int(colourSpec[0] or curColours[0]), int(colourSpec[1]))
elif len(colourSpec) == 1 \
or len(colourSpec[1]) == 0:
return (int(colourSpec[0]), curColours[1])
else:
return (15, 1)
# }}}
# {{{ importAnsiFile(self, inPathName, encoding="cp437"): XXX
def importAnsiFile(self, inPathName, encoding="cp437"):
return self.importAnsiFileBuffer(open(inPathName, "rb"), encoding)
# }}}
# {{{ importAnsiFileBuffer(self, inFile, encoding="cp437"): XXX
def importAnsiFileBuffer(self, inFile, encoding="cp437"):
self.inSize, self.outMap = None, None; inMaxCols, inSize, outMap = 0, [0, 0], [[]];
inFileData, row, rowChars = inFile.read().decode(encoding), "", 0
# {{{ importAnsiBuffer(self, inFile, encoding="cp437", width=None): XXX
def importAnsiBuffer(self, inFile, encoding="cp437", width=None):
curBg, curBgAnsi, curBoldAnsi, curFg, curFgAnsi = 1, 30, False, 15, 37
done, outMap, outMaxCols = False, [[]], 0
inFileData = inFile.read().decode(encoding)
inFileChar, inFileCharMax = 0, len(inFileData)
curBg, curFg, done, inCurRow = 1, 15, False, 0; curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37;
while True:
if inFileChar >= inFileCharMax:
break
else:
m = re.match('\x1b\[((?:\d{1,3};?)+)m', inFileData[inFileChar:])
m = re.match("\x1b\[((?:\d{1,3};?)+m|\d+C)", inFileData[inFileChar:])
if m:
if m[1][-1] == "C":
outMap[-1] += [[curFg, curBg, self._CellState.CS_NONE, " "]] * int(m[1][:-1])
elif m[1][-1] == "m":
newBg, newFg = -1, -1
for ansiCode in m[1].split(";"):
ansiCode = int(ansiCode)
for ansiCode in [int(c) for c in m[1][:-1].split(";")]:
if ansiCode == 0:
curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37; newBg, newFg = 1, 15;
curBgAnsi, curBoldAnsi, curFgAnsi, newBg, newFg = 30, False, 37, 1, 15
elif ansiCode == 1:
curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi]
elif ansiCode == 2:
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi]
elif ansiCode == 7:
newBg, newFg = curFg, curBg; curBgAnsi, curFgAnsi = curFgAnsi, curBgAnsi;
curBgAnsi, curFgAnsi, newBg, newFg = curFgAnsi, curBgAnsi, curFg, curBg
elif ansiCode in AnsiBgToMiRCARTColours:
curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode]
elif ansiCode in AnsiFgToMiRCARTColours:
if curBoldAnsi:
newFg = AnsiFgBoldToMiRCARTColours[ansiCode]
else:
newFg = AnsiFgToMiRCARTColours[ansiCode]
curFgAnsi = ansiCode
elif ansiCode in AnsiFgBoldToMiRCARTColours:
curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode]
if ((newBg != -1) and (newFg != -1)) \
and ((newBg == curFg) and (newFg == curBg)):
curBg, curFg = newBg, newFg
elif ((newBg != -1) and (newFg != -1)) \
and ((newBg != curBg) and (newFg != curFg)):
curBg, curFg = newBg, newFg
elif (newBg != -1) and (newBg != curBg):
curBg = newBg
elif (newFg != -1) and (newFg != curFg):
curFg = newFg
inFileChar += len(m[0])
else:
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:])
if m:
for numRepeat in range(int(m[1])):
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
elif ansiCode in AnsiFgToMiRCARTColours:
newFg = AnsiFgBoldToMiRCARTColours[ansiCode] if curBoldAnsi else AnsiFgToMiRCARTColours[ansiCode]
curFgAnsi = ansiCode
curBg = newBg if newBg != -1 else curBg; curFg = newFg if newFg != -1 else curFg;
inFileChar += len(m[0])
elif inFileData[inFileChar:inFileChar + 2] == "\r\n":
inFileChar += 2; done = True;
elif inFileData[inFileChar] == "\r" \
or inFileData[inFileChar] == "\n":
inFileChar += 1; done = True;
done = True; inFileChar += 2;
elif inFileData[inFileChar] in set("\r\n"):
done = True; inFileChar += 1;
else:
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]])
inFileChar += 1; rowChars += 1;
if done:
inMaxCols = max(inMaxCols, len(outMap[inCurRow])); inSize[1] += 1;
done = False; rowChars = 0; inCurRow += 1; outMap.append([]);
inSize[0] = inMaxCols
for numRow in range(inSize[1]):
for numCol in range(len(outMap[numRow]), inSize[0]):
outMap[-1].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]])
inFileChar += 1
if done or (width == len(outMap[-1])):
done, outMaxCols, = False, max(outMaxCols, len(outMap[-1])); outMap.append([]);
if len(outMap[0]):
for numRow in range(len(outMap)):
for numCol in range(len(outMap[numRow]), outMaxCols):
outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
self.inSize, self.outMap = inSize, outMap
self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap
return (True, None)
else:
return (False, "empty output map")
# }}}
# {{{ importIntoPanel(self): XXX
def importIntoPanel(self):
self.parentCanvas.onStoreUpdate(self.inSize, self.outMap)
# }}}
# {{{ importNew(self, newCanvasSize=None): XXX
def importNew(self, newCanvasSize=None):
newMap = [[[1, 1, 0, " "] \
for x in range(newCanvasSize[0])] \
for y in range(newCanvasSize[1])]
self.parentCanvas.onStoreUpdate(newCanvasSize, newMap)
# {{{ importAnsiFile(self, inPathName, encoding="cp437"): XXX
def importAnsiFile(self, inPathName, encoding="cp437"):
return self.importAnsiBuffer(open(inPathName, "rb"), encoding)
# }}}
# {{{ importSauceFile(self, inPathName): XXX
def importSauceFile(self, inPathName):
with open(inPathName, "rb") as inFile:
self.inSize, self.outMap = None, None; inMaxCols, inSize, outMap = 0, [0, 0], [[]];
inFileStat = os.stat(inPathName)
inFile.seek(inFileStat.st_size - 128, 0)
inFile.seek(5 + 2 + 35 + 20 + 20 + 8 + 4, 1)
if (inFile.read(1) == b'\x01') \
and (inFile.read(1) == b'\x01'):
width, height = struct.unpack("H", inFile.read(2))[0], struct.unpack("H", inFile.read(2))[0]
inFile.seek(0, 0)
inFileData, row, rowChars = inFile.read(inFileStat.st_size - 128).decode("cp437"), "", 0
inFileChar, inFileCharMax = 0, len(inFileData)
curBg, curFg, inCurRow = 1, 15, 0; curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37;
while True:
if inFileChar >= inFileCharMax:
break
inFileStat = os.stat(inPathName); inFile.seek(inFileStat.st_size - 128, 0); inFile.seek(94);
if inFile.read(2) == b'\x01\x01':
width = struct.unpack("H", inFile.read(2))[0]
inFile.seek(0, 0); inFileData = inFile.read(inFileStat.st_size - 128);
return self.importAnsiFileBuffer(io.StringIO(inFileData), width)
else:
m = re.match('\x1b\[((?:\d{1,3};?)+)m', inFileData[inFileChar:])
return (False, "only character based ANSi SAUCE files are supported")
# }}}
# {{{ importTextBuffer(self, inFile): XXX
def importTextBuffer(self, inFile):
inLine, outMap, outMaxCols = inFile.readline(), [], 0
while inLine:
inCellState, inCurCol, inCurColours, inMaxCol = self._CellState.CS_NONE, 0, (15, 1), len(inLine); outMap.append([]);
while inCurCol < inMaxCol:
inChar = inLine[inCurCol]
if inChar in set("\r\n"):
inCurCol += 1
elif inChar == "\u0002":
inCellState = self._flipCellStateBit(self._CellState.CS_BOLD, inCellState); inCurCol += 1;
elif inChar == "\u0003":
m = re.match("\u0003((1[0-5]|0?[0-9])?(?:,(1[0-5]|0?[0-9]))?)", inLine[inCurCol:])
if m:
newBg, newFg = -1, -1
for ansiCode in m[1].split(";"):
ansiCode = int(ansiCode)
if ansiCode == 0:
curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37; newBg, newFg = 1, 15;
elif ansiCode == 1:
curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi]
elif ansiCode == 2:
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi]
elif ansiCode == 7:
newBg, newFg = curFg, curBg; curBgAnsi, curFgAnsi = curFgAnsi, curBgAnsi;
elif ansiCode in AnsiBgToMiRCARTColours:
curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode]
elif ansiCode in AnsiFgToMiRCARTColours:
if curBoldAnsi:
newFg = AnsiFgBoldToMiRCARTColours[ansiCode]
if (m[2] != None) and (m[3] != None):
inCurColours = (int(m[2]), int(m[3]))
elif (m[2] == None) and (m[3] != None):
inCurColours = (int(m[2]), int(curColours[1]))
else:
newFg = AnsiFgToMiRCARTColours[ansiCode]
curFgAnsi = ansiCode
elif ansiCode in AnsiFgBoldToMiRCARTColours:
curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode]
if ((newBg != -1) and (newFg != -1)) \
and ((newBg == curFg) and (newFg == curBg)):
curBg, curFg = newBg, newFg
elif ((newBg != -1) and (newFg != -1)) \
and ((newBg != curBg) and (newFg != curFg)):
curBg, curFg = newBg, newFg
elif (newBg != -1) and (newBg != curBg):
curBg = newBg
elif (newFg != -1) and (newFg != curFg):
curFg = newFg
inFileChar += len(m[0])
inCurColours = (15, 1)
inCurCol += len(m[0])
else:
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:])
if m:
for numRepeat in range(int(m[1])):
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
inFileChar += len(m[0])
elif inFileData[inFileChar:inFileChar+2] == "\r\n":
inFileChar += 2; rowChars = width;
elif inFileData[inFileChar] == "\r" \
or inFileData[inFileChar] == "\n":
inFileChar += 1; rowChars = width;
inCurColours = (15, 1); inCurCol += 1;
elif inChar == "\u0006":
inCellState = self._flipCellStateBit(self._CellState.CS_ITALIC, inCellState); inCurCol += 1;
elif inChar == "\u000f":
inCellState |= self._CellState.CS_NONE; inCurColours = (15, 1); inCurCol += 1;
elif inChar == "\u0016":
inCurColours = (inCurColours[1], inCurColours[0]); inCurCol += 1;
elif inChar == "\u001f":
inCellState = self._flipCellStateBit(self._CellState.CS_UNDERLINE, inCellState); inCurCol += 1;
else:
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]])
inFileChar += 1; rowChars += 1;
if rowChars >= width:
inMaxCols = max(inMaxCols, len(outMap[inCurRow])); inSize[1] += 1;
rowChars = 0; inCurRow += 1; outMap.append([]);
inSize[0] = inMaxCols
for numRow in range(inSize[1]):
for numCol in range(len(outMap[numRow]), inSize[0]):
outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
self.inSize, self.outMap = inSize, outMap
outMap[-1].append([*inCurColours, inCellState, inChar]); inCurCol += 1;
inLine, outMaxCols = inFile.readline(), max(outMaxCols, len(outMap[-1]))
if len(outMap[0]):
self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap
return (True, None)
else:
return (False, "empty output map")
# }}}
# {{{ importTextFile(self, pathName): XXX
def importTextFile(self, pathName):
return self.importTextFileBuffer(open(pathName, "r", encoding="utf-8-sig"))
# }}}
# {{{ importTextFileBuffer(self, inFile): XXX
def importTextFileBuffer(self, inFile):
self.inSize, self.outMap = None, None
inCurColourSpec, inCurRow, inMaxCols, inSize, outMap = "", -1, 0, [0, 0], []
inLine = inFile.readline()
while inLine:
inCellState = self._CellState.CS_NONE
inParseState = self._ParseState.PS_CHAR
inCurCol = 0; inMaxCol = len(inLine);
inCurColourDigits = 0; inCurColours = (15, 1); inCurColourSpec = "";
inCurRow += 1; outMap.append([]); inRowCols = 0; inSize[1] += 1;
while inCurCol < inMaxCol:
inChar = inLine[inCurCol]
if inChar in set("\r\n"): \
inCurCol += 1
elif inParseState == self._ParseState.PS_CHAR:
inCurCol += 1
if inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_BOLD)
elif inChar == "":
inParseState = self._ParseState.PS_COLOUR_DIGIT0
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_ITALIC)
elif inChar == "":
inCellState |= self._CellState.CS_NONE
inCurColours = (15, 1)
elif inChar == "":
inCurColours = (inCurColours[1], inCurColours[0])
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_UNDERLINE)
else:
inRowCols += 1
outMap[inCurRow].append([*inCurColours, inCellState, inChar])
elif inParseState == self._ParseState.PS_COLOUR_DIGIT0 \
or inParseState == self._ParseState.PS_COLOUR_DIGIT1:
if inChar == "," \
and inParseState == self._ParseState.PS_COLOUR_DIGIT0:
if (inCurCol + 1) < inMaxCol \
and not inLine[inCurCol + 1] in set("0123456789"):
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
else:
inCurCol += 1
inCurColourDigits = 0; inCurColourSpec += inChar;
inParseState = self._ParseState.PS_COLOUR_DIGIT1
elif inChar in set("0123456789") \
and inCurColourDigits == 0:
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("0123456789") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "0":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("012345") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "1":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
else:
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
inMaxCols = max(inMaxCols, inRowCols)
inLine = inFile.readline()
inSize[0] = inMaxCols; self.inSize, self.outMap = inSize, outMap;
inFile.close()
with open(pathName, "r", encoding="utf-8-sig") as inFile:
return self.importTextBuffer(inFile)
# }}}
#
# __init__(self, inFile=None, parentCanvas=None): initialisation method
def __init__(self, inFile=None, parentCanvas=None):
self.inSize, self.outMap, self.parentCanvas = None, None, parentCanvas
# __init__(self, inFile=None): initialisation method
def __init__(self, inFile=None):
self.inSize, self.outMap = None, None
if inFile != None:
self.importTextFile(inFile)

View File

@ -10,8 +10,7 @@ class CanvasJournal():
# {{{ popCursor(self): XXX
def popCursor(self):
if len(self.patchesCursor):
patchesCursor = self.patchesCursor
self.patchesCursor = []
patchesCursor = self.patchesCursor; self.patchesCursor = [];
return patchesCursor
else:
return []
@ -19,8 +18,7 @@ class CanvasJournal():
# {{{ popRedo(self): XXX
def popRedo(self):
if self.patchesUndoLevel > 0:
self.patchesUndoLevel -= 1
patches = self.patchesUndo[self.patchesUndoLevel]
self.patchesUndoLevel -= 1; patches = self.patchesUndo[self.patchesUndoLevel];
return patches[1]
else:
return []
@ -28,8 +26,7 @@ class CanvasJournal():
# {{{ popUndo(self): XXX
def popUndo(self):
if self.patchesUndo[self.patchesUndoLevel] != None:
patches = self.patchesUndo[self.patchesUndoLevel]
self.patchesUndoLevel += 1
patches = self.patchesUndo[self.patchesUndoLevel]; self.patchesUndoLevel += 1;
return patches[0]
else:
return []
@ -38,13 +35,11 @@ class CanvasJournal():
def pushCursor(self, patches):
self.patchesCursor.append(patches)
# }}}
# {{{ pushDeltas(self, undoPatches, redoPatches): XXX
def pushDeltas(self, undoPatches, redoPatches):
# {{{ pushDeltas(self, redoPatches, undoPatches): XXX
def pushDeltas(self, redoPatches, undoPatches):
if self.patchesUndoLevel > 0:
del self.patchesUndo[0:self.patchesUndoLevel]
self.patchesUndoLevel = 0
deltaItem = [undoPatches, redoPatches]
self.patchesUndo.insert(0, deltaItem)
del self.patchesUndo[0:self.patchesUndoLevel]; self.patchesUndoLevel = 0;
deltaItem = [undoPatches, redoPatches]; self.patchesUndo.insert(0, deltaItem);
return deltaItem
# }}}
# {{{ resetCursor(self): XXX
@ -59,10 +54,9 @@ class CanvasJournal():
self.patchesUndo.clear()
self.patchesUndo = [None]; self.patchesUndoLevel = 0;
# }}}
# {{{ updateCurrentDeltas(self, undoPatches, redoPatches): XXX
def updateCurrentDeltas(self, undoPatches, redoPatches):
self.patchesUndo[0][0].append(undoPatches)
self.patchesUndo[0][1].append(redoPatches)
# {{{ updateCurrentDeltas(self, redoPatches, undoPatches): XXX
def updateCurrentDeltas(self, redoPatches, undoPatches):
self.patchesUndo[0][0].append(undoPatches); self.patchesUndo[0][1].append(redoPatches);
# }}}
# {{{ __del__(self): destructor method

View File

@ -19,13 +19,11 @@ import io, os, random, wx, wx.adv
class GuiCanvasInterface():
"""XXX"""
# {{{ _dialogSaveChanges(self)
# {{{ _dialogSaveChanges(self): XXX
def _dialogSaveChanges(self):
with wx.MessageDialog(self.parentCanvas, \
"Do you want to save changes to {}?".format( \
self.canvasPathName), "", \
wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
"Do you want to save changes to {}?".format(self.canvasPathName), \
"", wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
dialogChoice = dialog.ShowModal()
return dialogChoice
# }}}
@ -54,6 +52,105 @@ class GuiCanvasInterface():
def canvasCut(self, event):
pass
# }}}
# {{{ canvasDelete(self, event): XXX
def canvasDelete(self, event):
pass
# }}}
# {{{ canvasExit(self, event): XXX
def canvasExit(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentFrame.Close(True)
# }}}
# {{{ canvasNew(self, event, newCanvasSize=None): XXX
def canvasNew(self, event, newCanvasSize=None):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
if newCanvasSize == None:
newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
newMap = [[[1, 1, 0, " "] for x in range(newCanvasSize[0])] for y in range(newCanvasSize[1])]
self.parentCanvas.onStoreUpdate(newCanvasSize, newMap)
self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="", undoLevel=-1)
# }}}
# {{{ canvasOpen(self, event): XXX
def canvasOpen(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
import pdb; pdb.set_trace()
rc, error = self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName=self.canvasPathName, undoLevel=-1)
return True
else:
print("error: {}".format(error), file=sys.stderr)
return False
# }}}
# {{{ canvasPaste(self, event): XXX
def canvasPaste(self, event):
pass
# }}}
# {{{ canvasRedo(self, event): XXX
def canvasRedo(self, event):
self.parentCanvas._dispatchDeltaPatches(self.parentCanvas.canvasJournal.popRedo())
# }}}
# {{{ canvasSave(self, event): XXX
def canvasSave(self, event):
if self.canvasPathName == None:
if self.canvasSaveAs(event) == False:
return
try:
with open(self.canvasPathName, "w", encoding="utf-8") as outFile:
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportTextFile( \
self.parentCanvas.canvasMap, self.parentCanvas.canvasSize, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
except IOError as error:
return False
# }}}
# {{{ canvasSaveAs(self, event): XXX
def canvasSaveAs(self, event):
with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
return self.canvasSave(event)
# }}}
# {{{ canvasUndo(self, event): XXX
def canvasUndo(self, event):
self.parentCanvas._dispatchDeltaPatches(self.parentCanvas.canvasJournal.popUndo())
# }}}
# {{{ canvasDecrBrushHeight(self, event): XXX
def canvasDecrBrushHeight(self, event):
if self.parentCanvas.brushSize[1] > 1:
@ -74,9 +171,7 @@ class GuiCanvasInterface():
# {{{ canvasDecrCanvasHeight(self, event): XXX
def canvasDecrCanvasHeight(self, event):
if self.parentCanvas.canvasSize[1] > 1:
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0], \
self.parentCanvas.canvasSize[1]-1])
self.parentCanvas.resize([self.parentCanvas.canvasSize[0], self.parentCanvas.canvasSize[1] - 1])
# }}}
# {{{ canvasDecrCanvasHeightWidth(self, event): XXX
def canvasDecrCanvasHeightWidth(self, event):
@ -86,36 +181,37 @@ class GuiCanvasInterface():
# {{{ canvasDecrCanvasWidth(self, event): XXX
def canvasDecrCanvasWidth(self, event):
if self.parentCanvas.canvasSize[0] > 1:
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0]-1, \
self.parentCanvas.canvasSize[1]])
self.parentCanvas.resize([self.parentCanvas.canvasSize[0] - 1, self.parentCanvas.canvasSize[1]])
# }}}
# {{{ canvasDelete(self, event): XXX
def canvasDelete(self, event):
pass
# {{{ canvasIncrBrushHeight(self, event): XXX
def canvasIncrBrushHeight(self, event):
self.parentCanvas.brushSize[1] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasExit(self, event): XXX
def canvasExit(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentFrame.Close(True)
# {{{ canvasIncrBrushHeightWidth(self, event): XXX
def canvasIncrBrushHeightWidth(self, event):
self.canvasIncrBrushHeight(event)
self.canvasIncrBrushWidth(event)
# }}}
# {{{ canvasExportToClipboard(self, event): XXX
def canvasExportToClipboard(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
outBuffer = self.parentCanvas.canvasExportStore.exportTextBuffer(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize)
if wx.TheClipboard.Open():
wx.TheClipboard.SetData(wx.TextDataObject(outBuffer))
wx.TheClipboard.Close()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
# {{{ canvasIncrBrushWidth(self, event): XXX
def canvasIncrBrushWidth(self, event):
self.parentCanvas.brushSize[0] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasIncrCanvasHeight(self, event): XXX
def canvasIncrCanvasHeight(self, event):
self.parentCanvas.resize([self.parentCanvas.canvasSize[0], self.parentCanvas.canvasSize[1] + 1])
# }}}
# {{{ canvasIncrCanvasHeightWidth(self, event): XXX
def canvasIncrCanvasHeightWidth(self, event):
self.canvasIncrCanvasHeight(event)
self.canvasIncrCanvasWidth(event)
# }}}
# {{{ canvasIncrCanvasWidth(self, event): XXX
def canvasIncrCanvasWidth(self, event):
self.parentCanvas.resize([self.parentCanvas.canvasSize[0] + 1, self.parentCanvas.canvasSize[1]])
# }}}
# {{{ canvasExportAsAnsi(self, event): XXX
def canvasExportAsAnsi(self, event):
with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
@ -145,20 +241,15 @@ class GuiCanvasInterface():
# {{{ canvasExportImgur(self, event): XXX
def canvasExportImgur(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
imgurResult = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \
self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, \
"", "", wx.BITMAP_TYPE_PNG)
rc, status, result = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \
self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, "", "", wx.BITMAP_TYPE_PNG)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
if imgurResult[0] == 200:
if rc:
if not wx.TheClipboard.IsOpened():
wx.TheClipboard.Open()
wx.TheClipboard.SetData(wx.TextDataObject(imgurResult[1]))
wx.TheClipboard.Close()
wx.MessageBox("Exported to Imgur: " + imgurResult[1], \
"Export to Imgur", wx.OK|wx.ICON_INFORMATION)
wx.TheClipboard.Open(); wx.TheClipboard.SetData(wx.TextDataObject(result)); wx.TheClipboard.Close();
wx.MessageBox("Exported to Imgur: {}".format(result), "Export to Imgur", wx.ICON_INFORMATION | wx.OK)
else:
wx.MessageBox("Failed to export to Imgur: " + imgurResult[1], \
"Export to Imgur", wx.OK|wx.ICON_EXCLAMATION)
wx.MessageBox("Failed to export to Imgur: {}".format(result), "Export to Imgur", wx.ICON_EXCLAMATION | wx.OK)
# }}}
# {{{ canvasExportPastebin(self, event): XXX
def canvasExportPastebin(self, event):
@ -174,11 +265,19 @@ class GuiCanvasInterface():
wx.TheClipboard.Open()
wx.TheClipboard.SetData(wx.TextDataObject(pasteResult))
wx.TheClipboard.Close()
wx.MessageBox("Exported to Pastebin: " + pasteResult, \
"Export to Pastebin", wx.OK|wx.ICON_INFORMATION)
wx.MessageBox("Exported to Pastebin: " + pasteResult, "Export to Pastebin", wx.OK|wx.ICON_INFORMATION)
else:
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, \
"Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION)
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, "Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION)
# }}}
# {{{ canvasExportToClipboard(self, event): XXX
def canvasExportToClipboard(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
rc, outBuffer = self.parentCanvas.canvasExportStore.exportTextBuffer(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize)
if rc and wx.TheClipboard.Open():
wx.TheClipboard.SetData(wx.TextDataObject(outBuffer))
wx.TheClipboard.Close()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
# }}}
# {{{ canvasImportAnsi(self, event): XXX
def canvasImportAnsi(self, event):
@ -196,12 +295,16 @@ class GuiCanvasInterface():
else:
self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importAnsiFile(self.canvasPathName)
self.parentCanvas.canvasImportStore.importIntoPanel()
rc, error = self.parentCanvas.canvasImportStore.importAnsiFile(self.canvasPathName)
if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.canvasPathName = "(Imported)"
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
return True
else:
print("error: {}".format(error), file=sys.stderr)
return False
# }}}
# {{{ canvasImportFromClipboard(self, event): XXX
def canvasImportFromClipboard(self, event):
@ -219,12 +322,14 @@ class GuiCanvasInterface():
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importTextFileBuffer(io.StringIO(inBuffer.GetText()))
self.parentCanvas.canvasImportStore.importIntoPanel()
rc, error = self.parentCanvas.canvasImportStore.importTextBuffer(io.StringIO(inBuffer.GetText()))
if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.canvasPathName = "(Clipboard)"
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="(Clipboard)", undoLevel=-1)
rc = True
else:
print("error: {}".format(error), file=sys.stderr)
wx.TheClipboard.Close()
if not rc:
with wx.MessageDialog(self.parentCanvas, "Clipboard does not contain text data and/or cannot be opened", "", wx.ICON_QUESTION | wx.OK | wx.OK_DEFAULT) as dialog:
@ -246,121 +351,18 @@ class GuiCanvasInterface():
else:
self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importSauceFile(self.canvasPathName)
self.parentCanvas.canvasImportStore.importIntoPanel()
rc, error = self.parentCanvas.canvasImportStore.importSauceFile(self.canvasPathName)
if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.canvasPathName = "(Imported)"
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
return True
# }}}
# {{{ canvasIncrBrushHeight(self, event): XXX
def canvasIncrBrushHeight(self, event):
self.parentCanvas.brushSize[1] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasIncrBrushHeightWidth(self, event): XXX
def canvasIncrBrushHeightWidth(self, event):
self.canvasIncrBrushHeight(event)
self.canvasIncrBrushWidth(event)
# }}}
# {{{ canvasIncrBrushWidth(self, event): XXX
def canvasIncrBrushWidth(self, event):
self.parentCanvas.brushSize[0] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasIncrCanvasHeight(self, event): XXX
def canvasIncrCanvasHeight(self, event):
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0], \
self.parentCanvas.canvasSize[1] + 1])
# }}}
# {{{ canvasIncrCanvasHeightWidth(self, event): XXX
def canvasIncrCanvasHeightWidth(self, event):
self.canvasIncrCanvasHeight(event)
self.canvasIncrCanvasWidth(event)
# }}}
# {{{ canvasIncrCanvasWidth(self, event): XXX
def canvasIncrCanvasWidth(self, event):
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0] + 1, \
self.parentCanvas.canvasSize[1]])
# }}}
# {{{ canvasNew(self, event, newCanvasSize=None): XXX
def canvasNew(self, event, newCanvasSize=None):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
if newCanvasSize == None:
newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
self.parentCanvas.canvasImportStore.importNew(newCanvasSize)
self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="", undoLevel=-1)
# }}}
# {{{ canvasOpen(self, event): XXX
def canvasOpen(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
print(self.canvasPathName)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
self.parentCanvas.canvasImportStore.importIntoPanel()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate( \
pathName=self.canvasPathName, undoLevel=-1)
return True
# }}}
# {{{ canvasPaste(self, event): XXX
def canvasPaste(self, event):
pass
# }}}
# {{{ canvasRedo(self, event): XXX
def canvasRedo(self, event):
self.parentCanvas._dispatchDeltaPatches( \
self.parentCanvas.canvasJournal.popRedo())
# }}}
# {{{ canvasSave(self, event): XXX
def canvasSave(self, event):
if self.canvasPathName == None:
if self.canvasSaveAs(event) == False:
return
try:
with open(self.canvasPathName, "w", encoding="utf-8") as outFile:
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportTextFile( \
self.parentCanvas.canvasMap, \
self.parentCanvas.canvasSize, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
except IOError as error:
print("error: {}".format(error), file=sys.stderr)
return False
# }}}
# {{{ canvasSaveAs(self, event): XXX
def canvasSaveAs(self, event):
with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
return self.canvasSave(event)
# }}}
# {{{ canvasToolCircle(self, event): XXX
def canvasToolCircle(self, event):
self.canvasTool = ToolCircle(self.parentCanvas)
@ -417,11 +419,6 @@ class GuiCanvasInterface():
toolBar.ToggleTool(self.parentFrame.CID_TEXT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasUndo(self, event): XXX
def canvasUndo(self, event):
self.parentCanvas._dispatchDeltaPatches( \
self.parentCanvas.canvasJournal.popUndo())
# }}}
#
# __init__(self, parentCanvas, parentFrame):

View File

@ -19,9 +19,12 @@ def main(*argv):
if len(argv) > 1 \
and len(argv[1]) > 0:
appFrame.panelCanvas.canvasInterface.canvasPathName = argv[1]
appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1])
appFrame.panelCanvas.canvasImportStore.importIntoPanel()
rc, error = appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1])
if rc:
appFrame.panelCanvas.onStoreUpdate(appFrame.panelCanvas.canvasImportStore.inSize, appFrame.panelCanvas.canvasImportStore.outMap)
appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1)
else:
print("error: {}".format(error), file=sys.stderr)
wxApp.MainLoop()
if __name__ == "__main__":
main(*sys.argv)