diff --git a/common.pri b/common.pri
index 28f63c91..1a23b61a 100644
--- a/common.pri
+++ b/common.pri
@@ -16,3 +16,4 @@ include(sparkle.pri)
include(harfbuzz.pri)
include(freetype.pri)
include(fontconfig.pri)
+include(scintilla.pri)
diff --git a/openscad.pro b/openscad.pro
index 62fdbdf3..50d7aca6 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -1,14 +1,14 @@
# Environment variables which can be set to specify library locations:
-# MPIRDIR
-# MPFRDIR
-# BOOSTDIR
-# CGALDIR
-# EIGENDIR
-# GLEWDIR
-# OPENCSGDIR
-# OPENSCAD_LIBRARIES
+# MPIRDIR
+# MPFRDIR
+# BOOSTDIR
+# CGALDIR
+# EIGENDIR
+# GLEWDIR
+# OPENCSGDIR
+# OPENSCAD_LIBRARIES
#
-# Please see the 'Building' sections of the OpenSCAD user manual
+# Please see the 'Building' sections of the OpenSCAD user manual
# for updated tips & workarounds.
#
# http://en.wikibooks.org/wiki/OpenSCAD_User_Manual
@@ -135,13 +135,13 @@ netbsd* {
}
# Prevent LD_LIBRARY_PATH problems when running the openscad binary
-# on systems where uni-build-dependencies.sh was used.
+# on systems where uni-build-dependencies.sh was used.
# Will not affect 'normal' builds.
!isEmpty(OPENSCAD_LIBDIR) {
unix:!macx {
QMAKE_LFLAGS = -Wl,-R$$OPENSCAD_LIBDIR/lib $$QMAKE_LFLAGS
# need /lib64 beause GLEW installs itself there on 64 bit machines
- QMAKE_LFLAGS = -Wl,-R$$OPENSCAD_LIBDIR/lib64 $$QMAKE_LFLAGS
+ QMAKE_LFLAGS = -Wl,-R$$OPENSCAD_LIBDIR/lib64 $$QMAKE_LFLAGS
}
}
@@ -179,8 +179,8 @@ CONFIG += harfbuzz
CONFIG += freetype
CONFIG += fontconfig
-#Uncomment the following line to enable QCodeEdit
-#CONFIG += qcodeedit
+#Uncomment the following line to enable the QScintilla editor
+CONFIG += scintilla
# Make experimental features available
experimental {
@@ -208,7 +208,7 @@ win* {
RESOURCES = openscad.qrc
-FORMS += src/MainWindow.ui \
+FORMS += src/MainWindow.ui \
src/Preferences.ui \
src/OpenCSGWarningDialog.ui \
src/AboutDialog.ui \
@@ -283,9 +283,9 @@ HEADERS += src/typedefs.h \
src/GeometryEvaluator.h \
src/CSGTermEvaluator.h \
src/Tree.h \
- src/DrawingCallback.h \
- src/FreetypeRenderer.h \
- src/FontCache.h \
+src/DrawingCallback.h \
+src/FreetypeRenderer.h \
+src/FontCache.h \
src/mathc99.h \
src/memory.h \
src/linalg.h \
@@ -305,7 +305,8 @@ HEADERS += src/typedefs.h \
src/system-gl.h \
src/CsgInfo.h \
\
- src/AutoUpdater.h
+ src/AutoUpdater.h \
+ src/legacyeditor.h
SOURCES += src/version_check.cc \
src/ProgressWidget.cc \
@@ -360,9 +361,9 @@ SOURCES += src/version_check.cc \
src/ModuleCache.cc \
src/GeometryCache.cc \
src/Tree.cc \
- src/DrawingCallback.cc \
- src/FreetypeRenderer.cc \
- src/FontCache.cc \
+src/DrawingCallback.cc \
+src/FreetypeRenderer.cc \
+src/FontCache.cc \
\
src/rendersettings.cc \
src/highlighter.cc \
@@ -391,7 +392,8 @@ SOURCES += src/version_check.cc \
\
src/openscad.cc \
src/mainwin.cc \
- src/FontListDialog.cc
+ src/FontListDialog.cc \
+ src/legacyeditor.cc
# ClipperLib
SOURCES += src/polyclipping/clipper.cpp
@@ -488,4 +490,3 @@ INSTALLS += man
CONFIG(winconsole) {
include(winconsole.pri)
}
-
diff --git a/openscad.pro.user b/openscad.pro.user
index 087d6e65..ef6a7d28 100644
--- a/openscad.pro.user
+++ b/openscad.pro.user
@@ -1,6 +1,6 @@
-
+
ProjectExplorer.Project.ActiveTarget
@@ -11,22 +11,24 @@
true
false
+ true
Cpp
- CppGlobal
+ CppGlobal
QmlJS
- QmlJSGlobal
+ QmlJSGlobal
2
- System
+ UTF-8
false
4
+ false
true
1
true
@@ -49,135 +51,34 @@
ProjectExplorer.Project.Target.0
- Desktop
- Desktop
- Qt4ProjectManager.Target.DesktopTarget
- 1
+ Qt 4.8.6 (qt4)
+ Qt 4.8.6 (qt4)
+ {90222843-28c9-4a66-ac82-99bd31ae7263}
+ 0
0
0
- INVALID
+
+ true
qmake
QtProjectManager.QMakeBuildStep
false
false
-
- false
-
-
- Make
-
- Qt4ProjectManager.MakeStep
- false
-
-
-
- 2
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- Make
-
- Qt4ProjectManager.MakeStep
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- OPENSCAD_LIBRARIES=$$PWD/../libraries/install
-
- MacPorts QT4 Release
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 0
- $$PWD/../openscad-build-desktop
- -1
- true
-
-
- ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb
-
-
- qmake
-
- QtProjectManager.QMakeBuildStep
- false
- false
- -spec macx-g++
- false
-
-
- Make
-
- Qt4ProjectManager.MakeStep
- false
- -j4
-
-
- 2
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- Make
-
- Qt4ProjectManager.MakeStep
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- OPENSCAD_LIBRARIES=$$PWD/../libraries/install
- CCACHE_BASEDIR=$$PWD/..
- PATH=/opt/local/libexec/ccache:/usr/bin:$QTDIR/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin
- EIGEN2DIR=$$PWD/../libraries/install/include/eigen2
-
- Desktop Qt 4.7.4 for GCC (Qt SDK) Debug
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 2
- $$PWD
- 3
- false
-
-
- INVALID
-
-
- qmake
-
- QtProjectManager.QMakeBuildStep
- false
- false
-
+ CONFIG+=experimental
false
+ true
Make
Qt4ProjectManager.MakeStep
+
+ -w
+ -r
+
false
@@ -189,9 +90,14 @@
+ true
Make
Qt4ProjectManager.MakeStep
+
+ -w
+ -r
+
true
clean
@@ -204,117 +110,13 @@
2
false
- 4.7.4 Debug
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 2
- $$PWD/../openscad-build-desktop
- -1
- true
-
-
- INVALID
-
-
- qmake
-
- QtProjectManager.QMakeBuildStep
- false
- false
-
- false
-
-
- Make
-
- Qt4ProjectManager.MakeStep
- false
-
-
-
- 2
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- Make
-
- Qt4ProjectManager.MakeStep
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- 4.7.4 Release
+ Release
Qt4ProjectManager.Qt4BuildConfiguration
0
- $$PWD/../openscad-build-desktop
- -1
true
-
- ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb
-
-
- qmake
- Clone of qmake
- QtProjectManager.QMakeBuildStep
- false
- false
- -spec macx-g++
- false
-
-
- Make
- Clone of Make
- Qt4ProjectManager.MakeStep
- false
-
-
-
- 2
- Build
- Clone of Build
- ProjectExplorer.BuildSteps.Build
-
-
-
- Make
- Clone of Make
- Qt4ProjectManager.MakeStep
- true
- clean
-
-
- 1
- Clean
- Clone of Clean
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- OPENSCAD_LIBRARIES=$$PWD/../libraries/install
-
- Desktop Qt 4.7.4 for GCC (Qt SDK) Debug
- Desktop Qt 4.7.4 for GCC (Qt SDK)
- Qt4ProjectManager.Qt4BuildConfiguration
- 0
- $$PWD/../openscad-release-desktop
- 3
- true
-
- 5
+ 1
0
@@ -323,39 +125,29 @@
ProjectExplorer.BuildSteps.Deploy
1
- No deployment
+ Deploy locally
ProjectExplorer.DefaultDeployConfiguration
1
+
- true
- true
-
false
- false
- false
false
false
- false
- false
false
true
- true
- 0.01
0.01
10
- 10
true
- true
- 25
+ 1
25
-
+ 1
+ true
+ false
true
- true
- valgrind
valgrind
0
@@ -374,37 +166,22 @@
13
14
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
+ 2
+
openscad
- Qt4ProjectManager.Qt4RunConfiguration
- 2
+ Qt4ProjectManager.Qt4RunConfiguration:/home/shaina/letsbegin/openscad/openscad.pro
openscad.pro
false
false
-
3768
true
+ false
+ false
false
- false
+ true
1
@@ -415,10 +192,10 @@
ProjectExplorer.Project.Updater.EnvironmentId
- {b7a15081-01e1-47e4-b2e5-20f6404deb62}
+ {56f57d1a-fe9b-42b2-a96b-3ac76cf7565f}
ProjectExplorer.Project.Updater.FileVersion
- 10
+ 15
diff --git a/qscintilla2.prf b/qscintilla2.prf
new file mode 100644
index 00000000..a3043f91
--- /dev/null
+++ b/qscintilla2.prf
@@ -0,0 +1,12 @@
+greaterThan(QT_MAJOR_VERSION, 4) {
+ QT += widgets printsupport
+
+ greaterThan(QT_MINOR_VERSION, 1) {
+ macx:QT += macextras
+ }
+}
+
+INCLUDEPATH += $$[QT_INSTALL_HEADERS]
+
+LIBS += -L$$[QT_INSTALL_LIBS]
+LIBS += -lqscintilla2
diff --git a/scintilla.pri b/scintilla.pri
new file mode 100644
index 00000000..aebb1262
--- /dev/null
+++ b/scintilla.pri
@@ -0,0 +1,11 @@
+scintilla {
+ HEADERS += src/scintillaeditor.h src/scadlexer.h
+ SOURCES += src/scintillaeditor.cpp src/scadlexer.cpp
+
+ DEFINES += USE_SCINTILLA_EDITOR
+
+ # The qscintilla2.prf which ships with QScintilla is broken for Mac/Windows
+ # debug builds, so we supply our own
+ win32|macx: include(qscintilla2.prf)
+ else: CONFIG += qscintilla2
+}
diff --git a/scripts/common-build-dependencies.sh b/scripts/common-build-dependencies.sh
index 3e60a775..87a2bed0 100644
--- a/scripts/common-build-dependencies.sh
+++ b/scripts/common-build-dependencies.sh
@@ -55,6 +55,7 @@ build_libxml2()
build_fontconfig()
{
version=$1
+ extra_config_flags="$2"
if [ -e $DEPLOYDIR/include/fontconfig ]; then
echo "fontconfig already installed. not building"
@@ -70,10 +71,10 @@ build_fontconfig()
tar xzf "fontconfig-$version.tar.gz"
cd "fontconfig-$version"
export PKG_CONFIG_PATH="$DEPLOYDIR/lib/pkgconfig"
- ./configure --prefix="$DEPLOYDIR" --enable-libxml2 --disable-docs
+ ./configure --prefix=/ --enable-libxml2 --disable-docs $extra_config_flags
unset PKG_CONFIG_PATH
- make -j$NUMCPU
- make install
+ DESTDIR="$DEPLOYDIR" make -j$NUMCPU
+ DESTDIR="$DEPLOYDIR" make install
}
build_libffi()
diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh
index 355239d0..575e76f5 100755
--- a/scripts/macosx-build-dependencies.sh
+++ b/scripts/macosx-build-dependencies.sh
@@ -133,6 +133,22 @@ build_qt5()
make -j"$NUMCPU" install
}
+build_qscintilla()
+{
+ version=$1
+ echo "Building QScintilla" $version "..."
+ cd $BASEDIR/src
+ rm -rf QScintilla-gpl-$version
+ if [ ! -f QScintilla-gpl-$version.tar.gz ]; then
+ curl -LO http://downloads.sourceforge.net/project/pyqt/QScintilla2/QScintilla-$version/QScintilla-gpl-$version.tar.gz
+ fi
+ tar xzf QScintilla-gpl-$version.tar.gz
+ cd QScintilla-gpl-$version/Qt4Qt5
+ qmake qscintilla.pro
+ make -j6 install
+ install_name_tool -id $DEPLOYDIR/lib/libqscintilla2.dylib $DEPLOYDIR/lib/libqscintilla2.dylib
+}
+
# Hack warning: gmplib is built separately in 32-bit and 64-bit mode
# and then merged afterwards. gmplib's header files are dependent on
# the CPU architecture on which configure was run and will be patched accordingly.
@@ -754,6 +770,7 @@ fi
echo "Using basedir:" $BASEDIR
mkdir -p $SRCDIR $DEPLOYDIR
build_qt5 5.3.1
+build_qscintilla 2.8.3
# NB! For eigen, also update the path in the function
build_eigen 3.2.1
build_gmp 5.1.3
diff --git a/scripts/mingw-x-build-dependencies.sh b/scripts/mingw-x-build-dependencies.sh
index 95f971d1..23519801 100755
--- a/scripts/mingw-x-build-dependencies.sh
+++ b/scripts/mingw-x-build-dependencies.sh
@@ -65,14 +65,14 @@ if [ "`echo $* | grep 64`" ]; then
if [ "`echo $* | grep download`" ]; then
PACKAGES='download-mpfr download-eigen download-opencsg download-cgal download-qtbase download-glib download-freetype download-fontconfig download-harfbuzz'
else
- PACKAGES='qtbase mpfr eigen opencsg cgal glib freetype fontconfig harfbuzz'
+ PACKAGES='qtbase qscintilla2 mpfr eigen opencsg cgal glib freetype fontconfig harfbuzz'
fi
else
MXE_TARGETS='i686-w64-mingw32.static'
if [ "`echo $* | grep download`" ]; then
PACKAGES='download-mpfr download-eigen download-opencsg download-cgal download-qtbase download-nsis download-glib download-freetype download-fontconfig download-harfbuzz'
else
- PACKAGES='qtbase mpfr eigen opencsg cgal nsis glib freetype fontconfig harfbuzz'
+ PACKAGES='qtbase qscintilla2 mpfr eigen opencsg cgal nsis glib freetype fontconfig harfbuzz'
fi
fi
echo make $PACKAGES MXE_TARGETS=$MXE_TARGETS -j $NUMCPU JOBS=$NUMJOBS
diff --git a/scripts/openscad-linux b/scripts/openscad-linux
index 1246199c..3ca48611 100755
--- a/scripts/openscad-linux
+++ b/scripts/openscad-linux
@@ -4,5 +4,6 @@ cd "$( dirname "$( type -p $0 )" )"
libdir=$PWD/../lib/openscad/
cd "$OLDPWD"
+export LIBGL_DRIVERS_PATH="$libdir"/dri
export LD_LIBRARY_PATH="$libdir${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
exec $libdir/openscad "$@"
diff --git a/scripts/release-common.sh b/scripts/release-common.sh
index 337dab9b..80402ef2 100755
--- a/scripts/release-common.sh
+++ b/scripts/release-common.sh
@@ -455,12 +455,26 @@ case $OS in
gcc -o chrpath_linux -DSIZEOF_VOID_P=4 scripts/chrpath_linux.c
fi
./chrpath_linux -d openscad-$VERSION/lib/openscad/openscad
- ldd openscad | sed -re 's,.* => ,,; s,[\t ].*,,;' -e '/Qt|boost/ { p; d; };' \
- -e '/lib(icu.*|stdc.*|audio|CGAL|GLEW|opencsg|png|gmp|gmpxx|mpfr)\.so/ { p; d; };' \
- -e 'd;' | xargs cp -vt openscad-$VERSION/lib/openscad/
+
+ QTLIBDIR=$(dirname $(ldd openscad | grep Qt5Gui | head -n 1 | awk '{print $3;}'))
+ ( ldd openscad ; ldd "$QTLIBDIR"/qt5/plugins/platforms/libqxcb.so ) \
+ | sed -re 's,.* => ,,; s,[\t ].*,,;' -e '/^$/d' -e '/libc\.so|libm\.so|libdl\.so|libgcc_|libpthread\.so/d' \
+ | sort -u \
+ | xargs cp -vt "openscad-$VERSION/lib/openscad/"
+ PLATFORMDIR="openscad-$VERSION/lib/openscad/platforms/"
+ mkdir -p "$PLATFORMDIR"
+ cp -av "$QTLIBDIR"/qt5/plugins/platforms/libqxcb.so "$PLATFORMDIR"
+ DRIDRIVERDIR=$(find /usr/lib -xdev -type d -name dri)
+ if [ -d "$DRIDRIVERDIR" ]
+ then
+ DRILIB="openscad-$VERSION/lib/openscad/dri/"
+ mkdir -p "$DRILIB"
+ cp -av "$DRIDRIVERDIR"/swrast_dri.so "$DRILIB"
+ fi
+
strip openscad-$VERSION/lib/openscad/*
mkdir -p openscad-$VERSION/share/appdata
- cp openscad.appdata.xml openscad-$VERSION/share/appdata
+ cp icons/openscad.{desktop,png,xml} openscad-$VERSION/share/appdata
cp scripts/installer-linux.sh openscad-$VERSION/install.sh
chmod 755 -R openscad-$VERSION/
PACKAGEFILE=openscad-$VERSION.x86-$ARCH.tar.gz
diff --git a/scripts/uni-build-dependencies.sh b/scripts/uni-build-dependencies.sh
index 00f3ffdd..5ee34919 100755
--- a/scripts/uni-build-dependencies.sh
+++ b/scripts/uni-build-dependencies.sh
@@ -131,6 +131,56 @@ build_qt4()
echo "----------"
}
+build_qt5()
+{
+ version=$1
+
+ if [ -f $DEPLOYDIR/lib/libQt5Core.a ]; then
+ echo "Qt5 already installed. not building"
+ return
+ fi
+
+ echo "Building Qt" $version "..."
+ cd $BASEDIR/src
+ rm -rf qt-everywhere-opensource-src-$version
+ v=`echo "$version" | sed -e 's/\.[0-9]$//'`
+ if [ ! -f qt-everywhere-opensource-src-$version.tar.gz ]; then
+ curl -O -L http://download.qt-project.org/official_releases/qt/$v/$version/single/qt-everywhere-opensource-src-$version.tar.gz
+ fi
+ tar xzf qt-everywhere-opensource-src-$version.tar.gz
+ cd qt-everywhere-opensource-src-$version
+ ./configure -prefix $DEPLOYDIR -release -static -opensource -confirm-license \
+ -nomake examples -nomake tests \
+ -qt-xcb -no-c++11 -no-glib -no-harfbuzz -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc \
+ -no-sql-psql -no-sql-sqlite2 -no-sql-tds -no-cups -no-qml-debug \
+ -skip activeqt -skip connectivity -skip declarative -skip doc \
+ -skip enginio -skip graphicaleffects -skip location -skip multimedia \
+ -skip quick1 -skip quickcontrols -skip script -skip sensors -skip serialport \
+ -skip svg -skip webkit -skip webkit-examples -skip websockets -skip xmlpatterns
+ make -j"$NUMCPU" install
+}
+
+build_qt5scintilla2()
+{
+ version=$1
+
+ if [ -d $DEPLOYDIR/lib/libqt5scintilla2.a ]; then
+ echo "Qt5Scintilla2 already installed. not building"
+ return
+ fi
+
+ echo "Building Qt5Scintilla2" $version "..."
+ cd $BASEDIR/src
+ #rm -rf QScintilla-gpl-$version.tar.gz
+ if [ ! -f QScintilla-gpl-$version.tar.gz ]; then
+ curl -L -o "QScintilla-gpl-$version.tar.gz" "http://downloads.sourceforge.net/project/pyqt/QScintilla2/QScintilla-$version/QScintilla-gpl-$version.tar.gz?use_mirror=switch"
+ fi
+ tar xzf QScintilla-gpl-$version.tar.gz
+ cd QScintilla-gpl-$version/Qt4Qt5/
+ qmake CONFIG+=staticlib
+ make -j"$NUMCPU" install
+}
+
build_bison()
{
version=$1
@@ -210,7 +260,7 @@ build_gmp()
cd $BASEDIR/src
rm -rf gmp-$version
if [ ! -f gmp-$version.tar.bz2 ]; then
- curl --insecure -O ftp://ftp.gmplib.org/pub/gmp-$version/gmp-$version.tar.bz2
+ curl --insecure -O https://gmplib.org/download/gmp/gmp-$version.tar.bz2
fi
tar xjf gmp-$version.tar.bz2
cd gmp-$version
@@ -315,6 +365,7 @@ build_cgal()
echo "Building CGAL" $version "..."
cd $BASEDIR/src
rm -rf CGAL-$version
+ ver4_4="curl --insecure -O https://gforge.inria.fr/frs/download.php/file/33524/CGAL-4.4.tar.bz2"
ver4_2="curl --insecure -O https://gforge.inria.fr/frs/download.php/32360/CGAL-4.2.tar.bz2"
ver4_1="curl --insecure -O https://gforge.inria.fr/frs/download.php/31640/CGAL-4.1.tar.bz2"
ver4_0_2="curl --insecure -O https://gforge.inria.fr/frs/download.php/31174/CGAL-4.0.2.tar.bz2"
@@ -509,6 +560,7 @@ build_eigen()
cd $BASEDIR/src
rm -rf eigen-$version
EIGENDIR="none"
+ if [ $version = "3.2.2" ]; then EIGENDIR=eigen-eigen-1306d75b4a21; fi
if [ $version = "3.1.1" ]; then EIGENDIR=eigen-eigen-43d9075b23ef; fi
if [ $EIGENDIR = "none" ]; then
echo Unknown eigen version. Please edit script.
@@ -697,7 +749,7 @@ if [ $1 ]; then
exit $?
fi
if [ $1 = "cgal" ]; then
- build_cgal 4.0.2 use-sys-libs
+ build_cgal 4.4 use-sys-libs
exit $?
fi
if [ $1 = "opencsg" ]; then
@@ -709,6 +761,11 @@ if [ $1 ]; then
build_qt4 4.8.4
exit $?
fi
+ if [ $1 = "qt5" ]; then
+ build_qt5 5.3.1
+ build_qt5scintilla2 2.8.3
+ exit $?
+ fi
if [ $1 = "glu" ]; then
# Mesa and GLU split in late 2012, so it's not on some systems
build_glu 9.0.0
@@ -741,21 +798,21 @@ fi
#
# Some of these are defined in scripts/common-build-dependencies.sh
-build_eigen 3.1.1
+build_eigen 3.2.2
build_gmp 5.0.5
build_mpfr 3.1.1
-build_boost 1.53.0
+build_boost 1.56.0
# NB! For CGAL, also update the actual download URL in the function
-build_cgal 4.0.2
+build_cgal 4.4
build_glew 1.9.0
build_opencsg 1.3.2
build_gettext 0.18.3.1
build_glib2 2.38.2
# the following are only needed for text()
-build_freetype 2.5.0.1
+build_freetype 2.5.0.1 --without-png
build_libxml2 2.9.1
-build_fontconfig 2.11.0
+build_fontconfig 2.11.0 --with-add-fonts=/usr/X11R6/lib/X11/fonts,/usr/local/share/fonts
build_ragel 6.8
build_harfbuzz 0.9.23 --with-glib=yes
diff --git a/scripts/uni-get-dependencies.sh b/scripts/uni-get-dependencies.sh
index 16cfa93a..92e17d65 100755
--- a/scripts/uni-get-dependencies.sh
+++ b/scripts/uni-get-dependencies.sh
@@ -57,7 +57,7 @@ get_mageia_deps()
get_debian_deps()
{
- for pkg in build-essential libqt4-dev libqt4-opengl-dev \
+ for pkg in build-essential curl libffi-dev qtbase5-dev \
libxmu-dev cmake bison flex git-core libboost-all-dev \
libXi-dev libmpfr-dev libboost-dev libglew-dev \
libeigen3-dev libcgal-dev libopencsg-dev libgmp3-dev libgmp-dev \
@@ -65,6 +65,15 @@ get_debian_deps()
libharfbuzz-dev gtk-doc-tools libglib2.0-dev gettext; do
sudo apt-get -y install $pkg;
done
+
+ # The following packages are only needed to build the static
+ # Qt5 version for release builds / older distributions.
+ for pkg in libdbus-1-dev \
+ libxcb1-dev libx11-xcb-dev libxcb-keysyms1-dev libxcb-image0-dev \
+ libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev \
+ libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev; do
+ sudo apt-get -y install $pkg;
+ done
}
unknown()
diff --git a/setenv_mac-qt4.sh b/setenv_mac-qt4.sh
index 1616245d..22ccbb69 100644
--- a/setenv_mac-qt4.sh
+++ b/setenv_mac-qt4.sh
@@ -1,4 +1,4 @@
-export OPENSCAD_LIBRARIES=$PWD/../libraries/install
+export OPENSCAD_LIBRARIES=$PWD/../libraries/install-qt4
export DYLD_LIBRARY_PATH=$OPENSCAD_LIBRARIES/lib
export DYLD_FRAMEWORK_PATH=$OPENSCAD_LIBRARIES/lib
export QMAKESPEC=unsupported/macx-clang
diff --git a/src/LibraryInfo.cc b/src/LibraryInfo.cc
index 443b4e10..b15cb7e4 100644
--- a/src/LibraryInfo.cc
+++ b/src/LibraryInfo.cc
@@ -1,6 +1,9 @@
#include "LibraryInfo.h"
#include
#include
+#ifdef USE_SCINTILLA_EDITOR
+#include
+#endif
#include "version_check.h"
#define STRINGIFY(x) #x
@@ -82,6 +85,9 @@ std::string LibraryInfo::info()
<< "\nCGAL version, kernels: " << TOSTRING(CGAL_VERSION) << ", " << cgal_3d_kernel << ", " << cgal_2d_kernel << ", " << cgal_2d_kernelEx
<< "\nOpenCSG version: " << OPENCSG_VERSION_STRING
<< "\nQt version: " << qtVersion
+#ifdef USE_SCINTILLA_EDITOR
+ << "\nQScintilla version: " << QSCINTILLA_VERSION_STR
+#endif
<< "\nMingW build: " << mingwstatus
<< "\nGLib version: " << GLIB_MAJOR_VERSION << "." << GLIB_MINOR_VERSION << "." << GLIB_MICRO_VERSION
<< "\nOPENSCADPATH: " << (env_path == NULL ? "" : env_path)
diff --git a/src/MainWindow.h b/src/MainWindow.h
index be4e338b..2843102d 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -7,6 +7,7 @@
#include "module.h"
#include "Tree.h"
#include "memory.h"
+#include "editor.h"
#include
#include
#include
@@ -65,6 +66,9 @@ public:
static const int maxRecentFiles = 10;
QAction *actionRecentFile[maxRecentFiles];
QMap knownFileExtensions;
+
+ QString editortype;
+ bool useScintilla;
MainWindow(const QString &filename);
~MainWindow();
@@ -105,6 +109,8 @@ private:
void show_examples();
void setDockWidgetTitle(QDockWidget *dockWidget, QString prefix, bool topLevel);
+ EditorInterface *editor;
+
class QMessageBox *openglbox;
class FontListDialog *font_list_dialog;
@@ -135,14 +141,13 @@ private slots:
private slots:
void selectFindType(int);
void find();
+ void findString(QString);
void findAndReplace();
void findNext();
void findPrev();
- void useSelectionForFind();
void replace();
void replaceAll();
protected:
- bool findOperation(QTextDocument::FindFlags options = 0);
virtual bool eventFilter(QObject* obj, QEvent *event);
private slots:
diff --git a/src/MainWindow.ui b/src/MainWindow.ui
index 31d6d49a..6ae8c7c2 100644
--- a/src/MainWindow.ui
+++ b/src/MainWindow.ui
@@ -179,7 +179,6 @@
-
@@ -295,6 +294,15 @@
0
+
+ 0
+
+
+ 0
+
+
+ 0
+
-
-
@@ -361,25 +369,6 @@
- -
-
-
-
- 100
- 100
-
-
-
-
- Monaco
- 8
-
-
-
- Qt::WheelFocus
-
-
-
@@ -461,7 +450,7 @@
Ctrl+Z
- Qt::WidgetWithChildrenShortcut
+ Qt::WindowShortcut
@@ -472,7 +461,7 @@
Ctrl+Shift+Z
- Qt::WidgetWithChildrenShortcut
+ Qt::WindowShortcut
@@ -483,7 +472,7 @@
Ctrl+X
- Qt::WidgetWithChildrenShortcut
+ Qt::WindowShortcut
@@ -494,7 +483,7 @@
Ctrl+C
- Qt::WidgetWithChildrenShortcut
+ Qt::WindowShortcut
@@ -505,7 +494,7 @@
Ctrl+V
- Qt::WidgetWithChildrenShortcut
+ Qt::WindowShortcut
@@ -776,9 +765,6 @@
Center
-
- Ctrl+P
-
@@ -975,15 +961,8 @@
1
-
- Editor
- QWidget
-
-
-
-
-
+
fileActionClose
diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc
index eb348c3d..a7f6c61a 100644
--- a/src/PlatformUtils.cc
+++ b/src/PlatformUtils.cc
@@ -3,6 +3,9 @@
#include "PlatformUtils.h"
#include "boosty.h"
#include
+#ifdef USE_SCINTILLA_EDITOR
+#include
+#endif
extern std::vector librarypath;
extern std::vector fontpath;
diff --git a/src/Preferences.cc b/src/Preferences.cc
index a0bf5b49..5a47d880 100644
--- a/src/Preferences.cc
+++ b/src/Preferences.cc
@@ -66,6 +66,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
this->defaultmap["editor/fontfamily"] = found_family;
this->defaultmap["editor/fontsize"] = 12;
this->defaultmap["editor/syntaxhighlight"] = "For Light Background";
+ this->defaultmap["editor/editortype"] = "Simple Editor";
#if defined (Q_OS_MAC)
this->defaultmap["editor/ctrlmousewheelzoom"] = false;
@@ -85,9 +86,12 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
connect(this->fontSize, SIGNAL(currentIndexChanged(const QString&)),
this, SLOT(on_fontSize_editTextChanged(const QString &)));
+ connect(this->editorType, SIGNAL(currentIndexChanged(const QString&)),
+ this, SLOT(on_editorType_editTextChanged(const QString &)));
+
// reset GUI fontsize if fontSize->addItem emitted signals that changed it.
this->fontSize->setEditText( QString("%1").arg( savedsize ) );
-
+
// Setup default settings
this->defaultmap["advanced/opencsg_show_warning"] = true;
this->defaultmap["advanced/enable_opencsg_opengl1x"] = true;
@@ -261,6 +265,12 @@ void Preferences::on_fontSize_editTextChanged(const QString &size)
emit fontChanged(getValue("editor/fontfamily").toString(), intsize);
}
+void Preferences::on_editorType_editTextChanged(const QString &type)
+{
+ QSettings settings;
+ settings.setValue("editor/editortype", type);
+}
+
void Preferences::on_syntaxHighlight_currentIndexChanged(const QString &s)
{
QSettings settings;
@@ -430,6 +440,10 @@ void Preferences::updateGUI()
int shidx = this->syntaxHighlight->findText(shighlight);
if (shidx >= 0) this->syntaxHighlight->setCurrentIndex(shidx);
+ QString editortypevar = getValue("editor/editortype").toString();
+ int edidx = this->editorType->findText(editortypevar);
+ if (edidx >=0) this->editorType->setCurrentIndex(edidx);
+
this->mouseWheelZoomBox->setChecked(getValue("editor/ctrlmousewheelzoom").toBool());
if (AutoUpdater *updater = AutoUpdater::updater()) {
diff --git a/src/Preferences.h b/src/Preferences.h
index 4aad048d..be951ade 100644
--- a/src/Preferences.h
+++ b/src/Preferences.h
@@ -35,7 +35,7 @@ public slots:
void on_mdiCheckBox_toggled(bool);
void on_undockCheckBox_toggled(bool);
void on_checkNowButton_clicked();
-
+ void on_editorType_editTextChanged(const QString &);
signals:
void requestRedraw() const;
void updateMdiMode(bool mdi) const;
@@ -44,6 +44,7 @@ signals:
void colorSchemeChanged(const QString &scheme) const;
void openCSGSettingsChanged() const;
void syntaxHighlightChanged(const QString &s);
+ void editorTypeChanged(const QString &type);
private:
Preferences(QWidget *parent = NULL);
diff --git a/src/Preferences.ui b/src/Preferences.ui
index 80cff0cf..f880fb57 100644
--- a/src/Preferences.ui
+++ b/src/Preferences.ui
@@ -6,8 +6,8 @@
0
0
- 823
- 440
+ 584
+ 403
@@ -23,26 +23,32 @@
true
-
- -
-
-
- 4
-
-
-
+
+
+
+ 10
+ 10
+ 470
+ 899
+
+
+
+ 1
+
+
+
+
-
+
-
-
+
+
-
+
+
+ Color scheme:
+
+
+
-
-
-
-
-
-
- Color scheme:
-
-
-
- -
@@ -92,64 +98,330 @@
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
+
- Qt::Vertical
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 645
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Editor Type
+
+
+
+ -
+
+
-
+
+ Simple Editor
+
+
+ -
+
+ QScintilla Editor
+
+
+
+
+ -
+
+
+
+ 10
+ 50
+ false
+
+
+
+ (requires restart)
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
QSizePolicy::Expanding
- 20
- 645
+ 30
+ 20
-
-
-
+
+ -
+
-
-
-
-
-
-
-
- 75
- true
-
-
+
+
+
+ 75
+ true
+
+
+
+ Font
+
+
+ false
+
+
+
+ -
+
+
+
+ Helvetica
+ 12
+
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Color syntax highlighting
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
-
+
+ For Light Background
+
+
+ -
+
+ For Dark Background
+
+
+ -
+
+ Monokai
+
+
+ -
+
+ Solarized
+
+
+ -
+
+ Off
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 30
+ 20
+
+
+
+
+
+
+ -
+
+
+ 5
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Use Ctrl/Cmd-Mouse-wheel to zoom text
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 723
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
- Font
+ Automatically check for updates
-
- false
+
+ true
- -
-
+
-
+
+
+ Include development snapshots
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
-
+
Qt::Horizontal
@@ -161,25 +433,15 @@
- -
-
-
-
- DejaVu Sans
- 12
-
+
-
+
+
+ Check Now
- -
-
-
- true
-
-
-
- -
-
+
-
+
Qt::Horizontal
@@ -194,10 +456,7 @@
-
-
-
- 0
-
+
-
@@ -241,46 +500,31 @@
Qt::Horizontal
-
- QSizePolicy::Expanding
-
- 30
+ 40
20
-
-
- -
-
-
- 5
-
-
-
+
+
+ false
+
- 75
- true
+ 11
- Use Ctrl/Cmd-Mouse-wheel to zoom text
+ Last checked:
-
-
-
-
-
-
-
- -
-
+
Qt::Horizontal
@@ -294,367 +538,223 @@
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 77
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- Automatically check for updates
-
-
- true
-
-
-
- -
-
-
- Include development snapshots
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- 0
-
-
-
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Check Now
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- false
-
-
-
- 11
-
-
-
- Last checked:
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 89
-
-
-
-
-
-
-
-
-
- 0
+
+ -
+
+
+ Qt::Vertical
-
-
-
-
-
-
-
-
- 75
- true
-
-
-
- Features
-
-
-
- -
-
-
- QFrame::NoFrame
-
-
- QFrame::Plain
-
-
- Qt::ScrollBarAlwaysOff
-
-
- true
-
-
-
-
- 0
- 0
- 803
- 325
-
-
-
-
-
-
-
- 8
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 282
-
-
-
-
+
+
+ 20
+ 89
+
+
+
+
+
+
+
+
+
+ 0
+
+ -
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Features
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 83
+ 36
+
+
+
+
-
+
+
+ 8
+
-
-
-
-
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 282
+
+
+
+
+
+
+
-
-
-
- -
-
-
- OpenCSG
-
-
+
+
+
+
+
+ -
+
+
+ OpenCSG
+
+
+
-
+
+
+ Show capability warning
+
+
+ true
+
+
+
+ -
+
+
+ Enable for OpenGL 1.x
+
+
+
+ -
+
-
-
+
- Show capability warning
-
-
- true
+ Turn off rendering at
-
-
-
- Enable for OpenGL 1.x
-
-
+
-
-
-
-
-
-
- Turn off rendering at
-
-
-
- -
-
-
- -
-
-
- elements
-
-
-
-
-
- -
-
+
- Force Goldfeather
+ elements
-
-
+
+ -
+
+
+ Force Goldfeather
+
+
+
+
+
+
+ -
+
-
-
-
-
-
-
- CGAL Cache size
-
-
-
- -
-
-
- -
-
-
- bytes
-
-
-
-
-
- -
-
-
-
-
-
- PolySet Cache size
-
-
-
- -
-
-
- -
-
-
- bytes
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 11
-
-
-
-
- -
-
+
- Allow to open multiple documents
+ CGAL Cache size
-
-
+
+
+ -
+
- Enable undocking of Editor and Console
+ bytes
-
-
-
-
+
+ -
+
+
-
+
+
+ PolySet Cache size
+
+
+
+ -
+
+
+ -
+
+
+ bytes
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 11
+
+
+
+
+ -
+
+
+ Allow to open multiple documents
+
+
+
+ -
+
+
+ Enable undocking of Editor and Console
+
+
+
+
+
+
diff --git a/src/editor.cc b/src/editor.cc
index c870db6a..b9d528d0 100644
--- a/src/editor.cc
+++ b/src/editor.cc
@@ -1,173 +1,16 @@
#include "editor.h"
#include "Preferences.h"
-Editor::Editor(QWidget *parent) : QTextEdit(parent)
-{
- setAcceptRichText(false);
- // This needed to avoid QTextEdit accepting filename drops as we want
- // to handle these ourselves in MainWindow
- setAcceptDrops(false);
- this->highlighter = new Highlighter(this->document());
-}
-
-void Editor::indentSelection()
-{
- QTextCursor cursor = textCursor();
- int p1 = cursor.selectionStart();
- QString txt = cursor.selectedText();
-
- txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("\t"));
- if (txt.endsWith(QString(QChar(8233)) + QString("\t")))
- txt.chop(1);
- txt = QString("\t") + txt;
-
- cursor.insertText(txt);
- int p2 = cursor.position();
- cursor.setPosition(p1, QTextCursor::MoveAnchor);
- cursor.setPosition(p2, QTextCursor::KeepAnchor);
- setTextCursor(cursor);
-}
-
-void Editor::unindentSelection()
-{
- QTextCursor cursor = textCursor();
- int p1 = cursor.selectionStart();
- QString txt = cursor.selectedText();
-
- txt.replace(QString(QChar(8233)) + QString("\t"), QString(QChar(8233)));
- if (txt.startsWith(QString("\t")))
- txt.remove(0, 1);
-
- cursor.insertText(txt);
- int p2 = cursor.position();
- cursor.setPosition(p1, QTextCursor::MoveAnchor);
- cursor.setPosition(p2, QTextCursor::KeepAnchor);
- setTextCursor(cursor);
-}
-
-void Editor::commentSelection()
-{
- QTextCursor cursor = textCursor();
- int p1 = cursor.selectionStart();
- QString txt = cursor.selectedText();
-
- txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("//"));
- if (txt.endsWith(QString(QChar(8233)) + QString("//")))
- txt.chop(2);
- txt = QString("//") + txt;
-
- cursor.insertText(txt);
- int p2 = cursor.position();
- cursor.setPosition(p1, QTextCursor::MoveAnchor);
- cursor.setPosition(p2, QTextCursor::KeepAnchor);
- setTextCursor(cursor);
-}
-
-void Editor::uncommentSelection()
-{
- QTextCursor cursor = textCursor();
- int p1 = cursor.selectionStart();
- QString txt = cursor.selectedText();
-
- txt.replace(QString(QChar(8233)) + QString("//"), QString(QChar(8233)));
- if (txt.startsWith(QString("//")))
- txt.remove(0, 2);
-
- cursor.insertText(txt);
- int p2 = cursor.position();
- cursor.setPosition(p1, QTextCursor::MoveAnchor);
- cursor.setPosition(p2, QTextCursor::KeepAnchor);
- setTextCursor(cursor);
-}
-
-void Editor::zoomIn()
-{
- // See also QT's implementation in QEditor.cpp
- QSettings settings;
- QFont tmp_font = this->font() ;
- if ( font().pointSize() >= 1 )
- tmp_font.setPointSize( 1 + font().pointSize() );
- else
- tmp_font.setPointSize( 1 );
- settings.setValue("editor/fontsize", tmp_font.pointSize());
- this->setFont( tmp_font );
-}
-
-void Editor::zoomOut()
-{
- QSettings settings;
- QFont tmp_font = this->font();
- if ( font().pointSize() >= 2 )
- tmp_font.setPointSize( -1 + font().pointSize() );
- else
- tmp_font.setPointSize( 1 );
- settings.setValue("editor/fontsize", tmp_font.pointSize());
- this->setFont( tmp_font );
-}
-
-void Editor::wheelEvent ( QWheelEvent * event )
+void EditorInterface::wheelEvent(QWheelEvent *event)
{
QSettings settings;
bool wheelzoom_enabled = Preferences::inst()->getValue("editor/ctrlmousewheelzoom").toBool();
- if ((event->modifiers() == Qt::ControlModifier) && wheelzoom_enabled ) {
- if (event->delta() > 0 )
+ if ((event->modifiers() == Qt::ControlModifier) && wheelzoom_enabled) {
+ if (event->delta() > 0)
zoomIn();
- else if (event->delta() < 0 )
+ else if (event->delta() < 0)
zoomOut();
} else {
- QTextEdit::wheelEvent( event );
+ QWidget::wheelEvent(event);
}
}
-
-void Editor::setPlainText(const QString &text)
-{
- int y = verticalScrollBar()->sliderPosition();
- // Save current cursor position
- QTextCursor cursor = textCursor();
- int n = cursor.position();
- QTextEdit::setPlainText(text);
- // Restore cursor position
- if (n < text.length()) {
- cursor.setPosition(n);
- setTextCursor(cursor);
- verticalScrollBar()->setSliderPosition(y);
- }
-}
-
-void Editor::highlightError(int error_pos)
-{
- highlighter->highlightError( error_pos );
- QTextCursor cursor = this->textCursor();
- cursor.setPosition( error_pos );
- this->setTextCursor( cursor );
-}
-
-void Editor::unhighlightLastError()
-{
- highlighter->unhighlightLastError();
-}
-
-void Editor::setHighlightScheme(const QString &name)
-{
- highlighter->assignFormatsToTokens( name );
- highlighter->rehighlight(); // slow on large files
-}
-
-QSize Editor::sizeHint() const
-{
- if (initialSizeHint.width() <= 0) {
- return QTextEdit::sizeHint();
- } else {
- return initialSizeHint;
- }
-}
-
-void Editor::setInitialSizeHint(const QSize &size)
-{
- initialSizeHint = size;
-}
-
-Editor::~Editor()
-{
- delete highlighter;
-}
diff --git a/src/editor.h b/src/editor.h
index 8abb20af..6aa20472 100644
--- a/src/editor.h
+++ b/src/editor.h
@@ -1,35 +1,52 @@
+#pragma once
+
#include
#include
#include
#include
#include
#include
-#include "highlighter.h"
-class Editor : public QTextEdit
+class EditorInterface : public QWidget
{
Q_OBJECT
public:
- Editor(QWidget *parent);
- ~Editor();
- QSize sizeHint() const;
- void setInitialSizeHint(const QSize &size);
+ EditorInterface(QWidget *parent) : QWidget(parent) {}
+ virtual ~EditorInterface() {}
+ virtual QSize sizeHint(){ QSize size; return size;}
+ virtual void setInitialSizeHint(const QSize&) { }
+ virtual void wheelEvent(QWheelEvent*);
+ virtual QString toPlainText() = 0;
+ virtual QTextDocument *document(){QTextDocument *t = new QTextDocument; return t;}
+ virtual QString selectedText() = 0;
+ virtual bool find(const QString &, bool findNext = false, bool findBackwards = false) = 0;
+ virtual void replaceSelectedText(const QString &) = 0;
+
+signals:
+ void contentsChanged();
+ void modificationChanged(bool);
+
public slots:
- void zoomIn();
- void zoomOut();
- void setLineWrapping(bool on) { if(on) setWordWrapMode(QTextOption::WrapAnywhere); }
- void setContentModified(bool y) { document()->setModified(y); }
- bool isContentModified() { return document()->isModified(); }
- void indentSelection();
- void unindentSelection();
- void commentSelection();
- void uncommentSelection();
- void setPlainText(const QString &text);
- void highlightError(int error_pos);
- void unhighlightLastError();
- void setHighlightScheme(const QString &name);
+ virtual void zoomIn() = 0;
+ virtual void zoomOut() = 0;
+ virtual void setContentModified(bool) = 0;
+ virtual bool isContentModified() = 0;
+ virtual void indentSelection() = 0;
+ virtual void unindentSelection() = 0;
+ virtual void commentSelection() = 0;
+ virtual void uncommentSelection() = 0;
+ virtual void setPlainText(const QString &) = 0;
+ virtual void highlightError(int) = 0;
+ virtual void unhighlightLastError() = 0;
+ virtual void setHighlightScheme(const QString&) = 0;
+ virtual void insert(const QString&) = 0;
+ virtual void undo() = 0;
+ virtual void redo() = 0;
+ virtual void cut() = 0;
+ virtual void copy() = 0;
+ virtual void paste() = 0;
+ virtual void initFont(const QString&, uint) = 0;
+
private:
- void wheelEvent ( QWheelEvent * event );
- Highlighter *highlighter;
- QSize initialSizeHint;
+ QSize initialSizeHint;
};
diff --git a/src/legacyeditor.cc b/src/legacyeditor.cc
new file mode 100644
index 00000000..d9259339
--- /dev/null
+++ b/src/legacyeditor.cc
@@ -0,0 +1,267 @@
+#include "legacyeditor.h"
+#include "Preferences.h"
+#include "highlighter.h"
+
+LegacyEditor::LegacyEditor(QWidget *parent) : EditorInterface(parent)
+{
+ QVBoxLayout *legacyeditorLayout = new QVBoxLayout(this);
+ legacyeditorLayout->setContentsMargins(0, 0, 0, 0);
+ this->textedit = new QTextEdit(this);
+ legacyeditorLayout->addWidget(this->textedit);
+ this->textedit->setAcceptRichText(false);
+ // This needed to avoid the editor accepting filename drops as we want
+ // to handle these ourselves in MainWindow
+ this->textedit->setAcceptDrops(false);
+ this->textedit->setWordWrapMode(QTextOption::WrapAnywhere);
+ this->textedit->setTabStopWidth(30);
+
+ this->highlighter = new Highlighter(this->textedit->document());
+
+ connect(this->textedit, SIGNAL(textChanged()), this, SIGNAL(contentsChanged()));
+ connect(this->textedit->document(), SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool)));
+}
+
+void LegacyEditor::indentSelection()
+{
+ QTextCursor cursor = textedit->textCursor();
+ int p1 = cursor.selectionStart();
+ QString txt = cursor.selectedText();
+
+ txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("\t"));
+ if (txt.endsWith(QString(QChar(8233)) + QString("\t")))
+ txt.chop(1);
+ txt = QString("\t") + txt;
+
+ cursor.insertText(txt);
+ int p2 = cursor.position();
+ cursor.setPosition(p1, QTextCursor::MoveAnchor);
+ cursor.setPosition(p2, QTextCursor::KeepAnchor);
+ textedit->setTextCursor(cursor);
+}
+
+void LegacyEditor::unindentSelection()
+{
+ QTextCursor cursor = textedit->textCursor();
+ int p1 = cursor.selectionStart();
+ QString txt = cursor.selectedText();
+
+ txt.replace(QString(QChar(8233)) + QString("\t"), QString(QChar(8233)));
+ if (txt.startsWith(QString("\t")))
+ txt.remove(0, 1);
+
+ cursor.insertText(txt);
+ int p2 = cursor.position();
+ cursor.setPosition(p1, QTextCursor::MoveAnchor);
+ cursor.setPosition(p2, QTextCursor::KeepAnchor);
+ textedit->setTextCursor(cursor);
+}
+
+void LegacyEditor::commentSelection()
+{
+ QTextCursor cursor = textedit->textCursor();
+ int p1 = cursor.selectionStart();
+ QString txt = cursor.selectedText();
+
+ txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("//"));
+ if (txt.endsWith(QString(QChar(8233)) + QString("//")))
+ txt.chop(2);
+ txt = QString("//") + txt;
+
+ cursor.insertText(txt);
+ int p2 = cursor.position();
+ cursor.setPosition(p1, QTextCursor::MoveAnchor);
+ cursor.setPosition(p2, QTextCursor::KeepAnchor);
+ textedit->setTextCursor(cursor);
+
+}
+
+void LegacyEditor::uncommentSelection()
+{
+ QTextCursor cursor = textedit->textCursor();
+ int p1 = cursor.selectionStart();
+ QString txt = cursor.selectedText();
+
+ txt.replace(QString(QChar(8233)) + QString("//"), QString(QChar(8233)));
+ if (txt.startsWith(QString("//")))
+ txt.remove(0, 2);
+
+ cursor.insertText(txt);
+ int p2 = cursor.position();
+ cursor.setPosition(p1, QTextCursor::MoveAnchor);
+ cursor.setPosition(p2, QTextCursor::KeepAnchor);
+ textedit->setTextCursor(cursor);
+}
+
+void LegacyEditor::zoomIn()
+{
+ // See also QT's implementation in QLegacyEditor.cpp
+ QSettings settings;
+ QFont tmp_font = this->font() ;
+ if (font().pointSize() >= 1)
+ tmp_font.setPointSize(1 + font().pointSize());
+ else
+ tmp_font.setPointSize(1);
+ settings.setValue("editor/fontsize", tmp_font.pointSize());
+ this->setFont(tmp_font);
+}
+
+void LegacyEditor::zoomOut()
+{
+
+ QSettings settings;
+ QFont tmp_font = this->font();
+ if (font().pointSize() >= 2)
+ tmp_font.setPointSize(-1 + font().pointSize());
+ else
+ tmp_font.setPointSize(1);
+ settings.setValue("editor/fontsize", tmp_font.pointSize());
+ this->setFont(tmp_font);
+
+}
+
+void LegacyEditor::setPlainText(const QString &text)
+{
+
+ int y = textedit->verticalScrollBar()->sliderPosition();
+ // Save current cursor position
+ QTextCursor cursor = textedit->textCursor();
+ int n = cursor.position();
+ textedit->setPlainText(text);
+ // Restore cursor position
+ if (n < text.length()) {
+ cursor.setPosition(n);
+ textedit->setTextCursor(cursor);
+ textedit->verticalScrollBar()->setSliderPosition(y);
+ }
+}
+
+void LegacyEditor::highlightError(int error_pos)
+{
+ highlighter->highlightError(error_pos);
+ QTextCursor cursor = this->textedit->textCursor();
+ cursor.setPosition(error_pos);
+ this->textedit->setTextCursor(cursor);
+
+}
+
+void LegacyEditor::unhighlightLastError()
+{
+ highlighter->unhighlightLastError();
+}
+
+void LegacyEditor::setHighlightScheme(const QString &name)
+{
+ highlighter->assignFormatsToTokens(name);
+ highlighter->rehighlight(); // slow on large files
+}
+
+QSize LegacyEditor::sizeHint() const
+{
+ if (initialSizeHint.width() <= 0) {
+ return textedit->sizeHint();
+ } else {
+ return initialSizeHint;
+ }
+}
+
+void LegacyEditor::setInitialSizeHint(const QSize &size)
+{
+ initialSizeHint = size;
+}
+
+QString LegacyEditor::toPlainText()
+{
+ return textedit->toPlainText();
+}
+
+void LegacyEditor::insert(const QString &text)
+{
+ textedit->insertPlainText(text);
+}
+
+void LegacyEditor::undo()
+{
+ textedit->undo();
+}
+
+void LegacyEditor::redo()
+{
+ textedit->redo();
+}
+
+void LegacyEditor::cut()
+{
+ textedit->cut();
+}
+
+void LegacyEditor::copy()
+{
+ textedit->copy();
+}
+
+void LegacyEditor::paste()
+{
+ textedit->paste();
+}
+
+LegacyEditor::~LegacyEditor()
+{
+ delete highlighter;
+}
+
+void LegacyEditor::replaceSelectedText(const QString &newText)
+{
+ QTextCursor cursor = this->textedit->textCursor();
+ if (cursor.selectedText() != newText) {
+ cursor.insertText(newText);
+ }
+}
+
+bool LegacyEditor::findString(const QString & exp, bool findBackwards) const
+{
+ return textedit->find(exp, findBackwards ? QTextDocument::FindBackward : QTextDocument::FindFlags(0));
+}
+
+bool LegacyEditor::find(const QString &newText, bool findNext, bool findBackwards)
+{
+ bool success = this->findString(newText, findBackwards);
+ if (!success) { // Implement wrap-around search behavior
+ QTextCursor old_cursor = this->textedit->textCursor();
+ QTextCursor tmp_cursor = old_cursor;
+ tmp_cursor.movePosition(findBackwards ? QTextCursor::End : QTextCursor::Start);
+ this->textedit->setTextCursor(tmp_cursor);
+ bool success = this->findString(newText, findBackwards);
+ if (!success) {
+ this->textedit->setTextCursor(old_cursor);
+ }
+ return success;
+ }
+ return true;
+
+}
+
+void LegacyEditor::initFont(const QString& family, uint size)
+{
+ QFont font;
+ if (!family.isEmpty()) font.setFamily(family);
+ else font.setFixedPitch(true);
+ if (size > 0) font.setPointSize(size);
+ font.setStyleHint(QFont::TypeWriter);
+ this->setFont(font);
+
+}
+
+QString LegacyEditor::selectedText()
+{
+ return textedit->textCursor().selectedText();
+}
+
+void LegacyEditor::setContentModified(bool y)
+{
+ textedit->document()->setModified(y);
+}
+
+bool LegacyEditor::isContentModified()
+{
+ return textedit->document()->isModified();
+}
diff --git a/src/legacyeditor.h b/src/legacyeditor.h
new file mode 100644
index 00000000..eb8e7b41
--- /dev/null
+++ b/src/legacyeditor.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "editor.h"
+
+class LegacyEditor : public EditorInterface
+{
+ Q_OBJECT
+public:
+ LegacyEditor(class QWidget *parent);
+ virtual ~LegacyEditor();
+ QSize sizeHint() const;
+ void setInitialSizeHint(const QSize&);
+ QString toPlainText();
+ QString selectedText();
+ bool find(const QString &, bool findNext = false, bool findBackwards = false);
+ void replaceSelectedText(const QString &newText);
+ bool findString(const QString & exp, bool findBackwards) const;
+
+public slots:
+ void zoomIn();
+ void zoomOut();
+ void setContentModified(bool);
+ bool isContentModified();
+ void indentSelection();
+ void unindentSelection();
+ void commentSelection();
+ void uncommentSelection();
+ void setPlainText(const QString&);
+ void highlightError(int);
+ void unhighlightLastError();
+ void setHighlightScheme(const QString&);
+ void insert(const QString&);
+ void undo();
+ void redo();
+ void cut();
+ void copy();
+ void paste();
+ void initFont(const QString&, uint);
+private:
+ class QTextEdit *textedit;
+ class Highlighter *highlighter;
+ QSize initialSizeHint;
+};
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 3a142ebc..4e8d2928 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -23,7 +23,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-
#include "GeometryCache.h"
#include "ModuleCache.h"
#include "MainWindow.h"
@@ -40,6 +39,10 @@
#include "expression.h"
#include "progress.h"
#include "dxfdim.h"
+#include "legacyeditor.h"
+#ifdef USE_SCINTILLA_EDITOR
+#include "scintillaeditor.h"
+#endif
#include "AboutDialog.h"
#include "FontListDialog.h"
#ifdef ENABLE_OPENCSG
@@ -166,6 +169,20 @@ MainWindow::MainWindow(const QString &filename)
: root_inst("group"), font_list_dialog(NULL), tempFile(NULL), progresswidget(NULL)
{
setupUi(this);
+
+ editortype = Preferences::inst()->getValue("editor/editortype").toString();
+
+ useScintilla = (editortype == "QScintilla Editor");
+#ifdef USE_SCINTILLA_EDITOR
+ if (useScintilla) {
+ editor = new ScintillaEditor(editorDockContents);
+ }
+ else
+#endif
+ editor = new LegacyEditor(editorDockContents);
+
+ editorDockContents->layout()->addWidget(editor);
+
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
@@ -219,8 +236,6 @@ MainWindow::MainWindow(const QString &filename)
connect(this, SIGNAL(highlightError(int)), editor, SLOT(highlightError(int)));
connect(this, SIGNAL(unhighlightLastError()), editor, SLOT(unhighlightLastError()));
- editor->setTabStopWidth(30);
- editor->setLineWrapping(true); // Not designable
this->qglview->statusLabel = new QLabel(this);
statusBar()->addWidget(this->qglview->statusLabel);
@@ -315,7 +330,6 @@ MainWindow::MainWindow(const QString &filename)
connect(this->editActionFindAndReplace, SIGNAL(triggered()), this, SLOT(findAndReplace()));
connect(this->editActionFindNext, SIGNAL(triggered()), this, SLOT(findNext()));
connect(this->editActionFindPrevious, SIGNAL(triggered()), this, SLOT(findPrev()));
- connect(this->editActionUseSelectionForFind, SIGNAL(triggered()), this, SLOT(useSelectionForFind()));
// Design menu
connect(this->designActionAutoReload, SIGNAL(toggled(bool)), this, SLOT(autoReloadSet(bool)));
@@ -397,15 +411,15 @@ MainWindow::MainWindow(const QString &filename)
}
updateRecentFileActions();
- connect(editor->document(), SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
- connect(editor->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
+ connect(editor, SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
+ connect(editor, SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
connect(this->qglview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
connect(Preferences::inst(), SIGNAL(requestRedraw()), this->qglview, SLOT(updateGL()));
connect(Preferences::inst(), SIGNAL(updateMdiMode(bool)), this, SLOT(updateMdiMode(bool)));
connect(Preferences::inst(), SIGNAL(updateUndockMode(bool)), this, SLOT(updateUndockMode(bool)));
connect(Preferences::inst(), SIGNAL(fontChanged(const QString&,uint)),
- this, SLOT(setFont(const QString&,uint)));
+ editor, SLOT(initFont(const QString&,uint)));
connect(Preferences::inst(), SIGNAL(openCSGSettingsChanged()),
this, SLOT(openCSGSettingsChanged()));
connect(Preferences::inst(), SIGNAL(syntaxHighlightChanged(const QString&)),
@@ -417,7 +431,9 @@ MainWindow::MainWindow(const QString &filename)
QString cs = Preferences::inst()->getValue("3dview/colorscheme").toString();
this->setColorScheme(cs);
+ //find and replace panel
connect(this->findTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectFindType(int)));
+ connect(this->findInputField, SIGNAL(textChanged(QString)), this, SLOT(findString(QString)));
connect(this->findInputField, SIGNAL(returnPressed()), this->nextButton, SLOT(animateClick()));
find_panel->installEventFilter(this);
@@ -470,8 +486,7 @@ MainWindow::MainWindow(const QString &filename)
clearCurrentOutput();
}
-void
-MainWindow::loadViewSettings(){
+void MainWindow::loadViewSettings(){
QSettings settings;
if (settings.value("view/showEdges").toBool()) {
viewActionShowEdges->setChecked(true);
@@ -498,8 +513,7 @@ MainWindow::loadViewSettings(){
updateUndockMode(settings.value("advanced/undockableWindows").toBool());
}
-void
-MainWindow::loadDesignSettings()
+void MainWindow::loadDesignSettings()
{
QSettings settings;
if (settings.value("design/autoReload").toBool()) {
@@ -591,8 +605,8 @@ void MainWindow::requestOpenFile(const QString &filename)
one is not empty. Otherwise the current window content is overwritten.
Any check whether to replace the content have to be made before.
*/
-void
-MainWindow::openFile(const QString &new_filename)
+
+void MainWindow::openFile(const QString &new_filename)
{
if (MainWindow::mdiMode) {
if (!editor->toPlainText().isEmpty()) {
@@ -622,8 +636,7 @@ MainWindow::openFile(const QString &new_filename)
clearCurrentOutput();
}
-void
-MainWindow::setFileName(const QString &filename)
+void MainWindow::setFileName(const QString &filename)
{
if (filename.isEmpty()) {
this->fileName.clear();
@@ -1091,6 +1104,7 @@ void MainWindow::show_examples()
{
bool found_example = false;
QStringList categories;
+ //categories in File menu item - Examples
categories << "Basics" << "Shapes" << "Extrusion" << "Advanced";
foreach (const QString &cat, categories){
@@ -1243,19 +1257,17 @@ void MainWindow::actionReload()
void MainWindow::pasteViewportTranslation()
{
- QTextCursor cursor = editor->textCursor();
QString txt;
txt.sprintf("[ %.2f, %.2f, %.2f ]", -qglview->cam.object_trans.x(), -qglview->cam.object_trans.y(), -qglview->cam.object_trans.z());
- cursor.insertText(txt);
+ this->editor->insert(txt);
}
void MainWindow::pasteViewportRotation()
{
- QTextCursor cursor = editor->textCursor();
QString txt;
txt.sprintf("[ %.2f, %.2f, %.2f ]",
fmodf(360 - qglview->cam.object_rot.x() + 90, 360), fmodf(360 - qglview->cam.object_rot.y(), 360), fmodf(360 - qglview->cam.object_rot.z(), 360));
- cursor.insertText(txt);
+ this->editor->insert(txt);
}
void MainWindow::find()
@@ -1265,10 +1277,16 @@ void MainWindow::find()
replaceButton->hide();
replaceAllButton->hide();
find_panel->show();
+ findInputField->setText(editor->selectedText());
findInputField->setFocus();
findInputField->selectAll();
}
+void MainWindow::findString(QString textToFind)
+{
+ editor->find(textToFind, false, false);
+}
+
void MainWindow::findAndReplace()
{
findTypeComboBox->setCurrentIndex(1);
@@ -1285,55 +1303,25 @@ void MainWindow::selectFindType(int type) {
if (type == 1) findAndReplace();
}
-bool MainWindow::findOperation(QTextDocument::FindFlags options) {
- bool success = editor->find(findInputField->text(), options);
- if (!success) { // Implement wrap-around search behavior
- QTextCursor old_cursor = editor->textCursor();
- QTextCursor tmp_cursor = old_cursor;
- tmp_cursor.movePosition((options & QTextDocument::FindBackward) ? QTextCursor::End : QTextCursor::Start);
- editor->setTextCursor(tmp_cursor);
- bool success = editor->find(findInputField->text(), options);
- if (!success) {
- editor->setTextCursor(old_cursor);
- }
- return success;
- }
- return true;
-}
-
void MainWindow::replace() {
- QTextCursor cursor = editor->textCursor();
- QString selectedText = cursor.selectedText();
- if (selectedText == findInputField->text()) {
- cursor.insertText(replaceInputField->text());
- }
- findNext();
+ this->editor->replaceSelectedText(this->replaceInputField->text());
+ this->editor->find(this->findInputField->text());
}
void MainWindow::replaceAll() {
- QTextCursor old_cursor = editor->textCursor();
- QTextCursor tmp_cursor = old_cursor;
- tmp_cursor.movePosition(QTextCursor::Start);
- editor->setTextCursor(tmp_cursor);
- while (editor->find(findInputField->text())) {
- editor->textCursor().insertText(replaceInputField->text());
+ while (this->editor->find(this->findInputField->text(), true)) {
+ this->editor->replaceSelectedText(this->replaceInputField->text());
}
- editor->setTextCursor(old_cursor);
}
void MainWindow::findNext()
{
- findOperation();
+ editor->find(this->findInputField->text(), true);
}
void MainWindow::findPrev()
{
- findOperation(QTextDocument::FindBackward);
-}
-
-void MainWindow::useSelectionForFind()
-{
- findInputField->setText(editor->textCursor().selectedText());
+ editor->find(this->findInputField->text(), true, true);
}
bool MainWindow::eventFilter(QObject* obj, QEvent *event)
@@ -1473,6 +1461,7 @@ void MainWindow::compileTopLevelDocument()
resetPrintedDeprecations();
this->last_compiled_doc = editor->toPlainText();
+
std::string fulltext =
std::string(this->last_compiled_doc.toLocal8Bit().constData()) +
"\n" + commandline_commands;
@@ -1481,10 +1470,8 @@ void MainWindow::compileTopLevelDocument()
this->root_module = NULL;
this->root_module = parse(fulltext.c_str(),
- this->fileName.isEmpty() ?
- "" :
- QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
- false);
+ this->fileName.isEmpty() ? "" :
+ QFileInfo(this->fileName).absolutePath().toLocal8Bit(), false);
updateCamera();
}
@@ -1921,8 +1908,9 @@ void MainWindow::actionExportCSG()
}
QString csg_filename = QFileDialog::getSaveFileName(this, "Export CSG File",
- this->fileName.isEmpty() ? "Untitled.csg" : QFileInfo(this->fileName).baseName()+".csg",
- "CSG Files (*.csg)");
+ this->fileName.isEmpty() ? "Untitled.csg" : QFileInfo(this->fileName).baseName()+".csg",
+ "CSG Files (*.csg)");
+
if (csg_filename.isEmpty()) {
PRINT("No filename specified. CSG export aborted.");
clearCurrentOutput();
@@ -2071,7 +2059,7 @@ void MainWindow::viewModeAnimate()
void MainWindow::animateUpdateDocChanged()
{
- QString current_doc = editor->toPlainText();
+ QString current_doc = editor->toPlainText();
if (current_doc != last_compiled_doc)
animateUpdate();
}
@@ -2260,7 +2248,7 @@ void MainWindow::handleFileDrop(const QString &filename)
}
openFile(filename);
} else {
- editor->insertPlainText(cmd.arg(filename));
+ editor->insert(cmd.arg(filename));
}
}
@@ -2402,7 +2390,8 @@ void MainWindow::consoleOutput(const std::string &msg, void *userdata)
// originates in a worker thread.
MainWindow *thisp = static_cast(userdata);
QMetaObject::invokeMethod(thisp->console, "append", Qt::QueuedConnection,
- Q_ARG(QString, QString::fromLocal8Bit(msg.c_str())));
+ Q_ARG(QString, QString::fromLocal8Bit(msg.c_str())));
+
if (thisp->procevents) QApplication::processEvents();
}
@@ -2419,6 +2408,7 @@ void MainWindow::clearCurrentOutput()
void MainWindow::openCSGSettingsChanged()
{
#ifdef ENABLE_OPENCSG
- OpenCSG::setOption(OpenCSG::AlgorithmSetting, Preferences::inst()->getValue("advanced/forceGoldfeather").toBool() ? OpenCSG::Goldfeather : OpenCSG::Automatic);
+ OpenCSG::setOption(OpenCSG::AlgorithmSetting, Preferences::inst()->getValue("advanced/forceGoldfeather").toBool() ?
+ OpenCSG::Goldfeather : OpenCSG::Automatic);
#endif
}
diff --git a/src/scadlexer.cpp b/src/scadlexer.cpp
new file mode 100644
index 00000000..ff774dff
--- /dev/null
+++ b/src/scadlexer.cpp
@@ -0,0 +1,38 @@
+#include "scadlexer.h"
+
+ScadLexer::ScadLexer(QObject *parent)
+ : QsciLexerCPP(parent)
+{ }
+
+ScadLexer::~ScadLexer()
+{ }
+
+const char *ScadLexer::language() const
+{
+ return "SCAD";
+}
+
+const char *ScadLexer::keywords(int set) const
+{
+
+ if (set == 1)
+ return "if else for module function intersection_for assign echo search "
+ " str let true false "; // -> Style: Keyword
+
+ if (set == 2)
+ return " abs sign acos asin atan atan2 sin cos tan floor round ceil len ln "
+ " log lookup min max pow sqrt exp rands version version_num "
+ " group difference union intersection render translate rotate scale multmatrix color "
+ " projection hull resize mirror minkowski glide subdiv child "
+ " include use dxf_dim dxf_cross "
+ " linear_extrude rotate_extrude "; // -> Style: KeywordSet2
+
+ if (set == 3)
+ return " param author "; // -> used in comments only like /*! \cube */
+
+ if (set == 4)
+ return "cube circle cylinder polygon polyhedron square sphere "
+ "surface import "; // -> Style: GlobalClass
+
+ return 0;
+}
diff --git a/src/scadlexer.h b/src/scadlexer.h
new file mode 100644
index 00000000..50e6347a
--- /dev/null
+++ b/src/scadlexer.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include
+
+#include
+#include
+
+class ScadLexer : public QsciLexerCPP
+{
+public:
+ ScadLexer(QObject *parent);
+ virtual ~ScadLexer();
+ const char *language() const;
+ const char *keywords(int set) const;
+
+private:
+ ScadLexer(const ScadLexer &);
+ ScadLexer &operator=(const ScadLexer &);
+};
diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp
new file mode 100644
index 00000000..e41b66b4
--- /dev/null
+++ b/src/scintillaeditor.cpp
@@ -0,0 +1,349 @@
+#include
+#include
+#include
+#include "scintillaeditor.h"
+#include
+#include "Preferences.h"
+
+ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent)
+{
+ scintillaLayout = new QVBoxLayout(this);
+ qsci = new QsciScintilla(this);
+
+
+ //
+ // Remapping some scintilla key binding which conflict with OpenSCAD global
+ // key bindings, as well as some minor scintilla bugs
+ //
+ QsciCommand *c;
+#ifdef Q_OS_MAC
+ // Alt-Backspace should delete left word (Alt-Delete already deletes right word)
+ c= qsci->standardCommands()->find(QsciCommand::DeleteWordLeft);
+ c->setKey(Qt::Key_Backspace | Qt::ALT);
+#endif
+ // Cmd/Ctrl-T is handled by the menu
+ c = qsci->standardCommands()->boundTo(Qt::Key_T | Qt::CTRL);
+ c->setKey(0);
+ // Cmd/Ctrl-D is handled by the menu
+ c = qsci->standardCommands()->boundTo(Qt::Key_D | Qt::CTRL);
+ c->setKey(0);
+ // Ctrl-Shift-Z should redo on all platforms
+ c= qsci->standardCommands()->find(QsciCommand::Redo);
+ c->setKey(Qt::Key_Z | Qt::CTRL | Qt::SHIFT);
+
+ scintillaLayout->setContentsMargins(0, 0, 0, 0);
+ scintillaLayout->addWidget(qsci);
+
+ qsci->setBraceMatching (QsciScintilla::SloppyBraceMatch);
+ qsci->setWrapMode(QsciScintilla::WrapCharacter);
+ qsci->setWrapVisualFlags(QsciScintilla::WrapFlagByBorder, QsciScintilla::WrapFlagNone, 0);
+ qsci->setAutoIndent(true);
+ qsci->indicatorDefine(QsciScintilla::RoundBoxIndicator, indicatorNumber);
+ qsci->markerDefine(QsciScintilla::Circle, markerNumber);
+ qsci->setUtf8(true);
+ lexer = new ScadLexer(this);
+ initLexer();
+ initMargin();
+ qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4);
+ qsci->setCaretLineVisible(true);
+ this->setHighlightScheme(Preferences::inst()->getValue("editor/syntaxhighlight").toString());
+
+ connect(qsci, SIGNAL(textChanged()), this, SIGNAL(contentsChanged()));
+ connect(qsci, SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool)));
+}
+
+void ScintillaEditor::setPlainText(const QString &text)
+{
+ qsci->setText(text);
+ setContentModified(false);
+}
+
+QString ScintillaEditor::toPlainText()
+{
+ return qsci->text();
+}
+
+void ScintillaEditor::setContentModified(bool modified)
+{
+ qsci->setModified(modified);
+}
+
+bool ScintillaEditor::isContentModified()
+{
+ return qsci->isModified();
+}
+
+void ScintillaEditor::highlightError(int error_pos)
+{
+ int line, index;
+ qsci->lineIndexFromPosition(error_pos, &line, &index);
+ qsci->fillIndicatorRange(line, index, line, index+1, indicatorNumber);
+ qsci->setIndicatorForegroundColor(QColor(255,0,0,100));
+ qsci->markerAdd(line, markerNumber);
+}
+
+void ScintillaEditor::unhighlightLastError()
+{
+ int totalLength = qsci->text().length();
+ int line, index;
+ qsci->lineIndexFromPosition(totalLength, &line, &index);
+ qsci->clearIndicatorRange(0, 0, line, index, indicatorNumber);
+ qsci->markerDeleteAll(markerNumber);
+}
+
+//Editor themes
+void ScintillaEditor::forLightBackground()
+{
+ lexer->setPaper("#fff");
+ lexer->setColor(QColor("#272822")); // -> Style: Default text
+ lexer->setColor(QColor("Green"), QsciLexerCPP::Keyword); // -> Style: Keyword
+ lexer->setColor(QColor("Green"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
+ lexer->setColor(Qt::blue, QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
+ lexer->setColor(QColor("DarkBlue"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
+ lexer->setColor(Qt::blue, QsciLexerCPP::Operator);
+ lexer->setColor(Qt::darkMagenta, QsciLexerCPP::DoubleQuotedString);
+ lexer->setColor(Qt::darkCyan, QsciLexerCPP::Comment);
+ lexer->setColor(Qt::darkCyan, QsciLexerCPP::CommentLine);
+ lexer->setColor(QColor("DarkRed"), QsciLexerCPP::Number);
+ qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
+ qsci->setCaretLineBackgroundColor(QColor("#ffe4e4"));
+ qsci->setMarginsBackgroundColor(QColor("#ccc"));
+ qsci->setMarginsForegroundColor(QColor("#111"));
+ qsci->setMatchedBraceBackgroundColor(QColor("#333"));
+ qsci->setMatchedBraceForegroundColor(QColor("#fff"));
+}
+
+void ScintillaEditor::forDarkBackground()
+{
+ lexer->setPaper(QColor("#272822"));
+ lexer->setColor(QColor(Qt::white));
+ lexer->setColor(QColor("#f12971"), QsciLexerCPP::Keyword);
+ lexer->setColor(QColor("#56dbf0"),QsciLexerCPP::KeywordSet2);
+ lexer->setColor(QColor("#ccdf32"), QsciLexerCPP::CommentDocKeyword);
+ lexer->setColor(QColor("#56d8f0"), QsciLexerCPP::GlobalClass);
+ lexer->setColor(QColor("#d8d8d8"), QsciLexerCPP::Operator);
+ lexer->setColor(QColor("#e6db74"), QsciLexerCPP::DoubleQuotedString);
+ lexer->setColor(QColor("#e6db74"), QsciLexerCPP::CommentLine);
+ lexer->setColor(QColor("#af7dff"), QsciLexerCPP::Number);
+ qsci->setCaretLineBackgroundColor(QColor(104,225,104, 127));
+ qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
+ qsci->setMarginsBackgroundColor(QColor("20,20,20,150"));
+ qsci->setMarginsForegroundColor(QColor("#fff"));
+ qsci->setCaretWidth(2);
+ qsci->setCaretForegroundColor(QColor("#ffff00"));
+}
+
+void ScintillaEditor::Monokai()
+{
+ lexer->setPaper("#272822");
+ lexer->setColor(QColor("#f8f8f2")); // -> Style: Default text
+ lexer->setColor(QColor("#66c3b3"), QsciLexerCPP::Keyword); // -> Style: Keyword
+ lexer->setColor(QColor("#79abff"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
+ lexer->setColor(QColor("#ccdf32"), QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
+ lexer->setColor(QColor("#ffffff"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
+ lexer->setColor(QColor("#d8d8d8"), QsciLexerCPP::Operator);
+ lexer->setColor(QColor("#e6db74"), QsciLexerCPP::DoubleQuotedString);
+ lexer->setColor(QColor("#75715e"), QsciLexerCPP::CommentLine);
+ lexer->setColor(QColor("#7fb347"), QsciLexerCPP::Number);
+ qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
+ qsci->setCaretLineBackgroundColor(QColor("#3e3d32"));
+ qsci->setMarginsBackgroundColor(QColor("#757575"));
+ qsci->setMarginsForegroundColor(QColor("#f8f8f2"));
+ qsci->setCaretWidth(2);
+ qsci->setCaretForegroundColor(QColor("#ffff00"));
+}
+
+void ScintillaEditor::Solarized_light()
+{
+ lexer->setPaper("#fdf6e3");
+ lexer->setColor(QColor("#657b83")); // -> Style: Default text
+ lexer->setColor(QColor("#268ad1"), QsciLexerCPP::Keyword); // -> Style: Keyword
+ lexer->setColor(QColor("#6c71c4"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
+ lexer->setColor(QColor("#b58900"), QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
+ lexer->setColor(QColor("#b58800"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
+ lexer->setColor(QColor("#859900"), QsciLexerCPP::Operator);
+ lexer->setColor(QColor("#2aa198"), QsciLexerCPP::DoubleQuotedString);
+ lexer->setColor(QColor("#b58800"), QsciLexerCPP::CommentLine);
+ lexer->setColor(QColor("#cb4b16"), QsciLexerCPP::Number);
+ qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
+ qsci->setCaretLineBackgroundColor(QColor("#eeead5"));
+ qsci->setMarginsBackgroundColor(QColor("#eee8d5"));
+ qsci->setMarginsForegroundColor(QColor("#93a1a1"));
+ qsci->setMatchedBraceBackgroundColor(QColor("#0000ff"));
+ qsci->setMatchedBraceBackgroundColor(QColor("#333"));
+ qsci->setMatchedBraceForegroundColor(QColor("#fff"));
+}
+
+void ScintillaEditor::noColor()
+{
+ lexer->setPaper(Qt::white);
+ lexer->setColor(Qt::black);
+ qsci->setMarginsBackgroundColor(QColor("#ccc"));
+ qsci->setMarginsForegroundColor(QColor("#111"));
+
+}
+
+void ScintillaEditor::setHighlightScheme(const QString &name)
+{
+ if(name == "For Light Background") {
+ forLightBackground();
+ }
+ else if(name == "For Dark Background") {
+ forDarkBackground();
+ }
+ else if(name == "Monokai") {
+ Monokai();
+ }
+ else if(name == "Solarized") {
+ Solarized_light();
+ }
+ else if(name == "Off") {
+ noColor();
+ }
+}
+
+void ScintillaEditor::insert(const QString &text)
+{
+ qsci->insert(text);
+}
+
+void ScintillaEditor::undo()
+{
+ qsci->undo();
+}
+
+void ScintillaEditor::redo()
+{
+ qsci->redo();
+}
+
+void ScintillaEditor::cut()
+{
+ qsci->cut();
+}
+
+void ScintillaEditor::copy()
+{
+ qsci->copy();
+}
+
+void ScintillaEditor::paste()
+{
+ qsci->paste();
+}
+
+void ScintillaEditor::zoomIn()
+{
+ qsci->zoomIn();
+}
+
+void ScintillaEditor::zoomOut()
+{
+ qsci->zoomOut();
+}
+
+void ScintillaEditor::initFont(const QString& fontName, uint size)
+{
+ QFont font(fontName, size);
+ font.setFixedPitch(true);
+ lexer->setFont(font);
+}
+
+void ScintillaEditor::initLexer()
+{
+ qsci->setLexer(lexer);
+}
+
+void ScintillaEditor::initMargin()
+{
+ QFontMetrics fontmetrics = QFontMetrics(qsci->font());
+ qsci->setMarginsFont(qsci->font());
+ qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
+ qsci->setMarginLineNumbers(1, true);
+
+ connect(qsci, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
+}
+
+void ScintillaEditor::onTextChanged()
+{
+ QFontMetrics fontmetrics = qsci->fontMetrics();
+ qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
+}
+
+bool ScintillaEditor::find(const QString &expr, bool findNext, bool findBackwards)
+{
+ int startline = -1, startindex = -1;
+
+ // If findNext, start from the end of the current selection
+ if (qsci->hasSelectedText()) {
+ int lineFrom, indexFrom, lineTo, indexTo;
+ qsci->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
+
+ startline = !(findBackwards xor findNext) ? std::min(lineFrom, lineTo) : std::max(lineFrom, lineTo);
+ startindex = !(findBackwards xor findNext) ? std::min(indexFrom, indexTo) : std::max(indexFrom, indexTo);
+ }
+
+ return qsci->findFirst(expr, false, false, false, true,
+ !findBackwards, startline, startindex);
+}
+
+void ScintillaEditor::replaceSelectedText(const QString &newText)
+{
+ if (qsci->selectedText() != newText) qsci->replaceSelectedText(newText);
+}
+
+void ScintillaEditor::get_range(int *lineFrom, int *lineTo)
+{
+ int indexFrom, indexTo;
+ if (qsci->hasSelectedText()) {
+ qsci->getSelection(lineFrom, &indexFrom, lineTo, &indexTo);
+ } else {
+ qsci->getCursorPosition(lineFrom, &indexFrom);
+ *lineTo = *lineFrom;
+ }
+}
+
+void ScintillaEditor::indentSelection()
+{
+ int lineFrom, lineTo;
+ get_range(&lineFrom, &lineTo);
+ for (int line = lineFrom;line <= lineTo;line++) {
+ qsci->indent(line);
+ }
+}
+
+void ScintillaEditor::unindentSelection()
+{
+ int lineFrom, lineTo;
+ get_range(&lineFrom, &lineTo);
+ for (int line = lineFrom;line <= lineTo;line++) {
+ qsci->unindent(line);
+ }
+}
+
+void ScintillaEditor::commentSelection()
+{
+ int lineFrom, lineTo;
+ get_range(&lineFrom, &lineTo);
+ for (int line = lineFrom;line <= lineTo;line++) {
+ qsci->insertAt("//", line, 0);
+ }
+}
+
+void ScintillaEditor::uncommentSelection()
+{
+ int lineFrom, lineTo;
+ get_range(&lineFrom, &lineTo);
+ for (int line = lineFrom;line <= lineTo;line++) {
+ QString lineText = qsci->text(line);
+ if (lineText.startsWith("//")) {
+ qsci->setSelection(line, 0, line, 2);
+ qsci->removeSelectedText();
+ }
+ }
+}
+
+QString ScintillaEditor::selectedText()
+{
+ return qsci->selectedText();
+}
diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h
new file mode 100644
index 00000000..14287f5b
--- /dev/null
+++ b/src/scintillaeditor.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include "editor.h"
+#include "scadlexer.h"
+
+class ScintillaEditor : public EditorInterface
+{
+ Q_OBJECT;
+public:
+ ScintillaEditor(QWidget *parent);
+ virtual ~ScintillaEditor() {}
+ QsciScintilla *qsci;
+ QString toPlainText();
+ void initMargin();
+ void initLexer();
+ void forLightBackground();
+ void forDarkBackground();
+ void Monokai();
+ void Solarized_light();
+ void noColor();
+ QString selectedText();
+ bool find(const QString &, bool findNext = false, bool findBackwards = false);
+ void replaceSelectedText(const QString&);
+
+private:
+ void get_range(int *lineFrom, int *lineTo);
+
+public slots:
+ void zoomIn();
+ void zoomOut();
+ void setPlainText(const QString&);
+ void setContentModified(bool);
+ bool isContentModified();
+ void highlightError(int);
+ void unhighlightLastError();
+ void setHighlightScheme(const QString&);
+ void indentSelection();
+ void unindentSelection();
+ void commentSelection();
+ void uncommentSelection();
+ void insert(const QString&);
+ void undo();
+ void redo();
+ void cut();
+ void copy();
+ void paste();
+ void initFont(const QString&, uint);
+
+private slots:
+ void onTextChanged();
+
+private:
+ QVBoxLayout *scintillaLayout;
+ static const int indicatorNumber = 1;
+ static const int markerNumber = 2;
+ ScadLexer *lexer;
+};