mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-23 07:36:37 +00:00
Implements importing from {ANSI,SAUCE} and exporting to ANSI files.
assets/tools/{MiRCARTTo{Ansi,PngFile},SAUCETo{Ansi,MiRCART}}.py: reimplemented using Canvas{Ex,Im}portStore. libcanvas/Canvas.py: minor cleanup. libcanvas/CanvasExportStore.py:export{Ansi,Png}File(): merged from assets/tools/MiRCARTTo{Ansi,PngFile}.py. libcanvas/CanvasImportStore.py:import{Ansi,Sauce}File(): merged from assets/tools/SAUCETo{Ansi,MiRCART}.py. libcanvas/Colours.py:{AnsiBgToMiRCARTColours,AnsiFgToMiRCARTColours,AnsiFgBoldToMiRCARTColours}{}: merged from assets/tools/SAUCEToMiRCART.py. libcanvas/Colours.py:{ColourMap{Bold,Normal}}[]: merged from assets/tools/MiRCARTToPngFile.py. libcanvas/Colours.py: minor cleanup. libgui/GuiCanvasInterface.py:canvas{ExportAsAnsi,Import{Ansi,Sauce}}(): implemented. libgui/GuiFrame.py: adds CID_{EXPORT_AS_{ANSI,SAUCE},IMPORT_{ANSI,SAUCE}}. assets/text/TODO: updated.
This commit is contained in:
parent
e481c8026c
commit
bffcc644f2
@ -1,15 +1,14 @@
|
|||||||
1) General {cleanup,refactor}
|
1) General {cleanup,refactor}
|
||||||
2) Incremental auto{load,save} & {backup,restore}
|
2) Implement ANSI CSI CU[BDPU] sequences
|
||||||
3) Open and toggle a reference image in the background
|
3) Incremental auto{load,save} & {backup,restore}
|
||||||
4) Client-Server or Peer-to-Peer realtime collaboration
|
4) Open and toggle a reference image in the background
|
||||||
5) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
5) Client-Server or Peer-to-Peer realtime collaboration
|
||||||
6) Hotkey & graphical interfaces to {composed,parametrised} tools
|
6) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
||||||
7) Layer, layout (e.g. for comics, zines, etc.) & {re,un}do canvas traits
|
7) Hotkey & graphical interfaces to {composed,parametrised} tools
|
||||||
8) GUI: a) scrollbar b) switch from wxPython to GTK c) revisit About dialogue
|
8) GUI: a) scrollbar b) switch from wxPython to GTK c) revisit About dialogue
|
||||||
9) {Insert,{ex,im}port}ing from/to ANSI, Blender, GIF, HTML, mIRC, printer, SAUCE, WEBM, etc. {clipboard,file}
|
9) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking}
|
||||||
10) Asset management (e.g. kade, lion, etc.) & traits w/ simple linking & synchronised editing respecting layers
|
10) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
|
||||||
11) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
|
11) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools:
|
||||||
12) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools:
|
|
||||||
a) geometric primitives (arrow, circle, cloud/speech bubble, curve, heart, hexagon, line, pentagon, polygon, rhombus, triangle, square, star)
|
a) geometric primitives (arrow, circle, cloud/speech bubble, curve, heart, hexagon, line, pentagon, polygon, rhombus, triangle, square, star)
|
||||||
b) regions (crop, duplicate, erase, fill, invert, measure, pick, rotate, scale, select, shift, slice, tile, translate)
|
b) regions (crop, duplicate, erase, fill, invert, measure, pick, rotate, scale, select, shift, slice, tile, translate)
|
||||||
c) text (edit, Unicode sets)
|
c) text (edit, Unicode sets)
|
||||||
|
@ -8,59 +8,20 @@
|
|||||||
import os, sys
|
import os, sys
|
||||||
[sys.path.append(os.path.join(os.getcwd(), "..", "..", path)) for path in ["libcanvas", "librtl"]]
|
[sys.path.append(os.path.join(os.getcwd(), "..", "..", path)) for path in ["libcanvas", "librtl"]]
|
||||||
|
|
||||||
|
from CanvasExportStore import CanvasExportStore
|
||||||
from CanvasImportStore import CanvasImportStore
|
from CanvasImportStore import CanvasImportStore
|
||||||
|
|
||||||
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
|
|
||||||
];
|
|
||||||
|
|
||||||
def ToAnsi(inPathName):
|
|
||||||
canvasStore = CanvasImportStore(inPathName)
|
|
||||||
inMap = canvasStore.outMap.copy(); del canvasStore;
|
|
||||||
with open(inPathName, "w+") as outFile:
|
|
||||||
for inCurRow in range(len(inMap)):
|
|
||||||
lastAttribs = CanvasImportStore._CellState.CS_NONE
|
|
||||||
lastColours = None
|
|
||||||
for inCurCol in range(len(inMap[inCurRow])):
|
|
||||||
inCurCell = inMap[inCurRow][inCurCol]
|
|
||||||
if lastAttribs != inCurCell[2]:
|
|
||||||
if inCurCell[2] & CanvasImportStore._CellState.CS_BOLD:
|
|
||||||
print("\u001b[1m", end="", file=outFile)
|
|
||||||
if inCurCell[2] & CanvasImportStore._CellState.CS_UNDERLINE:
|
|
||||||
print("\u001b[4m", end="", file=outFile)
|
|
||||||
lastAttribs = inCurCell[2]
|
|
||||||
if lastColours == None or lastColours != inCurCell[:2]:
|
|
||||||
ansiBg = MiRCARTToAnsiColours[int(inCurCell[1])] + 10
|
|
||||||
ansiFg = MiRCARTToAnsiColours[int(inCurCell[0])]
|
|
||||||
print("\u001b[{:02d}m\u001b[{:02d}m{}".format(ansiBg, ansiFg, inCurCell[3]), end="", file=outFile)
|
|
||||||
lastColours = inCurCell[:2]
|
|
||||||
else:
|
|
||||||
print(inCurCell[3], end="", file=outFile)
|
|
||||||
print("\u001b[0m\n", end="", file=outFile)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Entry point
|
# Entry point
|
||||||
def main(*argv):
|
def main(*argv):
|
||||||
ToAnsi(argv[1])
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if (len(sys.argv) - 1) != 1:
|
if (len(sys.argv) - 1) != 1:
|
||||||
print("usage: {} <MiRCART input file pathname>".format(sys.argv[0]), file=sys.stderr)
|
print("usage: {} <MiRCART input file pathname>".format(sys.argv[0]), file=sys.stderr)
|
||||||
else:
|
else:
|
||||||
|
canvasImportStore = CanvasImportStore()
|
||||||
|
canvasImportStore.importAnsiFile(argv[1])
|
||||||
|
canvasExportStore = CanvasExportStore()
|
||||||
|
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, sys.stdout)
|
||||||
|
if __name__ == "__main__":
|
||||||
main(*sys.argv)
|
main(*sys.argv)
|
||||||
|
|
||||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||||
|
@ -6,122 +6,11 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import os, sys
|
import os, sys
|
||||||
[sys.path.append(os.path.join(os.getcwd(), "..", "..", path)) for path in ["libcanvas", "librtl", "libtools"]]
|
[sys.path.append(os.path.join(os.getcwd(), "..", "..", path)) for path in ["libcanvas", "librtl"]]
|
||||||
|
|
||||||
|
from CanvasExportStore import CanvasExportStore
|
||||||
from CanvasImportStore import CanvasImportStore
|
from CanvasImportStore import CanvasImportStore
|
||||||
from getopt import getopt, GetoptError
|
from getopt import getopt, GetoptError
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
|
||||||
|
|
||||||
class MiRCARTToPngFile:
|
|
||||||
"""XXX"""
|
|
||||||
inFile = inFromTextFile = None
|
|
||||||
outFontFilePath = outFontSize = None
|
|
||||||
|
|
||||||
# {{{ _ColourMapBold: mIRC colour number to RGBA map given ^B (bold)
|
|
||||||
_ColourMapBold = [
|
|
||||||
[255, 255, 255], # Bright White
|
|
||||||
[85, 85, 85], # Black
|
|
||||||
[85, 85, 255], # Light Blue
|
|
||||||
[85, 255, 85], # Green
|
|
||||||
[255, 85, 85], # Red
|
|
||||||
[255, 85, 85], # Light Red
|
|
||||||
[255, 85, 255], # Pink
|
|
||||||
[255, 255, 85], # Yellow
|
|
||||||
[255, 255, 85], # Light Yellow
|
|
||||||
[85, 255, 85], # Light Green
|
|
||||||
[85, 255, 255], # Cyan
|
|
||||||
[85, 255, 255], # Light Cyan
|
|
||||||
[85, 85, 255], # Blue
|
|
||||||
[255, 85, 255], # Light Pink
|
|
||||||
[85, 85, 85], # Grey
|
|
||||||
[255, 255, 255], # Light Grey
|
|
||||||
]
|
|
||||||
# }}}
|
|
||||||
# {{{ _ColourMapNormal: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
|
|
||||||
_ColourMapNormal = [
|
|
||||||
[255, 255, 255], # Bright White
|
|
||||||
[0, 0, 0], # Black
|
|
||||||
[0, 0, 187], # Light Blue
|
|
||||||
[0, 187, 0], # Green
|
|
||||||
[255, 85, 85], # Red
|
|
||||||
[187, 0, 0], # Light Red
|
|
||||||
[187, 0, 187], # Pink
|
|
||||||
[187, 187, 0], # Yellow
|
|
||||||
[255, 255, 85], # Light Yellow
|
|
||||||
[85, 255, 85], # Light Green
|
|
||||||
[0, 187, 187], # Cyan
|
|
||||||
[85, 255, 255], # Light Cyan
|
|
||||||
[85, 85, 255], # Blue
|
|
||||||
[255, 85, 255], # Light Pink
|
|
||||||
[85, 85, 85], # Grey
|
|
||||||
[187, 187, 187], # Light Grey
|
|
||||||
]
|
|
||||||
# }}}
|
|
||||||
# {{{ _drawUnderline(self, curPos, fontSize, imgDraw, fillColour): XXX
|
|
||||||
def _drawUnderLine(self, curPos, fontSize, imgDraw, fillColour):
|
|
||||||
imgDraw.line( \
|
|
||||||
xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \
|
|
||||||
curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \
|
|
||||||
fill=fillColour)
|
|
||||||
# }}}
|
|
||||||
# {{{ export(self, outFilePath): XXX
|
|
||||||
def export(self, outFilePath):
|
|
||||||
inSize = (len(self.inCanvasMap[0]), len(self.inCanvasMap))
|
|
||||||
outSize = [a*b for a,b in zip(inSize, self.outImgFontSize)]
|
|
||||||
outCurPos = [0, 0]
|
|
||||||
outImg = Image.new("RGBA", outSize, (*self._ColourMapNormal[1], 255))
|
|
||||||
outImgDraw = ImageDraw.Draw(outImg)
|
|
||||||
outImgDraw.fontmode = "1"
|
|
||||||
for inCurRow in range(len(self.inCanvasMap)):
|
|
||||||
for inCurCol in range(len(self.inCanvasMap[inCurRow])):
|
|
||||||
inCurCell = self.inCanvasMap[inCurRow][inCurCol]
|
|
||||||
outColours = [0, 0]
|
|
||||||
if inCurCell[2] & CanvasImportStore._CellState.CS_BOLD:
|
|
||||||
if inCurCell[3] != " ":
|
|
||||||
if inCurCell[3] == "█":
|
|
||||||
outColours[1] = self._ColourMapNormal[inCurCell[0]]
|
|
||||||
else:
|
|
||||||
outColours[0] = self._ColourMapBold[inCurCell[0]]
|
|
||||||
outColours[1] = self._ColourMapNormal[inCurCell[1]]
|
|
||||||
else:
|
|
||||||
outColours[1] = self._ColourMapNormal[inCurCell[1]]
|
|
||||||
else:
|
|
||||||
if inCurCell[3] != " ":
|
|
||||||
if inCurCell[3] == "█":
|
|
||||||
outColours[1] = self._ColourMapNormal[inCurCell[0]]
|
|
||||||
else:
|
|
||||||
outColours[0] = self._ColourMapNormal[inCurCell[0]]
|
|
||||||
outColours[1] = self._ColourMapNormal[inCurCell[1]]
|
|
||||||
else:
|
|
||||||
outColours[1] = self._ColourMapNormal[inCurCell[1]]
|
|
||||||
outImgDraw.rectangle((*outCurPos, \
|
|
||||||
outCurPos[0] + self.outImgFontSize[0], \
|
|
||||||
outCurPos[1] + self.outImgFontSize[1]), \
|
|
||||||
fill=(*outColours[1], 255))
|
|
||||||
if not inCurCell[3] in " █" \
|
|
||||||
and outColours[0] != outColours[1]:
|
|
||||||
# XXX implement italic
|
|
||||||
outImgDraw.text(outCurPos, \
|
|
||||||
inCurCell[3], (*outColours[0], 255), self.outImgFont)
|
|
||||||
if inCurCell[2] & CanvasImportStore._CellState.CS_UNDERLINE:
|
|
||||||
outColours[0] = self._ColourMapNormal[inCurCell[0]]
|
|
||||||
self._drawUnderLine(outCurPos, \
|
|
||||||
self.outImgFontSize, \
|
|
||||||
outImgDraw, (*outColours[0], 255))
|
|
||||||
outCurPos[0] += self.outImgFontSize[0];
|
|
||||||
outCurPos[0] = 0
|
|
||||||
outCurPos[1] += self.outImgFontSize[1]
|
|
||||||
outImg.save(outFilePath);
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
#
|
|
||||||
# __init__(self, inCanvasMap, fontFilePath, fontSize): initialisation method
|
|
||||||
def __init__(self, inCanvasMap, fontFilePath, fontSize):
|
|
||||||
self.inCanvasMap = inCanvasMap
|
|
||||||
self.outFontFilePath, self.outFontSize = fontFilePath, fontSize
|
|
||||||
self.outImgFont = ImageFont.truetype(self.outFontFilePath, self.outFontSize)
|
|
||||||
self.outImgFontSize = [*self.outImgFont.getsize(" ")]
|
|
||||||
self.outImgFontSize[1] += 3
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Entry point
|
# Entry point
|
||||||
@ -137,8 +26,10 @@ def main(*argv):
|
|||||||
optdict["-f"] = os.path.join("..", "fonts", "DejaVuSansMono.ttf")
|
optdict["-f"] = os.path.join("..", "fonts", "DejaVuSansMono.ttf")
|
||||||
optdict["-s"] = 11 if not "-s" in optdict else int(optdict["-s"])
|
optdict["-s"] = 11 if not "-s" in optdict else int(optdict["-s"])
|
||||||
for inFile in argv:
|
for inFile in argv:
|
||||||
canvasStore, outFile = CanvasImportStore(inFile=inFile), os.path.splitext(inFile)[0] + ".png"
|
canvasImportStore = CanvasImportStore()
|
||||||
MiRCARTToPngFile(canvasStore.outMap, fontFilePath=optdict["-f"], fontSize=optdict["-s"]).export(outFile)
|
canvasImportStore.importTextFile(inFile)
|
||||||
|
canvasExportStore = CanvasExportStore()
|
||||||
|
canvasExportStore.exportPngFile(canvasImportStore.outMap, os.path.splitext(inFile)[0] + ".png", optdict["-f"], optdict["-s"])
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(*sys.argv)
|
main(*sys.argv)
|
||||||
|
|
||||||
|
@ -5,52 +5,24 @@
|
|||||||
# This project is licensed under the terms of the MIT licence.
|
# This project is licensed under the terms of the MIT licence.
|
||||||
#
|
#
|
||||||
|
|
||||||
import os, re, struct, sys
|
import os, sys
|
||||||
|
[sys.path.append(os.path.join(os.getcwd(), "..", "..", path)) for path in ["libcanvas", "librtl"]]
|
||||||
|
|
||||||
def SAUCEToAnsi(inPathName, outPathName):
|
from CanvasExportStore import CanvasExportStore
|
||||||
with open(inPathName, "rb") as inFile:
|
from CanvasImportStore import CanvasImportStore
|
||||||
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') \
|
|
||||||
or (inFile.read(1) != b'\x01'):
|
|
||||||
print("error: only character based ANSi SAUCE files are supported.", file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
width, height = struct.unpack("H", inFile.read(2))[0], struct.unpack("H", inFile.read(2))[0]
|
|
||||||
with open(outPathName, "w+") as outFile:
|
|
||||||
inFile.seek(0, 0)
|
|
||||||
inFileData, row, rowChars = inFile.read(inFileStat.st_size - 128).decode("cp437"), "", 0
|
|
||||||
inFileChar, inFileCharMax = 0, len(inFileData)
|
|
||||||
while True:
|
|
||||||
if inFileChar >= inFileCharMax:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
m = re.match('\x1b\[((?:\d{1,3};?)+)m', inFileData[inFileChar:])
|
|
||||||
if m:
|
|
||||||
row += m[0]; inFileChar += len(m[0]);
|
|
||||||
else:
|
|
||||||
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:])
|
|
||||||
if m:
|
|
||||||
row += m[0]; inFileChar += len(m[0]); rowChars += int(m[1]);
|
|
||||||
elif inFileData[inFileChar:inFileChar+2] == "\r\n":
|
|
||||||
inFileChar += 2; rowChars = width;
|
|
||||||
elif inFileData[inFileChar] == "\r" \
|
|
||||||
or inFileData[inFileChar] == "\n":
|
|
||||||
inFileChar += 1; rowChars = width;
|
|
||||||
else:
|
|
||||||
row += inFileData[inFileChar]; inFileChar += 1; rowChars += 1;
|
|
||||||
if rowChars >= width:
|
|
||||||
print(row, file=outFile); row = ""; rowChars = 0;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Entry point
|
# Entry point
|
||||||
def main(*argv):
|
def main(*argv):
|
||||||
SAUCEToAnsi(argv[1], argv[2])
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if (len(sys.argv) - 1) != 2:
|
if (len(sys.argv) - 1) != 2:
|
||||||
print("usage: {} <SAUCE input file pathname> <ANSI output file pathname>".format(sys.argv[0]), file=sys.stderr)
|
print("usage: {} <SAUCE input file pathname> <ANSI output file pathname>".format(sys.argv[0]), file=sys.stderr)
|
||||||
else:
|
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)
|
||||||
|
if __name__ == "__main__":
|
||||||
main(*sys.argv)
|
main(*sys.argv)
|
||||||
|
|
||||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||||
|
@ -5,146 +5,24 @@
|
|||||||
# This project is licensed under the terms of the MIT licence.
|
# This project is licensed under the terms of the MIT licence.
|
||||||
#
|
#
|
||||||
|
|
||||||
import os, re, struct, sys
|
import os, sys
|
||||||
|
[sys.path.append(os.path.join(os.getcwd(), "..", "..", path)) for path in ["libcanvas", "librtl"]]
|
||||||
|
|
||||||
AnsiBgToMiRCARTColours = {
|
from CanvasExportStore import CanvasExportStore
|
||||||
107: 0, # Bright White
|
from CanvasImportStore import CanvasImportStore
|
||||||
40: 1, # Black
|
|
||||||
104: 2, # Blue
|
|
||||||
42: 3, # Green
|
|
||||||
101: 4, # Red
|
|
||||||
41: 5, # Light Red
|
|
||||||
45: 6, # Pink
|
|
||||||
43: 7, # Yellow
|
|
||||||
103: 8, # Light Yellow
|
|
||||||
102: 9, # Light Green
|
|
||||||
46: 10, # Cyan
|
|
||||||
106: 11, # Light Cyan
|
|
||||||
44: 12, # Light Blue
|
|
||||||
105: 13, # Light Pink
|
|
||||||
100: 14, # Grey
|
|
||||||
47: 15, # Light Grey
|
|
||||||
};
|
|
||||||
|
|
||||||
AnsiFgToMiRCARTColours = {
|
|
||||||
97: 0, # Bright White
|
|
||||||
30: 1, # Black
|
|
||||||
94: 2, # Blue
|
|
||||||
32: 3, # Green
|
|
||||||
91: 4, # Red
|
|
||||||
31: 5, # Light Red
|
|
||||||
35: 6, # Pink
|
|
||||||
33: 7, # Yellow
|
|
||||||
93: 8, # Light Yellow
|
|
||||||
92: 9, # Light Green
|
|
||||||
36: 10, # Cyan
|
|
||||||
96: 11, # Light Cyan
|
|
||||||
34: 12, # Light Blue
|
|
||||||
95: 13, # Light Pink
|
|
||||||
90: 14, # Grey
|
|
||||||
37: 15, # Light Grey
|
|
||||||
};
|
|
||||||
|
|
||||||
AnsiFgBoldToMiRCARTColours = {
|
|
||||||
97: 0, # Bright White
|
|
||||||
30: 14, # Grey
|
|
||||||
94: 12, # Light Blue
|
|
||||||
32: 9, # Light Green
|
|
||||||
91: 4, # Light Red
|
|
||||||
31: 4, # Light Red
|
|
||||||
35: 13, # Light Pink
|
|
||||||
33: 8, # Light Yellow
|
|
||||||
93: 8, # Light Yellow
|
|
||||||
92: 9, # Light Green
|
|
||||||
36: 11, # Light Cyan
|
|
||||||
96: 11, # Light Cyan
|
|
||||||
34: 12, # Light Blue
|
|
||||||
95: 13, # Light Pink
|
|
||||||
90: 14, # Grey
|
|
||||||
37: 0, # Bright White
|
|
||||||
};
|
|
||||||
|
|
||||||
def SAUCEToMiRCART(inPathName, outPathName):
|
|
||||||
with open(inPathName, "rb") as inFile:
|
|
||||||
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') \
|
|
||||||
or (inFile.read(1) != b'\x01'):
|
|
||||||
print("error: only character based ANSi SAUCE files are supported.", file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
width, height = struct.unpack("H", inFile.read(2))[0], struct.unpack("H", inFile.read(2))[0]
|
|
||||||
with open(outPathName, "w+") as outFile:
|
|
||||||
inFile.seek(0, 0)
|
|
||||||
inFileData, row, rowChars = inFile.read(inFileStat.st_size - 128).decode("cp437"), "", 0
|
|
||||||
inFileChar, inFileCharMax = 0, len(inFileData)
|
|
||||||
curBg, curFg = 1, 15; 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)):
|
|
||||||
row += "\u0016"; curBg, curFg = newBg, newFg;
|
|
||||||
elif ((newBg != -1) and (newFg != -1)) \
|
|
||||||
and ((newBg != curBg) and (newFg != curFg)):
|
|
||||||
row += "\u0003{},{}".format(newFg, newBg); curBg, curFg = newBg, newFg;
|
|
||||||
elif (newBg != -1) and (newBg != curBg):
|
|
||||||
row += "\u0003{},{}".format(curFg, newBg); curBg = newBg;
|
|
||||||
elif (newFg != -1) and (newFg != curFg):
|
|
||||||
row += "\u0003{}".format(newFg); curFg = newFg;
|
|
||||||
inFileChar += len(m[0])
|
|
||||||
else:
|
|
||||||
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:])
|
|
||||||
if m:
|
|
||||||
row += m[0]; inFileChar += len(m[0]); rowChars += int(m[1]);
|
|
||||||
elif inFileData[inFileChar:inFileChar+2] == "\r\n":
|
|
||||||
inFileChar += 2; rowChars = width;
|
|
||||||
elif inFileData[inFileChar] == "\r" \
|
|
||||||
or inFileData[inFileChar] == "\n":
|
|
||||||
inFileChar += 1; rowChars = width;
|
|
||||||
else:
|
|
||||||
row += inFileData[inFileChar]; inFileChar += 1; rowChars += 1;
|
|
||||||
if rowChars >= width:
|
|
||||||
print(row, file=outFile); row = ""; rowChars = 0;
|
|
||||||
if (curBg != 1) and (curFg != 15):
|
|
||||||
row += "\u0003{},{}".format(curFg, curBg);
|
|
||||||
elif curBg != 1:
|
|
||||||
row += "\u0003{},{}".format(curFg, curBg);
|
|
||||||
elif curFg != 1:
|
|
||||||
row += "\u0003{}".format(curFg);
|
|
||||||
#
|
#
|
||||||
# Entry point
|
# Entry point
|
||||||
def main(*argv):
|
def main(*argv):
|
||||||
SAUCEToMiRCART(argv[1], argv[2])
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if (len(sys.argv) - 1) != 2:
|
if (len(sys.argv) - 1) != 2:
|
||||||
print("usage: {} <SAUCE input file pathname> <mIRC art output file pathname>".format(sys.argv[0]), file=sys.stderr)
|
print("usage: {} <SAUCE input file pathname> <mIRC art output file pathname>".format(sys.argv[0]), file=sys.stderr)
|
||||||
else:
|
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)
|
||||||
|
if __name__ == "__main__":
|
||||||
main(*sys.argv)
|
main(*sys.argv)
|
||||||
|
|
||||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
from CanvasBackend import CanvasBackend
|
from CanvasBackend import CanvasBackend
|
||||||
from CanvasJournal import CanvasJournal
|
from CanvasJournal import CanvasJournal
|
||||||
from CanvasExportStore import CanvasExportStore, haveToPngFile, haveUrllib
|
from CanvasExportStore import CanvasExportStore, havePIL, haveUrllib
|
||||||
from CanvasImportStore import CanvasImportStore
|
from CanvasImportStore import CanvasImportStore
|
||||||
from ImgurApiKey import ImgurApiKey
|
from ImgurApiKey import ImgurApiKey
|
||||||
import wx
|
import wx
|
||||||
@ -183,7 +183,7 @@ class Canvas(wx.Panel):
|
|||||||
|
|
||||||
self.canvasBackend = CanvasBackend(defaultCanvasSize, defaultCellSize)
|
self.canvasBackend = CanvasBackend(defaultCanvasSize, defaultCellSize)
|
||||||
self.canvasJournal = CanvasJournal()
|
self.canvasJournal = CanvasJournal()
|
||||||
self.canvasExportStore = CanvasExportStore(parentCanvas=self)
|
self.canvasExportStore = CanvasExportStore()
|
||||||
self.canvasImportStore = CanvasImportStore(parentCanvas=self)
|
self.canvasImportStore = CanvasImportStore(parentCanvas=self)
|
||||||
self.canvasInterface = canvasInterface(self, parentFrame)
|
self.canvasInterface = canvasInterface(self, parentFrame)
|
||||||
|
|
||||||
|
@ -4,13 +4,14 @@
|
|||||||
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from Colours import ColourMapBold, ColourMapNormal, MiRCARTToAnsiColours
|
||||||
import io, os, tempfile
|
import io, os, tempfile
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ToPngFile import ToPngFile
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
haveToPngFile = True
|
havePIL = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
haveToPngFile = False
|
havePIL = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import base64, json, requests, urllib.request
|
import base64, json, requests, urllib.request
|
||||||
@ -20,9 +21,23 @@ except ImportError:
|
|||||||
|
|
||||||
class CanvasExportStore():
|
class CanvasExportStore():
|
||||||
"""XXX"""
|
"""XXX"""
|
||||||
|
# {{{ _CellState(): Cell state
|
||||||
|
class _CellState():
|
||||||
|
CS_NONE = 0x00
|
||||||
|
CS_BOLD = 0x01
|
||||||
|
CS_ITALIC = 0x02
|
||||||
|
CS_UNDERLINE = 0x04
|
||||||
|
# }}}
|
||||||
ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
|
ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
|
||||||
PastebinPostUrl = "https://pastebin.com/api/api_post.php"
|
PastebinPostUrl = "https://pastebin.com/api/api_post.php"
|
||||||
|
|
||||||
|
# {{{ _drawUnderline(self, curPos, fontSize, imgDraw, fillColour): XXX
|
||||||
|
def _drawUnderLine(self, curPos, fontSize, imgDraw, fillColour):
|
||||||
|
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
|
# {{{ _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName): upload single PNG file to Imgur
|
||||||
def _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName):
|
def _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName):
|
||||||
with open(pathName, "rb") as requestImage:
|
with open(pathName, "rb") as requestImage:
|
||||||
@ -42,6 +57,30 @@ class CanvasExportStore():
|
|||||||
return [responseHttp.status_code, ""]
|
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
|
||||||
|
for inCurCol in range(len(canvasMap[inCurRow])):
|
||||||
|
inCurCell = canvasMap[inCurRow][inCurCol]
|
||||||
|
if lastAttribs != inCurCell[2]:
|
||||||
|
if inCurCell[2] & self._CellState.CS_BOLD:
|
||||||
|
outBuffer += "\u001b[1m"
|
||||||
|
if inCurCell[2] & self._CellState.CS_UNDERLINE:
|
||||||
|
outBuffer += "\u001b[4m"
|
||||||
|
lastAttribs = inCurCell[2]
|
||||||
|
if lastColours == None or lastColours != inCurCell[:2]:
|
||||||
|
ansiBg = MiRCARTToAnsiColours[int(inCurCell[1])] + 10
|
||||||
|
ansiFg = MiRCARTToAnsiColours[int(inCurCell[0])]
|
||||||
|
outBuffer += "\u001b[{:02d}m\u001b[{:02d}m{}".format(ansiBg, ansiFg, inCurCell[3])
|
||||||
|
lastColours = inCurCell[:2]
|
||||||
|
else:
|
||||||
|
outBuffer += inCurCell[3]
|
||||||
|
outBuffer += "\u001b[0m\n"
|
||||||
|
outFile.write(outBuffer)
|
||||||
|
# }}}
|
||||||
# {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): XXX
|
# {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): XXX
|
||||||
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
|
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
|
||||||
tmpPathName = tempfile.mkstemp()
|
tmpPathName = tempfile.mkstemp()
|
||||||
@ -77,10 +116,53 @@ class CanvasExportStore():
|
|||||||
else:
|
else:
|
||||||
return (False, "missing requests and/or urllib3 module(s)")
|
return (False, "missing requests and/or urllib3 module(s)")
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ exportPngFile(self, canvasMap, outPathName): XXX
|
# {{{ exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize): XXX
|
||||||
def exportPngFile(self, canvasMap, outPathName):
|
def exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize):
|
||||||
if haveToPngFile:
|
if havePIL:
|
||||||
ToPngFile(canvasMap).export(outPathName)
|
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]
|
||||||
|
outImg = Image.new("RGBA", outSize, (*ColourMapNormal[1], 255))
|
||||||
|
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]
|
||||||
|
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]]
|
||||||
|
else:
|
||||||
|
outColours[1] = ColourMapNormal[inCurCell[1]]
|
||||||
|
else:
|
||||||
|
if inCurCell[3] != " ":
|
||||||
|
if inCurCell[3] == "█":
|
||||||
|
outColours[1] = ColourMapNormal[inCurCell[0]]
|
||||||
|
else:
|
||||||
|
outColours[0] = ColourMapNormal[inCurCell[0]]
|
||||||
|
outColours[1] = ColourMapNormal[inCurCell[1]]
|
||||||
|
else:
|
||||||
|
outColours[1] = ColourMapNormal[inCurCell[1]]
|
||||||
|
outImgDraw.rectangle((*outCurPos, outCurPos[0] + outImgFontSize[0], outCurPos[1] + outImgFontSize[1]), fill=(*outColours[1], 255))
|
||||||
|
if not inCurCell[3] in " █" \
|
||||||
|
and outColours[0] != outColours[1]:
|
||||||
|
# XXX implement italic
|
||||||
|
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))
|
||||||
|
outCurPos[0] += outImgFontSize[0];
|
||||||
|
outCurPos[0] = 0
|
||||||
|
outCurPos[1] += outImgFontSize[1]
|
||||||
|
outImg.save(outPathName);
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@ -117,9 +199,4 @@ class CanvasExportStore():
|
|||||||
outFile.write(outBuffer)
|
outFile.write(outBuffer)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
#
|
|
||||||
# __init__(self, parentCanvas): initialisation method
|
|
||||||
def __init__(self, parentCanvas):
|
|
||||||
self.parentCanvas = parentCanvas
|
|
||||||
|
|
||||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||||
|
@ -5,23 +5,24 @@
|
|||||||
# This project is licensed under the terms of the MIT licence.
|
# This project is licensed under the terms of the MIT licence.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from Colours import AnsiBgToMiRCARTColours, AnsiFgToMiRCARTColours, AnsiFgBoldToMiRCARTColours
|
||||||
|
import os, re, struct, sys
|
||||||
|
|
||||||
class CanvasImportStore():
|
class CanvasImportStore():
|
||||||
"""XXX"""
|
"""XXX"""
|
||||||
|
# {{{ _CellState(): Cell state
|
||||||
#
|
|
||||||
# _CellState(): Cell state
|
|
||||||
class _CellState():
|
class _CellState():
|
||||||
CS_NONE = 0x00
|
CS_NONE = 0x00
|
||||||
CS_BOLD = 0x01
|
CS_BOLD = 0x01
|
||||||
CS_ITALIC = 0x02
|
CS_ITALIC = 0x02
|
||||||
CS_UNDERLINE = 0x04
|
CS_UNDERLINE = 0x04
|
||||||
|
# }}}
|
||||||
#
|
# {{{ _ParseState(): Parsing loop state
|
||||||
# _ParseState(): Parsing loop state
|
|
||||||
class _ParseState():
|
class _ParseState():
|
||||||
PS_CHAR = 1
|
PS_CHAR = 1
|
||||||
PS_COLOUR_DIGIT0 = 2
|
PS_COLOUR_DIGIT0 = 2
|
||||||
PS_COLOUR_DIGIT1 = 3
|
PS_COLOUR_DIGIT1 = 3
|
||||||
|
# }}}
|
||||||
|
|
||||||
# {{{ _flipCellStateBit(self, cellState, bit): XXX
|
# {{{ _flipCellStateBit(self, cellState, bit): XXX
|
||||||
def _flipCellStateBit(self, cellState, bit):
|
def _flipCellStateBit(self, cellState, bit):
|
||||||
@ -41,6 +42,77 @@ class CanvasImportStore():
|
|||||||
return (15, 1)
|
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
|
||||||
|
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:])
|
||||||
|
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])
|
||||||
|
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
|
||||||
|
# }}}
|
||||||
# {{{ importIntoPanel(self): XXX
|
# {{{ importIntoPanel(self): XXX
|
||||||
def importIntoPanel(self):
|
def importIntoPanel(self):
|
||||||
self.parentCanvas.onStoreUpdate(self.inSize, self.outMap)
|
self.parentCanvas.onStoreUpdate(self.inSize, self.outMap)
|
||||||
@ -52,6 +124,81 @@ class CanvasImportStore():
|
|||||||
for y in range(newCanvasSize[1])]
|
for y in range(newCanvasSize[1])]
|
||||||
self.parentCanvas.onStoreUpdate(newCanvasSize, newMap)
|
self.parentCanvas.onStoreUpdate(newCanvasSize, newMap)
|
||||||
# }}}
|
# }}}
|
||||||
|
# {{{ 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])
|
||||||
|
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
|
||||||
|
# }}}
|
||||||
# {{{ importTextFile(self, pathName): XXX
|
# {{{ importTextFile(self, pathName): XXX
|
||||||
def importTextFile(self, pathName):
|
def importTextFile(self, pathName):
|
||||||
return self.importTextFileBuffer(open(pathName, "r", encoding="utf-8-sig"))
|
return self.importTextFileBuffer(open(pathName, "r", encoding="utf-8-sig"))
|
||||||
|
@ -4,9 +4,107 @@
|
|||||||
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
# {{{ AnsiBgToMiRCARTColours: XXX
|
||||||
# Colours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline],
|
AnsiBgToMiRCARTColours = {
|
||||||
#
|
107: 0, # Bright White
|
||||||
|
40: 1, # Black
|
||||||
|
104: 2, # Blue
|
||||||
|
42: 3, # Green
|
||||||
|
101: 4, # Red
|
||||||
|
41: 5, # Light Red
|
||||||
|
45: 6, # Pink
|
||||||
|
43: 7, # Yellow
|
||||||
|
103: 8, # Light Yellow
|
||||||
|
102: 9, # Light Green
|
||||||
|
46: 10, # Cyan
|
||||||
|
106: 11, # Light Cyan
|
||||||
|
44: 12, # Light Blue
|
||||||
|
105: 13, # Light Pink
|
||||||
|
100: 14, # Grey
|
||||||
|
47: 15, # Light Grey
|
||||||
|
};
|
||||||
|
# }}}
|
||||||
|
# {{{ AnsiFgBoldToMiRCARTColours: XXX
|
||||||
|
AnsiFgBoldToMiRCARTColours = {
|
||||||
|
97: 0, # Bright White
|
||||||
|
30: 14, # Grey
|
||||||
|
94: 12, # Light Blue
|
||||||
|
32: 9, # Light Green
|
||||||
|
91: 4, # Light Red
|
||||||
|
31: 4, # Light Red
|
||||||
|
35: 13, # Light Pink
|
||||||
|
33: 8, # Light Yellow
|
||||||
|
93: 8, # Light Yellow
|
||||||
|
92: 9, # Light Green
|
||||||
|
36: 11, # Light Cyan
|
||||||
|
96: 11, # Light Cyan
|
||||||
|
34: 12, # Light Blue
|
||||||
|
95: 13, # Light Pink
|
||||||
|
90: 14, # Grey
|
||||||
|
37: 0, # Bright White
|
||||||
|
};
|
||||||
|
# }}}
|
||||||
|
# {{{ AnsiFgToMiRCARTColours: XXX
|
||||||
|
AnsiFgToMiRCARTColours = {
|
||||||
|
97: 0, # Bright White
|
||||||
|
30: 1, # Black
|
||||||
|
94: 2, # Blue
|
||||||
|
32: 3, # Green
|
||||||
|
91: 4, # Red
|
||||||
|
31: 5, # Light Red
|
||||||
|
35: 6, # Pink
|
||||||
|
33: 7, # Yellow
|
||||||
|
93: 8, # Light Yellow
|
||||||
|
92: 9, # Light Green
|
||||||
|
36: 10, # Cyan
|
||||||
|
96: 11, # Light Cyan
|
||||||
|
34: 12, # Light Blue
|
||||||
|
95: 13, # Light Pink
|
||||||
|
90: 14, # Grey
|
||||||
|
37: 15, # Light Grey
|
||||||
|
};
|
||||||
|
# }}}
|
||||||
|
# {{{ ColourMapBold: mIRC colour number to RGBA map given ^B (bold)
|
||||||
|
ColourMapBold = [
|
||||||
|
[255, 255, 255], # Bright White
|
||||||
|
[85, 85, 85], # Black
|
||||||
|
[85, 85, 255], # Light Blue
|
||||||
|
[85, 255, 85], # Green
|
||||||
|
[255, 85, 85], # Red
|
||||||
|
[255, 85, 85], # Light Red
|
||||||
|
[255, 85, 255], # Pink
|
||||||
|
[255, 255, 85], # Yellow
|
||||||
|
[255, 255, 85], # Light Yellow
|
||||||
|
[85, 255, 85], # Light Green
|
||||||
|
[85, 255, 255], # Cyan
|
||||||
|
[85, 255, 255], # Light Cyan
|
||||||
|
[85, 85, 255], # Blue
|
||||||
|
[255, 85, 255], # Light Pink
|
||||||
|
[85, 85, 85], # Grey
|
||||||
|
[255, 255, 255], # Light Grey
|
||||||
|
]
|
||||||
|
# }}}
|
||||||
|
# {{{ ColourMapNormal: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
|
||||||
|
ColourMapNormal = [
|
||||||
|
[255, 255, 255], # Bright White
|
||||||
|
[0, 0, 0], # Black
|
||||||
|
[0, 0, 187], # Light Blue
|
||||||
|
[0, 187, 0], # Green
|
||||||
|
[255, 85, 85], # Red
|
||||||
|
[187, 0, 0], # Light Red
|
||||||
|
[187, 0, 187], # Pink
|
||||||
|
[187, 187, 0], # Yellow
|
||||||
|
[255, 255, 85], # Light Yellow
|
||||||
|
[85, 255, 85], # Light Green
|
||||||
|
[0, 187, 187], # Cyan
|
||||||
|
[85, 255, 255], # Light Cyan
|
||||||
|
[85, 85, 255], # Blue
|
||||||
|
[255, 85, 255], # Light Pink
|
||||||
|
[85, 85, 85], # Grey
|
||||||
|
[187, 187, 187], # Light Grey
|
||||||
|
]
|
||||||
|
# }}}
|
||||||
|
# {{{ Colours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline],
|
||||||
Colours = [
|
Colours = [
|
||||||
[255, 255, 255, 255, "White"],
|
[255, 255, 255, 255, "White"],
|
||||||
[0, 0, 0, 255, "Black"],
|
[0, 0, 0, 255, "Black"],
|
||||||
@ -24,6 +122,27 @@ Colours = [
|
|||||||
[255, 85, 255, 255, "Pink"],
|
[255, 85, 255, 255, "Pink"],
|
||||||
[85, 85, 85, 255, "Grey"],
|
[85, 85, 85, 255, "Grey"],
|
||||||
[187, 187, 187, 255, "Light Grey"],
|
[187, 187, 187, 255, "Light Grey"],
|
||||||
]
|
];
|
||||||
|
# }}}
|
||||||
|
# {{{ 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
|
||||||
|
];
|
||||||
|
# }}}
|
||||||
|
|
||||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||||
|
@ -115,9 +115,22 @@ class GuiCanvasInterface():
|
|||||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||||
return True
|
return True
|
||||||
# }}}
|
# }}}
|
||||||
|
# {{{ 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:
|
||||||
|
if dialog.ShowModal() == wx.ID_CANCEL:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
outPathName = dialog.GetPath()
|
||||||
|
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||||
|
with open(outPathName, "w", encoding="utf-8") as outFile:
|
||||||
|
self.parentCanvas.canvasExportStore.exportAnsiFile(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize, outFile)
|
||||||
|
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||||
|
return True
|
||||||
|
# }}}
|
||||||
# {{{ canvasExportAsPng(self, event): XXX
|
# {{{ canvasExportAsPng(self, event): XXX
|
||||||
def canvasExportAsPng(self, event):
|
def canvasExportAsPng(self, event):
|
||||||
with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "*.png", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
|
with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "PNG (*.png)|*.png|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
|
||||||
if dialog.ShowModal() == wx.ID_CANCEL:
|
if dialog.ShowModal() == wx.ID_CANCEL:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
@ -166,6 +179,29 @@ class GuiCanvasInterface():
|
|||||||
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, \
|
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, \
|
||||||
"Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION)
|
"Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION)
|
||||||
# }}}
|
# }}}
|
||||||
|
# {{{ canvasImportAnsi(self, event): XXX
|
||||||
|
def canvasImportAnsi(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(), "", "ANSI files (*.ans;*.txt)|*.ans;*.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))
|
||||||
|
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
|
||||||
|
# }}}
|
||||||
# {{{ canvasImportFromClipboard(self, event): XXX
|
# {{{ canvasImportFromClipboard(self, event): XXX
|
||||||
def canvasImportFromClipboard(self, event):
|
def canvasImportFromClipboard(self, event):
|
||||||
rc = False
|
rc = False
|
||||||
@ -193,6 +229,29 @@ class GuiCanvasInterface():
|
|||||||
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:
|
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:
|
||||||
dialog.ShowModal()
|
dialog.ShowModal()
|
||||||
# }}}
|
# }}}
|
||||||
|
# {{{ canvasImportSauce(self, event): XXX
|
||||||
|
def canvasImportSauce(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(), "", "SAUCE files (*.ans;*.txt)|*.ans;*.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))
|
||||||
|
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
|
# {{{ canvasIncrBrushHeight(self, event): XXX
|
||||||
def canvasIncrBrushHeight(self, event):
|
def canvasIncrBrushHeight(self, event):
|
||||||
self.parentCanvas.brushSize[1] += 1
|
self.parentCanvas.brushSize[1] += 1
|
||||||
@ -253,12 +312,12 @@ class GuiCanvasInterface():
|
|||||||
pass
|
pass
|
||||||
elif saveChanges == wx.ID_YES:
|
elif saveChanges == wx.ID_YES:
|
||||||
self.canvasSave(event)
|
self.canvasSave(event)
|
||||||
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", \
|
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
|
||||||
"*.txt", wx.FD_OPEN) as dialog:
|
|
||||||
if dialog.ShowModal() == wx.ID_CANCEL:
|
if dialog.ShowModal() == wx.ID_CANCEL:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.canvasPathName = dialog.GetPath()
|
self.canvasPathName = dialog.GetPath()
|
||||||
|
print(self.canvasPathName)
|
||||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||||
self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
|
self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
|
||||||
self.parentCanvas.canvasImportStore.importIntoPanel()
|
self.parentCanvas.canvasImportStore.importIntoPanel()
|
||||||
@ -282,7 +341,7 @@ class GuiCanvasInterface():
|
|||||||
if self.canvasSaveAs(event) == False:
|
if self.canvasSaveAs(event) == False:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
with open(self.canvasPathName, "w") as outFile:
|
with open(self.canvasPathName, "w", encoding="utf-8") as outFile:
|
||||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||||
self.parentCanvas.canvasExportStore.exportTextFile( \
|
self.parentCanvas.canvasExportStore.exportTextFile( \
|
||||||
self.parentCanvas.canvasMap, \
|
self.parentCanvas.canvasMap, \
|
||||||
@ -294,8 +353,7 @@ class GuiCanvasInterface():
|
|||||||
# }}}
|
# }}}
|
||||||
# {{{ canvasSaveAs(self, event): XXX
|
# {{{ canvasSaveAs(self, event): XXX
|
||||||
def canvasSaveAs(self, event):
|
def canvasSaveAs(self, event):
|
||||||
with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", \
|
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:
|
||||||
"*.txt", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
|
|
||||||
if dialog.ShowModal() == wx.ID_CANCEL:
|
if dialog.ShowModal() == wx.ID_CANCEL:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -26,11 +26,14 @@ class GuiFrame(GuiGeneralFrame):
|
|||||||
CID_SAVE = [0x0102, TID_COMMAND, "Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None, GuiCanvasInterface.canvasSave]
|
CID_SAVE = [0x0102, TID_COMMAND, "Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None, GuiCanvasInterface.canvasSave]
|
||||||
CID_SAVEAS = [0x0103, TID_COMMAND, "Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None, GuiCanvasInterface.canvasSaveAs]
|
CID_SAVEAS = [0x0103, TID_COMMAND, "Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None, GuiCanvasInterface.canvasSaveAs]
|
||||||
CID_EXPORT_CLIPB = [0x0104, TID_COMMAND, "Export to clipboard", "&Export to clipboard", None, None, None, GuiCanvasInterface.canvasExportToClipboard]
|
CID_EXPORT_CLIPB = [0x0104, TID_COMMAND, "Export to clipboard", "&Export to clipboard", None, None, None, GuiCanvasInterface.canvasExportToClipboard]
|
||||||
CID_EXPORT_AS_PNG = [0x0105, TID_COMMAND, "Export as PNG...", "Export as PN&G...", None, None, None, GuiCanvasInterface.canvasExportAsPng]
|
CID_EXPORT_AS_ANSI = [0x0105, TID_COMMAND, "Export as ANSI...", "Export as ANSI...", None, None, None, GuiCanvasInterface.canvasExportAsAnsi]
|
||||||
CID_EXPORT_IMGUR = [0x0106, TID_COMMAND, "Export to Imgur...", "Export to I&mgur...", None, None, haveUrllib, GuiCanvasInterface.canvasExportImgur]
|
CID_EXPORT_AS_PNG = [0x0106, TID_COMMAND, "Export as PNG...", "Export as PN&G...", None, None, None, GuiCanvasInterface.canvasExportAsPng]
|
||||||
CID_EXPORT_PASTEBIN = [0x0107, TID_COMMAND, "Export to Pastebin...", "Export to Pasteb&in...", None, None, haveUrllib, GuiCanvasInterface.canvasExportPastebin]
|
CID_EXPORT_IMGUR = [0x0107, TID_COMMAND, "Export to Imgur...", "Export to I&mgur...", None, None, haveUrllib, GuiCanvasInterface.canvasExportImgur]
|
||||||
CID_IMPORT_CLIPB = [0x0108, TID_COMMAND, "Import from clipboard", "&Import from clipboard", None, None, None, GuiCanvasInterface.canvasImportFromClipboard]
|
CID_EXPORT_PASTEBIN = [0x0108, TID_COMMAND, "Export to Pastebin...", "Export to Pasteb&in...", None, None, haveUrllib, GuiCanvasInterface.canvasExportPastebin]
|
||||||
CID_EXIT = [0x0109, TID_COMMAND, "Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None, GuiCanvasInterface.canvasExit]
|
CID_IMPORT_ANSI = [0x0109, TID_COMMAND, "Import ANSI...", "Import ANSI...", None, None, None, GuiCanvasInterface.canvasImportAnsi]
|
||||||
|
CID_IMPORT_CLIPB = [0x010a, TID_COMMAND, "Import from clipboard", "&Import from clipboard", None, None, None, GuiCanvasInterface.canvasImportFromClipboard]
|
||||||
|
CID_IMPORT_SAUCE = [0x010b, TID_COMMAND, "Import SAUCE...", "Import SAUCE...", None, None, None, GuiCanvasInterface.canvasImportSauce]
|
||||||
|
CID_EXIT = [0x010c, TID_COMMAND, "Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None, GuiCanvasInterface.canvasExit]
|
||||||
|
|
||||||
#
|
#
|
||||||
# MID_EDIT
|
# MID_EDIT
|
||||||
@ -92,7 +95,7 @@ class GuiFrame(GuiGeneralFrame):
|
|||||||
CID_ABOUT = [0x0500, TID_COMMAND, "About", "&About", None, None, True, GuiCanvasInterface.canvasAbout]
|
CID_ABOUT = [0x0500, TID_COMMAND, "About", "&About", None, None, True, GuiCanvasInterface.canvasAbout]
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ Menus (0x1100-0x1fff)
|
# {{{ Menus (0x1100-0x1fff)
|
||||||
MID_FILE = (0x1100, TID_MENU, "File", "&File", (CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_MENU_SEP, CID_EXPORT_CLIPB, CID_EXPORT_AS_PNG, CID_EXPORT_IMGUR, CID_EXPORT_PASTEBIN, NID_MENU_SEP, CID_IMPORT_CLIPB, NID_MENU_SEP, CID_EXIT))
|
MID_FILE = (0x1100, TID_MENU, "File", "&File", (CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_MENU_SEP, CID_EXPORT_AS_ANSI, CID_EXPORT_CLIPB, CID_EXPORT_IMGUR, CID_EXPORT_PASTEBIN, CID_EXPORT_AS_PNG, NID_MENU_SEP, CID_IMPORT_ANSI, CID_IMPORT_CLIPB, CID_IMPORT_SAUCE, NID_MENU_SEP, CID_EXIT))
|
||||||
MID_EDIT = (0x1101, TID_MENU, "Edit", "&Edit", (CID_UNDO, CID_REDO, NID_MENU_SEP, CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_MENU_SEP, CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_MENU_SEP, CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_MENU_SEP, CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_MENU_SEP, CID_INCRHW_BRUSH, CID_DECRHW_BRUSH, NID_MENU_SEP, CID_SOLID_BRUSH))
|
MID_EDIT = (0x1101, TID_MENU, "Edit", "&Edit", (CID_UNDO, CID_REDO, NID_MENU_SEP, CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_MENU_SEP, CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_MENU_SEP, CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_MENU_SEP, CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_MENU_SEP, CID_INCRHW_BRUSH, CID_DECRHW_BRUSH, NID_MENU_SEP, CID_SOLID_BRUSH))
|
||||||
MID_TOOLS = (0x1102, TID_MENU, "Tools", "&Tools", (CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT))
|
MID_TOOLS = (0x1102, TID_MENU, "Tools", "&Tools", (CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT))
|
||||||
MID_HELP = (0x1103, TID_MENU, "Help", "&Help", (CID_ABOUT,))
|
MID_HELP = (0x1103, TID_MENU, "Help", "&Help", (CID_ABOUT,))
|
||||||
|
Loading…
Reference in New Issue
Block a user