Set material and color properties of Blob objects.
[blender-addons-contrib.git] / text_intellisense.py
1 # ***** BEGIN GPL LICENSE BLOCK *****
2 #
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #
18 # ***** END GPL LICENCE BLOCK *****
19
20 bl_info = {
21     "name": "Intellisense for Text Editor",
22     "author": "Mackraken",
23     "version": (0, 2),
24     "blender": (2, 60, 0),
25     "location": "Ctrl + Space at Text Editor",
26     "description": "Adds intellense to the Text Editor",
27     "warning": "Only works with 2.57 intellisense",
28     "wiki_url": "",
29     "tracker_url": "",
30     "category": "Development"}
31
32 import bpy
33
34 def complete(context):
35         from console import intellisense
36         from console_python import get_console
37
38         sc = context.space_data
39         text = sc.text
40
41         region = context.region
42         for area in context.screen.areas:
43                 if area.type=="CONSOLE":
44                         region = area.regions[1]
45                         break
46
47         console = get_console(hash(region))[0]
48
49         line = text.current_line.body
50         cursor = text.current_character
51
52         result  = intellisense.expand(line, cursor, console.locals, bpy.app.debug)
53
54         return result
55
56
57 class Intellimenu(bpy.types.Menu):
58         bl_label = ""
59         bl_idname = "IntelliMenu"
60
61         text = ""
62
63         def draw(self, context):
64                 layout = self.layout
65                 #Very ugly see how can i fix this
66                 options = complete(context)
67
68                 options = options[2].split("  ")
69                 for op in options:
70                         layout.operator("text.intellioptions", text=op).text=op
71
72 #This operator executes when hits Ctrl+Space at the text editor
73
74 class Intellisense(bpy.types.Operator):
75         #"""Tooltip"""
76         bl_idname = "text.intellisense"
77         bl_label = "Text Editor Intellisense"
78
79         text = ""
80
81 #       @classmethod
82 #       def poll(cls, context):
83 #               return context.active_object is not None
84
85         def execute(self, context):
86                 sc = context.space_data
87                 text = sc.text
88
89                 if text.current_character>0:
90                         result = complete(context)
91
92                         #print(result)
93
94                         if result[2]=="":
95                                 text.current_line.body = result[0]
96                                 bpy.ops.text.move(type='LINE_END')
97                         else:
98                                 bpy.ops.wm.call_menu(name=Intellimenu.bl_idname)
99
100                 return {'FINISHED'}
101
102 #this operator completes the line with the options you choose from the menu
103 class Intellioptions(bpy.types.Operator):
104         #"""Tooltip"""
105         bl_idname = "text.intellioptions"
106         bl_label = "Intellisense options"
107
108         text = bpy.props.StringProperty()
109
110         @classmethod
111         def poll(cls, context):
112                 return context.active_object is not None
113
114         def execute(self, context):
115                 sc = context.space_data
116                 text = sc.text
117
118                 comp = self.text
119                 line = text.current_line.body
120
121                 lline = len(line)
122                 lcomp = len(comp)
123
124                 #intersect text
125                 intersect = [-1,-1]
126
127                 for i in range(lcomp):
128                         val1 = comp[0:i+1]
129
130                         for j in range(lline):
131                                 val2 = line[lline-j-1::]
132                                 #print("        ",j, val2)
133
134                                 if val1==val2:
135                                         intersect = [i, j]
136                                         break
137
138                 if intersect[0]>-1:
139                         newline = line[0:lline-intersect[1]-1]+comp
140                 else:
141                         newline = line + comp
142
143                 #print(newline)
144                 text.current_line.body = newline
145
146                 bpy.ops.text.move(type='LINE_END')
147
148
149                 return {'FINISHED'}
150
151 def send_console(context, all=0):
152
153         sc = context.space_data
154         text = sc.text
155
156         console = None
157
158         for area in bpy.context.screen.areas:
159                 if area.type=="CONSOLE":
160                         from console_python import get_console
161
162                         console = get_console(hash(area.regions[1]))[0]
163
164         if console==None:
165                 return {'FINISHED'}
166
167         if all:
168
169                 for l in text.lines:
170                         console.push(l.body)
171
172         else:
173                 #print(console.prompt)
174                 console.push(text.current_line.body)
175
176
177
178
179 class TestLine(bpy.types.Operator):
180         #"""Tooltip"""
181         bl_idname = "text.test_line"
182         bl_label = "Test line"
183
184         all = bpy.props.BoolProperty(default=False)
185
186
187 #   @classmethod
188 #   def poll(cls, context):
189 #          return context.active_object is not None
190
191         def execute(self, context):
192                 #print("test line")
193
194                 #send_console(context, self.all)
195                 sc = context.space_data
196                 text = sc.text
197
198                 line = text.current_line.body
199                 console = None
200
201                 for area in bpy.context.screen.areas:
202                         if area.type=="CONSOLE":
203                                 from console_python import get_console
204
205                                 console = get_console(hash(area.regions[1]))[0]
206
207                 if console==None:
208                         return {'FINISHED'}
209
210                 command = ""
211
212                 forindex = line.find("for ")
213                 if forindex >-1:
214
215                         var = line[forindex+4:-1]
216                         var = var[0:var.find(" ")]
217                         state = line[line.rindex(" ")+1:-1]
218
219                         command = var + " = " +state+"[0]"
220
221
222                 else:
223                         command = line
224
225                 #print(command)
226                 try:
227                         console.push(command)
228                 except:
229                         pass
230
231                 bpy.ops.text.line_break()
232
233
234                 return {'FINISHED'}
235 class SetBreakPoint(bpy.types.Operator):
236         bl_idname = "text.set_breakpoint"
237         bl_label = "Set Breakpoint"
238
239         def execute(self, context):
240
241                 sc = bpy.context.space_data
242                 text = sc.text
243
244                 line = text.current_line
245                 br = " #breakpoint"
246                 #print(line.body.find(br))
247                 if line.body.find(br)>-1:
248
249                         line.body = line.body.replace(br, "")
250                 else:
251
252                         line.body += br
253
254                 return {'FINISHED'}
255
256 class Debug(bpy.types.Operator):
257         bl_idname = "text.debug"
258         bl_label = "Debug"
259
260         def execute(self, context):
261
262                 binpath = bpy.app.binary_path
263
264                 addonspath = binpath[0:binpath.rindex("\\")+1]+str(bpy.app.version[0])+"."+str(bpy.app.version[1])+"\\scripts\\addons\\"
265
266                 print(addonspath)
267
268                 sc = context.space_data
269                 text = sc.text
270
271                 br = " #breakpoint"
272
273                 filepath = addonspath+"debug.py"
274                 file = open(filepath, "w")
275                 file.write("import pdb\n")
276
277                 for line in text.lines:
278                         l = line.body
279
280                         if line.body.find(br)>-1:
281                                 indent = ""
282                                 for letter in line.body:
283
284                                         if not letter.isalpha():
285                                                 indent+=letter
286                                         else:
287                                                 break
288                                 file.write(l[0:-len(br)]+"\n")
289
290                                 file.write(indent+"pdb.set_trace()\n")
291
292                         else:
293                                 file.write(line.body+"\n")
294
295
296
297                 file.close()
298
299                 import pdb
300                 import debug
301
302                 pdb.runcall("debug")
303
304
305                 return {'FINISHED'}
306
307
308 class DebugPanel(bpy.types.Panel):
309         bl_label = "Debug"
310         bl_idname = "text.test_line"
311         bl_space_type = "TEXT_EDITOR"
312         bl_region_type = "UI"
313         #bl_context = "object"
314
315         text = bpy.props.StringProperty()
316
317         def draw(self, context):
318                 layout = self.layout
319                 row = layout.row()
320
321                 text = self.text
322                 row = layout.row()
323                 row.operator("text.debug", text ="Debug")
324                 row = layout.row()
325                 row.operator("text.set_breakpoint")
326                 row = layout.row()
327                 row.operator("text.test_line").all=False
328                 row = layout.row()
329                 row.operator("text.test_line", text ="Test All").all=True
330
331                 row = layout.row()
332                 row.label(text="Coming Soon ...")
333
334
335 ### ASSIGN A KEY
336
337 #section = Input section. "Window, Text, ..."
338 #name = operator name or wm.call_menu
339 #type = key
340 #event = keyboard event (Press, release, ...)
341 #mods = array containing key modifiers (["ctrl", "alt", "shift"]
342 #propvalue = menu name, if name is set to "wm.call_menu"
343 #overwrite doesnt work at the moment
344
345 def assignKey(section, name, type, event, mods=[],propvalue = "",  overwrite=0):
346
347         kconf = bpy.context.window_manager.keyconfigs.active
348
349
350         #check section
351         validsections = [item.name for item in kconf.keymaps]
352         if not section in validsections:
353                 print(section  + " is not a valid section.")
354                 #print(validsections)
355                 return False
356
357         #check type
358         type = type.upper()
359         validkeys = [item.identifier for item in bpy.types.KeyMapItem.bl_rna.properties['type'].enum_items]
360         if not type in validkeys:
361                 print(type + " is not a valid key.")
362                 #print(validkeys)
363                 return False
364
365
366         #check event
367         event = event.upper()
368         validevents = [item.identifier for item in bpy.types.KeyMapItem.bl_rna.properties['value'].enum_items]
369         if not event in validevents:
370                 print(event + " is not a valid event.")
371                 #print(validevents)
372
373         kmap = kconf.keymaps[section]
374
375
376 #   get mods
377         for i, mod in enumerate(mods):
378                 mods[i]= mod.lower()
379
380         #any, shift, ctrl, alt, oskey
381         kmod = [False, False, False, False, False]
382
383         if "any" in mods: kmod[0] = True
384         if "shift" in mods: kmod[1] = True
385         if "ctrl" in mods: kmod[2] = True
386         if "alt" in mods: kmod[3] = True
387         if "oskey" in mods: kmod[4] = True
388
389 #   #check if key exist
390         kexists = False
391
392         for key in kmap.keymap_items:
393                 keymods = [key.any, key.shift, key.ctrl, key.alt, key.oskey]
394                 if key.type == type and keymods == kmod:
395                         kexists = True
396                         print(key,"key exists")
397                         break
398
399         if kexists:
400                 #overwrite?
401                 if overwrite:
402                         key.idname=name
403
404                         #key.type = type
405
406         else:
407                 #create key
408                 key = kmap.keymap_items.new(name, type, event, False)
409                 key.any = kmod[0]
410                 key.shift = kmod[1]
411                 key.ctrl = kmod[2]
412                 key.alt = kmod[3]
413                 key.oskey = kmod[4]
414
415                 if propvalue!="": key.properties.name = propvalue
416
417
418
419
420 classes = [Intellisense, Intellioptions, Intellimenu, DebugPanel, TestLine, SetBreakPoint, Debug]
421
422 def register():
423
424         for c in classes:
425                 bpy.utils.register_class(c)
426
427         assignKey("Text", "text.intellisense", "SPACE", "Press",  ["ctrl"])
428         assignKey("Text", "text.test_line", "RET", "Press", [],"",1)
429
430 def unregister():
431         for c in classes:
432                 bpy.utils.unregister_class(c)
433
434 if __name__ == "__main__":
435         register()