File: ScintillaCallable.py

package info (click to toggle)
mysql-workbench 6.3.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 113,932 kB
  • ctags: 87,814
  • sloc: ansic: 955,521; cpp: 427,465; python: 59,728; yacc: 59,129; xml: 54,204; sql: 7,091; objc: 965; makefile: 638; sh: 613; java: 237; perl: 30; ruby: 6; php: 1
file content (159 lines) | stat: -rw-r--r-- 4,970 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# -*- coding: utf-8 -*-

from __future__ import unicode_literals

import ctypes, os, sys

from ctypes import c_int, c_ulong, c_char_p, c_wchar_p, c_ushort, c_uint, c_long

class TEXTRANGE(ctypes.Structure):
	_fields_= (\
		('cpMin', c_long),
		('cpMax', c_long),
		('lpstrText', ctypes.POINTER(ctypes.c_char)),
	)

class FINDTEXT(ctypes.Structure):
	_fields_= (\
		('cpMin', c_long),
		('cpMax', c_long),
		('lpstrText', c_char_p),
		('cpMinText', c_long),
		('cpMaxText', c_long),
	)

class SciCall:
	def __init__(self, fn, ptr, msg, stringResult=False):
		self._fn = fn
		self._ptr = ptr
		self._msg = msg
		self._stringResult = stringResult
	def __call__(self, w=0, l=0):
		ww = ctypes.cast(w, c_char_p)
		if self._stringResult:
			lengthBytes = self._fn(self._ptr, self._msg, ww, None)
			if lengthBytes == 0:
				return bytearray()
			result = (ctypes.c_byte * lengthBytes)(0)
			lengthBytes2 = self._fn(self._ptr, self._msg, ww, ctypes.cast(result, c_char_p))
			assert lengthBytes == lengthBytes2
			return bytearray(result)[:lengthBytes]
		else:
			ll = ctypes.cast(l, c_char_p)
			return self._fn(self._ptr, self._msg, ww, ll)

sciFX = ctypes.CFUNCTYPE(c_long, c_char_p, c_int, c_char_p, c_char_p)

class ScintillaCallable:
	def __init__(self, face, scifn, sciptr):
		self.__dict__["face"] = face
		self.__dict__["used"] = set()
		self.__dict__["all"] = set()
		# The k member is for accessing constants as a dictionary
		self.__dict__["k"] = {}
		for f in face.features:
			self.all.add(f)
			if face.features[f]["FeatureType"] == "val":
				self.k[f] = int(self.face.features[f]["Value"], 0)
			elif face.features[f]["FeatureType"] == "evt":
				self.k["SCN_"+f] = int(self.face.features[f]["Value"], 0)
		scifn = sciFX(scifn)
		self.__dict__["_scifn"] = scifn
		self.__dict__["_sciptr"] = sciptr
	def __getattr__(self, name):
		if name in self.face.features:
			self.used.add(name)
			feature = self.face.features[name]
			value = int(feature["Value"], 0)
			#~ print("Feature", name, feature)
			if feature["FeatureType"] == "val":
				self.__dict__[name] = value
				return value
			else:
				if feature["Param2Type"] == "stringresult" and \
					name not in ["GetText", "GetLine", "GetCurLine"]:
					return SciCall(self._scifn, self._sciptr, value, True)
				else:
					return SciCall(self._scifn, self._sciptr, value)
		elif ("Get" + name) in self.face.features:
			self.used.add("Get" + name)
			feature = self.face.features["Get" + name]
			value = int(feature["Value"], 0)
			if feature["FeatureType"] == "get" and \
				not name.startswith("Get") and \
				not feature["Param1Type"] and \
				not feature["Param2Type"] and \
				feature["ReturnType"] in ["bool", "int", "position"]:
				#~ print("property", feature)
				return self._scifn(self._sciptr, value, None, None)
		elif name.startswith("SCN_") and name in self.k:
			self.used.add(name)
			feature = self.face.features[name[4:]]
			value = int(feature["Value"], 0)
			#~ print("Feature", name, feature)
			if feature["FeatureType"] == "val":
				return value
		raise AttributeError(name)
	def __setattr__(self, name, val):
		if ("Set" + name) in self.face.features:
			self.used.add("Set" + name)
			feature = self.face.features["Set" + name]
			value = int(feature["Value"], 0)
			#~ print("setproperty", feature)
			if feature["FeatureType"] == "set" and not name.startswith("Set"):
				if feature["Param1Type"] in ["bool", "int", "position"]:
					return self._scifn(self._sciptr, value, c_char_p(val), None)
				elif feature["Param2Type"] in ["string"]:
					return self._scifn(self._sciptr, value, None, c_char_p(val))
				raise AttributeError(name)
		raise AttributeError(name)
	def getvalue(self, name):
		if name in self.face.features:
			feature = self.face.features[name]
			if feature["FeatureType"] != "evt":
				try:
					return int(feature["Value"], 0)
				except ValueError:
					return -1
		return -1


	def ByteRange(self, start, end):
		tr = TEXTRANGE()
		tr.cpMin = start
		tr.cpMax = end
		length = end - start
		tr.lpstrText = ctypes.create_string_buffer(length + 1)
		self.GetTextRange(0, ctypes.byref(tr))
		text = tr.lpstrText[:length]
		text += b"\0" * (length - len(text))
		return text
	def StyledTextRange(self, start, end):
		tr = TEXTRANGE()
		tr.cpMin = start
		tr.cpMax = end
		length = 2 * (end - start)
		tr.lpstrText = ctypes.create_string_buffer(length + 2)
		self.GetStyledText(0, ctypes.byref(tr))
		styledText = tr.lpstrText[:length]
		styledText += b"\0" * (length - len(styledText))
		return styledText
	def FindBytes(self, start, end, s, flags):
		ft = FINDTEXT()
		ft.cpMin = start
		ft.cpMax = end
		ft.lpstrText = s
		ft.cpMinText = 0
		ft.cpMaxText = 0
		pos = self.FindText(flags, ctypes.byref(ft))
		#~ print(start, end, ft.cpMinText, ft.cpMaxText)
		return pos

	def Contents(self):
		return self.ByteRange(0, self.Length)
		
	def SetContents(self, s):
		self.TargetStart = 0
		self.TargetEnd = self.Length
		self.ReplaceTarget(len(s), s)