chiark / gitweb /
Merge pull request #724 from Dim3nsioneer/SteamEngine
[cura.git] / Cura / gui / util / gcodeTextArea.py
1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
2
3 import wx
4 import wx.stc
5 import sys
6
7 from Cura.util import profile
8
9 class GcodeTextArea(wx.stc.StyledTextCtrl):
10         def __init__(self, parent):
11                 super(GcodeTextArea, self).__init__(parent)
12
13                 self.SetLexer(wx.stc.STC_LEX_CONTAINER)
14                 self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyle)
15         
16                 fontSize = wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize()
17                 fontName = wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL).GetFaceName()
18                 self.SetStyleBits(5)
19                 self.StyleSetSpec(0, "face:%s,size:%d" % (fontName, fontSize))
20                 self.StyleSetSpec(1, "fore:#006000,face:%s,size:%d" % (fontName, fontSize))
21                 self.IndicatorSetStyle(0, wx.stc.STC_INDIC_TT)
22                 self.IndicatorSetForeground(0, "#0000FF")
23                 self.IndicatorSetStyle(1, wx.stc.STC_INDIC_SQUIGGLE)
24                 self.IndicatorSetForeground(1, "#FF0000")
25                 self.SetWrapMode(wx.stc.STC_WRAP_NONE)
26                 self.SetScrollWidth(1000)
27                 if sys.platform == 'darwin':
28                         self.Bind(wx.EVT_KEY_DOWN, self.OnMacKeyDown)
29         
30                 #GCodes and MCodes as supported by Marlin
31                 #GCode 21 is not really supported by Marlin, but we still do not report it as error as it's often used.
32                 self.supportedGCodes = [0,1,2,3,4,21,28,90,91,92]
33                 self.supportedMCodes = [17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,42,80,81,82,83,84,85,92,104,105,106,107,109,114,115,117,119,140,190,201,202,203,204,205,206,220,221,240,301,302,303,400,500,501,502,503,999]
34         
35         def OnMacKeyDown(self, e):
36                 code = e.GetKeyCode();
37                 stopPropagation = True
38                 #Command
39                 if e.CmdDown():
40                         if code == wx._core.WXK_LEFT:
41                                 self.GotoLine(self.GetCurrentLine())
42                         elif code == wx._core.WXK_RIGHT:
43                                 self.GotoPos(self.GetLineEndPosition(self.GetCurrentLine()))
44                         elif code == wx._core.WXK_UP:
45                                 self.GotoPos(0)
46                         elif code == wx._core.WXK_DOWN:
47                                 self.GotoPos(self.GetLength())
48                         else:
49                                 stopPropagation = False
50                 # Control
51                 elif e.GetModifiers() & 0xF0:
52                         if code == 65: # A
53                                 self.GotoLine(self.GetCurrentLine())
54                         elif code == 69: # E
55                                 self.GotoPos(self.GetLineEndPosition(self.GetCurrentLine()))
56                         else:
57                                 stopPropagation = False
58                 else:
59                         stopPropagation = False
60                 # Event propagation
61                 if stopPropagation:
62                         e.StopPropagation()
63                 else:
64                         e.Skip()
65         
66         def OnStyle(self, e):
67                 lineNr = self.LineFromPosition(self.GetEndStyled())
68                 while self.PositionFromLine(lineNr) > -1:
69                         line = self.GetLine(lineNr)
70                         start = self.PositionFromLine(lineNr)
71                         length = self.LineLength(lineNr)
72                         self.StartStyling(start, 255)
73                         self.SetStyling(length, 0)
74                         if ';' in line:
75                                 pos = line.index(';')
76                                 self.StartStyling(start + pos, 31)
77                                 self.SetStyling(length - pos, 1)
78                                 length = pos
79                 
80                         pos = 0
81                         while pos < length:
82                                 if line[pos] in " \t\n\r":
83                                         while pos < length and line[pos] in " \t\n\r":
84                                                 pos += 1
85                                 else:
86                                         end = pos
87                                         while end < length and not line[end] in " \t\n\r":
88                                                 end += 1
89                                         if self.checkGCodePart(line[pos:end], start + pos):
90                                                 self.StartStyling(start + pos, 0x20)
91                                                 self.SetStyling(end - pos, 0x20)
92                                         pos = end
93                         lineNr += 1
94
95         def checkGCodePart(self, part, pos):
96                 if len(part) < 2:
97                         self.StartStyling(pos, 0x40)
98                         self.SetStyling(1, 0x40)
99                         return True
100                 if not part[0] in "GMXYZFESTBPIDCJ":
101                         self.StartStyling(pos, 0x40)
102                         self.SetStyling(1, 0x40)
103                         return True
104                 if part[1] == '{':
105                         if part[-1] != '}':
106                                 return True
107                         tag = part[2:-1]
108                         if not profile.isProfileSetting(tag) and not profile.isPreference(tag):
109                                 self.StartStyling(pos + 2, 0x40)
110                                 self.SetStyling(len(tag), 0x40)
111                                 return True
112                 elif part[0] in "GM":
113                         try:
114                                 code = int(part[1:])
115                         except (ValueError):
116                                 self.StartStyling(pos + 1, 0x40)
117                                 self.SetStyling(len(part) - 1, 0x40)
118                                 return True
119                         if part[0] == 'G':
120                                 if not code in self.supportedGCodes:
121                                         return True
122                         if part[0] == 'M':
123                                 if not code in self.supportedMCodes:
124                                         return True
125                 else:
126                         try:
127                                 float(part[1:])
128                         except (ValueError):
129                                 self.StartStyling(pos + 1, 0x40)
130                                 self.SetStyling(len(part) - 1, 0x40)
131                                 return True
132                 return False
133
134         def GetValue(self):
135                 return self.GetText()
136
137         def SetValue(self, s):
138                 self.SetText(s)
139