[game-baker commit] r309 - in trunk/trunk: . GUI GUI/lib GUI/lib/pygtkcodebuffer

2 views
Skip to first unread message

codesite...@google.com

unread,
Mar 7, 2009, 9:45:38 AM3/7/09
to game-ba...@googlegroups.com
Author: timwintle
Date: Sat Mar 7 06:44:29 2009
New Revision: 309

Added:
trunk/trunk/GUI/lib/
trunk/trunk/GUI/lib/__init__.py
trunk/trunk/GUI/lib/pygtkcodebuffer/
trunk/trunk/GUI/lib/pygtkcodebuffer/LICENSE
trunk/trunk/GUI/lib/pygtkcodebuffer/README
trunk/trunk/GUI/lib/pygtkcodebuffer/__init__.py
trunk/trunk/GUI/lib/pygtkcodebuffer/gtkcodebuffer.py
trunk/trunk/GUI/lib/pygtkcodebuffer/python.xml
trunk/trunk/GUI/lib/pygtkcodebuffer/simple.py (contents, props changed)
Modified:
trunk/trunk/GUI/main_window_events.py
trunk/trunk/gamebaker.py

Log:
Added Python Syntax Highlighting using pyGtkCodeBuffer

Added: trunk/trunk/GUI/lib/__init__.py
==============================================================================

Added: trunk/trunk/GUI/lib/pygtkcodebuffer/LICENSE
==============================================================================
--- (empty file)
+++ trunk/trunk/GUI/lib/pygtkcodebuffer/LICENSE Sat Mar 7 06:44:29 2009
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this
license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.

Added: trunk/trunk/GUI/lib/pygtkcodebuffer/README
==============================================================================
--- (empty file)
+++ trunk/trunk/GUI/lib/pygtkcodebuffer/README Sat Mar 7 06:44:29 2009
@@ -0,0 +1,33 @@
+Modified By Tim Wintle for Game Baker.
+Source taken from PyGTKCodeBuffer RC2
+http://code.google.com/p/pygtkcodebuffer/
+on Jan 27, 2008
+
+Origional Readme:
+=============================================================================
+
+ === PyGTKCodeBuffer is a lightweight syntax-highlighting engine ===
+ === depending only on PyGTK! ===
+
+
+
+About:
+ PyGTKCodeBuffer is written in pure Python to provide a maximum
portability.
+ It depends only on PyGTK and the Python standard library. No Gnome nor
+ Scintilla libraries are needed it should run perfectly under all
platforms
+ supported by PyGTK!
+
+
+Usage:
+ To keep this project lightweight the PyGTKCodeBuffer only provides you
a
+ model/buffer for code-viewing/editing. To view a code-buffer simply
use the
+ default gtk.TextView widget. This buffer provides you a simple way to
build
+ a editor with syntax-highlight support.
+
+ All the code for PyGTKCodeBuffer is located in one source-file to
allow you
+ to ship PyGTKCodeBuffer along with your application so your costumers
do not
+ have to care about having PyGTKCodeBuffer installed.
+ Note: In this case you have to tell PyGTKCodeBuffer where to find the
+ syntax-definitions. Or you "hard-code" the language-grammar.
+
+

Added: trunk/trunk/GUI/lib/pygtkcodebuffer/__init__.py
==============================================================================
--- (empty file)
+++ trunk/trunk/GUI/lib/pygtkcodebuffer/__init__.py Sat Mar 7 06:44:29 2009
@@ -0,0 +1,2 @@
+"""modified pygtkcodebuffer - modified by TimWintle"""
+from gtkcodebuffer import *

Added: trunk/trunk/GUI/lib/pygtkcodebuffer/gtkcodebuffer.py
==============================================================================
--- (empty file)
+++ trunk/trunk/GUI/lib/pygtkcodebuffer/gtkcodebuffer.py Sat Mar 7
06:44:29 2009
@@ -0,0 +1,680 @@
+""" This module contains the PyGTKCodeBuffer-class. This class is a
+ specialisation of the gtk.TextBuffer and enables syntax-highlighting
for
+ PyGTK's TextView-widget.
+
+ To use the syntax-highlighting feature you have load a
syntax-definition or
+ specify your own. To load one please read the docs for the
SyntaxLoader()
+ class. """
+
+
+# This library is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import gtk
+import pango
+import re
+import sys
+import os.path
+import xml.sax
+import imp
+from xml.sax.handler import ContentHandler
+from xml.sax.saxutils import unescape
+
+__version__ = "1.0RC2"
+__author__ = "Hannes Matuschek <hmatu...@gmail.com>"
+
+
+# defined the default styles
+DEFAULT_STYLES = {
+ 'DEFAULT': {'font': 'monospace'},
+ 'comment': {'foreground': '#0000FF'},
+ 'preprocessor': {'foreground': '#A020F0'},
+ 'keyword': {'foreground': '#A52A2A',
+ 'weight': pango.WEIGHT_BOLD},
+ 'special': {'foreground': 'turquoise'},
+ 'mark1': {'foreground': '#008B8B'},
+ 'mark2': {'foreground': '#6A5ACD'},
+ 'string': {'foreground': '#FF00FF'},
+ 'number': {'foreground': '#FF00FF'},
+ 'datatype': {'foreground': '#2E8B57',
+ 'weight': pango.WEIGHT_BOLD},
+ 'function': {'foreground': '#008A8C'},
+
+ 'link': {'foreground': '#0000FF',
+ 'underline': pango.UNDERLINE_SINGLE}}
+
+
+
+
+
+def _main_is_frozen():
+ """ Internal used function. """
+ return (hasattr(sys, "frozen") or # new py2exe
+ hasattr(sys, "importers") # old py2exe
+ or imp.is_frozen("__main__")) # tools/freeze
+
+
+if _main_is_frozen():
+ this_module_path = os.path.dirname(sys.executable)
+else:
+ this_module_path = os.path.abspath(os.path.dirname(__file__))
+
+
+# defines default-search paths for syntax-files
+SYNTAX_PATH = [ os.path.join('.', 'syntax'),
+ this_module_path,
+ os.path.join(os.path.expanduser('~'),".pygtkcodebuffer"),
+
os.path.join(sys.prefix,"share","pygtkcodebuffer","syntax")]
+
+
+# enable/disable debug-messages
+DEBUG_FLAG = False
+
+
+#
+# Some log functions...
+# (internal used)
+def _log_debug(msg):
+ if not DEBUG_FLAG:
+ return
+ sys.stderr.write("DEBUG: ")
+ sys.stderr.write(msg)
+ sys.stderr.write("\n")
+
+def _log_warn(msg):
+ sys.stderr.write("WARN: ")
+ sys.stderr.write(msg)
+ sys.stderr.write("\n")
+
+def _log_error(msg):
+ sys.stderr.write("ERROR: ")
+ sys.stderr.write(msg)
+ sys.stderr.write("\n")
+
+
+
+
+def add_syntax_path(path_or_list):
+ """ This function adds one (string) or many (list of strings) paths to
the
+ global search-paths for syntax-files. """
+ global SYNTAX_PATH
+ # handle list of strings
+ if isinstance(path_or_list, (list, tuple)):
+ for i in range(len(path_or_list)):
+ SYNTAX_PATH.insert(0, path_or_list[-i])
+ # handle single string
+ elif isinstance(path_or_list, basestring):
+ SYNTAX_PATH.insert(0, path_or_list)
+ # handle attr-error
+ else:
+ raise TypeError, "Argument must be path-string or list of strings"
+
+
+
+class Pattern:
+ """ More or less internal used class representing a pattern. You may
use
+ this class to "hard-code" your syntax-definition. """
+
+ def __init__(self, regexp, style="DEFAULT", group=0, flags=""):
+ """ The constructor takes at least on argument: the
regular-expression.
+
+ The optional kwarg style defines the style applied to the
string
+ matched by the regexp.
+
+ The kwarg group may be used to define which group of the
regular
+ expression will be used for highlighting (Note: This means
that only
+ the selected group will be highlighted but the complete
pattern must
+ match!)
+
+ The optional kwarg flags specifies flags for the regular
expression.
+ Look at the Python lib-ref for a list of flags and there
meaning."""
+ # assemble re-flag
+ flags += "ML"; flag = 0
+
+ _log_debug("init rule %s -> %s (%s)"%(regexp, style, flags))
+
+ for char in flags:
+ if char == 'M': flag |= re.M
+ if char == 'L': flag |= re.L
+ if char == 'S': flag |= re.S
+ if char == 'I': flag |= re.I
+ if char == 'U': flag |= re.U
+ if char == 'X': flag |= re.X
+
+ # compile re
+ try: self._regexp = re.compile(regexp, flag)
+ except re.error, e:
+ raise Exception("Invalid regexp \"%s\": %s"%(regexp,str(e)))
+
+ self._group = group
+ self.tag_name = style
+
+
+ def __call__(self, txt, start, end):
+ m = self._regexp.search(txt)
+ if not m: return None
+
+ mstart, mend = m.start(self._group), m.end(self._group)
+ s = start.copy(); s.forward_chars(mstart)
+ e = start.copy(); e.forward_chars(mend)
+
+ return (s,e)
+
+
+
+class KeywordList(Pattern):
+ """ This class may be used for hard-code a syntax-definition. It
specifies
+ a pattern for a keyword-list. This simplifies the definition of
+ keyword-lists. """
+
+ def __init__(self, keywords, style="keyword", flags=""):
+ """ The constructor takes at least on argument: A list of strings
+ specifying the keywords to highlight.
+
+ The optional kwarg style specifies the style used to highlight
these
+ keywords.
+
+ The optional kwarg flags specifies the flags for the
+ (internal generated) regular-expression. """
+ regexp = "(?:\W|^)(%s)\W"%("|".join(keywords),)
+ Pattern.__init__(self, regexp, style, group=1, flags=flags)
+
+
+
+class String:
+ """ This class may be used to hard-code a syntax-definition. It
simplifies
+ the definition of a "string". A "string" is something that
consists of
+ a start-pattern and an end-pattern. The end-pattern may be content
of
+ the string if it is escaped. """
+
+ def __init__(self, starts, ends, escape=None, style="string"):
+ """ The constructor needs at least two arguments: The start- and
+ end-pattern.
+
+ The optional kwarg escape specifies a escape-sequence escaping
the
+ end-pattern.
+
+ The optional kwarg style specifies the style used to highlight
the
+ string. """
+ try:
+ self._starts = re.compile(starts)
+ except re.error, e:
+ raise Exception("Invalid regexp \"%s\": %s"%(regexp,str(e)))
+
+ if escape:
+ end_exp = "[^%(esc)s](?:%(esc)s%(esc)s)*%(end)s"
+ end_exp = end_exp%{'esc':escape*2,'end':ends}
+ else:
+ end_exp = ends
+
+ try:
+ self._ends = re.compile(end_exp)
+ except re.error, e:
+ raise Exception("Invalid regexp \"%s\": %s"%(regexp,str(e)))
+
+ self.tag_name = style
+
+
+ def __call__(self, txt, start, end):
+ start_match = self._starts.search(txt)
+ if not start_match: return
+
+ start_it = start.copy()
+ start_it.forward_chars(start_match.start(0))
+ end_it = end.copy()
+
+ end_match = self._ends.search(txt, start_match.end(0)-1)
+ if end_match:
+ end_it.set_offset(start.get_offset()+end_match.end(0))
+
+ return start_it, end_it
+
+
+
+class LanguageDefinition:
+ """ This class is a container class for all rules (Pattern,
KeywordList,
+ ...) specifying the language. You have to used this class if you
like
+ to hard-code your syntax-definition. """
+
+ def __init__(self, rules):
+ """ The constructor takes only one argument: A list of rules (i.e
+ Pattern, KeywordList and String). """
+ self._grammar = rules
+ self._styles = dict()
+
+
+ def __call__(self, buf, start, end=None):
+ # if no end given -> end of buffer
+ if not end: end = buf.get_end_iter()
+
+ mstart = mend = end
+ mtag = None
+ txt = buf.get_slice(start, end)
+
+ # search min match
+ for rule in self._grammar:
+ # search pattern
+ m = rule(txt, start, end)
+ if not m: continue
+
+ # prefer match with smallest start-iter
+ if m[0].compare(mstart) < 0:
+ mstart, mend = m
+ mtag = rule.tag_name
+ continue
+
+ if m[0].compare(mstart)==0 and m[1].compare(mend)>0:
+ mstart, mend = m
+ mtag = rule.tag_name
+ continue
+
+ return (mstart, mend, mtag)
+
+
+ def get_styles(self):
+ return self._styles
+
+
+
+
+class SyntaxLoader(ContentHandler, LanguageDefinition):
+ """ This class loads a syntax definition. There have to be a file
+ named LANGUAGENAME.xml in one of the directories specified in the
+ global path-list. You may add a directory using the
add_syntax_path()
+ function. """
+
+ # some translation-tables for the style-defs:
+ style_weight_table = {'ultralight': pango.WEIGHT_ULTRALIGHT,
+ 'light': pango.WEIGHT_LIGHT,
+ 'normal': pango.WEIGHT_NORMAL,
+ 'bold': pango.WEIGHT_BOLD,
+ 'ultrabold': pango.WEIGHT_ULTRABOLD,
+ 'heavy': pango.WEIGHT_HEAVY}
+ style_variant_table = {'normal': pango.VARIANT_NORMAL,
+ 'smallcaps': pango.VARIANT_SMALL_CAPS}
+ style_underline_table = {'none': pango.UNDERLINE_NONE,
+ 'single': pango.UNDERLINE_SINGLE,
+ 'double': pango.UNDERLINE_DOUBLE}
+ style_style_table = {'normal': pango.STYLE_NORMAL,
+ 'oblique': pango.STYLE_OBLIQUE,
+ 'italic': pango.STYLE_ITALIC}
+ style_scale_table = {
+ 'xx_small': pango.SCALE_XX_SMALL,
+ 'x_small': pango.SCALE_X_SMALL,
+ 'small': pango.SCALE_SMALL,
+ 'medium': pango.SCALE_MEDIUM,
+ 'large': pango.SCALE_LARGE,
+ 'x_large': pango.SCALE_X_LARGE,
+ 'xx_large': pango.SCALE_XX_LARGE,
+ }
+
+
+ def __init__(self, lang_name):
+ """ The constructor takes only one argument: the language name.
+ The constructor tries to load the syntax-definition from a
+ syntax-file in one directory of the global path-list.
+
+ An instance of this class IS a LanguageDefinition. You can
pass it
+ to the constructor of the CodeBuffer class. """
+ LanguageDefinition.__init__(self, [])
+ ContentHandler.__init__(self)
+
+ # search for syntax-files:
+ fname = None
+ for syntax_dir in SYNTAX_PATH:
+ fname = os.path.join(syntax_dir, "%s.xml"%lang_name)
+ if os.path.isfile(fname): break
+
+ _log_debug("Loading syntaxfile %s"%fname)
+
+ if not os.path.isfile(fname):
+ raise Exception("No snytax-file for %s found!"%lang_name)
+
+ xml.sax.parse(fname, self)
+
+
+ # Dispatch start/end - document/element and chars
+ def startDocument(self):
+ self.__stack = []
+
+ def endDocument(self):
+ del self.__stack
+
+ def startElement(self, name, attr):
+ self.__stack.append( (name, attr) )
+ if hasattr(self, "start_%s"%name):
+ handler = getattr(self, "start_%s"%name)
+ handler(attr)
+
+ def endElement(self, name):
+ if hasattr(self, "end_%s"%name):
+ handler = getattr(self, "end_%s"%name)
+ handler()
+ del self.__stack[-1]
+
+ def characters(self, txt):
+ if not self.__stack: return
+ name, attr = self.__stack[-1]
+
+ if hasattr(self, "chars_%s"%name):
+ handler = getattr(self, "chars_%s"%name)
+ handler(txt)
+
+
+ # Handle regexp-patterns
+ def start_pattern(self, attr):
+ self.__pattern = ""
+ self.__group = 0
+ self.__flags = ''
+ self.__style = attr['style']
+ if 'group' in attr.keys(): self.__group = int(attr['group'])
+ if 'flags' in attr.keys(): self.__flags = attr['flags']
+
+ def end_pattern(self):
+ rule = Pattern(self.__pattern, self.__style, self.__group,
self.__flags)
+ self._grammar.append(rule)
+ del self.__pattern
+ del self.__group
+ del self.__flags
+ del self.__style
+
+ def chars_pattern(self, txt):
+ self.__pattern += unescape(txt)
+
+
+ # handle keyword-lists
+ def start_keywordlist(self, attr):
+ self.__style = "keyword"
+ self.__flags = ""
+ if 'style' in attr.keys():
+ self.__style = attr['style']
+ if 'flags' in attr.keys():
+ self.__flags = attr['flags']
+ self.__keywords = []
+
+ def end_keywordlist(self):
+ kwlist = KeywordList(self.__keywords, self.__style, self.__flags)
+ self._grammar.append(kwlist)
+ del self.__keywords
+ del self.__style
+ del self.__flags
+
+ def start_keyword(self, attr):
+ self.__keywords.append("")
+
+ def end_keyword(self):
+ if not self.__keywords[-1]:
+ del self.__keywords[-1]
+
+ def chars_keyword(self, txt):
+ parent,pattr = self.__stack[-2]
+ if not parent == "keywordlist": return
+ self.__keywords[-1] += unescape(txt)
+
+
+ #handle String-definitions
+ def start_string(self, attr):
+ self.__style = "string"
+ self.__escape = None
+ if 'escape' in attr.keys():
+ self.__escape = attr['escape']
+ if 'style' in attr.keys():
+ self.__style = attr['style']
+ self.__start_pattern = ""
+ self.__end_pattern = ""
+
+ def end_string(self):
+ strdef = String(self.__start_pattern, self.__end_pattern,
+ self.__escape, self.__style)
+ self._grammar.append(strdef)
+ del self.__style
+ del self.__escape
+ del self.__start_pattern
+ del self.__end_pattern
+
+ def chars_starts(self, txt):
+ self.__start_pattern += unescape(txt)
+
+ def chars_ends(self, txt):
+ self.__end_pattern += unescape(txt)
+
+
+ # handle style
+ def start_style(self, attr):
+ self.__style_props = dict()
+ self.__style_name = attr['name']
+
+ def end_style(self):
+ self._styles[self.__style_name] = self.__style_props
+ del self.__style_props
+ del self.__style_name
+
+ def start_property(self, attr):
+ self.__style_prop_name = attr['name']
+
+ def chars_property(self, value):
+ value.strip()
+
+ # convert value
+ if self.__style_prop_name in ['font','foreground','background',]:
+ pass
+
+ elif self.__style_prop_name == 'variant':
+ if not value in self.style_variant_table.keys():
+ Exception("Unknown style-variant: %s"%value)
+ value = self.style_variant_table[value]
+
+ elif self.__style_prop_name == 'underline':
+ if not value in self.style_underline_table.keys():
+ Exception("Unknown underline-style: %s"%value)
+ value = self.style_underline_table[value]
+
+ elif self.__style_prop_name == 'scale':
+ if not value in self.style_scale_table.keys():
+ Exception("Unknown scale-style: %s"%value)
+ value = self.style_scale_table[value]
+
+ elif self.__style_prop_name == 'weight':
+ if not value in self.style_weight_table.keys():
+ Exception("Unknown style-weight: %s"%value)
+ value = self.style_weight_table[value]
+
+ elif self.__style_prop_name == 'style':
+ if not value in self.style_style_table[value]:
+ Exception("Unknwon text-style: %s"%value)
+ value = self.style_style_table[value]
+
+ else:
+ raise Exception("Unknown
style-property %s"%self.__style_prop_name)
+
+ # store value
+ self.__style_props[self.__style_prop_name] = value
+
+
+
+
+class CodeBuffer(gtk.TextBuffer):
+ """ This class extends the gtk.TextBuffer to support
syntax-highlighting.
+ You can use this class like a normal TextBuffer. """
+
+ def __init__(self, table=None, lang=None, styles={}):
+ """ The constructor takes 3 optional arguments.
+
+ table specifies a tag-table associated with the
TextBuffer-instance.
+ This argument will be passed directly to the constructor of the
+ TextBuffer-class.
+
+ lang specifies the language-definition. You have to load one
using
+ the SyntaxLoader-class or you may hard-code your
syntax-definition
+ using the LanguageDefinition-class.
+
+ styles is a dictionary used to extend or overwrite the default
styles
+ provided by this module (DEFAULT_STYLE) and any language
specific
+ styles defined by the LanguageDefinition. """
+ gtk.TextBuffer.__init__(self, table)
+
+ # default styles
+ self.styles = DEFAULT_STYLES
+
+ # update styles with lang-spec:
+ if lang:
+ self.styles.update(lang.get_styles())
+ # update styles with user-defined
+ self.styles.update(styles)
+
+ # create tags
+ for name, props in self.styles.items():
+ style = dict(self.styles['DEFAULT']) # take default
+ style.update(props) # and update with props
+ self.create_tag(name, **style)
+
+ # store lang-definition
+ self._lang_def = lang
+
+ self.connect_after("insert-text", self._on_insert_text)
+ self.connect_after("delete-range", self._on_delete_range)
+ self.connect('apply-tag', self._on_apply_tag)
+
+ self._apply_tags = False
+
+
+ def _on_apply_tag(self, buf, tag, start, end):
+ # FIXME This is a hack! It allows apply-tag only while
+ # _on_insert_text() and _on_delete_range()
+ if not self._apply_tags:
+ self.emit_stop_by_name('apply-tag')
+ return True
+
+ _log_debug("tag \"%s\" as %s"%(self.get_slice(start,end),
tag.get_property("name")))
+
+
+ def _on_insert_text(self, buf, it, text, length):
+ # if no syntax defined -> nop
+ if not self._lang_def: return False
+
+ it = it.copy()
+ it.backward_chars(length)
+
+ if not it.begins_tag():
+ it.backward_to_tag_toggle(None)
+ _log_debug("Not tag-start -> moved iter to %i
(%s)"%(it.get_offset(), it.get_char()))
+
+ if it.begins_tag(self.get_tag_table().lookup("DEFAULT")):
+ it.backward_to_tag_toggle(None)
+ _log_debug("Iter at DEFAULT-start -> moved to %i
(%s)"%(it.get_offset(), it.get_char()))
+
+ self._apply_tags = True
+ self.update_syntax(it)
+ self._apply_tags = False
+
+
+ def _on_delete_range(self, buf, start, end):
+ # if no syntax defined -> nop
+ if not self._lang_def: return False
+
+ start = start.copy()
+ if not start.begins_tag():
+ start.backward_to_tag_toggle(None)
+
+ self._apply_tags = True
+ self.update_syntax(start)
+ self._apply_tags = False
+
+
+ def update_syntax(self, start, end=None):
+ """ More or less internal used method to update the
+ syntax-highlighting. """
+ # if no lang set
+ if not self._lang_def: return
+ _log_debug("Update syntax from %i"%start.get_offset())
+
+ # if not end defined
+ if not end: end = self.get_end_iter()
+
+ # We do not use recursion -> long files exceed rec-limit!
+ finished = False
+ while not finished:
+ # search first rule matching txt[start..end]
+ mstart, mend, tagname = self._lang_def(self, start, end)
+
+ # optimisation: if mstart-mend is allready tagged with tagname
+ # -> finished
+ if tagname: #if something found
+ tag = self.get_tag_table().lookup(tagname)
+ if mstart.begins_tag(tag) and mend.ends_tag(tag) and not
mstart.equal(start):
+ self.remove_all_tags(start,mstart)
+ self.apply_tag_by_name("DEFAULT", start, mstart)
+ _log_debug("Optimized: Found old tag at %i
(%s)"%(mstart.get_offset(), mstart.get_char()))
+ # finish
+ finished = True
+ continue
+
+ # remove all tags from start..mend (mend == buffer-end if no
match)
+ self.remove_all_tags(start, mend)
+ # make start..mstart = DEFAUL (mstart == buffer-end if no
match)
+ if not start.equal(mstart):
+ _log_debug("Apply DEFAULT")
+ self.apply_tag_by_name("DEFAULT", start, mstart)
+
+ # nothing found -> finished
+ if not tagname:
+ finished = True
+ continue
+
+ # apply tag
+ _log_debug("Apply %s"%tagname)
+ self.apply_tag_by_name(tagname, mstart, mend)
+
+ start = mend
+
+ if start == end:
+ finished = True
+ continue
+
+
+ def reset_language(self, lang_def):
+ """ Reset the currently used language-definition. """
+ # remove all tags from complete text
+ start = self.get_start_iter()
+ self.remove_all_tags(start, self.get_end_iter())
+ # store lexer
+ self._lang_def = lang_def
+ # update styles from lang_def:
+ if self._lang_def:
+ self.update_styles(self._lang_def.get_styles())
+ # and ...
+ self._apply_tags = True
+ self.update_syntax(start)
+ self._apply_tags = False
+
+
+ def update_styles(self, styles):
+ """ Update styles. This method may be used to reset any styles at
+ runtime. """
+ self.styles.update(styles)
+
+ table = self.get_tag_table()
+ for name, props in styles.items():
+ style = self.styles['DEFAULT']
+ style.update(props)
+ # if tagname is unknown:
+ if not table.lookup(name):
+ _log_debug("Create tag: %s (%s)"%(name, style))
+ self.create_tag(name, **style)
+ else: # update tag
+ tag = table.lookup(name)
+ _log_debug("Update tag %s with (%s)"%(name, style))
+ map(lambda i: tag.set_property(i[0],i[1]), style.items())
+
+

Added: trunk/trunk/GUI/lib/pygtkcodebuffer/python.xml
==============================================================================
--- (empty file)
+++ trunk/trunk/GUI/lib/pygtkcodebuffer/python.xml Sat Mar 7 06:44:29 2009
@@ -0,0 +1,195 @@
+<?xml version="1.0"?>
+<!--
+ This syntax-file was generated by sourceview2codebuffer.xsl from
+ GtkSourceView's Python-syntax-file!
+
+ This transformation is not perfect so it may need some hand-word
to fix
+ minor issues in this file.
+
+ You can get sourceview2codebuffer.xsl from
http://pygtkcodebuffer.googlecode.com/.
+ -->
+<syntax>
+
+
+
+ <string style="string" escape="\"><starts>([uUrR]|[uU][rR]|
[rR][uU])?"""</starts><ends>"""</ends></string>
+
+ <string style="string" escape="\"><starts>([uUrR]|[uU][rR]|
[rR][uU])?'''</starts><ends>'''</ends></string>
+
+ <string style="string" escape="\"><starts>([uUrR]|[uU][rR]|
[rR][uU])?"</starts><ends>"</ends></string>
+
+ <string style="string" escape="\"><starts>([uUrR]|[uU][rR]|
[rR][uU])?'</starts><ends>'</ends></string>
+
+ <pattern style="comment">#.*$</pattern>
+
+ <keywordlist style="preprocessor">
+ <keyword>import</keyword>
+ <keyword>from</keyword>
+ <keyword>as</keyword>
+ <keyword>False</keyword>
+ <keyword>None</keyword>
+ <keyword>True</keyword>
+ <keyword>__name__</keyword>
+ <keyword>__debug__</keyword>
+ </keywordlist>
+
+ <keywordlist style="keyword">
+ <keyword>def</keyword>
+ <keyword>class</keyword>
+ <keyword>return</keyword>
+ </keywordlist>
+
+ <keywordlist style="keyword">
+ <keyword>and</keyword>
+ <keyword>assert</keyword>
+ <keyword>break</keyword>
+ <keyword>continue</keyword>
+ <keyword>del</keyword>
+ <keyword>elif</keyword>
+ <keyword>else</keyword>
+ <keyword>except</keyword>
+ <keyword>exec</keyword>
+ <keyword>finally</keyword>
+ <keyword>for</keyword>
+ <keyword>global</keyword>
+ <keyword>if</keyword>
+ <keyword>in</keyword>
+ <keyword>is</keyword>
+ <keyword>lambda</keyword>
+ <keyword>not</keyword>
+ <keyword>or</keyword>
+ <keyword>pass</keyword>
+ <keyword>print</keyword>
+ <keyword>raise</keyword>
+ <keyword>try</keyword>
+ <keyword>while</keyword>
+ <keyword>yield</keyword>
+ </keywordlist>
+
+ <keywordlist style="special">
+ <keyword>ArithmeticError</keyword>
+ <keyword>AssertionError</keyword>
+ <keyword>AttributeError</keyword>
+ <keyword>EnvironmentError</keyword>
+ <keyword>EOFError</keyword>
+ <keyword>Exception</keyword>
+ <keyword>FloatingPointError</keyword>
+ <keyword>ImportError</keyword>
+ <keyword>IndentationError</keyword>
+ <keyword>IndexError</keyword>
+ <keyword>IOError</keyword>
+ <keyword>KeyboardInterrupt</keyword>
+ <keyword>KeyError</keyword>
+ <keyword>LookupError</keyword>
+ <keyword>MemoryError</keyword>
+ <keyword>NameError</keyword>
+ <keyword>NotImplementedError</keyword>
+ <keyword>OSError</keyword>
+ <keyword>OverflowError</keyword>
+ <keyword>ReferenceError</keyword>
+ <keyword>RuntimeError</keyword>
+ <keyword>StandardError</keyword>
+ <keyword>StopIteration</keyword>
+ <keyword>SyntaxError</keyword>
+ <keyword>SystemError</keyword>
+ <keyword>SystemExit</keyword>
+ <keyword>TabError</keyword>
+ <keyword>TypeError</keyword>
+ <keyword>UnboundLocalError</keyword>
+ <keyword>UnicodeDecodeError</keyword>
+ <keyword>UnicodeEncodeError</keyword>
+ <keyword>UnicodeError</keyword>
+ <keyword>UnicodeTranslateError</keyword>
+ <keyword>ValueError</keyword>
+ <keyword>WindowsError</keyword>
+ <keyword>ZeroDivisionError</keyword>
+
+ <keyword>Warning</keyword>
+ <keyword>UserWarning</keyword>
+ <keyword>DeprecationWarning</keyword>
+ <keyword>PendingDeprecationWarning</keyword>
+ <keyword>SyntaxWarning</keyword>
+ <keyword>OverflowWarning</keyword>
+ <keyword>RuntimeWarning</keyword>
+ <keyword>FutureWarning</keyword>
+
+ <keyword>__import__</keyword>
+ <keyword>abs</keyword>
+ <keyword>apply</keyword>
+ <keyword>basestring</keyword>
+ <keyword>bool</keyword>
+ <keyword>buffer</keyword>
+ <keyword>callable</keyword>
+ <keyword>chr</keyword>
+ <keyword>classmethod</keyword>
+ <keyword>cmp</keyword>
+ <keyword>coerce</keyword>
+ <keyword>compile</keyword>
+ <keyword>complex</keyword>
+ <keyword>delattr</keyword>
+ <keyword>dict</keyword>
+ <keyword>dir</keyword>
+ <keyword>divmod</keyword>
+ <keyword>enumerate</keyword>
+ <keyword>eval</keyword>
+ <keyword>execfile</keyword>
+ <keyword>file</keyword>
+ <keyword>filter</keyword>
+ <keyword>float</keyword>
+ <keyword>getattr</keyword>
+ <keyword>globals</keyword>
+ <keyword>hasattr</keyword>
+ <keyword>hash</keyword>
+ <keyword>hex</keyword>
+ <keyword>id</keyword>
+ <keyword>input</keyword>
+ <keyword>int</keyword>
+ <keyword>intern</keyword>
+ <keyword>isinstance</keyword>
+ <keyword>issubclass</keyword>
+ <keyword>iter</keyword>
+ <keyword>len</keyword>
+ <keyword>list</keyword>
+ <keyword>locals</keyword>
+ <keyword>long</keyword>
+ <keyword>map</keyword>
+ <keyword>max</keyword>
+ <keyword>min</keyword>
+ <keyword>object</keyword>
+ <keyword>oct</keyword>
+ <keyword>open</keyword>
+ <keyword>ord</keyword>
+ <keyword>pow</keyword>
+ <keyword>property</keyword>
+ <keyword>range</keyword>
+ <keyword>raw_input</keyword>
+ <keyword>reduce</keyword>
+ <keyword>reload</keyword>
+ <keyword>repr</keyword>
+ <keyword>round</keyword>
+ <keyword>setattr</keyword>
+ <keyword>slice</keyword>
+ <keyword>staticmethod</keyword>
+ <keyword>str</keyword>
+ <keyword>sum</keyword>
+ <keyword>super</keyword>
+ <keyword>tuple</keyword>
+ <keyword>type</keyword>
+ <keyword>unichr</keyword>
+ <keyword>unicode</keyword>
+ <keyword>vars</keyword>
+ <keyword>xrange</keyword>
+ <keyword>zip</keyword>
+ </keywordlist>
+
+ <pattern style="datatype">\bself\b</pattern>
+
+ <pattern style="number">\b([1-9][0-9]*|0)([Uu]([Ll]|LL|ll)?|([Ll]|LL|
ll)[Uu]?)?\b</pattern>
+
+ <pattern style="number">\b([0-9]+[Ee][-]?[0-9]+|([0-9]*\.[0-9]+|
[0-9]+\.)([Ee][-]?[0-9]+)?)[fFlL]?</pattern>
+
+ <pattern style="number">\b0[0-7]+([Uu]([Ll]|LL|ll)?|([Ll]|LL|
ll)[Uu]?)?\b</pattern>
+
+ <pattern style="number">\b0[xX][0-9a-fA-F]+([Uu]([Ll]|LL|ll)?|([Ll]|LL|
ll)[Uu]?)?\b</pattern>
+
+</syntax>

Added: trunk/trunk/GUI/lib/pygtkcodebuffer/simple.py
==============================================================================
--- (empty file)
+++ trunk/trunk/GUI/lib/pygtkcodebuffer/simple.py Sat Mar 7 06:44:29 2009
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+import gtk
+import sys
+
+# comment-out if CodeBuffer is installed
+sys.path.insert(0, "..")
+from gtkcodebuffer import CodeBuffer, SyntaxLoader, add_syntax_path
+
+
+# comment-out if CodeBuffer is installed
+add_syntax_path("../syntax")
+
+lang = SyntaxLoader("python")
+buff = CodeBuffer(lang=lang)
+
+win = gtk.Window(gtk.WINDOW_TOPLEVEL)
+scr = gtk.ScrolledWindow()
+win.add(scr)
+scr.add(gtk.TextView(buff))
+
+win.set_default_size(300,200)
+win.show_all()
+win.connect("destroy", lambda w: gtk.main_quit())
+
+buff.set_text(open(__file__,'r').read())
+
+gtk.main()

Modified: trunk/trunk/GUI/main_window_events.py
==============================================================================
--- trunk/trunk/GUI/main_window_events.py (original)
+++ trunk/trunk/GUI/main_window_events.py Sat Mar 7 06:44:29 2009
@@ -3,7 +3,7 @@
import gtk.glade
except: sys.exit(1)

-import sys,os
+import sys,os, compiler
import runtime
import gobject
import game
@@ -413,7 +413,6 @@
self.selectedsound.loop=True
else:
self.selectedsound.loop=False
-
self.get_widget("wnd_sound").hide()

def workstate_cancel(self,widget=None):
@@ -422,7 +421,6 @@

def change_event_selected(self,widget=None):

-
# Get the currently selected event code
text = self.get_widget("text_event_script")
textbuffer = text.get_buffer()
@@ -443,7 +441,9 @@
active = cb.get_active()
model = cb.get_model()

-
textbuffer.set_text(self.selectedworkstate.actions.get(int(model[active][1]),""))
+ event_code =
self.selectedworkstate.actions.get(int(model[active][1]),"")
+ textbuffer.set_text(event_code)
+ #print compiler.parse(event_code)
self.selected_workstate_event = int(model[active][1])

def save_event(self,widget=None):

Modified: trunk/trunk/gamebaker.py
==============================================================================
--- trunk/trunk/gamebaker.py (original)
+++ trunk/trunk/gamebaker.py Sat Mar 7 06:44:29 2009
@@ -32,6 +32,7 @@

from GUI.main_window_events import hide_window
from GUI.main_window_events import main_window_events
+from GUI.lib.pygtkcodebuffer import CodeBuffer, SyntaxLoader
import GUI

try:
@@ -94,7 +95,10 @@
text=0) # position of column
treeview.append_column(column)

-
+ # Set up code windows to use python syntax highlighting
+ pylang = SyntaxLoader("python")
+ self.wTree.get_widget("textview_load_events").set_buffer(
CodeBuffer(lang=pylang) )
+ self.wTree.get_widget("text_event_script").set_buffer(
CodeBuffer(lang=pylang) )
# Connect specific events

# Connect close button on dialog

Reply all
Reply to author
Forward
0 new messages