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> |