From 34d9df756bd45414a46f24cc35f43342a294144b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucio=20Andr=C3=A9s=20Illanes=20Albornoz?= Date: Fri, 6 Sep 2019 10:29:45 +0200 Subject: [PATCH] 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. --- assets/tools/MiRCARTReduce.py | 25 ++- assets/tools/MiRCARTToAnsi.py | 9 +- assets/tools/MiRCARTToPngFile.py | 9 +- assets/tools/SAUCEToAnsi.py | 11 +- assets/tools/SAUCEToMiRCART.py | 11 +- libcanvas/Canvas.py | 12 +- libcanvas/CanvasBackend.py | 93 +++----- libcanvas/CanvasExportStore.py | 95 ++++---- libcanvas/CanvasImportStore.py | 340 ++++++++-------------------- libcanvas/CanvasJournal.py | 26 +-- libcanvas/Colours.py | 32 +-- libgui/GuiCanvasInterface.py | 373 +++++++++++++++---------------- libgui/GuiFrame.py | 2 +- libtools/ToolRect.py | 2 +- roar.py | 9 +- 15 files changed, 440 insertions(+), 609 deletions(-) diff --git a/assets/tools/MiRCARTReduce.py b/assets/tools/MiRCARTReduce.py index 2637be8..e28aa99 100755 --- a/assets/tools/MiRCARTReduce.py +++ b/assets/tools/MiRCARTReduce.py @@ -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 @@ -25,15 +24,21 @@ def reduce(inPathName): if inCurCell[2] & CanvasImportStore._CellState.CS_UNDERLINE: print("\u001f", end="", file=outFile) lastAttribs = inCurCell[2] - if lastColours == None \ - or (lastColours[0] != inCurCell[:2][0] \ - and lastColours[1] != inCurCell[:2][1]): - print("\u0003{:d},{:d}{}".format(*inCurCell[:2], inCurCell[3]), end="", file=outFile) + 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) diff --git a/assets/tools/MiRCARTToAnsi.py b/assets/tools/MiRCARTToAnsi.py index c057d82..055ce39 100755 --- a/assets/tools/MiRCARTToAnsi.py +++ b/assets/tools/MiRCARTToAnsi.py @@ -18,9 +18,12 @@ def main(*argv): print("usage: {} ".format(sys.argv[0]), file=sys.stderr) else: canvasImportStore = CanvasImportStore() - canvasImportStore.importAnsiFile(argv[1]) - canvasExportStore = CanvasExportStore() - canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, sys.stdout) + 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) diff --git a/assets/tools/MiRCARTToPngFile.py b/assets/tools/MiRCARTToPngFile.py index a958b91..9ca686a 100755 --- a/assets/tools/MiRCARTToPngFile.py +++ b/assets/tools/MiRCARTToPngFile.py @@ -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) - canvasExportStore = CanvasExportStore() - canvasExportStore.exportPngFile(canvasImportStore.outMap, os.path.splitext(inFile)[0] + ".png", optdict["-f"], optdict["-s"]) + rc, error = canvasImportStore.importTextFile(inFile) + if rc: + canvasExportStore = CanvasExportStore() + 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) diff --git a/assets/tools/SAUCEToAnsi.py b/assets/tools/SAUCEToAnsi.py index cfc8301..1be0b98 100755 --- a/assets/tools/SAUCEToAnsi.py +++ b/assets/tools/SAUCEToAnsi.py @@ -18,10 +18,13 @@ def main(*argv): print("usage: {} ".format(sys.argv[0]), file=sys.stderr) else: canvasImportStore = CanvasImportStore() - canvasImportStore.importSauceFile(argv[1]) - canvasExportStore = CanvasExportStore() - with open(argv[2], "w", encoding="utf-8") as outFile: - canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile) + 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) diff --git a/assets/tools/SAUCEToMiRCART.py b/assets/tools/SAUCEToMiRCART.py index 91ee27e..f9eea10 100755 --- a/assets/tools/SAUCEToMiRCART.py +++ b/assets/tools/SAUCEToMiRCART.py @@ -18,10 +18,13 @@ def main(*argv): print("usage: {} ".format(sys.argv[0]), file=sys.stderr) else: canvasImportStore = CanvasImportStore() - canvasImportStore.importSauceFile(argv[1]) - canvasExportStore = CanvasExportStore() - with open(argv[2], "w", encoding="utf-8") as outFile: - canvasExportStore.exportTextFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile) + 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) diff --git a/libcanvas/Canvas.py b/libcanvas/Canvas.py index 215f685..0241dbb 100644 --- a/libcanvas/Canvas.py +++ b/libcanvas/Canvas.py @@ -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 diff --git a/libcanvas/CanvasBackend.py b/libcanvas/CanvasBackend.py index ed0255c..a8cb46e 100644 --- a/libcanvas/CanvasBackend.py +++ b/libcanvas/CanvasBackend.py @@ -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 diff --git a/libcanvas/CanvasExportStore.py b/libcanvas/CanvasExportStore.py index a9784bc..225f22d 100644 --- a/libcanvas/CanvasExportStore.py +++ b/libcanvas/CanvasExportStore.py @@ -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" - outFile.write(outBuffer) + 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)) - outSize = [a*b for a,b in zip(inSize, outImgFontSize)] - outCurPos = [0, 0] + outImgFontSize = [*outImgFont.getsize(" ")]; outImgFontSize[1] += 3; + outSize = [a * b for a, b in zip(inSize, outImgFontSize)] 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 diff --git a/libcanvas/CanvasImportStore.py b/libcanvas/CanvasImportStore.py index 65575a1..70d47cc 100644 --- a/libcanvas/CanvasImportStore.py +++ b/libcanvas/CanvasImportStore.py @@ -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: - 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] - 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 + 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 [int(c) for c in m[1][:-1].split(";")]: + if ansiCode == 0: + 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: + curBgAnsi, curFgAnsi, newBg, newFg = curFgAnsi, curBgAnsi, curFg, curBg + elif ansiCode in AnsiBgToMiRCARTColours: + curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode] + elif ansiCode in AnsiFgBoldToMiRCARTColours: + curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode] + 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": + done = True; inFileChar += 2; + elif inFileData[inFileChar] in set("\r\n"): + done = True; inFileChar += 1; 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; done = True; - elif inFileData[inFileChar] == "\r" \ - or inFileData[inFileChar] == "\n": - inFileChar += 1; done = True; - 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[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "]) - self.inSize, self.outMap = inSize, outMap + 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 = [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 - else: - m = re.match('\x1b\[((?:\d{1,3};?)+)m', inFileData[inFileChar:]) - 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] - 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]) + 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: + 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: + 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: - 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; - 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 + inCurColours = (15, 1) + inCurCol += len(m[0]) + else: + 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[-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) diff --git a/libcanvas/CanvasJournal.py b/libcanvas/CanvasJournal.py index 65163fc..7ac300a 100644 --- a/libcanvas/CanvasJournal.py +++ b/libcanvas/CanvasJournal.py @@ -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 diff --git a/libcanvas/Colours.py b/libcanvas/Colours.py index 213e0b3..55d949d 100644 --- a/libcanvas/Colours.py +++ b/libcanvas/Colours.py @@ -126,22 +126,22 @@ Colours = [ # }}} # {{{ MiRCARTToAnsiColours: XXX MiRCARTToAnsiColours = [ - 97, # Bright White - 30, # Black - 94, # Light Blue - 32, # Green - 91, # Red - 31, # Light Red - 35, # Pink - 33, # Yellow - 93, # Light Yellow - 92, # Light Green - 36, # Cyan - 96, # Light Cyan - 34, # Blue - 95, # Light Pink - 90, # Grey - 37, # Light Grey + 97, # Bright White + 30, # Black + 94, # Light Blue + 32, # Green + 91, # Red + 31, # Light Red + 35, # Pink + 33, # Yellow + 93, # Light Yellow + 92, # Light Green + 36, # Cyan + 96, # Light Cyan + 34, # Blue + 95, # Light Pink + 90, # Grey + 37, # Light Grey ]; # }}} diff --git a/libgui/GuiCanvasInterface.py b/libgui/GuiCanvasInterface.py index b9f8cb6..263638f 100644 --- a/libgui/GuiCanvasInterface.py +++ b/libgui/GuiCanvasInterface.py @@ -5,7 +5,7 @@ # from ToolCircle import ToolCircle -from ToolFill import ToolFill +from ToolFill import ToolFill from ToolLine import ToolLine from ToolSelectClone import ToolSelectClone from ToolSelectMove import ToolSelectMove @@ -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: + 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: 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: @@ -137,7 +233,7 @@ class GuiCanvasInterface(): else: outPathName = dialog.GetPath() self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) - self.parentCanvas.canvasExportStore.exportBitmapToPngFile( \ + self.parentCanvas.canvasExportStore.exportBitmapToPngFile( \ self.parentCanvas.canvasBackend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) return True @@ -145,28 +241,23 @@ 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): self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) - pasteStatus, pasteResult = \ - self.parentCanvas.canvasExportStore.exportPastebin( \ - "", \ - self.parentCanvas.canvasMap, \ + pasteStatus, pasteResult = \ + self.parentCanvas.canvasExportStore.exportPastebin( \ + "", \ + self.parentCanvas.canvasMap, \ self.parentCanvas.canvasSize) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) if pasteStatus: @@ -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,17 +295,21 @@ 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() - self.canvasPathName = "(Imported)" - self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) - self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1) - return True + 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): rc = False - if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \ + if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \ and wx.TheClipboard.Open(): inBuffer = wx.TextDataObject() if wx.TheClipboard.GetData(inBuffer): @@ -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() - self.canvasPathName = "(Clipboard)" - self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) - self.parentFrame.onCanvasUpdate(pathName="(Clipboard)", undoLevel=-1) - rc = True + 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) + 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() - 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: - 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) + 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 + else: + print("error: {}".format(error), file=sys.stderr) + return False # }}} + # {{{ 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): diff --git a/libgui/GuiFrame.py b/libgui/GuiFrame.py index 2031ec2..d605c62 100644 --- a/libgui/GuiFrame.py +++ b/libgui/GuiFrame.py @@ -180,7 +180,7 @@ class GuiFrame(GuiGeneralFrame): textItems.append("Current tool: {}".format( \ self.lastPanelState["toolName"])) self.statusBar.SetStatusText(" | ".join(textItems)) - if "undoLevel" in self.lastPanelState: + if "undoLevel" in self.lastPanelState: if self.lastPanelState["undoLevel"] >= 0: self.menuItemsById[self.CID_UNDO[0]].Enable(True) toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar() diff --git a/libtools/ToolRect.py b/libtools/ToolRect.py index 106f8bf..0458b83 100644 --- a/libtools/ToolRect.py +++ b/libtools/ToolRect.py @@ -28,7 +28,7 @@ class ToolRect(Tool): patch = [atPoint[0] + brushCol, atPoint[1] + brushRow, *brushColours, 0, " "] if isLeftDown or isRightDown: dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); - else: + else: dispatchFn(eventDc, True, patch) # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/roar.py b/roar.py index 7299f39..718f7ad 100755 --- a/roar.py +++ b/roar.py @@ -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() - appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1) + 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)