aboutsummaryrefslogtreecommitdiffhomepage
path: root/qt/ScintillaEditPy
diff options
context:
space:
mode:
authornyamatongwe <unknown>2012-05-17 12:46:29 +1000
committernyamatongwe <unknown>2012-05-17 12:46:29 +1000
commitbf8b35542c4be4b8eebb71ca2ad518da2e12b850 (patch)
treeeab094df23f84c33c7ed03f3412a63a060d31eac /qt/ScintillaEditPy
parent29c92749f25f24795ecd9fec2b6705129ebbd654 (diff)
downloadscintilla-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/README85
-rw-r--r--qt/ScintillaEditPy/ScintillaConstants.py.template6
-rw-r--r--qt/ScintillaEditPy/ScintillaEditPy.pro116
-rw-r--r--qt/ScintillaEditPy/global.h4
-rw-r--r--qt/ScintillaEditPy/sepbuild.py312
-rw-r--r--qt/ScintillaEditPy/testsepq.py157
-rw-r--r--qt/ScintillaEditPy/typesystem_ScintillaEdit.xml.template16
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>