From 0591f54ce8f69458f1b68d33d8c74b95ff436ead Mon Sep 17 00:00:00 2001
From: polos
Date: Fri, 25 Nov 2016 23:30:38 +0100
Subject: [PATCH] port of EQL/Qt4 to Qt5
---
.gitignore | 39 +
LICENSE-1.MIT | 20 +
LICENSE-2-MAKE-QIMAGE.txt | 25 +
Qt_EQL/README.txt | 27 +
Qt_EQL/auto-reload.lisp | 21 +
Qt_EQL/cpp/eql_cpp.pro | 12 +
Qt_EQL/cpp/lib.cpp | 32 +
Qt_EQL/cpp/lib.h | 26 +
Qt_EQL/cpp_calling_lisp/eql_cpp.pro | 13 +
Qt_EQL/cpp_calling_lisp/lib.cpp | 62 +
Qt_EQL/cpp_calling_lisp/lib.h | 26 +
Qt_EQL/looping.lisp | 15 +
Qt_EQL/make.bat | 4 +
Qt_EQL/reload.lisp | 30 +
Qt_EQL/test.lisp | 17 +
Qt_EQL/trafficlight/README.txt | 32 +
Qt_EQL/trafficlight/lib.cpp | 19 +
Qt_EQL/trafficlight/lib.h | 18 +
Qt_EQL/trafficlight/run.lisp | 23 +
Qt_EQL/trafficlight/trafficlight.cpp | 18 +
Qt_EQL/trafficlight/trafficlight.h | 134 +
Qt_EQL/trafficlight/trafficlight.pro | 15 +
Qt_EQL_plugin/Qt/main.cpp | 14 +
Qt_EQL_plugin/Qt/qt_application.cpp | 64 +
Qt_EQL_plugin/Qt/qt_application.h | 24 +
Qt_EQL_plugin/Qt/qt_application.pro | 10 +
Qt_EQL_plugin/README.txt | 34 +
Qt_EQL_plugin/ini.lisp | 49 +
Qt_EQL_plugin/qt_plugin.cpp | 19 +
Qt_EQL_plugin/qt_plugin.h | 23 +
Qt_EQL_plugin/qt_plugin.pro | 13 +
README-1.txt | 157 +
README-2-REBUILD.txt | 47 +
README-3-OPTIONAL.txt | 51 +
doc/Debugging.htm | 139 +
doc/Deploy.htm | 14 +
doc/EQL-Slime-Integration.htm | 64 +
doc/EQL.png | Bin 0 -> 2866 bytes
doc/Notes.htm | 71 +
doc/QtDesigner.htm | 23 +
doc/QtLinguist.htm | 21 +
doc/Slime-REPL-hook.htm | 102 +
doc/Slime.htm | 57 +
doc/auto-doc.htm | 529 ++
doc/auto-doc.lisp | 78 +
doc/debug-dialog.png | Bin 0 -> 19599 bytes
doc/index.html | 18 +
doc/style.css | 5 +
examples/0-Tutorial/0.lisp | 8 +
examples/0-Tutorial/1.lisp | 11 +
examples/0-Tutorial/2.lisp | 15 +
examples/0-Tutorial/3.lisp | 17 +
examples/0-Tutorial/4.lisp | 44 +
examples/1-hello-world.lisp | 10 +
examples/2-clock.lisp | 94 +
examples/3-main-window.lisp | 55 +
examples/4-wiggly-widget.lisp | 70 +
examples/5-colliding-mice.lisp | 248 +
examples/6-download.lisp | 48 +
examples/7-Sokoban/3rd-party/CONTRIBUTORS | 6 +
examples/7-Sokoban/3rd-party/COPYING | 3 +
examples/7-Sokoban/3rd-party/README.txt | 1 +
examples/7-Sokoban/3rd-party/levels.lisp | 816 +++
examples/7-Sokoban/3rd-party/sokoban.lisp | 101 +
examples/7-Sokoban/eql-sokoban.lisp | 197 +
examples/7-Sokoban/pics/goal.png | Bin 0 -> 284 bytes
examples/7-Sokoban/pics/object.png | Bin 0 -> 469 bytes
examples/7-Sokoban/pics/object2.png | Bin 0 -> 478 bytes
examples/7-Sokoban/pics/player.png | Bin 0 -> 841 bytes
examples/7-Sokoban/pics/player2.png | Bin 0 -> 841 bytes
examples/7-Sokoban/pics/wall.png | Bin 0 -> 165 bytes
examples/8-OpenGL/README.txt | 3 +
examples/8-OpenGL/gl-widget.lisp | 201 +
examples/8-OpenGL/main-window.lisp | 136 +
examples/8-OpenGL/run.lisp | 11 +
examples/9-simple-lisp-editor/README.txt | 83 +
.../data/auto-indent.lisp | 42 +
examples/9-simple-lisp-editor/data/editor.ui | 246 +
.../data/eql-keywords.lisp | 97 +
.../data/lisp-keywords.lisp | 769 ++
.../data/local_server.png | Bin 0 -> 1548 bytes
.../9-simple-lisp-editor/debug-dialog.lisp | 43 +
examples/9-simple-lisp-editor/editor.lisp | 1387 ++++
examples/9-simple-lisp-editor/exe/README.txt | 23 +
.../9-simple-lisp-editor/exe/local_server.pro | 13 +
examples/9-simple-lisp-editor/exe/main.cpp | 27 +
examples/9-simple-lisp-editor/exe/make.lisp | 30 +
examples/9-simple-lisp-editor/input-hook.lisp | 59 +
.../9-simple-lisp-editor/local-client.lisp | 61 +
.../9-simple-lisp-editor/local-server.lisp | 328 +
.../9-simple-lisp-editor/make-client.lisp | 21 +
.../9-simple-lisp-editor/make-editor.lisp | 23 +
.../9-simple-lisp-editor/make-server.lisp | 26 +
examples/9-simple-lisp-editor/my.lisp | 29 +
examples/9-simple-lisp-editor/new.lisp | 6 +
.../9-simple-lisp-editor/query-dialog.lisp | 25 +
examples/9-simple-lisp-editor/send.lisp | 76 +
examples/9-simple-lisp-editor/send/send | Bin 0 -> 20184 bytes
examples/9-simple-lisp-editor/send/send.cpp | 31 +
examples/9-simple-lisp-editor/send/send.pro | 9 +
examples/9-simple-lisp-editor/settings.lisp | 6 +
examples/9-simple-lisp-editor/top-level.lisp | 125 +
examples/M-modules/sql/sqlite.lisp | 57 +
.../Examples-Browser/README-GLUE-CODE.txt | 15 +
.../Examples-Browser/examples-browser.htm | 30 +
.../Examples-Browser/examples-browser.lisp | 131 +
.../webkit/Examples-Browser/lib/_invokables.h | 12 +
.../Examples-Browser/lib/webkit_bridge.cpp | 0
.../Examples-Browser/lib/webkit_bridge.h | 31 +
.../Examples-Browser/lib/webkit_bridge.pro | 18 +
.../M-modules/webkit/Examples-Browser/qt.lisp | 9 +
.../M-modules/webkit/README-GLUE-CODE.txt | 15 +
examples/M-modules/webkit/README.txt | 33 +
.../Tic-Tac-Toe/README-JS-CALLBACKS.txt | 33 +
.../M-modules/webkit/Tic-Tac-Toe/README.txt | 42 +
.../M-modules/webkit/Tic-Tac-Toe/h-utils.lisp | 481 ++
.../webkit/Tic-Tac-Toe/inspector.lisp | 13 +
.../webkit/Tic-Tac-Toe/lib/_invokables.h | 22 +
.../webkit/Tic-Tac-Toe/lib/webkit_bridge.cpp | 0
.../webkit/Tic-Tac-Toe/lib/webkit_bridge.h | 31 +
.../webkit/Tic-Tac-Toe/lib/webkit_bridge.pro | 18 +
examples/M-modules/webkit/Tic-Tac-Toe/qt.lisp | 9 +
.../M-modules/webkit/Tic-Tac-Toe/template.htm | 8 +
.../webkit/Tic-Tac-Toe/template.lisp | 23 +
.../webkit/Tic-Tac-Toe/tic-tac-toe.htm | 39 +
.../webkit/Tic-Tac-Toe/tic-tac-toe.lisp | 260 +
examples/M-modules/webkit/dom.lisp | 42 +
examples/M-modules/webkit/inspector.lisp | 11 +
examples/M-modules/webkit/lib/_invokables.h | 24 +
.../M-modules/webkit/lib/webkit_bridge.cpp | 0
examples/M-modules/webkit/lib/webkit_bridge.h | 31 +
.../M-modules/webkit/lib/webkit_bridge.pro | 18 +
examples/M-modules/webkit/plugin-widget.htm | 24 +
examples/M-modules/webkit/plugin-widget.lisp | 57 +
examples/M-modules/webkit/qt.lisp | 11 +
examples/M-modules/webkit/strip-html.lisp | 147 +
examples/M-modules/webkit/ui/README.txt | 1 +
examples/M-modules/webkit/ui/dom.ui | 80 +
examples/M-modules/webkit/ui/ui-dom.lisp | 78 +
examples/M-modules/webkit/webkit-bridge.htm | 59 +
examples/M-modules/webkit/webkit-bridge.lisp | 77 +
examples/X-extras/CLOS-encapsulation.lisp | 45 +
examples/X-extras/calculator.lisp | 227 +
examples/X-extras/cpp-move-blocks/lib.cpp | 24 +
examples/X-extras/cpp-move-blocks/lib.h | 25 +
examples/X-extras/cpp-move-blocks/lib.pro | 13 +
examples/X-extras/cpp-qimage/lib.cpp | 31 +
examples/X-extras/cpp-qimage/lib.h | 26 +
examples/X-extras/cpp-qimage/lib.pro | 13 +
examples/X-extras/lcd.lisp | 24 +
examples/X-extras/make-qimage.lisp | 547 ++
examples/X-extras/move-blocks.lisp | 393 +
examples/X-extras/palindrome/README.txt | 27 +
examples/X-extras/palindrome/definitions.lisp | 99 +
examples/X-extras/palindrome/exe/README.txt | 6 +
examples/X-extras/palindrome/exe/main.cpp | 46 +
examples/X-extras/palindrome/exe/main.h | 20 +
examples/X-extras/palindrome/exe/main.pro | 14 +
examples/X-extras/palindrome/exe/make.lisp | 26 +
.../X-extras/palindrome/meta/generate.lisp | 84 +
examples/X-extras/palindrome/palindrome.lisp | 389 +
examples/X-extras/primes-thread.lisp | 77 +
examples/X-extras/qimage.lisp | 169 +
examples/X-extras/screenshot.lisp | 30 +
examples/data/camera.png | Bin 0 -> 4221 bytes
examples/data/icons/cheese.jpg | Bin 0 -> 3029 bytes
examples/data/icons/open.png | Bin 0 -> 904 bytes
examples/data/icons/save.png | Bin 0 -> 1206 bytes
examples/data/image-manipulation.ui | 330 +
examples/data/main-window.ui | 59 +
examples/data/move-blocks.ui | 133 +
examples/data/utf8.htm | 84 +
examples/data/vernazza.jpg | Bin 0 -> 45837 bytes
gui/gui.lisp | 375 +
gui/gui.ui | 347 +
gui/properties.lisp | 63 +
gui/properties.ui | 51 +
helper/README.txt | 19 +
helper/generate.lisp | 1210 +++
helper/html2text.lisp | 52 +
helper/load-modules.lisp | 21 +
helper/missing-types.txt | 85 +
helper/modules.lisp | 1 +
helper/multiple-inheritance.txt | 5 +
helper/my-class-lists/gui/n-names.lisp | 169 +
helper/my-class-lists/gui/q-names.lisp | 186 +
helper/my-class-lists/help/n-names.lisp | 7 +
helper/my-class-lists/help/q-names.lisp | 13 +
helper/my-class-lists/network/n-names.lisp | 21 +
helper/my-class-lists/network/q-names.lisp | 16 +
helper/my-class-lists/opengl/n-names.lisp | 11 +
helper/my-class-lists/opengl/q-names.lisp | 8 +
helper/my-class-lists/sql/n-names.lisp | 13 +
helper/my-class-lists/sql/q-names.lisp | 10 +
helper/my-class-lists/svg/n-names.lisp | 6 +
helper/my-class-lists/svg/q-names.lisp | 8 +
helper/my-class-lists/webkit/n-names.lisp | 13 +
helper/my-class-lists/webkit/q-names.lisp | 12 +
helper/no-static-meta-object.lisp | 148 +
helper/parse-enums.lisp | 55 +
helper/parse.lisp | 276 +
helper/parsed/n-methods.lisp | 4448 +++++++++++
helper/parsed/n-override.lisp | 459 ++
helper/parsed/q-methods.lisp | 4889 +++++++++++++
helper/parsed/q-override.lisp | 1791 +++++
helper/share.lisp | 17 +
my_app/README.txt | 21 +
my_app/eql-lrelease | 1 +
my_app/eql-lrelease.bat | 1 +
my_app/eql-lupdate | 1 +
my_app/eql-lupdate.bat | 1 +
my_app/lisp/my.lisp | 17 +
my_app/lisp/my.ui | 18 +
my_app/main.cpp | 41 +
my_app/make.lisp | 26 +
my_app/my_app.pro | 13 +
my_app/tr.lisp | 26 +
slime/README.txt | 5 +
slime/eql-start-swank.lisp | 24 +
slime/old/process-qt-events.lisp | 18 +
slime/repl-hook.lisp | 31 +
slime/thread-safe.lisp | 118 +
src/dyn_object.cpp | 79 +
src/dyn_object.h | 43 +
src/ecl_fun.cpp | 2810 +++++++
src/ecl_fun.h | 317 +
src/eql.cpp | 181 +
src/eql.h | 52 +
src/eql_exe.pro | 18 +
src/eql_fun.h | 60 +
src/eql_global.h | 7 +
src/eql_lib.pro | 33 +
src/extras.cpp | 77 +
src/extras.h | 20 +
src/gen/_lobjects.cpp | 3276 +++++++++
src/gen/_lobjects.h | 149 +
src/gen/_main_n_classes.h | 2040 ++++++
src/gen/_main_n_methods.h | 4227 +++++++++++
src/gen/_main_q_classes.h | 6473 +++++++++++++++++
src/gen/_main_q_methods.h | 4864 +++++++++++++
src/gen/help/_ini.cpp | 70 +
src/gen/help/_ini.h | 24 +
src/gen/help/_ini2.h | 12 +
src/gen/help/_n_classes.h | 34 +
src/gen/help/_n_methods.h | 35 +
src/gen/help/_q_classes.h | 340 +
src/gen/help/_q_methods.h | 106 +
src/gen/my/_ini.cpp | 1 +
src/gen/my/_ini.h | 29 +
src/gen/my/_ini2.h | 31 +
src/gen/my/_n_classes.h | 1 +
src/gen/my/_n_methods.h | 1 +
src/gen/my/_q_classes.h | 1 +
src/gen/my/_q_methods.h | 1 +
src/gen/network/_ini.cpp | 136 +
src/gen/network/_ini.h | 30 +
src/gen/network/_ini2.h | 66 +
src/gen/network/_n_classes.h | 195 +
src/gen/network/_n_methods.h | 379 +
src/gen/network/_q_classes.h | 255 +
src/gen/network/_q_methods.h | 246 +
src/gen/opengl/_ini.cpp | 68 +
src/gen/opengl/_ini.h | 27 +
src/gen/opengl/_ini2.h | 78 +
src/gen/opengl/_n_classes.h | 90 +
src/gen/opengl/_n_methods.h | 204 +
src/gen/opengl/_q_classes.h | 108 +
src/gen/opengl/_q_methods.h | 208 +
src/gen/sql/_ini.cpp | 84 +
src/gen/sql/_ini.h | 32 +
src/gen/sql/_ini2.h | 54 +
src/gen/sql/_n_classes.h | 120 +
src/gen/sql/_n_methods.h | 241 +
src/gen/sql/_q_classes.h | 237 +
src/gen/sql/_q_methods.h | 130 +
src/gen/svg/_ini.cpp | 48 +
src/gen/svg/_ini.h | 24 +
src/gen/svg/_ini2.h | 12 +
src/gen/svg/_n_classes.h | 27 +
src/gen/svg/_n_methods.h | 36 +
src/gen/svg/_q_classes.h | 102 +
src/gen/svg/_q_methods.h | 61 +
src/gen/webkit/_ini.cpp | 84 +
src/gen/webkit/_ini.h | 29 +
src/gen/webkit/_ini2.h | 39 +
src/gen/webkit/_n_classes.h | 77 +
src/gen/webkit/_n_methods.h | 238 +
src/gen/webkit/_q_classes.h | 238 +
src/gen/webkit/_q_methods.h | 223 +
src/link-wrappers.lisp | 23 +
src/link.lisp | 17 +
src/lisp/COPYING-ECL-READLINE | 481 ++
src/lisp/all-wrappers-1.lisp | 1213 +++
src/lisp/all-wrappers-10.lisp | 2260 ++++++
src/lisp/all-wrappers-2.lisp | 1202 +++
src/lisp/all-wrappers-3.lisp | 1202 +++
src/lisp/all-wrappers-4.lisp | 1202 +++
src/lisp/all-wrappers-5.lisp | 755 ++
src/lisp/all-wrappers-6.lisp | 3601 +++++++++
src/lisp/all-wrappers-7.lisp | 3601 +++++++++
src/lisp/all-wrappers-8.lisp | 3601 +++++++++
src/lisp/all-wrappers-9.lisp | 3601 +++++++++
src/lisp/all-wrappers.lisp | 3 +
src/lisp/define-all-wrappers.lisp | 176 +
src/lisp/ecl-readline.lisp | 246 +
src/lisp/enum-lists/dynamic-enums.lisp | 3167 ++++++++
src/lisp/enum-lists/parsed-enums.lisp | 3288 +++++++++
src/lisp/enums1.lisp | 1263 ++++
src/lisp/enums2.lisp | 1263 ++++
src/lisp/enums3.lisp | 1263 ++++
src/lisp/enums4.lisp | 1167 +++
src/lisp/get-dynamic-enums.lisp | 37 +
src/lisp/ini.lisp | 956 +++
src/lisp/invokables.lisp | 100 +
src/lisp/mark.lisp | 16 +
src/lisp/merge-enums.lisp | 24 +
src/lisp/merged-enums.lisp | 4904 +++++++++++++
src/lisp/package.lisp | 113 +
src/lisp/profile.lisp | 10 +
src/lisp/qselect.lisp | 95 +
src/lisp/quic.lisp | 494 ++
src/lisp/restart-dialog.lisp | 140 +
src/lisp/special-extensions.lisp | 171 +
src/lisp/x.lisp | 161 +
src/main.cpp | 37 +
src/make-eql-lib-wrappers.lisp | 26 +
src/make-eql-lib.lisp | 23 +
src/module_help.pro | 19 +
src/module_network.pro | 19 +
src/module_opengl.pro | 19 +
src/module_sql.pro | 19 +
src/module_svg.pro | 19 +
src/module_webkit.pro | 21 +
src/qt_eql.cpp | 78 +
src/qt_eql.h | 44 +
src/rebuild | 29 +
src/single_shot.h | 31 +
src/ui_loader.h | 41 +
src/windows.pri | 4 +
339 files changed, 99935 insertions(+)
create mode 100644 .gitignore
create mode 100644 LICENSE-1.MIT
create mode 100644 LICENSE-2-MAKE-QIMAGE.txt
create mode 100644 Qt_EQL/README.txt
create mode 100644 Qt_EQL/auto-reload.lisp
create mode 100644 Qt_EQL/cpp/eql_cpp.pro
create mode 100644 Qt_EQL/cpp/lib.cpp
create mode 100644 Qt_EQL/cpp/lib.h
create mode 100644 Qt_EQL/cpp_calling_lisp/eql_cpp.pro
create mode 100644 Qt_EQL/cpp_calling_lisp/lib.cpp
create mode 100644 Qt_EQL/cpp_calling_lisp/lib.h
create mode 100644 Qt_EQL/looping.lisp
create mode 100644 Qt_EQL/make.bat
create mode 100644 Qt_EQL/reload.lisp
create mode 100644 Qt_EQL/test.lisp
create mode 100644 Qt_EQL/trafficlight/README.txt
create mode 100644 Qt_EQL/trafficlight/lib.cpp
create mode 100644 Qt_EQL/trafficlight/lib.h
create mode 100644 Qt_EQL/trafficlight/run.lisp
create mode 100644 Qt_EQL/trafficlight/trafficlight.cpp
create mode 100644 Qt_EQL/trafficlight/trafficlight.h
create mode 100644 Qt_EQL/trafficlight/trafficlight.pro
create mode 100644 Qt_EQL_plugin/Qt/main.cpp
create mode 100644 Qt_EQL_plugin/Qt/qt_application.cpp
create mode 100644 Qt_EQL_plugin/Qt/qt_application.h
create mode 100644 Qt_EQL_plugin/Qt/qt_application.pro
create mode 100644 Qt_EQL_plugin/README.txt
create mode 100644 Qt_EQL_plugin/ini.lisp
create mode 100644 Qt_EQL_plugin/qt_plugin.cpp
create mode 100644 Qt_EQL_plugin/qt_plugin.h
create mode 100644 Qt_EQL_plugin/qt_plugin.pro
create mode 100644 README-1.txt
create mode 100644 README-2-REBUILD.txt
create mode 100644 README-3-OPTIONAL.txt
create mode 100644 doc/Debugging.htm
create mode 100644 doc/Deploy.htm
create mode 100644 doc/EQL-Slime-Integration.htm
create mode 100644 doc/EQL.png
create mode 100644 doc/Notes.htm
create mode 100644 doc/QtDesigner.htm
create mode 100644 doc/QtLinguist.htm
create mode 100644 doc/Slime-REPL-hook.htm
create mode 100644 doc/Slime.htm
create mode 100644 doc/auto-doc.htm
create mode 100644 doc/auto-doc.lisp
create mode 100644 doc/debug-dialog.png
create mode 100644 doc/index.html
create mode 100644 doc/style.css
create mode 100644 examples/0-Tutorial/0.lisp
create mode 100644 examples/0-Tutorial/1.lisp
create mode 100644 examples/0-Tutorial/2.lisp
create mode 100644 examples/0-Tutorial/3.lisp
create mode 100644 examples/0-Tutorial/4.lisp
create mode 100644 examples/1-hello-world.lisp
create mode 100644 examples/2-clock.lisp
create mode 100644 examples/3-main-window.lisp
create mode 100644 examples/4-wiggly-widget.lisp
create mode 100644 examples/5-colliding-mice.lisp
create mode 100644 examples/6-download.lisp
create mode 100644 examples/7-Sokoban/3rd-party/CONTRIBUTORS
create mode 100644 examples/7-Sokoban/3rd-party/COPYING
create mode 100644 examples/7-Sokoban/3rd-party/README.txt
create mode 100644 examples/7-Sokoban/3rd-party/levels.lisp
create mode 100644 examples/7-Sokoban/3rd-party/sokoban.lisp
create mode 100644 examples/7-Sokoban/eql-sokoban.lisp
create mode 100644 examples/7-Sokoban/pics/goal.png
create mode 100644 examples/7-Sokoban/pics/object.png
create mode 100644 examples/7-Sokoban/pics/object2.png
create mode 100644 examples/7-Sokoban/pics/player.png
create mode 100644 examples/7-Sokoban/pics/player2.png
create mode 100644 examples/7-Sokoban/pics/wall.png
create mode 100644 examples/8-OpenGL/README.txt
create mode 100644 examples/8-OpenGL/gl-widget.lisp
create mode 100644 examples/8-OpenGL/main-window.lisp
create mode 100644 examples/8-OpenGL/run.lisp
create mode 100644 examples/9-simple-lisp-editor/README.txt
create mode 100644 examples/9-simple-lisp-editor/data/auto-indent.lisp
create mode 100644 examples/9-simple-lisp-editor/data/editor.ui
create mode 100644 examples/9-simple-lisp-editor/data/eql-keywords.lisp
create mode 100644 examples/9-simple-lisp-editor/data/lisp-keywords.lisp
create mode 100644 examples/9-simple-lisp-editor/data/local_server.png
create mode 100644 examples/9-simple-lisp-editor/debug-dialog.lisp
create mode 100644 examples/9-simple-lisp-editor/editor.lisp
create mode 100644 examples/9-simple-lisp-editor/exe/README.txt
create mode 100644 examples/9-simple-lisp-editor/exe/local_server.pro
create mode 100644 examples/9-simple-lisp-editor/exe/main.cpp
create mode 100644 examples/9-simple-lisp-editor/exe/make.lisp
create mode 100644 examples/9-simple-lisp-editor/input-hook.lisp
create mode 100644 examples/9-simple-lisp-editor/local-client.lisp
create mode 100644 examples/9-simple-lisp-editor/local-server.lisp
create mode 100644 examples/9-simple-lisp-editor/make-client.lisp
create mode 100644 examples/9-simple-lisp-editor/make-editor.lisp
create mode 100644 examples/9-simple-lisp-editor/make-server.lisp
create mode 100644 examples/9-simple-lisp-editor/my.lisp
create mode 100644 examples/9-simple-lisp-editor/new.lisp
create mode 100644 examples/9-simple-lisp-editor/query-dialog.lisp
create mode 100644 examples/9-simple-lisp-editor/send.lisp
create mode 100755 examples/9-simple-lisp-editor/send/send
create mode 100644 examples/9-simple-lisp-editor/send/send.cpp
create mode 100644 examples/9-simple-lisp-editor/send/send.pro
create mode 100644 examples/9-simple-lisp-editor/settings.lisp
create mode 100644 examples/9-simple-lisp-editor/top-level.lisp
create mode 100644 examples/M-modules/sql/sqlite.lisp
create mode 100644 examples/M-modules/webkit/Examples-Browser/README-GLUE-CODE.txt
create mode 100644 examples/M-modules/webkit/Examples-Browser/examples-browser.htm
create mode 100644 examples/M-modules/webkit/Examples-Browser/examples-browser.lisp
create mode 100644 examples/M-modules/webkit/Examples-Browser/lib/_invokables.h
create mode 100644 examples/M-modules/webkit/Examples-Browser/lib/webkit_bridge.cpp
create mode 100644 examples/M-modules/webkit/Examples-Browser/lib/webkit_bridge.h
create mode 100644 examples/M-modules/webkit/Examples-Browser/lib/webkit_bridge.pro
create mode 100644 examples/M-modules/webkit/Examples-Browser/qt.lisp
create mode 100644 examples/M-modules/webkit/README-GLUE-CODE.txt
create mode 100644 examples/M-modules/webkit/README.txt
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/README-JS-CALLBACKS.txt
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/README.txt
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/h-utils.lisp
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/inspector.lisp
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/lib/_invokables.h
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/lib/webkit_bridge.cpp
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/lib/webkit_bridge.h
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/lib/webkit_bridge.pro
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/qt.lisp
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/template.htm
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/template.lisp
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/tic-tac-toe.htm
create mode 100644 examples/M-modules/webkit/Tic-Tac-Toe/tic-tac-toe.lisp
create mode 100644 examples/M-modules/webkit/dom.lisp
create mode 100644 examples/M-modules/webkit/inspector.lisp
create mode 100644 examples/M-modules/webkit/lib/_invokables.h
create mode 100644 examples/M-modules/webkit/lib/webkit_bridge.cpp
create mode 100644 examples/M-modules/webkit/lib/webkit_bridge.h
create mode 100644 examples/M-modules/webkit/lib/webkit_bridge.pro
create mode 100644 examples/M-modules/webkit/plugin-widget.htm
create mode 100644 examples/M-modules/webkit/plugin-widget.lisp
create mode 100644 examples/M-modules/webkit/qt.lisp
create mode 100644 examples/M-modules/webkit/strip-html.lisp
create mode 100644 examples/M-modules/webkit/ui/README.txt
create mode 100644 examples/M-modules/webkit/ui/dom.ui
create mode 100644 examples/M-modules/webkit/ui/ui-dom.lisp
create mode 100644 examples/M-modules/webkit/webkit-bridge.htm
create mode 100644 examples/M-modules/webkit/webkit-bridge.lisp
create mode 100644 examples/X-extras/CLOS-encapsulation.lisp
create mode 100644 examples/X-extras/calculator.lisp
create mode 100644 examples/X-extras/cpp-move-blocks/lib.cpp
create mode 100644 examples/X-extras/cpp-move-blocks/lib.h
create mode 100644 examples/X-extras/cpp-move-blocks/lib.pro
create mode 100644 examples/X-extras/cpp-qimage/lib.cpp
create mode 100644 examples/X-extras/cpp-qimage/lib.h
create mode 100644 examples/X-extras/cpp-qimage/lib.pro
create mode 100644 examples/X-extras/lcd.lisp
create mode 100644 examples/X-extras/make-qimage.lisp
create mode 100644 examples/X-extras/move-blocks.lisp
create mode 100644 examples/X-extras/palindrome/README.txt
create mode 100644 examples/X-extras/palindrome/definitions.lisp
create mode 100644 examples/X-extras/palindrome/exe/README.txt
create mode 100644 examples/X-extras/palindrome/exe/main.cpp
create mode 100644 examples/X-extras/palindrome/exe/main.h
create mode 100644 examples/X-extras/palindrome/exe/main.pro
create mode 100644 examples/X-extras/palindrome/exe/make.lisp
create mode 100644 examples/X-extras/palindrome/meta/generate.lisp
create mode 100644 examples/X-extras/palindrome/palindrome.lisp
create mode 100644 examples/X-extras/primes-thread.lisp
create mode 100644 examples/X-extras/qimage.lisp
create mode 100644 examples/X-extras/screenshot.lisp
create mode 100644 examples/data/camera.png
create mode 100644 examples/data/icons/cheese.jpg
create mode 100644 examples/data/icons/open.png
create mode 100644 examples/data/icons/save.png
create mode 100644 examples/data/image-manipulation.ui
create mode 100644 examples/data/main-window.ui
create mode 100644 examples/data/move-blocks.ui
create mode 100644 examples/data/utf8.htm
create mode 100644 examples/data/vernazza.jpg
create mode 100644 gui/gui.lisp
create mode 100644 gui/gui.ui
create mode 100644 gui/properties.lisp
create mode 100644 gui/properties.ui
create mode 100644 helper/README.txt
create mode 100644 helper/generate.lisp
create mode 100644 helper/html2text.lisp
create mode 100644 helper/load-modules.lisp
create mode 100644 helper/missing-types.txt
create mode 100644 helper/modules.lisp
create mode 100644 helper/multiple-inheritance.txt
create mode 100644 helper/my-class-lists/gui/n-names.lisp
create mode 100644 helper/my-class-lists/gui/q-names.lisp
create mode 100644 helper/my-class-lists/help/n-names.lisp
create mode 100644 helper/my-class-lists/help/q-names.lisp
create mode 100644 helper/my-class-lists/network/n-names.lisp
create mode 100644 helper/my-class-lists/network/q-names.lisp
create mode 100644 helper/my-class-lists/opengl/n-names.lisp
create mode 100644 helper/my-class-lists/opengl/q-names.lisp
create mode 100644 helper/my-class-lists/sql/n-names.lisp
create mode 100644 helper/my-class-lists/sql/q-names.lisp
create mode 100644 helper/my-class-lists/svg/n-names.lisp
create mode 100644 helper/my-class-lists/svg/q-names.lisp
create mode 100644 helper/my-class-lists/webkit/n-names.lisp
create mode 100644 helper/my-class-lists/webkit/q-names.lisp
create mode 100644 helper/no-static-meta-object.lisp
create mode 100644 helper/parse-enums.lisp
create mode 100644 helper/parse.lisp
create mode 100644 helper/parsed/n-methods.lisp
create mode 100644 helper/parsed/n-override.lisp
create mode 100644 helper/parsed/q-methods.lisp
create mode 100644 helper/parsed/q-override.lisp
create mode 100644 helper/share.lisp
create mode 100644 my_app/README.txt
create mode 100755 my_app/eql-lrelease
create mode 100755 my_app/eql-lrelease.bat
create mode 100755 my_app/eql-lupdate
create mode 100755 my_app/eql-lupdate.bat
create mode 100644 my_app/lisp/my.lisp
create mode 100644 my_app/lisp/my.ui
create mode 100644 my_app/main.cpp
create mode 100644 my_app/make.lisp
create mode 100644 my_app/my_app.pro
create mode 100644 my_app/tr.lisp
create mode 100644 slime/README.txt
create mode 100644 slime/eql-start-swank.lisp
create mode 100644 slime/old/process-qt-events.lisp
create mode 100644 slime/repl-hook.lisp
create mode 100644 slime/thread-safe.lisp
create mode 100644 src/dyn_object.cpp
create mode 100644 src/dyn_object.h
create mode 100644 src/ecl_fun.cpp
create mode 100644 src/ecl_fun.h
create mode 100644 src/eql.cpp
create mode 100644 src/eql.h
create mode 100644 src/eql_exe.pro
create mode 100644 src/eql_fun.h
create mode 100644 src/eql_global.h
create mode 100644 src/eql_lib.pro
create mode 100644 src/extras.cpp
create mode 100644 src/extras.h
create mode 100644 src/gen/_lobjects.cpp
create mode 100644 src/gen/_lobjects.h
create mode 100644 src/gen/_main_n_classes.h
create mode 100644 src/gen/_main_n_methods.h
create mode 100644 src/gen/_main_q_classes.h
create mode 100644 src/gen/_main_q_methods.h
create mode 100644 src/gen/help/_ini.cpp
create mode 100644 src/gen/help/_ini.h
create mode 100644 src/gen/help/_ini2.h
create mode 100644 src/gen/help/_n_classes.h
create mode 100644 src/gen/help/_n_methods.h
create mode 100644 src/gen/help/_q_classes.h
create mode 100644 src/gen/help/_q_methods.h
create mode 100644 src/gen/my/_ini.cpp
create mode 100644 src/gen/my/_ini.h
create mode 100644 src/gen/my/_ini2.h
create mode 100644 src/gen/my/_n_classes.h
create mode 100644 src/gen/my/_n_methods.h
create mode 100644 src/gen/my/_q_classes.h
create mode 100644 src/gen/my/_q_methods.h
create mode 100644 src/gen/network/_ini.cpp
create mode 100644 src/gen/network/_ini.h
create mode 100644 src/gen/network/_ini2.h
create mode 100644 src/gen/network/_n_classes.h
create mode 100644 src/gen/network/_n_methods.h
create mode 100644 src/gen/network/_q_classes.h
create mode 100644 src/gen/network/_q_methods.h
create mode 100644 src/gen/opengl/_ini.cpp
create mode 100644 src/gen/opengl/_ini.h
create mode 100644 src/gen/opengl/_ini2.h
create mode 100644 src/gen/opengl/_n_classes.h
create mode 100644 src/gen/opengl/_n_methods.h
create mode 100644 src/gen/opengl/_q_classes.h
create mode 100644 src/gen/opengl/_q_methods.h
create mode 100644 src/gen/sql/_ini.cpp
create mode 100644 src/gen/sql/_ini.h
create mode 100644 src/gen/sql/_ini2.h
create mode 100644 src/gen/sql/_n_classes.h
create mode 100644 src/gen/sql/_n_methods.h
create mode 100644 src/gen/sql/_q_classes.h
create mode 100644 src/gen/sql/_q_methods.h
create mode 100644 src/gen/svg/_ini.cpp
create mode 100644 src/gen/svg/_ini.h
create mode 100644 src/gen/svg/_ini2.h
create mode 100644 src/gen/svg/_n_classes.h
create mode 100644 src/gen/svg/_n_methods.h
create mode 100644 src/gen/svg/_q_classes.h
create mode 100644 src/gen/svg/_q_methods.h
create mode 100644 src/gen/webkit/_ini.cpp
create mode 100644 src/gen/webkit/_ini.h
create mode 100644 src/gen/webkit/_ini2.h
create mode 100644 src/gen/webkit/_n_classes.h
create mode 100644 src/gen/webkit/_n_methods.h
create mode 100644 src/gen/webkit/_q_classes.h
create mode 100644 src/gen/webkit/_q_methods.h
create mode 100644 src/link-wrappers.lisp
create mode 100644 src/link.lisp
create mode 100644 src/lisp/COPYING-ECL-READLINE
create mode 100644 src/lisp/all-wrappers-1.lisp
create mode 100644 src/lisp/all-wrappers-10.lisp
create mode 100644 src/lisp/all-wrappers-2.lisp
create mode 100644 src/lisp/all-wrappers-3.lisp
create mode 100644 src/lisp/all-wrappers-4.lisp
create mode 100644 src/lisp/all-wrappers-5.lisp
create mode 100644 src/lisp/all-wrappers-6.lisp
create mode 100644 src/lisp/all-wrappers-7.lisp
create mode 100644 src/lisp/all-wrappers-8.lisp
create mode 100644 src/lisp/all-wrappers-9.lisp
create mode 100644 src/lisp/all-wrappers.lisp
create mode 100644 src/lisp/define-all-wrappers.lisp
create mode 100644 src/lisp/ecl-readline.lisp
create mode 100644 src/lisp/enum-lists/dynamic-enums.lisp
create mode 100644 src/lisp/enum-lists/parsed-enums.lisp
create mode 100644 src/lisp/enums1.lisp
create mode 100644 src/lisp/enums2.lisp
create mode 100644 src/lisp/enums3.lisp
create mode 100644 src/lisp/enums4.lisp
create mode 100644 src/lisp/get-dynamic-enums.lisp
create mode 100644 src/lisp/ini.lisp
create mode 100644 src/lisp/invokables.lisp
create mode 100644 src/lisp/mark.lisp
create mode 100644 src/lisp/merge-enums.lisp
create mode 100644 src/lisp/merged-enums.lisp
create mode 100644 src/lisp/package.lisp
create mode 100644 src/lisp/profile.lisp
create mode 100644 src/lisp/qselect.lisp
create mode 100644 src/lisp/quic.lisp
create mode 100644 src/lisp/restart-dialog.lisp
create mode 100644 src/lisp/special-extensions.lisp
create mode 100644 src/lisp/x.lisp
create mode 100644 src/main.cpp
create mode 100644 src/make-eql-lib-wrappers.lisp
create mode 100644 src/make-eql-lib.lisp
create mode 100644 src/module_help.pro
create mode 100644 src/module_network.pro
create mode 100644 src/module_opengl.pro
create mode 100644 src/module_sql.pro
create mode 100644 src/module_svg.pro
create mode 100644 src/module_webkit.pro
create mode 100644 src/qt_eql.cpp
create mode 100644 src/qt_eql.h
create mode 100755 src/rebuild
create mode 100644 src/single_shot.h
create mode 100644 src/ui_loader.h
create mode 100644 src/windows.pri
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9e7b0e4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+*.a
+*.dll
+*.dylib
+*.exe
+*.fas*
+*.*history
+*.lib
+*.o
+*.obj
+*.so*
+*.DS_Store
+*.qm
+*.ts
+*~
+*.~
+#*.*#
+.*.lisp
+.*.ui
+.*.txt
+*.user
+t.lisp
+tr.h
+moc_*.cpp
+Makefile
+eql
+eql5
+eql.app
+gui/.*
+my_app/my_app
+my_app/my_app.app/*
+my_app/.*
+src/ECL*
+src/tmp
+eql_profile*
+eql_local_server
+cache
+tmp
+palindrome.htm
+positions.js
diff --git a/LICENSE-1.MIT b/LICENSE-1.MIT
new file mode 100644
index 0000000..bebf914
--- /dev/null
+++ b/LICENSE-1.MIT
@@ -0,0 +1,20 @@
+Copyright (c) 2010-2014 Polos (Paul) Ruetz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/LICENSE-2-MAKE-QIMAGE.txt b/LICENSE-2-MAKE-QIMAGE.txt
new file mode 100644
index 0000000..3719562
--- /dev/null
+++ b/LICENSE-2-MAKE-QIMAGE.txt
@@ -0,0 +1,25 @@
+;; Copyright (c) 2012, Mark Cox
+;; All rights reserved.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions are
+;; met:
+
+;; - Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+
+;; - Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+
+;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+;; HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Qt_EQL/README.txt b/Qt_EQL/README.txt
new file mode 100644
index 0000000..a21fa0e
--- /dev/null
+++ b/Qt_EQL/README.txt
@@ -0,0 +1,27 @@
+BUILD / RUN
+===========
+
+Build the plugins in "cpp/", "cpp_calling_lisp/" before running the examples.
+
+See "trafficlight/" for an example of integrating a Qt/C++ application.
+
+
+
+NOTES
+=====
+
+This offers the same possibilities as found in the "Qt_EQL/" example,
+but with a better, more dynamic workflow, and without the restriction of
+"CONFIG += no_keywords" in your "*.pro" file.
+
+So, integrating any existing Qt/C++ project is straightforward, since you can
+call any property/method/slot/signal of any Qt class (see QFIND-CHILD,
+QFIND-CHILDREN, QFUN+).
+
+Calling Lisp from C++ through "eql_fun()" is easy, and you can use any Qt
+class/type supported by EQL, see examples in "cpp_calling_lisp/lib.cpp".
+
+To automatically generate generic function wrappers for your Qt functions,
+see function DEFINE-QT-WRAPPERS.
+
+Linux only: see also function QAUTO-RELOAD-C++.
diff --git a/Qt_EQL/auto-reload.lisp b/Qt_EQL/auto-reload.lisp
new file mode 100644
index 0000000..6013fc6
--- /dev/null
+++ b/Qt_EQL/auto-reload.lisp
@@ -0,0 +1,21 @@
+;;;
+;;; Linux only!
+;;;
+;;; just edit/recompile "cpp/*"
+;;;
+
+(in-package :eql-user)
+
+#+linux
+(qauto-reload-c++ *lib* (in-home "Qt_EQL/eql_cpp"))
+
+#+linux
+(setf *lib-reloaded* 'show-current-apropos)
+
+(defun show-current-apropos (variable plugin)
+ (qset (qapp) "quitOnLastWindowClosed" nil)
+ (let ((obj (symbol-value variable)))
+ (assert (qt-object-p obj))
+ (qmsg (with-output-to-string (*standard-output*)
+ (format t "Plugin ~S currently offers: " plugin)
+ (qapropos nil obj)))))
diff --git a/Qt_EQL/cpp/eql_cpp.pro b/Qt_EQL/cpp/eql_cpp.pro
new file mode 100644
index 0000000..172d93f
--- /dev/null
+++ b/Qt_EQL/cpp/eql_cpp.pro
@@ -0,0 +1,12 @@
+QT += widgets
+TEMPLATE = lib
+CONFIG += plugin release
+DESTDIR = ../
+TARGET = eql_cpp
+OBJECTS_DIR = ./tmp/
+MOC_DIR = ./tmp/
+
+include(../../src/windows.pri)
+
+HEADERS += lib.h
+SOURCES += lib.cpp
diff --git a/Qt_EQL/cpp/lib.cpp b/Qt_EQL/cpp/lib.cpp
new file mode 100644
index 0000000..2eacfc9
--- /dev/null
+++ b/Qt_EQL/cpp/lib.cpp
@@ -0,0 +1,32 @@
+#include "lib.h"
+
+QT_BEGIN_NAMESPACE
+
+QObject* ini()
+{
+ // any QObject inherited class will do (e.g. main window of a C++ application)
+ static QObject* cpp = 0;
+ if(!cpp) {
+ cpp = new CPP;
+ cpp->setObjectName("Qt_EQL_dynamic");
+ }
+ return cpp;
+}
+
+// insert here your function implementations
+
+QVariantList CPP::hello(const QVariantList& list)
+{
+ QString msg;
+ QDebug debug(&msg);
+ debug << list;
+ QMessageBox::information(0, "QVariantList", msg);
+
+ QVariantList ret(list);
+ if(!ret.isEmpty()) {
+ ret[0] = "hello from Lisp";
+ }
+ return ret;
+}
+
+QT_END_NAMESPACE
diff --git a/Qt_EQL/cpp/lib.h b/Qt_EQL/cpp/lib.h
new file mode 100644
index 0000000..dc3b5d4
--- /dev/null
+++ b/Qt_EQL/cpp/lib.h
@@ -0,0 +1,26 @@
+#ifndef LIB_H
+#define LIB_H
+
+#include
+
+#ifdef Q_WS_WIN
+#define LIB_EXPORT __declspec(dllexport)
+#else
+#define LIB_EXPORT
+#endif
+
+QT_BEGIN_NAMESPACE
+
+extern "C" { LIB_EXPORT QObject* ini(); }
+
+class CPP : public QObject
+{
+ Q_OBJECT
+public:
+ // insert here your function declarations, prepended by Q_INVOKABLE
+ Q_INVOKABLE QVariantList hello(const QVariantList&);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/Qt_EQL/cpp_calling_lisp/eql_cpp.pro b/Qt_EQL/cpp_calling_lisp/eql_cpp.pro
new file mode 100644
index 0000000..9e1ff96
--- /dev/null
+++ b/Qt_EQL/cpp_calling_lisp/eql_cpp.pro
@@ -0,0 +1,13 @@
+QT += widgets
+TEMPLATE = lib
+CONFIG += plugin release
+LIBS += -L../.. -leql5
+DESTDIR = ../
+TARGET = eql_fun_cpp
+OBJECTS_DIR = ./tmp/
+MOC_DIR = ./tmp/
+
+include(../../src/windows.pri)
+
+HEADERS += lib.h
+SOURCES += lib.cpp
diff --git a/Qt_EQL/cpp_calling_lisp/lib.cpp b/Qt_EQL/cpp_calling_lisp/lib.cpp
new file mode 100644
index 0000000..06c8b55
--- /dev/null
+++ b/Qt_EQL/cpp_calling_lisp/lib.cpp
@@ -0,0 +1,62 @@
+#include "lib.h"
+#include "../../src/eql_fun.h" // for eql_fun()
+
+QT_BEGIN_NAMESPACE
+
+QObject* ini()
+{
+ // any QObject inherited class will do (e.g. main window of a C++ application)
+ static QObject* cpp = 0;
+ if(!cpp) {
+ cpp = new CPP;
+ cpp->setObjectName("Qt_EQL_dynamic");
+ }
+ return cpp;
+}
+
+// insert here your function implementations
+
+void CPP::runExamples()
+{
+ ulong n = 123;
+
+ // (1) call user defined function
+ {
+ QVariant ret = eql_fun("eql-user:say-number", QVariant::String, // see: ecl_fun.cpp:toQVariant()
+ Q_ARG(ulong, n)); // see: ecl_fun.cpp:to_lisp_arg()
+
+ QMessageBox::information(0, "Example 1",
+ "eql_fun(\"eql-user:say-number\"...); " + ret.toString());
+ }
+
+ // (2) call FORMAT directly
+ {
+ QVariant ret = eql_fun("format", QVariant::String,
+ Q_ARG(bool, false), // max. 10 Q_ARG()
+ Q_ARG(QString, "~R"),
+ Q_ARG(ulong, n));
+
+ QMessageBox::information(0, "Example 2",
+ "eql_fun(\"format\"...); " + ret.toString());
+ }
+
+ // (3) returning a pointer
+ {
+ QVariant ret = eql_fun("qnew", QMetaType::VoidStar,
+ Q_ARG(QString, "QLabel"));
+
+ QLabel* object = Q_PTR(QLabel*, ret); // type checked at run time; 0 if check fails
+ if(object) {
+ // ...
+ }
+
+ QString msg;
+ QDebug out(&msg);
+ out << "Q_PTR returned:" << object << "
(type checked at run time)
";
+
+ QMessageBox::information(0, "Example 3",
+ "eql_fun(\"qnew\"...); " + msg);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/Qt_EQL/cpp_calling_lisp/lib.h b/Qt_EQL/cpp_calling_lisp/lib.h
new file mode 100644
index 0000000..7062422
--- /dev/null
+++ b/Qt_EQL/cpp_calling_lisp/lib.h
@@ -0,0 +1,26 @@
+#ifndef LIB_H
+#define LIB_H
+
+#include
+
+#ifdef Q_WS_WIN
+#define LIB_EXPORT __declspec(dllexport)
+#else
+#define LIB_EXPORT
+#endif
+
+QT_BEGIN_NAMESPACE
+
+extern "C" { LIB_EXPORT QObject* ini(); }
+
+class CPP : public QObject
+{
+ Q_OBJECT
+public:
+ // insert here your function declarations, prepended by Q_INVOKABLE
+ Q_INVOKABLE void runExamples();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/Qt_EQL/looping.lisp b/Qt_EQL/looping.lisp
new file mode 100644
index 0000000..fa5a723
--- /dev/null
+++ b/Qt_EQL/looping.lisp
@@ -0,0 +1,15 @@
+;;; Lisp calling C++ calling Lisp
+
+(in-package :eql-user)
+
+(defvar *lib* (qload-c++ (in-home "Qt_EQL/eql_fun_cpp")))
+
+(defun say-number (n)
+ (format nil "~R" n))
+
+;; see examples in "cpp_calling_lisp/lib.cpp"
+
+(! "runExamples" (:qt *lib*)) ; note :qt
+
+(qq)
+
diff --git a/Qt_EQL/make.bat b/Qt_EQL/make.bat
new file mode 100644
index 0000000..e763415
--- /dev/null
+++ b/Qt_EQL/make.bat
@@ -0,0 +1,4 @@
+@echo off
+
+cd cpp
+nmake
\ No newline at end of file
diff --git a/Qt_EQL/reload.lisp b/Qt_EQL/reload.lisp
new file mode 100644
index 0000000..7114af1
--- /dev/null
+++ b/Qt_EQL/reload.lisp
@@ -0,0 +1,30 @@
+;;;
+;;; OSX note: unloading may not work!
+;;;
+;;; Simple demo:
+;;;
+;;; 0) do: eql reload.lisp -qtpl
+;;;
+;;; 1) make some changes in "cpp/lib.h", "cpp/lib.cpp"
+;;; 2) do: (recompile-c++)
+;;; 3) goto 1)
+;;;
+;;; Call plugin functions like this:
+;;;
+;;; (qfun+ *lib* "myFunction") ; a)
+;;; (! "myFunction" (:qt *lib*)) ; b)
+;;;
+
+(in-package :eql-user)
+
+(defvar *lib* (qload-c++ (in-home "Qt_EQL/eql_cpp")))
+
+(defun recompile-c++ ()
+ (qload-c++ (in-home "Qt_EQL_dynamic/eql_cpp")
+ :unload)
+ (ext:run-program #+msvc "make.bat" #-msvc "make"
+ #+msvc nil #-msvc '("-C" "cpp/")
+ :output t)
+ (setf *lib* (qload-c++ (in-home "Qt_EQL/eql_cpp")))
+ (assert (qt-object-p *lib*))
+ (qapropos nil *lib*))
diff --git a/Qt_EQL/test.lisp b/Qt_EQL/test.lisp
new file mode 100644
index 0000000..3080d42
--- /dev/null
+++ b/Qt_EQL/test.lisp
@@ -0,0 +1,17 @@
+(in-package :eql-user)
+
+(defvar *lib* (qload-c++ (in-home "Qt_EQL/eql_cpp")))
+
+(assert (qt-object-p *lib*))
+
+(qapropos nil *lib*)
+
+;; test call
+
+(qlet ((a "QVariant(QString)" "hello from C++")
+ (b "QVariant(int)" 42)
+ (c "QVariant(double)" pi)
+ (d "QVariant(QByteArray)" #(69 81 76)))
+ (qmsg (! "hello" (:qt *lib*) (list a b c d)))) ; note :qt
+
+(qq)
diff --git a/Qt_EQL/trafficlight/README.txt b/Qt_EQL/trafficlight/README.txt
new file mode 100644
index 0000000..d8b72e2
--- /dev/null
+++ b/Qt_EQL/trafficlight/README.txt
@@ -0,0 +1,32 @@
+This is a simple example of integrating an existing Qt/C++ application
+
+
+BUILD / RUN / CALL
+==================
+
+qmake
+make
+
+eql run.lisp -qtpl
+
+________________________________________
+
+Option 1:
+
+ (qfun+ *trafficlight* "stop")
+ (qfun+ *trafficlight* "start")
+________________________________________
+
+Option 2:
+
+ (! "stop" (:qt *trafficlight*))
+ (! "start" (:qt *trafficlight*))
+________________________________________
+
+Option 3:
+
+ (define-qt-wrappers *trafficlight*)
+
+ (start *trafficlight*)
+ (stop *trafficlight*)
+________________________________________
diff --git a/Qt_EQL/trafficlight/lib.cpp b/Qt_EQL/trafficlight/lib.cpp
new file mode 100644
index 0000000..85a0161
--- /dev/null
+++ b/Qt_EQL/trafficlight/lib.cpp
@@ -0,0 +1,19 @@
+#include "lib.h"
+#include "trafficlight.h"
+
+QT_BEGIN_NAMESPACE
+
+QObject* ini()
+{
+ static QWidget* widget = 0;
+
+ if(!widget) {
+ widget = new TrafficLight;
+ widget->resize(110, 300);
+ widget->show();
+ }
+
+ return widget;
+}
+
+QT_END_NAMESPACE
diff --git a/Qt_EQL/trafficlight/lib.h b/Qt_EQL/trafficlight/lib.h
new file mode 100644
index 0000000..9728a28
--- /dev/null
+++ b/Qt_EQL/trafficlight/lib.h
@@ -0,0 +1,18 @@
+#ifndef LIB_H
+#define LIB_H
+
+#include
+
+#ifdef Q_WS_WIN
+#define LIB_EXPORT __declspec(dllexport)
+#else
+#define LIB_EXPORT
+#endif
+
+QT_BEGIN_NAMESPACE
+
+extern "C" { LIB_EXPORT QObject* ini(); }
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/Qt_EQL/trafficlight/run.lisp b/Qt_EQL/trafficlight/run.lisp
new file mode 100644
index 0000000..9a291fd
--- /dev/null
+++ b/Qt_EQL/trafficlight/run.lisp
@@ -0,0 +1,23 @@
+(in-package :eql-user)
+
+(defvar *trafficlight* (qload-c++ (in-home "Qt_EQL/trafficlight/trafficlight")))
+(defvar *lights* (qfind-children *trafficlight* nil "LightWidget"))
+(defvar *red* (first *lights*))
+(defvar *yellow* (second *lights*))
+(defvar *green* (third *lights*))
+
+(qapropos nil *trafficlight*)
+(qapropos nil *red*)
+
+;;; generate wrappers
+
+(define-qt-wrappers *trafficlight*)
+(define-qt-wrappers *red*)
+
+;;; now you can do:
+;;;
+;;; (start *trafficlight*)
+;;; (stop *trafficlight*)
+;;;
+;;; (turn-on *red*)
+;;; (turn-off *green*)
diff --git a/Qt_EQL/trafficlight/trafficlight.cpp b/Qt_EQL/trafficlight/trafficlight.cpp
new file mode 100644
index 0000000..be1112f
--- /dev/null
+++ b/Qt_EQL/trafficlight/trafficlight.cpp
@@ -0,0 +1,18 @@
+// original copyright:
+//
+// ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// ** You may use this file under the terms of the BSD license
+
+#include "trafficlight.h"
+
+void LightWidget::paintEvent(QPaintEvent *)
+{
+ if (!m_on)
+ return;
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setBrush(m_color);
+ painter.drawEllipse(0, 0, width(), height());
+}
+
diff --git a/Qt_EQL/trafficlight/trafficlight.h b/Qt_EQL/trafficlight/trafficlight.h
new file mode 100644
index 0000000..fd1535a
--- /dev/null
+++ b/Qt_EQL/trafficlight/trafficlight.h
@@ -0,0 +1,134 @@
+// original copyright:
+//
+// ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// ** You may use this file under the terms of the BSD license
+
+#ifndef TRAFFICLIGHT_H
+#define TRAFFICLIGHT_H
+
+#include
+
+class LightWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool on READ isOn WRITE setOn)
+public:
+ LightWidget(const QColor &color, QWidget *parent = 0)
+ : QWidget(parent), m_color(color), m_on(false) {}
+
+ bool isOn() const
+ { return m_on; }
+ void setOn(bool on)
+ {
+ if (on == m_on)
+ return;
+ m_on = on;
+ update();
+ }
+
+public slots:
+ void turnOff() { setOn(false); }
+ void turnOn() { setOn(true); }
+
+protected:
+ virtual void paintEvent(QPaintEvent *);
+
+private:
+ QColor m_color;
+ bool m_on;
+};
+
+class TrafficLightWidget : public QWidget
+{
+public:
+ TrafficLightWidget(QWidget *parent = 0)
+ : QWidget(parent)
+ {
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ m_red = new LightWidget(Qt::red);
+ m_red->setObjectName("red");
+ vbox->addWidget(m_red);
+ m_yellow = new LightWidget(Qt::yellow);
+ m_yellow->setObjectName("yellow");
+ vbox->addWidget(m_yellow);
+ m_green = new LightWidget(Qt::green);
+ m_green->setObjectName("green");
+ vbox->addWidget(m_green);
+ QPalette pal = palette();
+ pal.setColor(QPalette::Background, Qt::black);
+ setPalette(pal);
+ setAutoFillBackground(true);
+ }
+
+ LightWidget *redLight() const
+ { return m_red; }
+ LightWidget *yellowLight() const
+ { return m_yellow; }
+ LightWidget *greenLight() const
+ { return m_green; }
+
+private:
+ LightWidget *m_red;
+ LightWidget *m_yellow;
+ LightWidget *m_green;
+};
+
+class TrafficLight : public QWidget
+{
+ Q_OBJECT
+public:
+ TrafficLight(QWidget *parent = 0)
+ : QWidget(parent)
+ {
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ TrafficLightWidget *widget = new TrafficLightWidget();
+ vbox->addWidget(widget);
+ vbox->setMargin(0);
+
+ machine = new QStateMachine(this);
+ QState *redGoingYellow = createLightState(widget->redLight(), 2000);
+ redGoingYellow->setObjectName("redGoingYellow");
+ QState *yellowGoingGreen = createLightState(widget->yellowLight(), 500);
+ yellowGoingGreen->setObjectName("yellowGoingGreen");
+ redGoingYellow->addTransition(redGoingYellow, SIGNAL(finished()), yellowGoingGreen);
+ QState *greenGoingYellow = createLightState(widget->greenLight(), 2000);
+ greenGoingYellow->setObjectName("greenGoingYellow");
+ yellowGoingGreen->addTransition(yellowGoingGreen, SIGNAL(finished()), greenGoingYellow);
+ QState *yellowGoingRed = createLightState(widget->yellowLight(), 500);
+ yellowGoingRed->setObjectName("yellowGoingRed");
+ greenGoingYellow->addTransition(greenGoingYellow, SIGNAL(finished()), yellowGoingRed);
+ yellowGoingRed->addTransition(yellowGoingRed, SIGNAL(finished()), redGoingYellow);
+
+ machine->addState(redGoingYellow);
+ machine->addState(yellowGoingGreen);
+ machine->addState(greenGoingYellow);
+ machine->addState(yellowGoingRed);
+ machine->setInitialState(redGoingYellow);
+ machine->start();
+ }
+
+ QState *createLightState(LightWidget *light, int duration, QState *parent = 0)
+ {
+ QState *lightState = new QState(parent);
+ QTimer *timer = new QTimer(lightState);
+ timer->setInterval(duration);
+ timer->setSingleShot(true);
+ QState *timing = new QState(lightState);
+ QObject::connect(timing, SIGNAL(entered()), light, SLOT(turnOn()));
+ QObject::connect(timing, SIGNAL(entered()), timer, SLOT(start()));
+ QObject::connect(timing, SIGNAL(exited()), light, SLOT(turnOff()));
+ QFinalState *done = new QFinalState(lightState);
+ timing->addTransition(timer, SIGNAL(timeout()), done);
+ lightState->setInitialState(timing);
+ return lightState;
+ }
+
+ Q_INVOKABLE void start() { machine->start(); }
+ Q_INVOKABLE void stop() { machine->stop(); }
+
+private:
+ QStateMachine *machine;
+
+};
+
+#endif
diff --git a/Qt_EQL/trafficlight/trafficlight.pro b/Qt_EQL/trafficlight/trafficlight.pro
new file mode 100644
index 0000000..2e18422
--- /dev/null
+++ b/Qt_EQL/trafficlight/trafficlight.pro
@@ -0,0 +1,15 @@
+QT += widgets
+TEMPLATE = lib
+CONFIG += plugin release
+DESTDIR = ./
+TARGET = trafficlight
+OBJECTS_DIR = ./tmp/
+MOC_DIR = ./tmp/
+
+include(../../src/windows.pri)
+
+HEADERS += lib.h \
+ trafficlight.h
+
+SOURCES += lib.cpp \
+ trafficlight.cpp
diff --git a/Qt_EQL_plugin/Qt/main.cpp b/Qt_EQL_plugin/Qt/main.cpp
new file mode 100644
index 0000000..83d8b7e
--- /dev/null
+++ b/Qt_EQL_plugin/Qt/main.cpp
@@ -0,0 +1,14 @@
+#include
+#include
+#include "qt_application.h"
+
+int main(int argc, char** argv)
+{
+ QApplication qapp(argc, argv);
+
+ MainWindow window;
+ window.setGeometry(50, 50, 500, 300);
+ window.show();
+
+ return qapp.exec();
+}
diff --git a/Qt_EQL_plugin/Qt/qt_application.cpp b/Qt_EQL_plugin/Qt/qt_application.cpp
new file mode 100644
index 0000000..1ada75f
--- /dev/null
+++ b/Qt_EQL_plugin/Qt/qt_application.cpp
@@ -0,0 +1,64 @@
+#include
+#include
+#include
+
+#include "qt_application.h"
+
+typedef void (*OnShowPlugin)(QWidget*);
+typedef void (*OnHidePlugin)();
+
+static OnShowPlugin onShowPlugin = 0;
+static OnHidePlugin onHidePlugin = 0;
+
+MainWindow::MainWindow() : pluginWidget(0)
+{
+ setWindowTitle("Qt Application");
+
+ QWidget* central = new QWidget;
+ QLabel* label = new QLabel;
+ label->setText(tr("QMainWindow with a dockable plugin widget. "));
+ QPushButton* buttonShow = new QPushButton(tr("show plugin"));
+ QPushButton* buttonHide = new QPushButton(tr("hide plugin"));
+ setCentralWidget(central);
+
+ QHBoxLayout* layout = new QHBoxLayout(central);
+ QVBoxLayout* buttonLayout = new QVBoxLayout;
+ buttonLayout->addWidget(buttonShow);
+ buttonLayout->addWidget(buttonHide);
+ buttonLayout->addStretch();
+ layout->addWidget(label);
+ layout->addLayout(buttonLayout);
+
+ connect(buttonShow, SIGNAL(clicked()), SLOT(showPlugin()));
+ connect(buttonHide, SIGNAL(clicked()), SLOT(hidePlugin()));
+}
+
+void MainWindow::showPlugin()
+{
+ static bool loaded = false;
+ if(!loaded) {
+ loaded = true;
+ QLibrary plugin("./qt_plugin");
+ onShowPlugin = (OnShowPlugin)plugin.resolve("onShowPlugin");
+ onHidePlugin = (OnHidePlugin)plugin.resolve("onHidePlugin");
+ pluginWidget = new QDockWidget(this);
+ addDockWidget(Qt::TopDockWidgetArea, pluginWidget);
+ }
+
+ if(onShowPlugin) {
+ onShowPlugin(pluginWidget);
+ }
+
+ pluginWidget->show();
+}
+
+void MainWindow::hidePlugin()
+{
+ if(pluginWidget) {
+ pluginWidget->hide();
+ }
+
+ if(onHidePlugin) {
+ onHidePlugin();
+ }
+}
diff --git a/Qt_EQL_plugin/Qt/qt_application.h b/Qt_EQL_plugin/Qt/qt_application.h
new file mode 100644
index 0000000..99b8481
--- /dev/null
+++ b/Qt_EQL_plugin/Qt/qt_application.h
@@ -0,0 +1,24 @@
+#ifndef QT_APPLICATION_H
+#define QT_APPLICATION_H
+
+#include
+
+QT_BEGIN_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow();
+
+ QDockWidget* pluginWidget;
+
+public slots:
+ void showPlugin();
+ void hidePlugin();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/Qt_EQL_plugin/Qt/qt_application.pro b/Qt_EQL_plugin/Qt/qt_application.pro
new file mode 100644
index 0000000..916c790
--- /dev/null
+++ b/Qt_EQL_plugin/Qt/qt_application.pro
@@ -0,0 +1,10 @@
+QT += widgets
+TEMPLATE = app
+CONFIG += release
+TARGET = qt_application
+DESTDIR = ../
+OBJECTS_DIR = ./tmp/
+MOC_DIR = ./tmp/
+
+HEADERS = qt_application.h
+SOURCES = qt_application.cpp main.cpp
diff --git a/Qt_EQL_plugin/README.txt b/Qt_EQL_plugin/README.txt
new file mode 100644
index 0000000..b4e7423
--- /dev/null
+++ b/Qt_EQL_plugin/README.txt
@@ -0,0 +1,34 @@
+*** N.B: MS folks: You'll need Windows >= 7 ***
+
+
+INTRO / DESCRIPTION
+===================
+
+This is a very basic example of using EQL in a Qt plugin.
+So, if some 3rd party Qt application offers a way to integrate Qt plugins, you
+can use EQL for your plugin.
+
+We assume that the 3rd party application offers us a QWidget as parent for
+our plugin. In this example it's a QDockWidget, which is bound to
+eql:*qt-main* in Lisp.
+
+
+
+BUILD / RUN
+===========
+
+- build dummy application in "Qt/"
+- build plugin in this directory
+- run the "qt_application" executable
+
+
+
+NOTES
+=====
+
+See also the function "set-data" in "ini.lisp": it shows a simple way for data
+exchange between the application and the plugin.
+It uses a dynamic Qt property, which can be accessed from both sides, C++ and
+Lisp, since the property is added to the plugin parent widget of the application:
+"pluginWidget" in C++, "*qt-main*" in Lisp.
+
diff --git a/Qt_EQL_plugin/ini.lisp b/Qt_EQL_plugin/ini.lisp
new file mode 100644
index 0000000..8870c1b
--- /dev/null
+++ b/Qt_EQL_plugin/ini.lisp
@@ -0,0 +1,49 @@
+(in-package :eql-user)
+
+(defvar *label* (qnew "QLabel"))
+(defvar *edit* (qnew "QLineEdit"))
+(defvar *font* (qnew "QFont(QString,int)"
+ #+darwin "Monaco" #+darwin 12
+ #+linux "Monospace" #+linux 9
+ #+windows "Courier New" #+windows 10))
+
+(defun ini ()
+ (let* ((widget (qnew "QWidget"))
+ (layout (qnew "QVBoxLayout(QWidget*)" widget)))
+ (dolist (w (list *label* *edit*))
+ (qset w "font" *font*)
+ (! "addWidget" layout w))
+ (! "setWidget" *qt-main* widget)
+ (qconnect *edit* "returnPressed()" 'eval-edit)
+ (qlater 'delayed-ini)))
+
+(defun delayed-ini ()
+ (qset *edit* "text" "(in-package :eql-user)")
+ (eval-edit)
+ (qset *label* "text" "Enter Lisp expression and hit Return:"))
+
+(defun eval-edit ()
+ (qset *label* "text"
+ (handler-case (let ((result (eval (read-from-string (qget *edit* "text")))))
+ (! "clear" *edit*)
+ (princ-to-string result))
+ (error (condition)
+ (x:cc "Error: " (qescape (princ-to-string condition)))))))
+
+(let (loaded)
+ (defun ? ()
+ (unless loaded
+ (setf loaded t)
+ (load "../src/lisp/qselect.lisp"))
+ (eql::%qselect (lambda (widget) (qset *label* "text" (format nil "~A ; see qsel:*q*" widget))))))
+
+(defun set-data (data)
+ "Example of using dynamic Qt properties for simple data exchange."
+ (! "setProperty" *qt-main* "data"
+ (typecase data
+ ;; 2 example cases
+ (string (qnew "QVariant(QString)" data)) ; string
+ (vector (qnew "QVariant(QByteArray)" data)))) ; binary data (vector of octets)
+ data)
+
+(ini)
diff --git a/Qt_EQL_plugin/qt_plugin.cpp b/Qt_EQL_plugin/qt_plugin.cpp
new file mode 100644
index 0000000..7c57b0d
--- /dev/null
+++ b/Qt_EQL_plugin/qt_plugin.cpp
@@ -0,0 +1,19 @@
+#include "qt_plugin.h"
+#include "eql.h"
+
+QT_BEGIN_NAMESPACE
+
+void onShowPlugin(QWidget* widget)
+{
+ static EQL* eql = 0;
+ if(!eql) {
+ eql = new EQL;
+ eql->exec(widget, "ini.lisp");
+ }
+}
+
+void onHidePlugin()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/Qt_EQL_plugin/qt_plugin.h b/Qt_EQL_plugin/qt_plugin.h
new file mode 100644
index 0000000..9a17dd4
--- /dev/null
+++ b/Qt_EQL_plugin/qt_plugin.h
@@ -0,0 +1,23 @@
+#ifndef QT_PLUGIN_H
+#define QT_PLUGIN_H
+
+#include
+
+#ifdef Q_WS_WIN
+#define LIB_EXPORT __declspec(dllexport)
+#else
+#define LIB_EXPORT
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+
+extern "C" {
+ LIB_EXPORT void onShowPlugin(QWidget*);
+ LIB_EXPORT void onHidePlugin();
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/Qt_EQL_plugin/qt_plugin.pro b/Qt_EQL_plugin/qt_plugin.pro
new file mode 100644
index 0000000..ec822c6
--- /dev/null
+++ b/Qt_EQL_plugin/qt_plugin.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+CONFIG += dll no_keywords release
+INCLUDEPATH += ../src
+LIBS += -L.. -leql5
+TARGET = qt_plugin
+DESTDIR = ./
+OBJECTS_DIR = ./tmp/
+MOC_DIR = ./tmp/
+
+include(../src/windows.pri)
+
+HEADERS = qt_plugin.h
+SOURCES = qt_plugin.cpp
diff --git a/README-1.txt b/README-1.txt
new file mode 100644
index 0000000..da42339
--- /dev/null
+++ b/README-1.txt
@@ -0,0 +1,157 @@
+*********************************
+* EQL5 is a Qt5 port of EQL/Qt4 *
+*********************************
+
+# contact: gmail, polos.ruetz
+# mailing list: http://groups.google.com/group/eql-user/topics
+#
+# MANY THANKS to the users of the eql-user mailing list for their contributions!
+
+
+
+TESTED WITH
+===========
+
+* ECL 16
+* Qt 5.5
+* Linux
+
+
+
+REQUIREMENTS
+============
+
+* ECL threads + unicode
+* Qt5
+* /should/ run cross-platform
+
+
+
+BUILD
+=====
+
+(N.B. for rebuilding, please see README-REBUILD.txt)
+
+ [Windows]
+ You first need to adapt the file src/windows.pri (include & library paths).
+
+ [MSVC]
+ substitute make with nmake
+
+ [OSX]
+ To force creation of a Makefile (instead of an Xcode project), use this flag:
+ qmake -spec macx-g++
+
+1) In src/ run:
+
+ ecl -shell make-eql-lib.lisp
+
+2) Do: (use qmake-qt4 if you have Qt5 installed)
+
+ qmake eql_lib.pro
+ make
+
+ qmake eql_exe.pro
+ make
+
+ This will build both the EQL executable and shared library.
+
+3) cd ..
+
+ [Linux]
+ You need to create links to EQL, something like (note the "5"):
+ cd /usr/lib
+ sudo ln -s ~/eql5/libeql5.so.1 libeql5.so.1
+ cd /usr/bin
+ sudo ln -s ~/eql5/eql5 eql5
+
+ [OSX]
+ You need to create links to EQL, something like (note the "5"):
+ cd /usr/lib
+ sudo ln -s ~/eql5/libeql5.1.dylib libeql5.1.dylib
+ cd /usr/bin
+ sudo ln -s ~/eql5/eql5.app/Contents/MacOS/eql5 eql5
+
+ [Windows]
+ Add your EQL directory to the Path environment variable, see:
+
+
+
+
+RUN
+===
+
+PLEASE NOTE:
+You will often need to "reset" (command) your console/shell after EQL finished
+working, especially during development time or other exits than "(eql:qquit)".
+
+
+You can run a simple interactive REPL UI doing:
+ eql5 -qgui
+
+To run a Lisp file without top-level, do:
+ eql5 examples/2-clock
+
+(If you don't see the application window, it might be in the background.
+Use your taskbar to show it.)
+
+If you start the EQL executable without arguments, it will start the usual ECL top-level
+(without processing Qt events).
+
+To _not_ load ~/.eclrc on startup, do:
+ eql5 -norc
+
+To quit the tool, do:
+ (eql:qquit) or
+ (eql:qq)
+
+In order to run (sort of) a top-level processing Qt events, do (requires ECL threads):
+ eql5 -qtpl
+
+ Note: If you want to use "ecl-readline" together with "-qtpl", just compile
+ "eql5/src/lisp/ecl-readline.lisp" (which depends on the "readline" C library).
+ It will then be loaded automatically on startup.
+
+
+
+QT MODULES (network, sql, opengl)
+==========
+
+To build an EQL module (corresponding to a Qt module), do the following in src/:
+
+ qmake module_.pro (e.g. qmake module_network.pro)
+ make
+
+ [Linux,OSX]
+ You need to create links to the modules, see EQL library above.
+
+In Lisp, use the function QREQUIRE to load a module:
+ (qrequire :network)
+
+
+
+TIP
+===
+
+You might want to put this in your ~/.eclrc file:
+
+ #+eql
+ (setf eql:*qtpl* t ; same as -qtpl
+ eql:*break-on-errors* t)
+
+
+
+NOTES
+=====
+
+For additional information see doc/index.html.
+
+
+
+LICENSE
+=======
+
+MIT
+
+for MAKE-QIMAGE (contributed by Mark Cox), please see LICENSE-MAKE-QIMAGE.txt
+
diff --git a/README-2-REBUILD.txt b/README-2-REBUILD.txt
new file mode 100644
index 0000000..6c7a4a7
--- /dev/null
+++ b/README-2-REBUILD.txt
@@ -0,0 +1,47 @@
+REBUILD STEPS (on every upgrade of: ECL, Qt, EQL)
+=============
+
+Change to eql/src/ and do:
+
+1) remove directory tmp/
+ remove slime/thread-safe.fas*
+ remove src/lisp/ecl-readline.fas* (only on upgrading ECL; to recompile manually)
+
+2) ecl -shell make-eql-lib.lisp
+
+3) qmake, make in this order: (MSVC: nmake; use qmake-qt4 if you have Qt5 installed)
+
+ eql_lib.pro
+ eql_exe.pro
+
+ module_network.pro
+ module_...
+
+Optionally (integrate wrapper functions):
+
+4) eql5 make-eql-lib-wrappers.lisp
+
+5) re-link EQL library:
+
+ touch tmp/eql.o (or delete "tmp/eql.o*")
+ qmake eql_lib.pro
+ make
+
+
+IMPORTANT NOTES
+===============
+
+C++:
+
+You always need to rebuild from any "*.pro" file (EQL modules, Qt_EQL...) after
+upgrading EQL.
+
+The simplest way to clean everything is to remove the whole "tmp/" directory in
+the respective build directory, since the Makefile generated by Qt not always
+works correctly with "make clean" (e.g. on Windows).
+
+Lisp:
+
+It's also recommended to recompile any compiled EQL code (because of the tight
+ECL/C++ integration).
+
diff --git a/README-3-OPTIONAL.txt b/README-3-OPTIONAL.txt
new file mode 100644
index 0000000..3faf44f
--- /dev/null
+++ b/README-3-OPTIONAL.txt
@@ -0,0 +1,51 @@
+Wrapper functions
+=================
+
+If you want to use wrapper functions for all Qt functions, see:
+
+ "src/lisp/all-wrappers.lisp"
+
+Examples:
+
+ (|show| widget)
+
+ (|toString| (|currentTime.QTime|)) ; static function
+
+ (|begin(QWidget*)| painter)
+
+
+Notes
+=====
+
+If you want to add the wrappers permanently, build EQL as usual, then run
+
+ eql5 make-eql-lib-wrappers.lisp
+
+Re-link EQL doing something like:
+
+ touch tmp/eql.o* (or delete "tmp/eql.o*")
+ qmake eql_lib.pro
+ make
+
+(The resulting shared library will be considerably bigger than before).
+
+---
+
+The convenience macro X:DO-WITH has been adapted to work with the wrappers:
+
+ (x:do-with item
+ (|setTextAlignment| 0 |Qt.AlignRight|)
+ (|setText| 0 "123"))
+
+---
+
+Normally not needed, but if you want to generate the wrappers for your
+Qt version (much different from Qt 5.5) do:
+
+ cd src/lisp
+ eql5 define-all-wrappers.lisp
+
+---
+
+See also note in Sokoban example (no more casts needed).
+
diff --git a/doc/Debugging.htm b/doc/Debugging.htm
new file mode 100644
index 0000000..79c7441
--- /dev/null
+++ b/doc/Debugging.htm
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
Debugging
+This is a simple
tutorial using the top-level processing Qt events:
+
+ $ eql5 -qtpl
+
+
+
Example 1: Error on REPL (trivial)
+
+
+ EQL-USER[1]> (/ 0)
+
+ Condition of type: DIVISION-BY-ZERO
+
+ Available restarts:
+
+ 1. (RESTART-TOPLEVEL) Go back to Top-Level REPL.
+ 2. (RESTART-QT-EVENTS) Restart Qt event processing.
+
+ ** BREAK [LEVEL 2]>
+
+
+
+
Note that all debug input is handled in a debug dialog, not in the
+console window.
+
So, either type the restart number in the dialog
+
:r1
+or just click Cancel / hit Escape, which will always choose
:r1.
+
Type
:h for all available debug options.
+
Both restarts will have the same effect here, see note at bottom.
+
+
Example 2: Error during Qt event processing
+Start calculator example:
+
+ $ eql5 -qtpl examples/X-extras/calculator
+
+
+Let's run this function:
+
+ EQL-USER[1]> (clc:auto "42 ? blah")
+
+
+This will output 2 errors, without breaking into the debugger:
+
+
+ [EQL:err] QFIND-CHILD #<QDialog "" 0x39737d0 [1]> "?"
+
+ [EQL:err] QINVOKE-METHOD NIL NIL "animateClick" (400)
+
+
+
Note : After eventual print output (like the above), you
+ won't see a fresh top-level prompt. Don't get confused by this, as
+ you can continue to enter commands.
+
+Now make EQL errors break into the debugger:
+
+ EQL-USER[2]> (setf eql:*break-on-errors* t)
+
+
+Run our function again:
+
+
+ EQL-USER[3]> (clc:auto "42 ? blah")
+
+ Condition of type: SIMPLE-CONDITION
+
+ [EQL:err] QFIND-CHILD #<QDialog "" 0x39737d0 [1]> "?"
+
+ Available restarts:
+
+ 1. (CONTINUE) Return from BREAK.
+ 2. (RESTART-QT-EVENTS) Restart Qt event processing.
+
+ ** BREAK [LEVEL 1]>
+
+
+
+
Now there are 2 possible restarts:
+
:r1
+
(CONTINUE) will continue execution, which will break on
+the next error, then finish our function.
+
:r2
+
(RESTART-QT-EVENTS) will abort execution, returning to
+the REPL immediately.
+
+
+
+
Notes
+There is one situation where interactive debugging won't work, and
+this is in code inside an (overridden)
+
"paintEvent(QPaintEvent*)" function, as this may cause
+recursive paint events and segfaults.
+
+
+To exit instantly from EQL during debugging (on nasty errors), just type
+
:qq / :exit
+in the debug dialog (or REPL).
+
+
+On simple
read errors on the REPL (e.g. non-existing packages, non-external symbols), the debugger will not be entered (as this would cause an unrecoverable
break, since
read runs in its own thread here); instead, the erroneous input string will be returned as-is.
+
+
+The conflicting case
+
(RESTART-TOPLEVEL)
+ (RESTART-QT-EVENTS)
+is resolved automatically (
RESTART-QT-EVENTS would block the REPL in this case).
+
+
+
+
Tips
+You might want to put this in your
~/.eclrc file:
+
+
+ #+eql
+ (setf eql:*qtpl* t ; same as -qtpl
+ eql:*break-on-errors* t)
+
+
+
+
In order to automatically switch the REPL to a given package after loading a file, add this line:
+
(qlater (lambda () (in-package :my-package)))
+
+
If you use ECL readline (see ecl-readline.lisp in sources): After entering :qq (quitting the top-level), the console/shell should always be reset (but you won't probably see the command while typing it; an alias might help):
+
+ $ reset
+
+
+
+
+
diff --git a/doc/Deploy.htm b/doc/Deploy.htm
new file mode 100644
index 0000000..9765812
--- /dev/null
+++ b/doc/Deploy.htm
@@ -0,0 +1,14 @@
+
+
+
+
+Deploy
+Please follow the my_app/README.txt (which assumes that your lisp files are in my_app/lisp/)
+The dependencies are:
+
+eql5, ecl, QtCore, QtGui, QtWidgets, QtPrintSupport shared libraries
+your *.ui files (if any)
+ your *.qm translation files (if any)
+
+A detailed description of deploying Qt applications can be found in Qt Assistant.
+
diff --git a/doc/EQL-Slime-Integration.htm b/doc/EQL-Slime-Integration.htm
new file mode 100644
index 0000000..d61c297
--- /dev/null
+++ b/doc/EQL-Slime-Integration.htm
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
EQL (ECL + Qt) in Slime -- how does it work?
+
+ Start swank using the EQL executable, running the swank server in an ECL thread, and using the main thread for the Qt main event loop.
+ Wrap every internal EQL function in a macro, which will call the function either directly (if called from GUI/main thread), or, if called from another ECL thread, will wrap the function call in a closure.
+ This closure will be passed to a queued, blocking Qt function running in the GUI thread, which will in turn call the closure.
+
+
The crucial part is passing a Lisp closure from an ECL thread to Qt and calling it from C++ in the GUI/main thread.
+
This is trivial in ECL/Qt, since both ECL and Qt use/wrap native C threads, and Qt offers a nice utility with Q_INVOKABLE.
+
First let's wrap the actual Lisp function, e.g. (foo x y) in a closure, so we only need to pass one ECL closure pointer to C++.
+
No need to pass Lisp arguments to C++, they are in the closure; no return value needed from C++, Lisp return values will be assigned in the closure:
+
+
+ ;; in some ECL thread
+ (let (values)
+ (run-in-gui-thread
+
+ ;; in ECL main/GUI thread
+ (lambda ()
+ (setf values (multiple-value-list (foo x y)))))
+
+ ;; back in some ECL thread
+ (values-list values))
+
+
+
Here the implementation of the ECL function run-in-gui-thread (embedded in Qt):
+
+
+ cl_object run_in_gui_thread(cl_object closure) // define ECL function
+ {
+ QMetaObject::invokeMethod(
+ object, // any QObject from GUI thread
+ "runInGuiThread", // see Q_INVOKABLE
+ Qt::BlockingQueuedConnection, // blocking for return values
+ Q_ARG(void*, closure)); // 'closure' is just a pointer
+
+ return Cnil;
+ }
+
+
+
Now the Lisp closure will run in the GUI/main thread, and the implementation of the Qt function runInGuiThread is as simple as:
+
+
+ Q_INVOKABLE void runInGuiThread(void* closure) // note Q_INVOKABLE
+ {
+ cl_funcall(1, (cl_object)closure); // ECL function call
+ }
+
+
+
After introducing a macro qrun*, and wrapping all EQL functions in it (see "slime/thread-safe.lisp" ), we are done!
+
(Please note that the above code is a stripped down version, see sources for the actual implementation.)
+
+
+
+
+
diff --git a/doc/EQL.png b/doc/EQL.png
new file mode 100644
index 0000000000000000000000000000000000000000..f7f661b788d0c50c23ab16f3f66d70ba003dc64c
GIT binary patch
literal 2866
zcmZ`*XH=7k68-2%SwKXZw9rBNvJ?dtL=rlomr$g)NE1R02t+^vibzxGHI#(16s7H>
z2ndOSi5RMM5u^ku0*1%_eCO=@ap%s=nKM7;%$z$JRu*7(76BFj0N9NohSrx{eF-Qt
z?WMhKvY&iOG!fQd0{~07v3VI>357UC001lZKcE3#yy61@mT6-{ecR}n@5M1NZm{5p
zpV$?xKO{V8lU0&ldD4VbeFG0S;Fh68hnDmWmuly{<;m$3YlSA~H9MCrd5|4_!lB*G
zz!nCRNe}}R`rNdRQ_&c*%ECGD><5Q(@Bok4m9&Gi%;Igr&IF>wuS6?Ke>GeyDb}xw
zsR5uoO71Ba4UriYWcgS3Uz7h+imbgGjd(mGfl*YHkyDVB+bHG2w_0rF~~D))-*`w@q;)8YCQ1m69X#oYjD+i!kVMG@3-AfRMigzK&HaJFeQwvxQHT+rpLnzFKs*B!Roo
z;`()*;avmC=s#~Fw_aHbQ-~{BK0{#PTQT1wXW7X+C9E}QgtD6I6q6&|$H~GdaN>KH
zbqh=i3rS}&O=np_yKV38dJRfM6=>z$(a0HL#c{4l3vA!&O<0(WjQlfr`xhlqVG6b2UoZoB|2av!G#ys{uCCo&H$DT<4Gjjf+U+
z1$FARkI*0^z!?nVElJnzjjl?zoJW=6)9&B4tJRcvbU0&aFC&=Kc1$rQBKZXl&EqZN
z&rEOl!B0LR!p9ef1IVrqXjQ{@HgqotPkUADy$wP?N3q6g=*SrGbxRw!w@
zw}iT_aDK!(+Wq9wlbg4|I`m1|I==U}?Rum&UbYWmrRm&ffiVrf(aZAli#W~7)ZxvzL;!Wmo80)X^BPGY0DrfECT5iM-c{cdCJ<)SNi%ah%;_X#M*Ay_ZYKonN%)RJ4JnN>Mi_qZk(nRW`g?^(>vV*
zSvk(|nv_eXij)cx4k=%cBtTG~le;^IW-YqLT5b{HDrqY!uIT}5-YC&x)P9r2(-jZw
z?=VFL+3CF>%o&i>o=8f%x2d$L4ltUECEN>tZg2HX&Q0TJy(Zjj$fo4)dsb|sAwno+
z!DQTgSJ(u$LC5&cjmErp6p5G94do3_3s5f34C!qOX{yZ84KwJnsrJ=K9U9I!t@yj?
z<`k)l>dLvo#)ri)$Z;Eocdap2^jF`qrjlg$Lfr4|^EZBTcg(m40JQVzTB#4C@{7x4
zc=a%T+L1fVuHVI`Tm2rvfoyWS;Sn7MH9(Xko!30{8aZn%Gz-!SF)Zc1-Vi?d4@954wVx;Ab
zIvZi(-_qqM3<#=&)7Mj98Iru^r2@o;axz#Gdkb8j=GL^rj6AZOv>6xU<(HpPoT;%n
z(Se&Y#d6IwfO#^y`3`mblgN9VHUDy^@LU24v3{RmrZ9OQOE4c*#BufbszQZCt%^gO
z4oX?`uA1W|uJX3=3E;}=lSh2QwI;oLUVqDkta8Nn41RnspKXJEYpc*vn1l-YMrbJ+@ohM<#!^DtwhRtG(0}&F>I&mT6j2+nY}Z$o#O!
zHC(RFJm`u~^9Q6**llyOON~x?HX~LxJ8>M2?s`QEJi#xge)bzDBXE}jrn=;Rf{c@*
z1q#&?_odw3Rx`>PWLd&?@(eH%s`|?88e_DKiP>zxy)Vy;r(UY|BRL5;)kE-XtQlKQb
ziYLjIBgU^`b_DeVhl%-NUIRb2ocMsh{~kb9=0=Am?NjAd-uN)pw`V4#&A!XHQ;Y0f
zq01Y}5e_nHyH#i2nfH*&+8EX(>orXf2lt&?aQ&Dx!jZS{&8OVUeqquR-?!%0%7|gh
z?zfBE8Cd+S#LWLNWy%69|LNl&BJ=CnmKYpYWXEji=?K%FQky#E*|P}e>5U)I<1c_^
zWPb0<2Kw_(c!%3-x=$5k{M2Gdejxzesk}A4+`6ZyPN}#fe#rOk;Fp9zmS`Sj{D6wKjG4zS
zjXh|ebwcbWW=AJxj=jgbgPQ&efet;=fyjPF_)Vhuc!{|mz>g`5BY
literal 0
HcmV?d00001
diff --git a/doc/Notes.htm b/doc/Notes.htm
new file mode 100644
index 0000000..6c0d676
--- /dev/null
+++ b/doc/Notes.htm
@@ -0,0 +1,71 @@
+
+
+
+
+
+Notes
+Pass -norc on the command line to not load ~/.eclrc on startup. Since :eql and :eql5 are in *features*, you can use e.g. #+eql / #-eql5.
+To run a Lisp file directly, do e.g. eql5
+ examples/5-colliding-mice -qtpl.
+See the EQL UI (command eql -qgui) for a complete list of all
+ supported classes and functions.
+In the above mentioned UI you find a "Select " button, allowing you
+ to select any Qt widget (even in other main widgets), if previously loaded
+ from the UI command line. After selecting a widget, the
+ parameter qsel:*q* will be set to it.
+ See command line option -qtpl for a top-level processing Qt
+ events (see also readline note in ../README.txt). It uses a simple GUI dialog for
+ debug input (needed because read runs in its own thread). On
+ eventual print output, you won't see a fresh prompt, but the REPL will
+ remain ready for input. You can set this option permanently by adding this in ~./eclrc:
+ #+eql (setf eql:*qtpl* t)
+
+If you want to use temporary Qt objects, you can use the qlet
+ convenience macro (see the function list). It's a let* variant
+ for Qt objects, deleting them when leaving its body.
+No universal GC (garbage collection) for Qt objects:
+
+Qt widgets always live inside an object hierarchy, so deleting a widget
+ will delete all its child widgets/objects.
+ For local widgets/objects, you have the qlet macro, which are
+ deleted when leaving the qlet body.
+
+
+So, always use qlet (instead of qnew) if you only
+ need a local Qt object inside a function (e.g. QDialog, QRegExp).
+ GC is implemented (using the ECL finalizer) for Qt value types (like QFont) returned by the functions
+ qget and qfun. These types are printed adding GC : #<QFont 0x9243840 GC>.
+
+
+Enumeration example: |Qt.AlignCenter|. So, all enumerations
+ are defined as constants, using case preserving symbol names (allowing
+ convenient tab completion in Emacs).
+
+Errors in EQL functions don't break into the debugger; if you want them to
+ do so, set the variable eql:*break-on-errors*
+ to T.
+ (So the choice is left to you: depending on the situation, either option
+may be more convenient than the other.)
+
+
+The currently available Qt5 Modules (see qrequire) are:
+:network :opengl :sql
+
+If you want to use CLOS together with qt-object instances
+ (which are of type struct), see
+ examples X-extras/CLOS-encapsulation.lisp
+ and 5-colliding-mice.lisp. So there's a simple way to
+ use either defclass or defstruct to
+ encapsulate a qt-object.
+
+If you're interested in embedding EQL in existing Qt/C++ projects,
+ see example in directory Qt_EQL_dynamic/ (which can be used
+ together with Slime).
+
+See also plugin example in directory Qt_EQL_plugin/.
+
+
+The necessary parsing for generating the src/gen/* files is
+ done by parsing the Qt documentation. See helper/README.txt if you want do it yourself
+
+
diff --git a/doc/QtDesigner.htm b/doc/QtDesigner.htm
new file mode 100644
index 0000000..6fdf1e8
--- /dev/null
+++ b/doc/QtDesigner.htm
@@ -0,0 +1,23 @@
+
+
+
+
+Qt Designer
+
+In Qt Designer, set a unique objectName to every object you want to use from Lisp.
+ In Lisp, load the *.ui file using qload-ui (which will return the main widget of the UI).
+ To get the single widgets from the UI, use qfind-child.
+
+For an example, see examples/3-main-window.lisp.
+
+
+If you want to translate your UI files to the corresponding EQL code, do the following
+at the command line:
+ eql -quic file.ui
+ which will generate a file named ui-file.lisp. See also function quic.
+
+
+For a quick test of the generated file, try this:
+ eql ui-file.lisp
+
+
diff --git a/doc/QtLinguist.htm b/doc/QtLinguist.htm
new file mode 100644
index 0000000..cf415fb
--- /dev/null
+++ b/doc/QtLinguist.htm
@@ -0,0 +1,21 @@
+
+
+
+
+Qt Linguist
+For every new project:
+
+In Lisp, wrap the strings you want to translate in the tr macro (as you would do in Qt), optionally passing a context and/or a plural indicator (see Qt Assistant). Both string and context can be Lisp forms evaluating to constant strings.
+ Adapt the my_app/eql-lupdate file, adding your Qt Designer *.ui files (if any), and listing the respective *.ts files for all languages you want to support.
+ Adapt the my_app/eql-lrelease file, simply listing all *.ts files (see above).
+
+For every new release (in order to create the *.qm files):
+
+In my_app/, run eql make.lisp (compiling all files). This will find all source strings to translate and save them in the file tr.h (only a dummy needed for the Qt lupdate function). This is done using a compiler macro, see my_app/tr.lisp.
+ Run the my_app/eql-lupdate script; this will create/update the single *.ts files for every language.
+ Use Qt Linguist on the *.ts files (as usual).
+ Run the my_app/eql-lrelease script.
+
+Note: you may need to copy the respective qt_*.qm files (see translations/ in the Qt sources), in order to load the translated texts used by Qt itself.
+See my_app/main.cpp for an example how to load your translation files.
+
diff --git a/doc/Slime-REPL-hook.htm b/doc/Slime-REPL-hook.htm
new file mode 100644
index 0000000..cd5c5d0
--- /dev/null
+++ b/doc/Slime-REPL-hook.htm
@@ -0,0 +1,102 @@
+
+
+
+
+Slime REPL Hook
+
+
Please note:
+
+You need to enable this mode manually by uncommenting this line in eql-start-swank.lisp in your Slime directory:
+ (setf eql:*slime-mode* :repl-hook)
+
+Requires ECL threads .
+
+This should work with any Slime version that plays together with ECL.
+ Tested with ECL 12.7.1 (Windows: ECL 12.12.1)
+
+
+Prepare
+
+Add to your ~/.emacs file:
+
+(add-to-list 'load-path "~/slime/") ; slime path
+(add-to-list 'load-path "~/slime/contrib/") ; slime/contrib path
+(require 'slime)
+(slime-require 'swank-listener-hooks) ; EQL requires a listener hook
+(slime-setup '(slime-fancy))
+
+ Add to your ~/.swank.lisp file (or copy file eql/slime/.swank.lisp in your home directory):
+ (Please note: this isn't really optional -- you need to set this option for a useful Slime + EQL.)
+
+(setf swank:*globally-redirect-io* t) ; show print output in Emacs
+
+ Copy file eql/slime/eql-start-swank.lisp in your slime/ directory
+
+
+Run
+
+Run the swank server (the command line option -slime can be omitted if the file name contains "start-swank"), optionally passing a Lisp file:
+
+eql <path-to-slime>/eql-start-swank.lisp [file.lisp]
+
+ Run Emacs and do:
+Meta-X slime-connect (please note:
+use slime-connect) and hit Return 2 times
+(confirming the default values).
+Please note: if :dont-close is set to T
+ in eql-start-swank.lisp, quitting/restarting Emacs will not
+ affect a running EQL program, that is: if you quit/restart Emacs, you can
+ connect to the same swank/EQL you left when quitting Emacs.
+
+
+Notes
+Eval Region
+
+Load your Lisp file from the Slime REPL : (load "file.lisp")
+Run your program from the Slime REPL (not using Eval Region).
+Only at this point you may use Eval Region for re-defining functions etc.
+
+The point here is: if you directly try to Eval Region an expression containing an
+ EQL function, your swank server will crash , because it will not be
+ evaluated in the GUI thread (Qt GUI methods need to be called from the GUI thread).
+
+So, only run EQL functions directly from the Slime REPL .
+ If you want to use Eval Region containing EQL functions, use the
+method described above.
+
+
+You may use the macro qeval if you want to ensure evaluation
+ in the GUI thread (this is meant to be used together with Eval Region only).
+ It behaves like a progn, so you can do something like this:
+
+(qeval
+ (defvar *label* (qnew "QLabel"))
+ (defvar *edit* (qnew "QLineEdit")))
+
+Wrapping forms in qeval will have no effect if you
+run your code outside of Slime (so there's no need to
+remove qeval in your final program).
+
+But note: the advantage using Eval Region
+ (without qeval) is that Lisp error conditions (not
+ driven by Qt events) will not stop/pause your EQL program (that is, Qt event
+ processing will continue).
+Instead, if there is an error in code you either enter in the Slime REPL, or
+ run with Eval Region wrapped in qeval, the
+program will always pause (Qt event processing will be stopped until you take some
+ action).
+
+Abort / Restart
+Be careful after entering the Slime debugger. If you see this:
+
+[ABORT] Return to SLIME's top level.
+[RESTART-QT-EVENTS] Last resort only - prefer "Return to SLIME's top level"
+
+ Always choose the first one, otherwise you'll be stuck.
+
+
+Help
+For help see the qapropos and qgui functions.
+
+
+
diff --git a/doc/Slime.htm b/doc/Slime.htm
new file mode 100644
index 0000000..5e1ec85
--- /dev/null
+++ b/doc/Slime.htm
@@ -0,0 +1,57 @@
+
+
+
+
+Slime
+Requires ECL threads .
+
+This should work with any Slime version that plays together with ECL.
+ Tested with ECL 12.7.1 (Windows: ECL 12.12.1)
+
+
+Prepare
+
+
+Run
+
+Run the swank server (the command line option -slime can be omitted if the file name contains "start-swank"), optionally passing a Lisp file:
+
+eql <path-to-slime>/eql-start-swank.lisp [file.lisp]
+
+ Run Emacs and do:
+Meta-X slime-connect (please note:
+use slime-connect) and hit Return 2 times
+(confirming the default values).
+Please note: if :dont-close is set to T
+ in eql-start-swank.lisp, quitting/restarting Emacs will not
+ affect a running EQL program, that is: if you quit/restart Emacs, you can
+ connect to the same swank/EQL you left when quitting Emacs.
+
+
+Loading files
+If you experience slow loading of files (compared to direct loading), use qload instead of load, which will reduce all thread switches during the load process to a single one.
+Another case where you need to use qload is when you use Qt classes which use threads internally (see e.g. examples/X-extras/move-blocks.lisp).
+
+Help
+For help see the qapropos and qgui functions.
+To kill the swank process (Slime), use function qquit / qq (since quitting Emacs will not kill it).
+
+Notes
+All EQL functions are wrapped in qrun* (see eql/slime/thread-safe.lisp), so it's safe to call them either directly from the REPL or using 'eval region' (or from any other ECL thread).
+This Slime mode is both convenient and simple to use, but conses a little more for every EQL function call.
+ If you absolutely want direct EQL function calls, please see the less convenient Slime REPL Hook mode.
+
+
diff --git a/doc/auto-doc.htm b/doc/auto-doc.htm
new file mode 100644
index 0000000..8bb2778
--- /dev/null
+++ b/doc/auto-doc.htm
@@ -0,0 +1,529 @@
+
+DEFINE-QT-WRAPPERS (qt-library &rest what)
+
Defines Lisp methods for all Qt methods/signals/slots of given library. (See example Qt_EQL_dynamic/trafficlight/).
+
+ (define-qt-wrappers *c++*) ; generate wrappers (see "Qt_EQL_dynamic/")
+ (define-qt-wrappers *c++* :slots) ; Qt slots only (any of :methods :slots :signals)
+
+ (my-qt-function *c++* x y) ; instead of: (! "myQtFunction" (:qt *c++*) x y)
+
+
+
+DEFVAR-UI (main-widget &rest variables)
+
This macro simplifies the definition of UI variables:
+
+ (defvar-ui *main* *label* *line-edit*...)
+
+ ;; the above will expand to:
+
+ (progn
+ (defvar *label* (qfind-child *main* "label"))
+ (defvar *line-edit* (qfind-child *main* "line_edit"))
+ ...)
+
+
+
+ENSURE-QT-OBJECT (object)
+
Returns the qt-object of the given class/struct (see method the-qt-object in example X-extras/CLOS-encapsulation.lisp). This function is used internally whenever a qt-object argument is expected.
+
+
+QADD-EVENT-FILTER (object event function)
+
Convenience function. Adds a Lisp function to be called on a given event type. If the object argument is NIL, the event will be captured for the whole application. If the Lisp function returns NIL, the event will be processed by Qt afterwards. Returns a handle which can be used to remove the filter, see qremove-event-filter. See also qoverride for QObject::eventFilter(QObject*,QEvent*) and QObject::installEventFilter(QObject*),QObject::removeEventFilter(QObject*). The event class corresponds to the respective event type (no cast needed).
+
+ (qadd-event-filter nil |QEvent.MouseButtonPress| (lambda (object mouse-event) (print object) nil))
+
+
+
+QAPP ()
+
Convenience function returning qApp.
+
+
+QAPROPOS (&optional search-string class-name)
+
Finds all occurrencies of the given search string in the given object's meta information. Constructors are listed under "Methods". To list the user defined functions of external C++ classes (see Qt_EQL), pass the object instead of the class name.
+
+ (qapropos "html" "QTextEdit")
+ (qapropos nil "QWidget")
+ (qapropos)
+ (qapropos '|toString|) ; wrapper function symbol
+ (qapropos nil *qt-main*) ; see Qt_EQL, Qt_EQL_dynamic (custom Qt classes, Qt3Support classes)
+
+
+
+QAPROPOS* (&optional search-string class-name)
+
Similar to qapropos, returning the results as nested list.
+
+
+QAUTO-RELOAD-C++ (variable library-name)
+
Linux only. Extends qload-c++ (see Qt_EQL_dynamic/). Defines a global variable (see return value of qload-c++), which will be updated on every change of the C++ plugin (e.g. after recompiling, the plugin will automatically be reloaded, and the variable will be set to its new value). If you want to be notified on every change of the plugin, set *<variable>-reloaded*. It will then be called after reloading, passing both the variable name and the plugin name. See qload-c++ for an example how to call plugin functions.
+
+ (qauto-reload-c++ *c++* "eql_cpp")
+
+ (setf *c++-reloaded* (lambda (var lib) (qapropos nil (symbol-value var)))) ; optional: set a notifier
+
+
+
+QCALL-DEFAULT ()
+
To use anywhere inside an overridden function (see qoverride). Calls the base implementation of the virtual Qt method after leaving the function body. Optionally call the base implementation directly (if you want to do post-processing of the return value).
+
+
+QCLEAR-EVENT-FILTERS ()
+
Clears all added event filters.
+
+
+QCONNECT (caller signal receiver/function &optional slot)
+
Connects either a Qt signal to a Qt slot, or a Qt signal to a Lisp function.
+
+ (qconnect edit "textChanged(QString)" label "setText(QString)")
+ (qconnect edit "textChanged(QString)" (lambda (txt) (print txt)))
+
+
+
+QCOPY (object)
+
Copies object using copy-on-write, if such a constructor is available (non QObject derived classes only). This function is short for e.g: (qnew "QPixmap(QPixmap)" pixmap) Note that the returned value will not be garbage collected (analogous to qnew).
+
+ (qcopy pixmap) ; QPen, QBrush, QFont, QPalette, QPixmap, QImage...
+
+
+
+QDELETE (object &optional later)
+
+QDEL
+
Deletes any Qt object, and sets the pointer value to 0. Deleting a widget deletes all its child widgets, too. If later is not NIL, the function QObject::deleteLater() will be called instead (but note: the object pointer will be set to 0 immediately.) Returns T if the object has effectively been deleted. See also qlet for local Qt objects.
+
+ (qdel widget)
+ (qdel socket :later)
+
+
+
+QDISCONNECT (caller &optional signal receiver/function slot)
+
Disconnects signals to either Qt slots or Lisp functions. Anything but the caller can be either NIL or omitted. Returns T if something has effectively been disconnected.
+
+ (qdisconnect edit "textChanged(QString)" label "setText(QString)")
+ (qdisconnect edit "textChanged(QString)")
+ (qdisconnect edit nil label)
+ (qdisconnect edit)
+
+
+
+QENUMS (class-name &optional enum-name)
+
Returns the meta enum list of the given class-name and enum-name (see Q_ENUMS in Qt sources). Omitting enum-name will return all meta enum lists of the class/scope.
+
+ (qenums "QLineEdit" "EchoMode") ; gives '("QLineEdit" ("EchoMode" ("Normal" . 0) ...))
+ (qenums "Qt")
+
+
+
+QEQL (object1 object2)
+
Returns T for same instances of a Qt class. To test for same Qt classes only, do:
+
+ (= (qt-object-id object1) (qt-object-id object2))
+
+
+
+QESCAPE (string)
+
Calls QString::toHtmlEscaped().
+
+
+QEVAL (&rest forms)
+
Slime mode :repl-hook only (not needed in default Slime mode): evaluate forms in GUI thread. Defaults to a simple progn outside of Slime.
+
+
+QEXEC (&optional milliseconds)
+
Convenience function to call QApplication::exec(). Optionally pass the time in milliseconds after which QEventLoop::exit() will be called. See also qsleep.
+
+
+QEXIT ()
+
Calls QEventLoop::exit(), in order to exit event processing after a call to qexec with a timeout. Returns T if the event loop has effectively been exited.
+
+
+QFIND-BOUND (&optional class-name)
+
Finds all symbols bound to Qt objects, returning both the Qt class names and the respective Lisp variables. Optionally finds the occurrencies of the passed Qt class name only.
+
+ (qfind-bound "QLineEdit")
+
+
+
+QFIND-BOUND* (&optional class-name)
+
Like qfind-bound, but returning the results as list of conses.
+
+
+QFIND-CHILD (object object-name)
+
Calls QObject::findChild<QObject*>(). Can be used to get the child objects of any Qt object (typically from a UI, see qload-ui), identified by QObject::objectName().
+
+ (qfind-child *main* "editor")
+
+
+
+QFIND-CHILDREN (object &optional object-name class-name)
+
Calls QObject::findChildren<QObject*>(), returning a list of all child objects matching object-name and class-name. Omitting the &optional arguments will find all children, recursively.
+
+ (qfind-children *qt-main* nil "LightWidget") ; see Qt_EQL example
+
+
+
+QFROM-UTF8 (byte-array)
+
Returns the byte array (vector of octets) converted using QString::fromUtf8().
+
+
+QGUI (&optional process-events)
+
Launches the EQL convenience GUI. If you don't have an interactive environment, you can pass T to run a pseudo Qt event loop. A better option is to start the tool like so:eql -qgui, in order to run the Qt event loop natively.
+
+
+QID (name)
+
Returns the internally used ID of the object name. Non QObject classes have negative ids.
+
+ (qid "QWidget")
+
+
+
+QINVOKE-METHOD (object function-name &rest arguments)
+
+QFUN
+
Calls any of Qt methods, slots, signals. Static methods can be called by passing the string name of an object. The most convenient way of calling Qt methods is to use the wrapper functions (see alternative 2 below), which allows for tab completion, showing all possible candidates in case of ambiguous type lists (overloaded methods). Additionally, static functions are shown as one symbol (easily catching the eye). (Optionally you can pass the argument types (as for qconnect and qoverride), which may result in better performance, but only in some edge cases.)
+
+ (qfun item "setText" 0 "Some objects are EQL.")
+ (qfun "QDateTime" "currentDateTime") ; static method
+ (qfun slider "valueChanged" 10) ; emit signal
+
+ ;; alternative 1: (macro '!')
+
+ (! "setText" item 0 "Some objects are EQL.")
+ (! "currentDateTime" "QDateTime")
+ (! "valueChanged" slider 10)
+
+ ;; alternative 2: (wrapper functions)
+
+ (|setText| item 0 "Some objects are EQL.")
+ (|currentDateTime.QDateTime|)
+ (|valueChanged| slider 10)
+
+
+
+QINVOKE-METHOD* (object cast-class-name function-name &rest arguments)
+
+QFUN*
+
Similar to qinvoke-method, additionally passing a class name, enforcing a cast to that class. Note that this cast is not type safe (the same as a C cast, so dirty hacks are possible). Note: using the (recommended) wrapper functions (see qfun), casts are applied automatically where needed.
+
+ (qfun* graphics-text-item "QGraphicsItem" "setPos" (list x y)) ; multiple inheritance problem
+ (qfun* event "QKeyEvent" "key") ; not needed with QADD-EVENT-FILTER
+
+ ;; alternatively:
+
+ (! "setPos" ("QGraphicsItem" graphics-text-item) (list x y))
+ (! "key" ("QKeyEvent" event))
+
+ ;; better/recommended:
+
+ (|setPos| graphics-text-item (list x y))
+
+
+
+QINVOKE-METHOD+ (object function-name &rest arguments)
+
+QFUN+
+
Use this variant to call user defined functions (declared Q_INVOKABLE), slots, signals from external C++ classes. In order to call ordinary functions, slots, signals from external C++ classes, just use the ordinary qfun.
+
+ (qfun+ *qt-main* "foo") ; see Qt_EQL, Qt_EQL_dynamic
+
+ ;; alternatively:
+
+ (! "foo" (:qt *qt-main*))
+
+
+
+QINVOKE-METHODS (object &rest functions)
+
+QFUNS
+
A simple syntax for nested qfun calls.
+
+ (qfuns object "funA" "funB" "funC") ; expands to: (qfun (qfun (qfun object "funA") "funB") "funC")
+ (qfuns object ("funA" 1) ("funB" a b c)) ; expands to: (qfun (qfun object "funA" 1) "funB" a b c)
+ (qfuns "QApplication" "font" "family")
+ (qfuns *table-view* "model" ("index" 0 2) "data" "toString")
+
+ ;; alternatively:
+
+ (! ("funC" "funB" "funA" object))
+ (! (("funB" a b c) ("funA" 1) object))
+ (! ("family" "font" "QApplication"))
+ (! ("toString" "data" ("index" 0 2) "model" *table-view*))
+
+ ;; using wrapper functions, the above reads:
+
+ (|funC| (|funB| (|funA| object)))
+ (|funB| (|funA| object 1) a b c)
+ (|family| (|font.QApplication|))
+ (|toString| (|data| (|index| (|model| *table-view*) 0 2)))
+
+
+
+QLATER (function)
+
Convenience macro: a qsingle-shot with a 0 timeout. This will call function as soon as the Qt event loop is idle.
+
+ (qlater 'delayed-ini)
+
+
+
+QLET (((variable-1 expression-1) (variable-2 expression-2)) &body body)
+
Similar to let* (and to local C++ variables). Creates temporary Qt objects, deleting them at the end of the qlet body. If expression is a string, it will be substituted with (qnew expression), optionally including constructor arguments.
+
+ (qlet ((painter "QPainter"))
+ ...)
+
+ (qlet ((reg-exp "QRegExp(QString)" "^\\S+$"))
+ ...)
+
+
+
+QLOAD (file-name)
+
Convenience function for Slime (or when loading EQL files from an ECL thread). Loading files that create many Qt objects can be slow on the Slime REPL (many thread switches). This function reduces all thread switches (GUI related) to a single one.
+
+
+QLOAD-C++
(library-name &optional unload)
+
Loads a custom Qt/C++ plugin (see Qt_EQL_dynamic/). The library-name has to be passed as path to the plugin, without file ending. This offers a simple way to extend your application with your own Qt/C++ functions. The plugin will be reloaded (if supported by the OS) every time you call this function (Linux: see also qauto-reload-c++). If the unload argument is not NIL, the plugin will be unloaded (if supported by the OS).
+
+ (defparameter *c++* (qload-c++ "eql_cpp")) ; load (Linux: see also QAUTO-RELOAD-C++)
+
+ (qapropos nil *c++*) ; documentation
+
+ (! "mySpeedyQtFunction" (:qt *c++*)) ; call library function (note :qt)
+
+
+
+QLOAD-UI (file-name)
+
Calls a custom QUiLoader::load() function, loading a UI file created by Qt Designer. Returns the top level widget of the UI. Use qfind-child to retrieve the child widgets.
+
+ (qload-ui "my-fancy-gui.ui")
+
+
+
+QLOCAL8BIT (string)
+
Converts a Unicode pathname to a simple ECL base string, using QString::toLocal8Bit() (see QLocale settings). Depending on the OS (namely Windows), this is necessary if you get a filename from Qt and want to use it in ECL. See also QUTF8 .
+
+
+QMESSAGE-BOX (x)
+
+QMSG
+
Convenience function: a simple message box, converting x to a string if necessary. Returns its argument (just like print).
+
+
+QNEW-INSTANCE (class-name &rest arguments/properties)
+
+QNEW
+
Creates a new Qt object, optionally passing the given arguments to the constructor. Additionally you can pass any number of property/value pairs. Please note how you can abbreviate long type lists.
+
+ (qnew "QWidget")
+ (qnew "QPixmap(int,int)" 50 50) ; constructor
+ (qnew "QLabel" "text" "Readme") ; set property
+ (qnew "QMatrix4x4(qreal...)" 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4)
+
+
+
+QNEW-INSTANCE* (class-name &rest arguments/properties)
+
+QNEW*
+
Convenience function for the REPL. Same as qnew, but showing the object immediately (if of type QWidget).
+
+
+QNULL-OBJECT (object)
+
+QNULL
+
Checks for a 0 Qt object pointer.
+
+
+QOBJECT-NAMES (&optional type)
+
Returns all supported object names. Passing either :q or :n returns only the QObject inherited, or not QObject inherited names, respectively.
+
+
+QOK ()
+
Needed to get the boolean ok value in cases like this:
+
+ (! "getFont(bool*)" "QFontDialog" nil)
+
+ (|getFont.QFontDialog| nil) ; NIL needed for <bool*>
+
+
+
+QOVERRIDE (object name function)
+
Sets a Lisp function to be called on a virtual Qt method. To remove a function, pass NIL instead of the function argument. If you call qcall-default anywhere inside your overridden function, the base implementation will be called afterwards . Instead of qcall-default you can directly call the base implementation, which is useful if you want to do post-processing of the returned value.
+
+ (qoverride edit "keyPressEvent(QKeyEvent*)" (lambda (ev) (print (|key| ev)) (qcall-default)))
+
+
+
+QPROCESS-EVENTS ()
+
Convenience function to call QApplication::processEvents().
+
+
+QPROPERTIES (object &optional (depth 1))
+
Prints all current properties of object, searching both all Qt properties and all Qt methods which don't require arguments (marked with '* '). Optionally pass a depth indicating how many super-classes to include. Pass T to include all super-classes.
+
+ (qproperties (|font.QApplication|))
+ (qproperties (qnew "QVariant(QString)" "42"))
+ (qproperties *tool-button* 2) ; depth 2: both QToolButton and QAbstractButton
+
+
+
+QPROPERTY (object name)
+
+QGET
+
Gets a Qt property. Enumerator values are returned as int values. Returns T as second return value for successful calls.
+
+ (qget label "text")
+
+
+
+QQUIT (&optional (exit-status 0) (kill-all-threads t))
+
+QQ
+
Terminates EQL. Use this function to quit gracefully, not ext:quit.
+
+
+QREMOVE-EVENT-FILTER (handle)
+
Removes the event filter corresponding to handle, which is the return value of qadd-event-filter. Returns handle if the event filter has effectively been removed. See also qclear-event-filters.
+
+
+QREQUIRE
(module &optional quiet)
+
Loads an EQL module, corresponding to a Qt module. Returns the module name if both loading and initializing have been successful. If the quiet argument is not NIL, no error message will be shown on failure. Currently available modules: :network :opengl :sql
+
+ (qrequire :network)
+
+
+
+QRGB (red green blue &optional (alpha 255))
+
Constructs a (unsigned-byte 32) value that represents a 32 bit pixel color specified by the red, green, blue and alpha values.
+
+
+QRUN-IN-GUI-THREAD (function &optional (blocking t))
+
+QRUN
+
Runs function in GUI thread while (by default) blocking the calling thread (if called from main thread, function will simply be called directly). This is needed to run GUI code from ECL threads other than the main thread. Returns T on success. There are 2 reasons to always wrap any EQL function like this, if called from another ECL thread:
Qt GUI methods always need to run in the GUI thread EQL functions are not designed to be reentrant (not needed for GUI code) See also macro qrun*.
+
+ (qrun 'update-view-data)
+
+
+
+QRUN-IN-GUI-THREAD* (&body body)
+
+QRUN*
+
Convenience macro for qrun, wrapping body in a closure (passing arguments, return values).
+
+ (qrun* (|setValue| ui:*progress-bar* value))
+
+ (let ((item (qrun* (qnew "QTableWidgetItem")))) ; return value(s)
+ ...)
+
+
+
+QSELECT (&optional on-selected)
+
+QSEL
+
Allows to select (by clicking) any (child) widget. The variable qsel:*q* is set to the latest selected widget. Optionally pass a function to be called upon selecting, with the selected widget as argument.
+
+ (qsel (lambda (widget) (qmsg widget)))
+
+
+
+QSENDER ()
+
Corresponding to QObject::sender(). To use inside a Lisp function connected to a Qt signal.
+
+
+QSET-COLOR (widget color-role color)
+
Convenience function for simple color settings (avoiding QPalette boilerplate). Use QPalette directly for anything more involved.
+
+ (qset-color widget |QPalette.Window| "white")
+
+
+
+QSET-NULL (object)
+
Sets the Qt object pointer to 0. This function is called automatically after qdel.
+
+
+QSET-PROPERTY (object name value)
+
+QSET
+
Sets a Qt property. Enumerators have to be passed as int values. Returns T as second return value for successful calls.
+
+ (qset label "alignment" |Qt.AlignCenter|)
+
+
+
+QSIGNAL (name)
+
Needed in functions which expect a const char* Qt signal (not needed in qconnect).
+
+
+QSINGLE-SHOT (milliseconds function)
+
A single shot timer similar to QTimer::singleShot().
+
+ (qsingle-shot 1000 'one-second-later)
+
+ (let ((ms 500))
+ (qsingle-shot ms (lambda () (qmsg ms))))
+
+
+
+QSLEEP (seconds)
+
Similar to sleep, but continuing to process Qt events.
+
+
+QSLOT (name)
+
Needed in functions which expect a const char* Qt slot (not needed in qconnect).
+
+
+QSTATIC-META-OBJECT (class-name)
+
Returns the ::staticMetaObject of the given class name.
+
+ (qstatic-meta-object "QEasingCurve")
+
+
+
+QSUPER-CLASS-NAME (name)
+
Returns the super class of an object name, or NIL if the class doesn't inherit another Qt class. Returns T as second return value for successful calls.
+
+ (qsuper-class-name "QGraphicsLineItem")
+
+
+
+QT-OBJECT-?
(object)
+
Returns the specific qt-object of a generic qt-object. Works for QObject and QEvent inherited classes only.
+
+ (qt-object-? (|parentWidget| widget))
+ (qt-object-? (|widget| (|itemAt| box-layout 0)))
+ (qt-object-? event)
+
+
+
+QT-OBJECT-NAME (object)
+
Returns the Qt class name.
+
+
+QUI-CLASS (file-name &optional object-name)
+
Finds the class name for the given user-defined object name in the given UI file. Omitting the object name will return the top level class name of the UI.
+
+ (qui-class "examples/data/main-window.ui" "editor") ; returns "QTextEdit"
+
+
+
+QUI-NAMES (file-name)
+
Finds all user-defined object names in the given UI file.
+
+ (qui-names "examples/data/main-window.ui")
+
+
+
+QUIC (&optional (file.h "ui.h") (file.lisp "ui.lisp") (ui-package :ui))
+
Takes C++ code from a file generated by the uic user interface compiler, and generates the corresponding EQL code. See also command line option -quic.
+
+
+QUTF8 (string)
+
Converts a Unicode pathname to a simple ECL base string, using QString::toUtf8(). Depending on the OS (namely OSX, Linux), this is necessary if you get a filename from Qt and want to use it in ECL. See also QLOCAL8BIT .
+
+
+QVERSION ()
+
Returns the EQL version number as "<year>.<month>.<counter>", analogous to the ECL version number. The second return value is the Qt version as returned by qVersion().
+
+
+TR (source &optional context plural-number)
+
Macro expanding to qtranslate, which calls QCoreApplication::translate(). Both source and context can be Lisp forms evaluating to constant strings (at compile time). The context argument defaults to the Lisp file name. For the plural-number, see Qt Assistant.
+
+
\ No newline at end of file
diff --git a/doc/auto-doc.lisp b/doc/auto-doc.lisp
new file mode 100644
index 0000000..2f16c0f
--- /dev/null
+++ b/doc/auto-doc.lisp
@@ -0,0 +1,78 @@
+;;; copyright (c) 2010-2013 Polos Ruetz
+
+(in-package :eql-user)
+
+(defparameter *help* nil)
+
+(defun add-cpp-docu ()
+ (with-open-file (s (eql:in-home "src/ecl_fun.cpp") :direction :input)
+ (let (curr ex)
+ (flet ((add-curr ()
+ (when curr
+ (push (reverse curr) *help*)
+ (setf curr nil)))
+ (trim (str)
+ (string-trim '(#\/ #\Space) str)))
+ (x:while-it (read-line s nil nil)
+ (let ((line (string-trim " " x:it)))
+ (when (x:starts-with "///" line)
+ (when (x:starts-with "cl_object " ex)
+ (add-curr)
+ (let* ((pos (search "///" ex :start2 3)) ; exception: Lisp name at end of line
+ (fun (if pos
+ (trim (subseq ex (+ 3 pos)))
+ (trim (subseq ex 10)))))
+ (push (if pos
+ fun
+ (substitute #\- #\_ (string-trim "2" (subseq fun 0 (position #\( fun)))))
+ curr)))
+ (push (trim line) curr))
+ (setf ex line)))
+ (add-curr)))))
+
+(defun add-lisp-docu ()
+ (do-external-symbols (sym (find-package :eql))
+ (let ((name (symbol-name sym)))
+ (when (or (char= #\Q (char name 0))
+ (find name '("ENSURE-QT-OBJECT" "DEFINE-QT-WRAPPERS" "DEFVAR-UI" "TR") :test 'string=))
+ (x:when-it (documentation sym 'function)
+ (let ((fun (string-downcase (symbol-name sym)))
+ (docu (mapcar #'(lambda (s) (string-trim " " s)) (x:split x:it #\Newline))))
+ (unless (string= fun (subseq (second docu) 7))
+ (push (cons fun docu) *help*))))))))
+
+(defun help ()
+ (setf *help* nil)
+ (add-cpp-docu)
+ (add-lisp-docu)
+ (with-open-file (s (eql:in-home "doc/auto-doc.htm") :direction :output :if-exists :supersede)
+ (write-string "" s)
+ (flet ((el (tag x)
+ (format nil "<~A>~A~A>" tag x tag))
+ (! (x)
+ (format s "~A~%" x))
+ (tab ()
+ (write-string " " s)))
+ (setf *help* (sort *help* #'string< :key #'first))
+ (dolist (curr *help*)
+ (! "")
+ (! (el "b" (format nil "~A ~A" (string-upcase (first curr)) (subseq (second curr) 6))))
+ (let ((n 2))
+ (when (x:starts-with "alias:" (third curr))
+ (incf n)
+ (! " ")
+ (! (el "b" (string-upcase (subseq (third curr) 7)))))
+ (! (el "p" (nth n curr)))
+ (let ((examples (nthcdr (1+ n) curr)))
+ (when examples
+ (! "
")
+ (dolist (example examples)
+ (tab)
+ (! example))
+ (! " "))))
+ (! " "))
+ (write-string "" s))))
+
+(progn
+ (help)
+ (eql:qq))
diff --git a/doc/debug-dialog.png b/doc/debug-dialog.png
new file mode 100644
index 0000000000000000000000000000000000000000..267e65760bd01a76d2bf017195ae03a06b5cd253
GIT binary patch
literal 19599
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
+
+
+
+
+
+
+ Mailing List (Google Groups)
+
+