Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/ui/space_console.py')
-rw-r--r--release/scripts/ui/space_console.py242
1 files changed, 242 insertions, 0 deletions
diff --git a/release/scripts/ui/space_console.py b/release/scripts/ui/space_console.py
new file mode 100644
index 00000000000..a65d7577c7a
--- /dev/null
+++ b/release/scripts/ui/space_console.py
@@ -0,0 +1,242 @@
+import bpy
+
+class CONSOLE_HT_header(bpy.types.Header):
+ __space_type__ = 'CONSOLE'
+
+ def draw(self, context):
+ sc = context.space_data
+ # text = sc.text
+ layout = self.layout
+
+ row= layout.row(align=True)
+ row.template_header()
+
+ if context.area.show_menus:
+ sub = row.row(align=True)
+
+ if sc.console_type == 'REPORT':
+ sub.itemM("CONSOLE_MT_report")
+ else:
+ sub.itemM("CONSOLE_MT_console")
+
+ layout.itemS()
+ layout.itemR(sc, "console_type", expand=True)
+
+ if sc.console_type == 'REPORT':
+ row = layout.row(align=True)
+ row.itemR(sc, "show_report_debug", text="Debug")
+ row.itemR(sc, "show_report_info", text="Info")
+ row.itemR(sc, "show_report_operator", text="Operators")
+ row.itemR(sc, "show_report_warn", text="Warnings")
+ row.itemR(sc, "show_report_error", text="Errors")
+
+ row = layout.row()
+ row.enabled = sc.show_report_operator
+ row.itemO("console.report_replay")
+ else:
+ row = layout.row(align=True)
+ row.itemO("console.autocomplete", text="Autocomplete")
+
+class CONSOLE_MT_console(bpy.types.Menu):
+ __space_type__ = 'CONSOLE'
+ __label__ = "Console"
+
+ def draw(self, context):
+ layout = self.layout
+ sc = context.space_data
+
+ layout.column()
+ layout.itemO("console.clear")
+ layout.itemO("console.copy")
+ layout.itemO("console.paste")
+
+class CONSOLE_MT_report(bpy.types.Menu):
+ __space_type__ = 'CONSOLE'
+ __label__ = "Report"
+
+ def draw(self, context):
+ layout = self.layout
+ sc = context.space_data
+
+ layout.column()
+ layout.itemO("console.select_all_toggle")
+ layout.itemO("console.select_border")
+ layout.itemO("console.report_delete")
+ layout.itemO("console.report_copy")
+
+def add_scrollback(text, text_type):
+ for l in text.split('\n'):
+ bpy.ops.console.scrollback_append(text=l.replace('\t', ' '), type=text_type)
+
+def get_console(console_id):
+ '''
+ helper function for console operators
+ currently each text datablock gets its own console - code.InteractiveConsole()
+ ...which is stored in this function.
+
+ console_id can be any hashable type
+ '''
+ import sys, code
+
+ try: consoles = get_console.consoles
+ except:consoles = get_console.consoles = {}
+
+ # clear all dead consoles, use text names as IDs
+ # TODO, find a way to clear IDs
+ '''
+ for console_id in list(consoles.keys()):
+ if console_id not in bpy.data.texts:
+ del consoles[id]
+ '''
+
+ try:
+ namespace, console, stdout, stderr = consoles[console_id]
+ except:
+ namespace = {'__builtins__':__builtins__} # locals()
+ namespace['bpy'] = bpy
+
+ console = code.InteractiveConsole(namespace)
+
+ import io
+ stdout = io.StringIO()
+ stderr = io.StringIO()
+
+ consoles[console_id]= namespace, console, stdout, stderr
+
+ return namespace, console, stdout, stderr
+
+class CONSOLE_OT_exec(bpy.types.Operator):
+ '''Execute the current console line as a python expression.'''
+ __idname__ = "console.execute"
+ __label__ = "Console Execute"
+ __register__ = False
+
+ # Both prompts must be the same length
+ PROMPT = '>>> '
+ PROMPT_MULTI = '... '
+
+ # is this working???
+ '''
+ def poll(self, context):
+ return (context.space_data.type == 'PYTHON')
+ ''' # its not :|
+
+ def execute(self, context):
+ import sys
+
+ sc = context.space_data
+
+ try:
+ line = sc.history[-1].line
+ except:
+ return ('CANCELLED',)
+
+ if sc.console_type != 'PYTHON':
+ return ('CANCELLED',)
+
+ namespace, console, stdout, stderr = get_console(hash(context.region))
+
+ # redirect output
+ sys.stdout = stdout
+ sys.stderr = stderr
+
+ # run the console
+ if not line.strip():
+ line_exec = '\n' # executes a multiline statement
+ else:
+ line_exec = line
+
+ is_multiline = console.push(line_exec)
+
+ stdout.seek(0)
+ stderr.seek(0)
+
+ output = stdout.read()
+ output_err = stderr.read()
+
+ # cleanup
+ sys.stdout = sys.__stdout__
+ sys.stderr = sys.__stderr__
+ sys.last_traceback = None
+
+ # So we can reuse, clear all data
+ stdout.truncate(0)
+ stderr.truncate(0)
+
+ bpy.ops.console.scrollback_append(text = sc.prompt+line, type='INPUT')
+
+ if is_multiline: sc.prompt = self.PROMPT_MULTI
+ else: sc.prompt = self.PROMPT
+
+ # insert a new blank line
+ bpy.ops.console.history_append(text="", current_character=0, remove_duplicates= True)
+
+ # Insert the output into the editor
+ # not quite correct because the order might have changed, but ok 99% of the time.
+ if output: add_scrollback(output, 'OUTPUT')
+ if output_err: add_scrollback(output_err, 'ERROR')
+
+
+ return ('FINISHED',)
+
+
+class CONSOLE_OT_autocomplete(bpy.types.Operator):
+ '''Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.'''
+ __idname__ = "console.autocomplete"
+ __label__ = "Console Autocomplete"
+ __register__ = False
+
+ def poll(self, context):
+ return context.space_data.console_type == 'PYTHON'
+
+ def execute(self, context):
+
+ sc = context.space_data
+
+ namespace, console, stdout, stderr = get_console(hash(context.region))
+
+ current_line = sc.history[-1]
+ line = current_line.line
+
+ if not console:
+ return ('CANCELLED',)
+
+ if sc.console_type != 'PYTHON':
+ return ('CANCELLED',)
+
+ # fake cursor, use for autocomp func.
+ bcon = {}
+ bcon['cursor'] = current_line.current_character
+ bcon['console'] = console
+ bcon['edit_text'] = line
+ bcon['namespace'] = namespace
+ bcon['scrollback'] = '' # nor from the BGE console
+
+
+ # This function isnt aware of the text editor or being an operator
+ # just does the autocomp then copy its results back
+ import autocomplete
+ autocomplete.execute(bcon)
+
+ # Now we need to copy back the line from blender back into the text editor.
+ # This will change when we dont use the text editor anymore
+ if bcon['scrollback']:
+ add_scrollback(bcon['scrollback'], 'INFO')
+
+ # copy back
+ current_line.line = bcon['edit_text']
+ current_line.current_character = bcon['cursor']
+
+ context.area.tag_redraw()
+
+ return ('FINISHED',)
+
+
+
+bpy.types.register(CONSOLE_HT_header)
+bpy.types.register(CONSOLE_MT_console)
+bpy.types.register(CONSOLE_MT_report)
+
+bpy.ops.add(CONSOLE_OT_exec)
+bpy.ops.add(CONSOLE_OT_autocomplete)
+