diff options
| author | nyamatongwe <unknown> | 2012-05-17 12:46:29 +1000 | 
|---|---|---|
| committer | nyamatongwe <unknown> | 2012-05-17 12:46:29 +1000 | 
| commit | bf8b35542c4be4b8eebb71ca2ad518da2e12b850 (patch) | |
| tree | eab094df23f84c33c7ed03f3412a63a060d31eac /qt/ScintillaEditPy | |
| parent | 29c92749f25f24795ecd9fec2b6705129ebbd654 (diff) | |
| download | scintilla-mirror-bf8b35542c4be4b8eebb71ca2ad518da2e12b850.tar.gz | |
Qt platform layer added. Based on an implementation from Jason Haslam
at Scientific Toolworks, Inc. with additions performed for Wingware.
Diffstat (limited to 'qt/ScintillaEditPy')
| -rw-r--r-- | qt/ScintillaEditPy/README | 85 | ||||
| -rw-r--r-- | qt/ScintillaEditPy/ScintillaConstants.py.template | 6 | ||||
| -rw-r--r-- | qt/ScintillaEditPy/ScintillaEditPy.pro | 116 | ||||
| -rw-r--r-- | qt/ScintillaEditPy/global.h | 4 | ||||
| -rw-r--r-- | qt/ScintillaEditPy/sepbuild.py | 312 | ||||
| -rw-r--r-- | qt/ScintillaEditPy/testsepq.py | 157 | ||||
| -rw-r--r-- | qt/ScintillaEditPy/typesystem_ScintillaEdit.xml.template | 16 | 
7 files changed, 696 insertions, 0 deletions
diff --git a/qt/ScintillaEditPy/README b/qt/ScintillaEditPy/README new file mode 100644 index 000000000..c07397031 --- /dev/null +++ b/qt/ScintillaEditPy/README @@ -0,0 +1,85 @@ +README for building of ScintillaEditPy on Qt with PySide
 +
 +This directory is for building a Python encapsulation of Scintilla for use
 +with PySide. For C++ libraries see the README in the parent directory.
 +
 +	Prerequisites
 +	
 +PySide and ScintillaEditPy currently only support Python 2.x.
 +
 +CMake may be used to rebuild PySide and is required on Windows.
 +It can be downloaded from
 +http://www.cmake.org/cmake/resources/software.html
 +
 +On Windows, PySide only supports Visual C++ 2008. The "Visual Studio 2008
 +Command Prompt" should be used to run all build commands.
 +Visual C++ 2008 Express Edition can be downloaded from
 +http://msdn.microsoft.com/en-us/express/future/bb421473
 +
 +Download and install PySide. Instructions are on the PySide web site
 +http://developer.qt.nokia.com/wiki/Category:LanguageBindings::PySide::Downloads
 +
 +For Linux, there may be both PySide library packages and PySide development
 +files. Both should be installed as ScintillaEditPy needs the headers and
 +libraries from the development package and runs with the normal library package.
 +On apt-based systems, the packages are libshiboken-dev, shiboken, libpyside-dev,
 +and python-pyside. python-dev is also needed for Python language headers.
 +On yum-based systems the libpyside-dev package is called python-pyside-devel.
 +The qmake program may not be in the path and can be found with
 +"find /usr -name qmake".
 +
 +On Windows, the PySide library packages can be downloaded from 
 +http://developer.qt.nokia.com/wiki/PySide_Binaries_Windows
 +The PySide development files must be built from source using CMake as 
 +described on the PySide site. This will create a Unix-style set of [bin, include,
 +lib, and share] directories in packaging\setuptools\install-py<ver>-qt<qver>. 
 +There is no standard place for the PySide development files so copy them
 +to "\usr", creating it if needed.
 +
 +On OS X, a combined package with PySide libraries and PySide development
 +files can be downloaded from 
 +http://developer.qt.nokia.com/wiki/PySide_Binaries_MacOSX
 +This package works best in combination with the Qt libraries for Mac from
 +http://qt.nokia.com/downloads/downloads#qt-lib
 +
 +The path should be modified so that a Python 2.x interpreter and Qt's "qmake"
 +program can be run by typing "python" or "qmake".
 +
 +	Building
 +
 +There are several steps to building and they are encapsulated in the sepbuild.py
 +script which is run:
 +
 +python sepbuild.py
 +
 +This script first runs the WidgetGen.py script to fill out the ScintillaEdit.h, 
 +ScintillaEdit.cpp and ScintillaConstants.py files.
 +
 +A short file "sepbuild.pri" is written out which contains a series of version and 
 +path properties discovered by sepbuild.py which are used by qmake.
 +
 +Then it runs PySide's "shiboken" program to create C++ code that will act as a
 +bridge between Python and the C++ libraries. This code goes into the 
 +ScintillaEditPy/ScintillaEditPy directory. Several log files are produced which can
 +help uncover problems in the bridge if it fails to build.
 +
 +The qmake program is run to produce make files from ScintillaEditPy.pro.
 +
 +The system make program is then run to build the library. The library is located in
 +the scintilla/bin directory as ScintillaEditPy.so for Unix systems and 
 +ScintillaEditPy.pyd for Windows.
 +
 +A demonstration program can be run:
 +
 +python testswp.py
 +
 +The individual steps in the script can be run manually if wanted although the
 +shiboken program has complex arguments and differs between systems so run 
 +sepbuild.py and copy the section starting with a line containing "generatorrunner"
 +and continuing to "typesystem_ScintillaEdit.xml".
 +
 +On Windows, it is more difficult to set up an environment to debug ScintillaEditPy
 +since all the libraries have to be debug or all have to be release. The easy path 
 +is to always build for release with "nmake release".
 +
 +To remove generated code, run "python sepbuild.py --clean".
 diff --git a/qt/ScintillaEditPy/ScintillaConstants.py.template b/qt/ScintillaEditPy/ScintillaConstants.py.template new file mode 100644 index 000000000..31b82398d --- /dev/null +++ b/qt/ScintillaEditPy/ScintillaConstants.py.template @@ -0,0 +1,6 @@ +# ScintillaConstants.py +# Define all the symbolic constants from Scintilla.iface so Python code can use them +# Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware + +# ++Autogenerated -- start of section automatically generated from Scintilla.iface */ +# --Autogenerated -- end of section automatically generated from Scintilla.iface */ diff --git a/qt/ScintillaEditPy/ScintillaEditPy.pro b/qt/ScintillaEditPy/ScintillaEditPy.pro new file mode 100644 index 000000000..c578a314c --- /dev/null +++ b/qt/ScintillaEditPy/ScintillaEditPy.pro @@ -0,0 +1,116 @@ +TEMPLATE = lib +QT += core gui + +TARGET = ScintillaEditPy + +# Clear debug & release so that sepbuild.pri can set one or the other +CONFIG -= debug release + +include(sepbuild.pri) + +VERSION = $$SCINTILLA_VERSION + +win32 { +	DebugBuild { +		TARGET_EXT = _d.pyd +	} +	else { +		TARGET_EXT = .pyd +	} +} + +INCLUDEPATH += ../ScintillaEdit +INCLUDEPATH += ../ScintillaEditBase +INCLUDEPATH += ../../include ../../lexlib ../../src + +INCLUDEPATH += $$PY_INCLUDES + +INCLUDEPATH += $$SHIBOKEN_INCLUDES +INCLUDEPATH += $$PYSIDE_INCLUDES +INCLUDEPATH += $$PYSIDE_INCLUDES/QtCore +INCLUDEPATH += $$PYSIDE_INCLUDES/QtGui + +unix:!mac { +	LIBS += -ldl +	LIBS += `pkg-config pyside --libs` +} + +macx { +	# Only build for x64 for now +	# QMAKE_CFLAGS = -arch i386 -arch x86_64 +	# QMAKE_CXXFLAGS = -arch i386 -arch x86_64 +	# QMAKE_LFLAGS = -arch i386 -arch x86_64 +	LIBS += -L$$PY_LIBDIR -lpython$$PY_VERSION_SUFFIX +	LIBS += -L$$PYSIDE_LIB +	debug { +		LIBS += -lshiboken-python$$PY_VERSION_SUFFIX-dbg +		LIBS += -lpyside-python$$PY_VERSION_SUFFIX-dbg +	} +	else { +		LIBS += -lshiboken-python$$PY_VERSION_SUFFIX +		LIBS += -lpyside-python$$PY_VERSION_SUFFIX +	} +} + +win32 { +	DebugBuild { +		DEFINES += DEBUG +		LIBS += -lQtCored4 +	} +	else { +		LIBS += -lQtCore +	} +	LIBS += -L$$PY_PREFIX/libs # Note python lib is pulled in via a #pragma +	LIBS += -L$$PYSIDE_LIB +	# PySide uses x.y suffix on Windows even though Python uses xy +	DebugBuild { +		LIBS += -lshiboken-python$${PY_VERSION}_d +		LIBS += -lpyside-python$${PY_VERSION}_d +	} +	else { +		LIBS += -lshiboken-python$${PY_VERSION} +		LIBS += -lpyside-python$${PY_VERSION} +	} +} + +# Wrapper sources; notifyheader commented out due to shiboken bug +SOURCES += \ +	ScintillaEditPy/scintillaeditpy_module_wrapper.cpp \ +	ScintillaEditPy/sci_notifyheader_wrapper.cpp \ +	ScintillaEditPy/scnotification_wrapper.cpp \ +	ScintillaEditPy/scintillaeditbase_wrapper.cpp \ +	ScintillaEditPy/scintillaedit_wrapper.cpp \ +	ScintillaEditPy/scintilladocument_wrapper.cpp + +# ScintillaEdit sources + +SOURCES += \ +    ../ScintillaEdit/ScintillaEdit.cpp \ +    ../ScintillaEdit/ScintillaDocument.cpp \ +    ../ScintillaEditBase/PlatQt.cpp \ +    ../ScintillaEditBase/ScintillaQt.cpp \ +    ../ScintillaEditBase/ScintillaEditBase.cpp \ +    ../../src/*.cxx \ +    ../../lexlib/*.cxx \ +    ../../lexers/*.cxx + +# HEADERS is used to find what needs to be run through moc +HEADERS  += \ +    ../ScintillaEdit/ScintillaEdit.h \ +    ../ScintillaEdit/ScintillaDocument.h \ +    ../ScintillaEditBase/ScintillaQt.h \ +    ../ScintillaEditBase/ScintillaEditBase.h + +DEFINES += SCINTILLA_QT=1 MAKING_LIBRARY=1 SCI_LEXER=1 _CRT_SECURE_NO_DEPRECATE=1 + +DESTDIR = ../../bin + +unix:!mac { +	# Rename to not have 'lib' at start +	QMAKE_POST_LINK += rm -rf ../../bin/ScintillaEditPy.so && ln -s libScintillaEditPy.so ../../bin/ScintillaEditPy.so +} + +macx { +	# Rename to .so and not have 'lib' at start +	QMAKE_POST_LINK += rm -rf ../../bin/ScintillaEditPy.so && ln -s libScintillaEditPy.dylib ../../bin/ScintillaEditPy.so +} diff --git a/qt/ScintillaEditPy/global.h b/qt/ScintillaEditPy/global.h new file mode 100644 index 000000000..8b4be843a --- /dev/null +++ b/qt/ScintillaEditPy/global.h @@ -0,0 +1,4 @@ +#include "pyside_global.h" + +#include "ScintillaEditBase.h" +#include "ScintillaEdit.h" diff --git a/qt/ScintillaEditPy/sepbuild.py b/qt/ScintillaEditPy/sepbuild.py new file mode 100644 index 000000000..b694f15b0 --- /dev/null +++ b/qt/ScintillaEditPy/sepbuild.py @@ -0,0 +1,312 @@ +import distutils.sysconfig +import getopt +import glob +import os +import platform +import shutil +import subprocess +import stat +import sys + +sys.path.append(os.path.join("..", "ScintillaEdit")) +import WidgetGen + +# Decide up front which platform, treat anything other than Windows or OS X as Linux +PLAT_WINDOWS = platform.system() == "Windows" +PLAT_DARWIN = platform.system() == "Darwin" +PLAT_LINUX = not (PLAT_DARWIN or PLAT_WINDOWS) + +def IsFileNewer(name1, name2): +	""" Returns whether file with name1 is newer than file with name2.  Returns 1 +	if name2 doesn't exist. """ + +	if not os.path.exists(name1): +		return 0 + +	if not os.path.exists(name2): +		return 1 + +	mod_time1 = os.stat(name1)[stat.ST_MTIME] +	mod_time2 = os.stat(name2)[stat.ST_MTIME] +	return (mod_time1 > mod_time2) + +def textFromRun(args): +	(stdoutdata, stderrdata) = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE).communicate() +	return stdoutdata + +def runProgram(args, exitOnFailure): +	print(" ".join(args)) +	retcode = subprocess.call(" ".join(args), shell=True, stderr=subprocess.STDOUT) +	if retcode: +		print("Failed in " + " ".join(args) + " return code = " + str(retcode)) +		if exitOnFailure: +			sys.exit() + +def usage(): +	print("sepbuild.py [-h|--help][-c|--clean][-u|--underscore-names]") +	print("") +	print("Generate PySide wappers and build them.") +	print("") +	print("options:") +	print("") +	print("-c --clean remove all object and generated files") +	print("-b --pyside-base  Location of the PySide+Qt4 sandbox to use") +	print("-h --help  display this text") +	print("-d --debug=yes|no  force debug build (or non-debug build)") +	print("-u --underscore-names  use method_names consistent with GTK+ standards") + +modifyFunctionElement = """		<modify-function signature="%s">%s +		</modify-function> +""" + +injectCode = """ +			<inject-code class="target" position="beginning">%s +			</inject-code>""" + +injectCheckN = """ +				if (!cppArg%d) { +					PyErr_SetString(PyExc_ValueError, "Null string argument"); +					return 0; +				}""" + +def methodSignature(name, v, options): +	argTypes = "" +	p1Type = WidgetGen.cppAlias(v["Param1Type"]) +	if p1Type: +		argTypes = argTypes + p1Type +	p2Type = WidgetGen.cppAlias(v["Param2Type"]) +	if p2Type and v["Param2Type"] != "stringresult": +		if p1Type: +			argTypes = argTypes + ", " +		argTypes = argTypes + p2Type +	methodName = WidgetGen.normalisedName(name, options, v["FeatureType"]) +	constDeclarator = " const" if v["FeatureType"] == "get" else "" +	return methodName + "(" + argTypes + ")" + constDeclarator + +def printTypeSystemFile(f,out, options): +	for name in f.order: +		v = f.features[name] +		if v["Category"] != "Deprecated": +			feat = v["FeatureType"] +			if feat in ["fun", "get", "set"]: +				checks = "" +				if v["Param1Type"] == "string": +					checks = checks + (injectCheckN % 0) +				if v["Param2Type"] == "string": +					if v["Param1Type"] == "":	# Only arg 2 -> treat as first +						checks = checks + (injectCheckN % 0) +					else: +						checks = checks + (injectCheckN % 1) +				if checks: +					inject = injectCode % checks +					out.write(modifyFunctionElement % (methodSignature(name, v, options), inject)) +				#if v["Param1Type"] == "string": +				#	out.write("<string-xml>" + name + "</string-xml>\n") + +def doubleBackSlashes(s): +	# Quote backslashes so qmake does not produce warnings +	return s.replace("\\", "\\\\") + +class SepBuilder: +	def __init__(self): +		# Discover configuration parameters +		self.ScintillaEditIncludes = [".", "../ScintillaEdit", "../ScintillaEditBase", "../../include"] +		if PLAT_WINDOWS: +			self.MakeCommand = "nmake" +			self.MakeTarget = "release" +		else: +			self.MakeCommand = "make" +			self.MakeTarget = "" + +		if PLAT_DARWIN: +			self.QMakeOptions = "-spec macx-g++" +		else: +			self.QMakeOptions = "" + +		# Default to debug build if running in a debug build interpreter +		self.DebugBuild = hasattr(sys, 'getobjects') + +		# Python +		self.PyVersion = "%d.%d" % sys.version_info[:2] +		self.PyVersionSuffix = distutils.sysconfig.get_config_var("VERSION") +		self.PyIncludes = distutils.sysconfig.get_python_inc() +		self.PyPrefix = distutils.sysconfig.get_config_var("prefix") +		self.PyLibDir = distutils.sysconfig.get_config_var( +			("LIBDEST" if sys.platform == 'win32' else "LIBDIR")) + +		# Scintilla +		with open("../../version.txt") as f: +			version = f.read() +			self.ScintillaVersion = version[0] + '.' + version[1] + '.' + version[2] + +		# Qt default location from qmake +		self._SetQtIncludeBase(textFromRun("qmake -query QT_INSTALL_HEADERS").rstrip()) + +		# PySide default location +		# No standard for installing PySide development headers and libs on Windows so +		# choose /usr to be like Linux +		self._setPySideBase('\\usr' if PLAT_WINDOWS else '/usr') + +		self.ProInclude = "sepbuild.pri" + +		self.qtStyleInterface = True + +	def _setPySideBase(self, base): +		 +		self.PySideBase = base +		if PLAT_LINUX: +			self.PySideTypeSystem = textFromRun("pkg-config --variable=typesystemdir pyside").rstrip() +			self.PySideIncludeBase = textFromRun("pkg-config --variable=includedir pyside").rstrip() +			self.ShibokenIncludeBase = textFromRun("pkg-config --variable=includedir shiboken").rstrip() +		else: +			self.PySideTypeSystem = os.path.join(self.PySideBase, "share", "PySide", "typesystems") +			self.ShibokenIncludeBase = os.path.join(self.PySideBase, "include", "shiboken") +			self.PySideIncludeBase = os.path.join(self.PySideBase, "include", "PySide") + +		self.PySideIncludes = [ +			self.ShibokenIncludeBase, +			self.PySideIncludeBase, +			os.path.join(self.PySideIncludeBase, "QtCore"), +			os.path.join(self.PySideIncludeBase, "QtGui")] + +		self.PySideLibDir = os.path.join(self.PySideBase, "lib") +		self.AllIncludes = os.pathsep.join(self.QtIncludes + self.ScintillaEditIncludes + self.PySideIncludes) + +		self.ShibokenGenerator = "shiboken" +		# Is this still needed? It doesn't work with latest shiboken sources +		#if PLAT_DARWIN: +		#	# On OS X, can not automatically find Shiboken dylib so provide a full path +		#	self.ShibokenGenerator = os.path.join(self.PySideLibDir, "generatorrunner", "shiboken") + +	def generateAPI(self, args): +		os.chdir(os.path.join("..", "ScintillaEdit")) +		if not self.qtStyleInterface: +			args.insert(0, '--underscore-names') +		WidgetGen.main(args) +		f = WidgetGen.readInterface(False) +		os.chdir(os.path.join("..", "ScintillaEditPy")) +		options = {"qtStyle": self.qtStyleInterface} +		WidgetGen.Generate("typesystem_ScintillaEdit.xml.template", "typesystem_ScintillaEdit.xml", printTypeSystemFile, f, options) + +	def runGenerator(self): +		generatorrunner = "shiboken" +		for name in ('shiboken', 'generatorrunner'): +			if PLAT_WINDOWS: +				name += '.exe' +			name = os.path.join(self.PySideBase, "bin", name) +			if os.path.exists(name): +				generatorrunner = name +				break +				 +		args = [ +			generatorrunner, +			"--generator-set=" + self.ShibokenGenerator, +			"global.h ", +			"--avoid-protected-hack", +			"--enable-pyside-extensions", +			"--include-paths=" + self.AllIncludes, +			"--typesystem-paths=" + self.PySideTypeSystem, +			"--output-directory=.", +			"typesystem_ScintillaEdit.xml"] +		print(" ".join(args)) +		retcode = subprocess.call(" ".join(args), shell=True, stderr=subprocess.STDOUT) +		if retcode: +			print("Failed in generatorrunner", retcode) +			sys.exit() + +	def writeVariables(self): +		# Write variables needed into file to be included from project so it does not have to discover much +		with open(self.ProInclude, "w") as f: +			f.write("SCINTILLA_VERSION=" + self.ScintillaVersion + "\n") +			f.write("PY_VERSION=" + self.PyVersion + "\n") +			f.write("PY_VERSION_SUFFIX=" + self.PyVersionSuffix + "\n") +			f.write("PY_PREFIX=" + doubleBackSlashes(self.PyPrefix) + "\n") +			f.write("PY_INCLUDES=" + doubleBackSlashes(self.PyIncludes) + "\n") +			f.write("PY_LIBDIR=" + doubleBackSlashes(self.PyLibDir) + "\n") +			f.write("PYSIDE_INCLUDES=" + doubleBackSlashes(self.PySideIncludeBase) + "\n") +			f.write("PYSIDE_LIB=" + doubleBackSlashes(self.PySideLibDir) + "\n") +			f.write("SHIBOKEN_INCLUDES=" + doubleBackSlashes(self.ShibokenIncludeBase) + "\n") +			if self.DebugBuild: +				f.write("CONFIG += debug\n") +			else: +				f.write("CONFIG += release\n") + +	def make(self): +		runProgram(["qmake", self.QMakeOptions], exitOnFailure=True) +		runProgram([self.MakeCommand, self.MakeTarget], exitOnFailure=True) + +	def cleanEverything(self): +		self.generateAPI(["--clean"]) +		runProgram([self.MakeCommand, "distclean"], exitOnFailure=False) +		try: +			os.remove(self.ProInclude) +		except OSError: +			pass +		for logFile in glob.glob("*.log"): +			try: +				os.remove(logFile) +			except OSError: +				pass +		shutil.rmtree("debug", ignore_errors=True) +		shutil.rmtree("release", ignore_errors=True) +		shutil.rmtree("ScintillaEditPy", ignore_errors=True) + +	def buildEverything(self): +		cleanGenerated = False +		opts, args = getopt.getopt(sys.argv[1:], "hcdub", +					["help", "clean", "debug=",  +					"underscore-names", "pyside-base="]) +		for opt, arg in opts: +			if opt in ("-h", "--help"): +				usage() +				sys.exit() +			elif opt in ("-c", "--clean"): +				cleanGenerated = True +			elif opt in ("-d", "--debug"): +				self.DebugBuild = (arg == '' or arg.lower() == 'yes') +				if self.DebugBuild and sys.platform == 'win32': +					self.MakeTarget = 'debug' +			elif opt in ("-b", '--pyside-base'): +				self._SetQtIncludeBase(os.path.join(os.path.normpath(arg), 'include')) +				self._setPySideBase(os.path.normpath(arg)) +			elif opt in ("-u", "--underscore-names"): +				self.qtStyleInterface = False + +		if cleanGenerated: +			self.cleanEverything() +		else: +			self.writeVariables() +			self.generateAPI([""]) +			self.runGenerator() +			self.make() +			self.copyScintillaConstants() +			 +	def copyScintillaConstants(self): +		 +		orig = 'ScintillaConstants.py' +		dest = '../../bin/' + orig +		if IsFileNewer(dest, orig): +			return +		 +		f = open(orig, 'r') +		contents = f.read() +		f.close() +		 +		f = open(dest, 'w') +		f.write(contents) +		f.close() + +	def _SetQtIncludeBase(self, base): + +		self.QtIncludeBase = base +		self.QtIncludes = [self.QtIncludeBase] + [os.path.join(self.QtIncludeBase, sub) for sub in ["QtCore", "QtGui"]] +		# Set path so correct qmake is found +		path = os.environ.get('PATH', '').split(os.pathsep) +		qt_bin_dir = os.path.join(os.path.dirname(base), 'bin') +		if qt_bin_dir not in path: +			path.insert(0, qt_bin_dir) +			os.environ['PATH'] = os.pathsep.join(path) + +if __name__ == "__main__": +	sepBuild = SepBuilder() +	sepBuild.buildEverything() diff --git a/qt/ScintillaEditPy/testsepq.py b/qt/ScintillaEditPy/testsepq.py new file mode 100644 index 000000000..a3849295d --- /dev/null +++ b/qt/ScintillaEditPy/testsepq.py @@ -0,0 +1,157 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import sys + +from PySide.QtCore import * +from PySide.QtGui import * + +import ScintillaConstants as sci + +sys.path.append("../..") +from bin import ScintillaEditPy + +txtInit =	"int main(int argc, char **argv) {\n" \ +		"    // Start up the gnome\n" \ +		"    gnome_init(\"stest\", \"1.0\", argc, argv);\n}\n"; + +keywords = \ +		"and and_eq asm auto bitand bitor bool break " \ +		"case catch char class compl const const_cast continue " \ +		"default delete do double dynamic_cast else enum explicit export extern false float for " \ +		"friend goto if inline int long mutable namespace new not not_eq " \ +		"operator or or_eq private protected public " \ +		"register reinterpret_cast return short signed sizeof static static_cast struct switch " \ +		"template this throw true try typedef typeid typename union unsigned using " \ +		"virtual void volatile wchar_t while xor xor_eq"; + +def uriDropped(): +	print "uriDropped" + +class Form(QDialog): + +	def __init__(self, parent=None): +		super(Form, self).__init__(parent) +		self.resize(460,300) +		# Create widgets +		self.edit = ScintillaEditPy.ScintillaEdit(self) +		self.edit.uriDropped.connect(uriDropped) +		self.edit.command.connect(self.receive_command) +		self.edit.notify.connect(self.receive_notification) + +		self.edit.styleClearAll() +		self.edit.setMarginWidthN(0, 35) +		self.edit.setScrollWidth(200) +		self.edit.setScrollWidthTracking(1) +		self.edit.setLexer(sci.SCLEX_CPP) +		self.edit.styleSetFore(sci.SCE_C_COMMENT, 0x008000) +		self.edit.styleSetFore(sci.SCE_C_COMMENTLINE, 0x008000) +		self.edit.styleSetFore(sci.SCE_C_COMMENTDOC, 0x008040) +		self.edit.styleSetItalic(sci.SCE_C_COMMENTDOC, 1) +		self.edit.styleSetFore(sci.SCE_C_NUMBER, 0x808000) +		self.edit.styleSetFore(sci.SCE_C_WORD, 0x800000) +		self.edit.styleSetBold(sci.SCE_C_WORD, True) +		self.edit.styleSetFore(sci.SCE_C_STRING, 0x800080) +		self.edit.styleSetFore(sci.SCE_C_PREPROCESSOR, 0x008080) +		self.edit.styleSetBold(sci.SCE_C_OPERATOR, True) +		self.edit.setMultipleSelection(1) +		self.edit.setVirtualSpaceOptions( +			sci.SCVS_RECTANGULARSELECTION | sci.SCVS_USERACCESSIBLE) +		self.edit.setAdditionalSelectionTyping(1) + +		self.edit.styleSetFore(sci.STYLE_INDENTGUIDE, 0x808080) +		self.edit.setIndentationGuides(sci.SC_IV_LOOKBOTH) + +		self.edit.setKeyWords(0, keywords) +		self.edit.addText(len(txtInit), txtInit) +		self.edit.setSel(1,10) +		retriever = str(self.edit.getLine(1)) +		print(type(retriever), len(retriever)) +		print('[' + retriever + ']') +		someText = str(self.edit.textRange(2,5)) +		print(len(someText), '[' + someText + ']') +		someText = self.edit.getCurLine(100) +		print(len(someText), '[' + someText + ']') +		someText = self.edit.styleGetFont(1) +		print(len(someText), '[' + someText + ']') +		someText = self.edit.getSelText() +		print(len(someText), '[' + someText + ']') +		someText = self.edit.getTag(1) +		print(len(someText), '[' + someText + ']') +		someText = self.edit.autoCGetCurrentText() +		print(len(someText), '[' + someText + ']') +		someText = self.edit.annotationText(1) +		print(len(someText), '[' + someText + ']') +		someText = self.edit.annotationStyles(1) +		print(len(someText), '[' + someText + ']') +		someText = self.edit.describeKeyWordSets() +		print(len(someText), '[' + someText + ']') +		someText = self.edit.propertyNames() +		print(len(someText), '[' + someText + ']') +		self.edit.setProperty("fold", "1") +		someText = self.edit.getProperty("fold") +		print(len(someText), '[' + someText + ']') +		someText = self.edit.getPropertyExpanded("fold") +		print(len(someText), '[' + someText + ']') +		someText = self.edit.lexerLanguage() +		print(len(someText), '[' + someText + ']') +		someText = self.edit.describeProperty("styling.within.preprocessor") +		print(len(someText), '[' + someText + ']') + +		xx = self.edit.findText(0, "main", 0, 25) +		print(type(xx), xx) +		print("isBold", self.edit.styleBold(sci.SCE_C_WORD)) + +		# Retrieve the document and write into it +		doc = self.edit.get_doc() +		doc.insert_string(40, "***") +		stars = doc.get_char_range(40,3) +		assert stars == "***" + +		# Create a new independent document and attach it to the editor +		doc = ScintillaEditPy.ScintillaDocument() +		doc.insert_string(0, "/***/\nif(a)\n") +		self.edit.set_doc(doc) +		self.edit.setLexer(sci.SCLEX_CPP) + +	def Call(self, message, wParam=0, lParam=0): +		return self.edit.send(message, wParam, lParam) + +	def resizeEvent(self, e): +		self.edit.resize(e.size().width(), e.size().height()) + +	def receive_command(self, wParam, lParam): +		# Show underline at start when focussed +		notifyCode = wParam >> 16 +		if (notifyCode == sci.SCEN_SETFOCUS) or (notifyCode == sci.SCEN_KILLFOCUS): +			self.edit.setIndicatorCurrent(sci.INDIC_CONTAINER); +			self.edit.indicatorClearRange(0, self.edit.length()) +			if notifyCode == sci.SCEN_SETFOCUS: +				self.edit.indicatorFillRange(0, 2); + +	def receive_notification(self, scn): +		if scn.nmhdr.code == sci.SCN_CHARADDED: +			print "Char %02X" % scn.ch +		elif scn.nmhdr.code == sci.SCN_SAVEPOINTREACHED: +			print "Saved" +		elif scn.nmhdr.code == sci.SCN_SAVEPOINTLEFT: +			print "Unsaved" +		elif scn.nmhdr.code == sci.SCN_MODIFIED: +			print "Modified" +		elif scn.nmhdr.code == sci.SCN_UPDATEUI: +			print "Update UI" +		elif scn.nmhdr.code == sci.SCN_PAINTED: +			#print "Painted" +			pass +		else: +			print "Notification", scn.nmhdr.code +			pass + +if __name__ == '__main__': +    # Create the Qt Application +    app = QApplication(sys.argv) +    # Create and show the form +    form = Form() +    form.show() +    # Run the main Qt loop +    sys.exit(app.exec_()) diff --git a/qt/ScintillaEditPy/typesystem_ScintillaEdit.xml.template b/qt/ScintillaEditPy/typesystem_ScintillaEdit.xml.template new file mode 100644 index 000000000..4c2c897a2 --- /dev/null +++ b/qt/ScintillaEditPy/typesystem_ScintillaEdit.xml.template @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<typesystem package="ScintillaEditPy"> +	<load-typesystem name="typesystem_core.xml" generate="no" /> +	<load-typesystem name="typesystem_gui_common.xml" generate="no"/> +	<primitive-type name="sptr_t"/> +	<primitive-type name="uptr_t"/> +	<value-type name="Sci_NotifyHeader" /> +	<rejection class="Sci_NotifyHeader" field-name="hwndFrom" /> +	<value-type name="SCNotification" /> +	<object-type name="ScintillaEditBase" /> +	<object-type name="ScintillaEdit"> +	<!-- ++Autogenerated start of section automatically generated from Scintilla.iface --> +	<!-- ~~Autogenerated end of section automatically generated from Scintilla.iface --> +	</object-type> +	<object-type name="ScintillaDocument" /> +</typesystem>  | 
