# HG changeset patch # User Jordi GutiƩrrez Hermoso # Date 1357238215 18000 # Node ID 1ca9beb2a1943b0cfd90bdb1b6c58004d41f9e98 # Parent 2b6fe094e6156e921ffa759ccffaf48c1130399e# Parent 44f30dcd87e0de84f357a12896cc618c8db600f2 maint: periodic merge of stdefault to classdef diff -r 2b6fe094e615 -r 1ca9beb2a194 .hgsub --- a/.hgsub Tue Jan 01 19:54:15 2013 -0500 +++ b/.hgsub Thu Jan 03 13:36:55 2013 -0500 @@ -1,1 +1,1 @@ -gnulib = [git]git://git.sv.gnu.org/gnulib +gnulib-hg = gnulib-hg diff -r 2b6fe094e615 -r 1ca9beb2a194 .hgsubstate --- a/.hgsubstate Tue Jan 01 19:54:15 2013 -0500 +++ b/.hgsubstate Thu Jan 03 13:36:55 2013 -0500 @@ -1,1 +1,1 @@ -e657573866e8aded3b3b1461c346cf9ad02a5148 gnulib +c960be36c9f3f690ceb43057314354e0df736416 gnulib-hg diff -r 2b6fe094e615 -r 1ca9beb2a194 .hgtags --- a/.hgtags Tue Jan 01 19:54:15 2013 -0500 +++ b/.hgtags Thu Jan 03 13:36:55 2013 -0500 @@ -69,3 +69,4 @@ 551566201318bf615b27c60ccf9368f4844008bd release-3-6-2 a95432e7309ca6fc776c02939264bb6d443f3525 release-3-6-3 2e8eb9ac43a5f8cfaf0423814a312ed47cb80485 rc-3-6-4-0 +df1aceb8f0bc6b5b5062907931cc663467f57d93 ss-3-7-1 diff -r 2b6fe094e615 -r 1ca9beb2a194 NEWS --- a/NEWS Tue Jan 01 19:54:15 2013 -0500 +++ b/NEWS Thu Jan 03 13:36:55 2013 -0500 @@ -142,10 +142,10 @@ ** Other new functions added in 3.8.0: - betaincinv dawson fminsearch rgbplot - cmpermute erfcinv iscolormap shrinkfaces - cmunique erfi lines splinefit - colorcube findfigs polyeig tetramesh + betaincinv dawson fminsearch polyeig tetramesh + cmpermute erfcinv importdata rgbplot + cmunique erfi iscolormap shrinkfaces + colorcube findfigs lines splinefit ** Deprecated functions. diff -r 2b6fe094e615 -r 1ca9beb2a194 build-aux/bootstrap_gnulib --- a/build-aux/bootstrap_gnulib Tue Jan 01 19:54:15 2013 -0500 +++ b/build-aux/bootstrap_gnulib Thu Jan 03 13:36:55 2013 -0500 @@ -205,8 +205,10 @@ # default. bootstrap_sync=false -# Use git to update gnulib sources -use_git=true +# Don't use git to update gnulib sources. We keep gnulib under a +# Mercurial subrepository instead +use_git=false +GNULIB_SRCDIR=gnulib-hg # find_tool ENVVAR NAMES... # ------------------------- diff -r 2b6fe094e615 -r 1ca9beb2a194 configure.ac --- a/configure.ac Tue Jan 01 19:54:15 2013 -0500 +++ b/configure.ac Thu Jan 03 13:36:55 2013 -0500 @@ -18,21 +18,14 @@ ### along with Octave; see the file COPYING. If not, see ### . -### Preserve CFLAGS and CXXFLAGS from the environment before doing -### anything else because we don't know which macros might call -### AC_PROG_CC or AC_PROG_CXX. - -EXTERN_CFLAGS="$CFLAGS" -EXTERN_CXXFLAGS="$CXXFLAGS" - AC_PREREQ([2.62]) -AC_INIT([GNU Octave], [3.7.0+], [http://octave.org/bugs.html], [octave]) +AC_INIT([GNU Octave], [3.7.1+], [http://octave.org/bugs.html], [octave]) dnl PACKAGE_VERSION is set by the AC_INIT VERSION arg OCTAVE_VERSION="$PACKAGE_VERSION" OCTAVE_API_VERSION_NUMBER="48" OCTAVE_API_VERSION="api-v$OCTAVE_API_VERSION_NUMBER+" -OCTAVE_RELEASE_DATE="2012-02-22" +OCTAVE_RELEASE_DATE="2013-01-02" OCTAVE_COPYRIGHT="Copyright (C) 2012 John W. Eaton and others." AC_SUBST(OCTAVE_VERSION) AC_SUBST(OCTAVE_API_VERSION_NUMBER) @@ -50,52 +43,19 @@ AM_INIT_AUTOMAKE([1.11 tar-ustar]) -OCTAVE_HOST_TYPE +OCTAVE_CANONICAL_HOST AC_DEFINE(OCTAVE_SOURCE, 1, [Define to 1 if this is Octave.]) AC_USE_SYSTEM_EXTENSIONS -### Path separator. - -sepchar=':' -AC_ARG_WITH([sepchar], - [AS_HELP_STRING([--with-sepchar=], - [use as the path separation character])]) -case $with_sepchar in - yes | "") - case $canonical_host_type in - *-*-mingw* | *-*-msdosmsvc) - sepchar=';' ;; - esac - ;; - no) - AC_MSG_ERROR([You are required to define a path separation character]) - ;; - *) - sepchar=$with_sepchar - ;; -esac -AC_SUBST(sepchar) -AC_DEFINE_UNQUOTED(SEPCHAR, ['$sepchar'], - [Define this to be the path separator for your system, as a character constant.]) -AC_DEFINE_UNQUOTED(SEPCHAR_STR, ["$sepchar"], - [Define this to be the path separator for your system, as a string.]) +### Make configure args available for other uses. + +config_opts=$ac_configure_args +AC_SUBST(config_opts) ### Set default file locations -OCTAVE_SET_DEFAULT([man1dir], '$(mandir)/man1') -OCTAVE_SET_DEFAULT([man1ext], '.1') -OCTAVE_SET_DEFAULT([doc_cache_file], '$(octetcdir)/doc-cache') -OCTAVE_SET_DEFAULT([texi_macros_file], '$(octetcdir)/macros.texi') -OCTAVE_SET_DEFAULT([infofile], '$(infodir)/octave.info') -OCTAVE_SET_DEFAULT([octincludedir], '$(includedir)/octave-$(version)/octave') -OCTAVE_SET_DEFAULT([fcnfiledir], '$(datadir)/octave/$(version)/m') -OCTAVE_SET_DEFAULT([localfcnfiledir], '$(datadir)/octave/site/m') -OCTAVE_SET_DEFAULT([localapifcnfiledir], - '$(datadir)/octave/site/$(api_version)/m') -OCTAVE_SET_DEFAULT([localverfcnfiledir], '$(datadir)/octave/$(version)/site/m') -OCTAVE_SET_DEFAULT([octetcdir], '$(datadir)/octave/$(version)/etc') OCTAVE_SET_DEFAULT([octlibdir], '$(libdir)/octave/$(version)') OCTAVE_SET_DEFAULT([archlibdir], '$(libexecdir)/octave/$(version)/exec/$(canonical_host_type)') @@ -113,16 +73,85 @@ '$(libdir)/octave/site/oct/$(api_version)/$(canonical_host_type)') OCTAVE_SET_DEFAULT([localveroctfiledir], '$(libdir)/octave/$(version)/site/oct/$(canonical_host_type)') +OCTAVE_SET_DEFAULT([octincludedir], '$(includedir)/octave-$(version)/octave') +OCTAVE_SET_DEFAULT([fcnfiledir], '$(datadir)/octave/$(version)/m') +OCTAVE_SET_DEFAULT([localfcnfiledir], '$(datadir)/octave/site/m') +OCTAVE_SET_DEFAULT([localapifcnfiledir], + '$(datadir)/octave/site/$(api_version)/m') +OCTAVE_SET_DEFAULT([localverfcnfiledir], '$(datadir)/octave/$(version)/site/m') +OCTAVE_SET_DEFAULT([octetcdir], '$(datadir)/octave/$(version)/etc') +OCTAVE_SET_DEFAULT([doc_cache_file], '$(octetcdir)/doc-cache') +OCTAVE_SET_DEFAULT([texi_macros_file], '$(octetcdir)/macros.texi') OCTAVE_SET_DEFAULT([imagedir], '$(datadir)/octave/$(version)/imagelib') - -### Find pkg-config executable (sets $PKG_CONFIG) - +OCTAVE_SET_DEFAULT([man1dir], '$(mandir)/man1') +OCTAVE_SET_DEFAULT([man1ext], '.1') +OCTAVE_SET_DEFAULT([infofile], '$(infodir)/octave.info') + +### Check for programs used in building, installing, and running Octave. + +## Programs used in configuring Octave. +## Find pkg-config executable (sets $PKG_CONFIG) PKG_PROG_PKG_CONFIG -### Make configure args available for other uses. - -config_opts=$ac_configure_args -AC_SUBST(config_opts) +## Programs used in Makefiles. +AC_PROG_AWK +OCTAVE_PROG_FIND +OCTAVE_PROG_SED +OCTAVE_PROG_PERL + +## Programs used to build parts of Octave. +OCTAVE_PROG_GPERF + +OCTAVE_PROG_FLEX +AC_SUBST([LEX_OUTPUT_ROOT], [lex.octave_]) + +OCTAVE_PROG_BISON + +OCTAVE_PROG_MAKEINFO +OCTAVE_PROG_TEXI2DVI +OCTAVE_PROG_TEXI2PDF + +## Programs used when installing Octave. +AC_PROG_LN_S +AC_PROG_MKDIR_P + +AC_PROG_INSTALL +INSTALL_SCRIPT='${INSTALL}' +AC_SUBST(INSTALL_SCRIPT) + +OCTAVE_PROG_DESKTOP_FILE_INSTALL + +## Programs used when running Octave +OCTAVE_PROG_GHOSTSCRIPT +OCTAVE_PROG_GNUPLOT +OCTAVE_PROG_PAGER +OCTAVE_PROG_PYTHON + +### Path separator. + +sepchar=':' +AC_ARG_WITH([sepchar], + [AS_HELP_STRING([--with-sepchar=], + [use as the path separation character])]) +case $with_sepchar in + yes | "") + case $host_os in + mingw* | msdosmsvc) + sepchar=';' ;; + esac + ;; + no) + AC_MSG_ERROR([You are required to define a path separation character]) + ;; + *) + sepchar=$with_sepchar + ;; +esac +AC_SUBST(sepchar) +AC_DEFINE_UNQUOTED(SEPCHAR, ['$sepchar'], + [Define this to be the path separator for your system, as a character constant.]) +AC_DEFINE_UNQUOTED(SEPCHAR_STR, ["$sepchar"], + [Define this to be the path separator for your system, as a string.]) ### Define the path to the shell on the host system. Most systems will ### ensure /bin/sh is the default shell so this can be safely ignored by @@ -276,11 +305,11 @@ ## Check for MSVC have_msvc=no -case $canonical_host_type in - *-*-msdosmsvc) +case $host_os in + msdosmsvc) have_msvc=yes ;; - *-*-mingw*) + mingw*) AC_MSG_CHECKING([for MSVC compiler]) AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ #ifndef _MSC_VER @@ -441,11 +470,11 @@ [(EXPERIMENTAL) use OpenMP SMP multi-threading])], [if test "$enableval" = yes; then USE_OPENMP=true; fi], []) if $USE_OPENMP; then - case $canonical_host_type in - *-*-mingw* | *-*-cygwin* | *-*-gnu*) + case $host_os in + mingw* | cygwin* | *-gnu*) OCTAVE_CHECK_OPENMP(-fopenmp) ;; - *-*-msdosmsvc) + msdosmsvc) ## FIXME: is this the right flag for MSVC? OCTAVE_CHECK_OPENMP(-openmp) ;; @@ -487,20 +516,12 @@ AC_ARG_VAR([BUILD_EXEEXT], [build system executable extension (used if cross compiling)]) -dnl This is bogus. We shouldn't have to explicitly add libc too! -dnl Keep this check before the check for the Fortran compiler, -dnl in case -lm is needed to compile Fortran programs. ### Look for math library. If found, this will add -lm to LIBS. -case $canonical_host_type in - *-*-linux*) - AC_CHECK_LIB(m, sin, , , -lc) - ;; - *) - AC_CHECK_LIB(m, sin) - ;; -esac +dnl Keep this check before the check for the Fortran compiler, +dnl in case -lm is needed to compile Fortran programs. +AC_CHECK_LIB(m, sin) ### Determine the Fortran compiler and how to invoke it @@ -1053,8 +1074,8 @@ FLTK_CFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --cflags` FLTK_LDFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags` - case $canonical_host_type in - *-*-mingw*) + case $host_os in + mingw*) FLTK_LDFLAGS=`echo $FLTK_LDFLAGS | sed -e 's/-mwindows//g'` ;; esac @@ -1164,8 +1185,8 @@ ## On OSX, try again with a wrapper library (without -ff2c!) if test $ax_blas_f77_func_ok = no; then - case $canonical_host_type in - *-*-darwin*) + case $host_os in + darwin*) ## test if wrapper functions help octave_blaswrap_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -DUSE_BLASWRAP" @@ -1399,9 +1420,7 @@ esac], [ENABLE_DYNAMIC_LINKING=true]) -if $STATIC_LIBS || $SHARED_LIBS; then - true -else +if ! $STATIC_LIBS && ! $SHARED_LIBS; then AC_MSG_ERROR([You can't disable building static AND shared libraries!]) fi @@ -1765,7 +1784,7 @@ ## Disable dynamic linking if capability is not present. if $dlopen_api || $shl_load_api || $loadlibrary_api || $dyld_api; then - true + : # some form of dynamic linking present else ENABLE_DYNAMIC_LINKING=false fi @@ -1795,8 +1814,8 @@ ### Check for existence of various libraries ## OS-specific test for dirent, opendir. -case $canonical_host_type in - *-*-mingw*) +case $host_os in + mingw*) if test $have_msvc = yes; then AC_CHECK_LIB([dirent], [opendir]) LIBS="$LIBS -ladvapi32 -lgdi32 -lws2_32 -luser32 -lkernel32" @@ -1805,7 +1824,7 @@ fi LIBS="$LIBS -lgdi32 -lws2_32 -luser32 -lkernel32" ;; - *-*-msdosmsvc*) + msdosmsvc) AC_CHECK_LIB([dirent], [opendir]) LIBS="$LIBS -ladvapi32 -lgdi32 -lws2_32 -luser32 -lkernel32" ;; @@ -1941,7 +1960,8 @@ AC_CHECK_FUNCS([endgrent endpwent execvp expm1 expm1f fork]) AC_CHECK_FUNCS([getegid geteuid getgid getgrent getgrgid getgrnam]) AC_CHECK_FUNCS([getpgrp getpid getppid getpwent getpwuid getuid]) -AC_CHECK_FUNCS([kill lgamma lgammaf lgamma_r lgammaf_r]) +AC_CHECK_FUNCS([isascii kill]) +AC_CHECK_FUNCS([lgamma lgammaf lgamma_r lgammaf_r]) AC_CHECK_FUNCS([log1p log1pf pipe]) AC_CHECK_FUNCS([realpath resolvepath roundl]) AC_CHECK_FUNCS([select setgrent setpwent siglongjmp strsignal]) @@ -1982,21 +2002,11 @@ OCTAVE_CHECK_FUNC_CMATH(isinf) OCTAVE_CHECK_FUNC_CMATH(isfinite) -dnl Would like to get rid of this crap, and just have -dnl -dnl AC_CHECK_FUNCS([finite isnan isinf]) -dnl -dnl instead, but that used to fail on some systems... -dnl -dnl Also just using AC_CHECK_FUNCS doesn't seem to work to find isinf -dnl and isnan on Linux systems, so we use AC_CHECK_FUNC, and if that -dnl fails, we try again by including math.h and invoking the function -dnl with an argument. - -### I am told that Inf and NaN don't work on m68k HP sytems. +## Check for Inf and NaN functions case $canonical_host_type in m68k-hp-hpux*) + ## I am told that Inf and NaN don't work on m68k HP sytems. ;; *) AC_CHECK_FUNCS([finite isnan isinf signbit]) @@ -2011,9 +2021,49 @@ AC_CHECK_FUNCS([acosh acoshf asinh asinhf atanh atanhf cbrt cbrtf]) AC_CHECK_FUNCS([erf erff erfc erfcf exp2f hypotf _hypotf log2 log2f]) +## Check for math defines such as M_LN2 in math.h +AC_CACHE_CHECK([for MATH DEFINES in math.h], + [octave_cv_header_math_defines], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], [[ + double x = M_LN2;]])], + octave_cv_header_math_defines=yes, + octave_cv_header_math_defines=no) + ]) + +if test $octave_cv_header_math_defines = no; then + ## Check again and try defining _USE_MATH_DEFINES + AC_CACHE_CHECK([whether _USE_MATH_DEFINES needs to be defined], + [octave_cv_header__use_math_defines], + [save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -D_USE_MATH_DEFINES" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], [[ + double x = M_LN2;]])], + octave_cv_header__use_math_defines=yes, + octave_cv_header__use_math_defines=no) + CPPFLAGS="$save_CPPFLAGS" + ]) + if test $octave_cv_header__use_math_defines = yes; then + octave_cv_header_math_defines=yes + AC_DEFINE(_USE_MATH_DEFINES, 1, + [Define to 1 if _USE_MATH_DEFINES is required to get math constants like M_LN2.]) + CPPFLAGS="$CPPFLAGS -D_USE_MATH_DEFINES" + fi +fi + +if test $octave_cv_header_math_defines = yes; then + AC_DEFINE(HAVE_MATH_DEFINES, 1, + [Define to 1 if defines such as M_PI are available in math.h]) +else + AC_MSG_ERROR([MATH DEFINES in math.h such as M_PI are required to build Octave]) +fi + ## Windows-specific tests for extra #defines -case $canonical_host_type in - *-*-msdosmsvc | *-*-mingw*) +case $host_os in + msdosmsvc | mingw*) AC_MSG_CHECKING([for required _WIN32_WINNT]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include @@ -2025,21 +2075,12 @@ [AC_DEFINE(_WIN32_WINNT, 0x0403, [Define to 0x0403 to access InitializeCriticalSectionAndSpinCount.]) AC_MSG_RESULT([0x0403])]) - AC_MSG_CHECKING([whether _USE_MATH_DEFINES needs to be defined]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - ]], [[ - int x = M_LN2;]])], - [AC_MSG_RESULT([no])], - [AC_DEFINE(_USE_MATH_DEFINES, 1, - [Define to 1 if your system needs to define math constants like M_LN2.]) - AC_MSG_RESULT([yes])]) ;; esac ## Windows-specific use of functions -case $canonical_host_type in - *-*-mingw* | *-*-msdosmsvc*) +case $host_os in + msdosmsvc | mingw*) AC_CHECK_FUNCS([setvbuf], [], [AC_MSG_ERROR([Missing function required to build Octave])]) ;; @@ -2047,8 +2088,8 @@ ## Cygwin kluge for getrusage. AC_CHECK_FUNCS([getrusage]) -case $canonical_host_type in - *-*-cygwin*) +case $host_os in + cygwin*) AC_DEFINE(RUSAGE_TIMES_ONLY, 1, [Define to 1 if your struct rusage only has time information.]) ;; @@ -2091,38 +2132,6 @@ #endif ]]) -### Checks for other programs used in building, testing, installing, and -### running Octave. - -AC_PROG_AWK -OCTAVE_PROG_FIND -OCTAVE_PROG_SED -OCTAVE_PROG_PERL -OCTAVE_PROG_PYTHON - -OCTAVE_PROG_FLEX -AC_SUBST([LEX_OUTPUT_ROOT], [lex.octave_]) - -OCTAVE_PROG_BISON - -AC_PROG_LN_S -AC_PROG_MKDIR_P - -AC_PROG_INSTALL -INSTALL_SCRIPT='${INSTALL}' -AC_SUBST(INSTALL_SCRIPT) - -OCTAVE_PROG_DESKTOP_FILE_INSTALL - -OCTAVE_PROG_GNUPLOT -OCTAVE_PROG_PAGER -OCTAVE_PROG_GPERF - -OCTAVE_PROG_GHOSTSCRIPT -OCTAVE_PROG_MAKEINFO -OCTAVE_PROG_TEXI2DVI -OCTAVE_PROG_TEXI2PDF - ### Need to disable building documentation if gnuplot was not found, ### unless it was already disabled previously. @@ -2257,21 +2266,22 @@ if test -z "$JAVA_HOME"; then ## Find JAVA_HOME for JRE by running java and querying properties. - JAVA_TMP_HOME="`\"$JAVA\" -classpath ${srcdir}/build-aux OctJavaQry JAVA_HOME`" + JAVA_TMP_HOME=`"$JAVA" -classpath ${srcdir}/build-aux OctJavaQry JAVA_HOME` ## Strip directory back to top-level installation dir (JAVA_HOME for JDK). - JAVA_HOME="`echo $JAVA_TMP_HOME | sed -e 's|[[/\\]]bin[[/\\]]\?$||' | sed -e 's|[[/\\]]jre[[/\\]]\?$||'`" + JAVA_HOME=`echo $JAVA_TMP_HOME | sed -e 's|[[/\\]]bin[[/\\]]\?$||' | sed -e 's|[[/\\]]jre[[/\\]]\?$||'` fi - case $canonical_host_type in - *-mingw* | *-msdosmsvc*) - ## Under Win32 platform, we want JAVA_HOME to be in MSYS format, that is without - ## colon and backslashes, as it is also used as path separator. Use quoted paths - ## as Java may be installed in a path with whitespaces (e.g. C:\Program Files\Java\...). + case $host_os in + mingw* | msdosmsvc) + ## Under Win32 platform, we want JAVA_HOME to be in MSYS format, that is + ## without colon and backslashes, as it is also used as path separator. + ## Use quoted paths as Java may be installed in a path with whitespaces + ## (e.g. C:\Program Files\Java\...). if test -n "$JAVA_HOME"; then - JAVA_HOME="`cd \"$JAVA_HOME\" && pwd`" - ## Maybe this will be useful in the future, as native Java won't probably - ## understand MSYS paths. - JAVA_HOME_NATIVE="`cd \"$JAVA_HOME\" && pwd -W`" + JAVA_HOME=`cd "$JAVA_HOME" && pwd` + ## Maybe this will be useful in the future, as native Java won't + ## understand MSYS paths. + JAVA_HOME_NATIVE=`cd "$JAVA_HOME" && pwd -W` fi ;; *) @@ -2307,19 +2317,19 @@ break fi - ## At this point Win32/MSVC systems have enough configuration data. We assume - ## that all appropriate variables (e.g. INCLUDE and LIB) have already the required - ## paths to compile and link against JDK. - case $canonical_host_type in - *-msdosmsvc*) + ## At this point Win32/MSVC systems have enough configuration data. We + ## assume that all appropriate variables (e.g. INCLUDE and LIB) already have + ## the required paths to compile and link against JDK. + case $host_os in + msdosmsvc) build_java=true JAVA_LIBS=-ladvapi32 AC_DEFINE(HAVE_JAVA, 1, [Define to 1 if Java is available and is at least version 1.5]) break ;; - *-mingw*) - if test "$have_msvc" = "yes"; then + mingw*) + if test $have_msvc = yes; then build_java=true JAVA_LIBS=-ladvapi32 AC_DEFINE(HAVE_JAVA, 1, @@ -2330,11 +2340,11 @@ esac ## Determine which library file name to search for. - case $canonical_host_type in - *-darwin*) + case $host_os in + darwin*) jvmlib=libjvm.dylib ;; - *-mingw* | *-cygwin*) + mingw* | cygwin*) jvmlib=jvm.dll ;; *) @@ -2404,8 +2414,8 @@ AC_MSG_CHECKING([for include file ]) ## Java and JVM found. Set up flags. - case $canonical_host_type in - *-darwin*) + case $host_os in + darwin*) ## Sneak the -framework flag into mkoctfile via LFLAGS LFLAGS="$LFLAGS -framework JavaVM" ## According to: http://developer.apple.com/unix/crossplatform.html @@ -2418,7 +2428,7 @@ fi JAVA_LIBS="-framework JavaVM" ;; - *-mingw* | *-cygwin*) + mingw* | cygwin*) if test -n "$JAVA_CPPFLAGS"; then JAVA_CPPFLAGS="-I${JAVA_CPPFLAGS}/include -I${JAVA_CPPFLAGS}/include/win32" else @@ -2436,11 +2446,11 @@ esac ## Verify jni.h include file exists. - JNI_PATH=`echo $JAVA_CPPFLAGS | sed -e 's/-I//g'` + JNI_PATH=`echo $JAVA_CPPFLAGS | sed -e 's/-I//g'` have_jni=false - for dir in $JNI_PATH; do - if test -f "${dir}/jni.h"; then have_jni=true; break; fi - done + for dir in $JNI_PATH; do + if test -f "${dir}/jni.h"; then have_jni=true; break; fi + done if test $have_jni = true; then AC_MSG_RESULT([$dir]) else @@ -2471,93 +2481,112 @@ QT_LDFLAGS= QT_LIBS= win32_terminal=no -build_gui=true +build_gui=yes GUIDIR=libgui AC_ARG_ENABLE([gui], [AS_HELP_STRING([--disable-gui], [don't build the GUI])], - [if test "$enableval" = no; then build_gui=false; fi], []) - -if test $build_gui = true; then + [if test "$enableval" = no; then build_gui=no; fi], []) + +if test $build_gui = yes; then ## Check for Qt libraries PKG_CHECK_MODULES(QT, [QtCore, QtGui, QtNetwork], [], - [AC_MSG_ERROR([Qt libraries are required to build the GUI])]) - - ## Retrieve Qt compilation and linker flags - QT_CPPFLAGS="`$PKG_CONFIG --cflags-only-I QtCore QtGui QtNetwork`" - QT_LDFLAGS="`$PKG_CONFIG --libs-only-L QtCore QtGui QtNetwork`" - QT_LIBS="`$PKG_CONFIG --libs-only-l QtCore QtGui QtNetwork`" - - ## Check for Qt4 - if ! `$PKG_CONFIG --atleast-version=4.0.0 QtCore`; then - AC_MSG_ERROR([Qt >= 4.0.0 is required to build the GUI]) + [AC_MSG_WARN([Qt libraries not found -- disabling GUI]) + build_gui=no]) + + if test $build_gui = yes; then + ## Retrieve Qt compilation and linker flags + QT_CPPFLAGS="`$PKG_CONFIG --cflags-only-I QtCore QtGui QtNetwork`" + QT_LDFLAGS="`$PKG_CONFIG --libs-only-L QtCore QtGui QtNetwork`" + QT_LIBS="`$PKG_CONFIG --libs-only-l QtCore QtGui QtNetwork`" + + ## Check for Qt4 + if ! `$PKG_CONFIG --atleast-version=4.0.0 QtCore`; then + AC_MSG_WARN([Qt >= 4.0.0 not found -- disabling GUI]) + build_gui=no + fi + fi + + if test $build_gui = yes; then + AC_CHECK_PROGS(MOC, [moc-qt5 moc-qt4 moc]) + AC_CHECK_PROGS(UIC, [uic-qt5 uic-qt4 uic]) + AC_CHECK_PROGS(RCC, [rcc]) + if test -n "$MOC" && test -n "$UIC" && test -n "$RCC"; then + AC_DEFINE(HAVE_QT, 1, + [Define to 1 if Qt is available (libraries, developer header files, utility programs (moc, uic, and rcc))]) + else + AC_MSG_WARN([Qt utility programs moc, uic, and rcc not found -- disabling GUI]) + build_gui=no + fi + fi + + if test $build_gui = yes; then + OCTAVE_CHECK_FUNC_SETPLACEHOLDERTEXT fi - AC_CHECK_PROGS(MOC, [moc-qt5 moc-qt4 moc]) - AC_CHECK_PROGS(UIC, [uic-qt5 uic-qt4 uic]) - AC_CHECK_PROGS(RCC, [rcc]) - if test -z "$MOC" || test -z "$UIC" || test -z "$RCC"; then - AC_MSG_ERROR([Qt utility programs moc, uic, and rcc are required to build the GUI]) - fi - - AC_DEFINE(HAVE_QT, 1, - [Define to 1 if Qt is available (libraries, developer header files, utility programs (moc, uic, and rcc))]) - - ## Check for Qscintilla library which is used in the GUI editor. - AC_CACHE_CHECK([whether Qscintilla library is installed], - [octave_cv_lib_qscintilla], - [save_CPPFLAGS="$CPPFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - CPPFLAGS="$QT_CPPFLAGS $CPPFLAGS" - LDFLAGS="$QT_LDFLAGS $LDFLAGS" - LIBS="$QT_LIBS -lqscintilla2" - AC_LANG_PUSH(C++) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - ]], [[ - QsciLexerSQL sqlLexer(0); - ]])], - octave_cv_lib_qscintilla=yes, - octave_cv_lib_qscintilla=no) - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - AC_LANG_POP([C++]) - ]) - if test $octave_cv_lib_qscintilla = no; then - AC_MSG_ERROR([Qscintilla library is required to build the GUI]) + if test $build_gui = yes; then + ## Check for Qscintilla library which is used in the GUI editor. + AC_CACHE_CHECK([whether Qscintilla library is installed], + [octave_cv_lib_qscintilla], + [save_CPPFLAGS="$CPPFLAGS" + save_LDFLAGS="$LDFLAGS" + save_LIBS="$LIBS" + CPPFLAGS="$QT_CPPFLAGS $CPPFLAGS" + LDFLAGS="$QT_LDFLAGS $LDFLAGS" + LIBS="$QT_LIBS -lqscintilla2" + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], [[ + QsciLexerSQL sqlLexer(0); + ]])], + octave_cv_lib_qscintilla=yes, + octave_cv_lib_qscintilla=no) + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + AC_LANG_POP([C++]) + ]) + if test $octave_cv_lib_qscintilla = no; then + AC_MSG_WARN([Qscintilla library not found -- disabling built-in GUI editor]) + else + ## Let's assume Qscintilla library is at the same location as + ## other regular Qt libraries. + QT_LIBS="$QT_LIBS -lqscintilla2" + OCTAVE_CHECK_FUNC_FINDFIRST_MODERN + AC_DEFINE(HAVE_QSCINTILLA, 1, + [Define to 1 if the QScintilla library and header files are available]) + fi + + AC_CHECK_FUNCS([setlocale], [], + [AC_MSG_WARN([setlocale not found -- disabling GUI]) + build_gui=no]) + + if test $build_gui = yes; then + case $host_os in + mingw* | msdosmsvc*) + AC_CHECK_FUNCS([setvbuf], [win32_terminal=yes], + [AC_MSG_WARN([setvbuf not found -- disabling GUI]) + build_gui=no]) + ;; + *) + AC_CHECK_HEADERS([pty.h libutil.h util.h]) + AC_SEARCH_LIBS([openpty], [util], + [AC_DEFINE(HAVE_OPENPTY, [], [Define whether openpty exists])]) + AC_CHECK_FUNCS([chmod chown ftruncate mmap munmap], [], + [AC_MSG_ERROR([At least one of chmod, chown, ftruncate, mmap, and munmap not found -- disabling GUI]) + build_gui=no]) + ;; + esac + fi fi - ## Let's assume Qscintilla library is at the same location as - ## other regular Qt libraries. - QT_LIBS="$QT_LIBS -lqscintilla2" - - ## Check for Qt functions which have changed their API over time - OCTAVE_CHECK_FUNC_FINDFIRST_MODERN - OCTAVE_CHECK_FUNC_SETPLACEHOLDERTEXT - - AC_CHECK_FUNCS([setlocale], [], - [AC_MSG_ERROR([Missing function required to build GUI])]) - - case $canonical_host_type in - *-*-mingw* | *-*-msdosmsvc*) - win32_terminal=yes - AC_CHECK_FUNCS([setvbuf], [], - [AC_MSG_ERROR([Missing function required to build GUI])]) - ;; - *) - AC_CHECK_HEADERS([pty.h libutil.h util.h]) - AC_SEARCH_LIBS([openpty], [util], - [AC_DEFINE(HAVE_OPENPTY, [], [Define whether openpty exists])]) - AC_CHECK_FUNCS([chmod chown ftruncate mmap munmap], [], - [AC_MSG_ERROR([Missing function required to build GUI])]) - ;; - esac -else +fi + +if test $build_gui = no; then ## GUI disabled. Eliminate building GUIDIR directory GUIDIR= fi -AM_CONDITIONAL([AMCOND_BUILD_GUI], [test $build_gui = true]) +AM_CONDITIONAL([AMCOND_BUILD_GUI], [test $build_gui = yes]) AM_CONDITIONAL([WIN32_TERMINAL], [test $win32_terminal = yes]) AC_SUBST(QT_CPPFLAGS) AC_SUBST(QT_LDFLAGS) diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp --- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp Thu Jan 03 13:36:55 2013 -0500 @@ -26,7 +26,7 @@ QUnixTerminalImpl::QUnixTerminalImpl(QWidget *parent) : QTerminalInterface(parent) { - setMinimumSize(600, 400); + setMinimumSize(300, 200); initialize(); } diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/m-editor/file-editor-interface.h --- a/libgui/src/m-editor/file-editor-interface.h Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/m-editor/file-editor-interface.h Thu Jan 03 13:36:55 2013 -0500 @@ -27,20 +27,15 @@ #include #include -class QTerminal; -class main_window; - class file_editor_interface : public QDockWidget { Q_OBJECT public: - file_editor_interface (QTerminal *terminal, main_window *mainWindow) - : QDockWidget ((QWidget*)mainWindow) // QDockWidget constructor is explicit, hence the cast. + file_editor_interface (QWidget *p) + : QDockWidget (p) { setObjectName ("FileEditor"); - _terminal = terminal; - _main_window = mainWindow; connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT (handle_visibility_changed (bool))); @@ -57,15 +52,12 @@ public slots: virtual void request_new_file () = 0; virtual void request_open_file () = 0; - virtual void request_open_file (const QString& fileName, bool silent = false) = 0; + virtual void request_open_file (const QString& fileName) = 0; signals: void active_changed (bool active); protected: - QTerminal* _terminal; - main_window* _main_window; - void closeEvent (QCloseEvent *e) { emit active_changed (false); diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/m-editor/file-editor-tab.cc --- a/libgui/src/m-editor/file-editor-tab.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/m-editor/file-editor-tab.cc Thu Jan 03 13:36:55 2013 -0500 @@ -24,6 +24,8 @@ #include #endif +#ifdef HAVE_QSCINTILLA + #include // Not available in the Debian repos yet! // #include @@ -42,19 +44,26 @@ #include "file-editor-tab.h" #include "file-editor.h" -#include "find-dialog.h" #include "octave-link.h" #include "debug.h" #include "oct-env.h" -file_editor_tab::file_editor_tab(file_editor *fileEditor) - : QWidget ((QWidget*)fileEditor) +// Make parent null for the file editor tab so that warning +// WindowModal messages don't affect grandparents. +file_editor_tab::file_editor_tab (QString directory) { - _file_editor = fileEditor; - _file_name = ""; + // Make sure there is a slash at the end of the directory name + // for identification when saved later. + if (directory.count () && directory.at (directory.count () - 1) != '/') + directory.append ("/"); + _file_name = directory; _edit_area = new QsciScintilla (this); + // Leave the find dialog box out of memory until requested. + _find_dialog = 0; + _find_dialog_is_visible = false; + // symbols _edit_area->setMarginType (1, QsciScintilla::SymbolMargin); _edit_area->setMarginSensitivity (1, true); @@ -106,57 +115,62 @@ connect (&_file_system_watcher, SIGNAL (fileChanged (QString)), this, SLOT (file_has_changed (QString))); - _file_name = ""; - notice_settings (); } -bool -file_editor_tab::copy_available () +file_editor_tab::~file_editor_tab () { - return _copy_available; + // Destroy items attached to _edit_area. + QsciLexer *lexer = _edit_area->lexer (); + if (lexer) + { + delete lexer; + _edit_area->setLexer(0); + } + if (_find_dialog) + { + delete _find_dialog; + _find_dialog = 0; + } + + // Destroy _edit_area. + delete _edit_area; } void file_editor_tab::closeEvent (QCloseEvent *e) { - if (_file_editor->get_main_window ()->is_closing ()) + // ignore close event if file is not saved and user cancels + // closing this window + if (check_file_modified ("Close File", + QMessageBox::Cancel) == QMessageBox::Cancel) { - // close whole application: save file or not if modified - check_file_modified ("Closing Octave", 0); // no cancel possible - e->accept (); + e->ignore (); } else { - // ignore close event if file is not saved and user cancels - // closing this window - if (check_file_modified ("Close File", - QMessageBox::Cancel) == QMessageBox::Cancel) - { - e->ignore (); - } - else - { - e->accept(); - } + e->accept(); } } void file_editor_tab::set_file_name (const QString& fileName) { - if (fileName != UNNAMED_FILE) - { - // update tracked file if wie really hae a file on disk - QStringList trackedFiles = _file_system_watcher.files (); - if (!trackedFiles.isEmpty ()) - _file_system_watcher.removePath (_file_name); - _file_system_watcher.addPath (fileName); - } + // update tracked file if we really have a file on disk + QStringList trackedFiles = _file_system_watcher.files (); + if (!trackedFiles.isEmpty ()) + _file_system_watcher.removePath (_file_name); + if (!fileName.isEmpty ()) + _file_system_watcher.addPath (fileName); _file_name = fileName; // update lexer after _file_name change update_lexer (); + + // update the file editor with current editing directory + emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name)); + // add the new file to the mru list + emit mru_add_file (QDir::cleanPath (_file_name)); } void @@ -191,7 +205,7 @@ void file_editor_tab::update_lexer () { - QsciLexer *lexer = _edit_area->lexer (); + QsciLexer *lexer = _edit_area->lexer (); delete lexer; if (_file_name.endsWith (".m") || _file_name.endsWith (".M")) @@ -246,151 +260,114 @@ } void -file_editor_tab::request_add_breakpoint (int line) +file_editor_tab::undo (const QWidget* ID) { - QFileInfo file_info (_file_name); - QString path = file_info.absolutePath (); - QString function_name = file_info.fileName (); + if (ID != this) + return; + + _edit_area->undo (); +} + +void +file_editor_tab::redo (const QWidget* ID) +{ + if (ID != this) + return; + + _edit_area->redo (); +} - // We have to cut off the suffix, because octave appends it. - function_name.chop (file_info.suffix ().length () + 1); +void +file_editor_tab::copy (const QWidget* ID) +{ + if (ID != this) + return; + + _edit_area->copy (); +} - bp_info info (path, function_name, line); +void +file_editor_tab::cut (const QWidget* ID) +{ + if (ID != this) + return; - octave_link::post_event - (this, &file_editor_tab::add_breakpoint_callback, info); + _edit_area->cut (); +} + +void +file_editor_tab::paste (const QWidget* ID) +{ + if (ID != this) + return; + + _edit_area->paste (); } void -file_editor_tab::request_remove_breakpoint (int line) +file_editor_tab::save_file (const QWidget* ID) +{ + if (ID != this) + return; + + save_file (_file_name); +} +void + +file_editor_tab::save_file (const QWidget* ID, const QString& fileName, bool remove_on_success) +{ + if (ID != this) + return; + + save_file (fileName, remove_on_success); +} + +void +file_editor_tab::save_file_as (const QWidget* ID) { + if (ID != this) + return; + + save_file_as (); +} + +void +file_editor_tab::run_file_callback (void) +{ + // Maybe someday we will do something here? +} + +void +file_editor_tab::run_file (const QWidget* ID) +{ + if (ID != this) + return; + + if (_edit_area->isModified ()) + save_file (_file_name); + QFileInfo file_info (_file_name); QString path = file_info.absolutePath (); + QString current_path + = QString::fromStdString (octave_link::last_working_directory ()); QString function_name = file_info.fileName (); // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - - bp_info info (path, function_name, line); - - octave_link::post_event - (this, &file_editor_tab::remove_breakpoint_callback, info); -} - -void -file_editor_tab::comment_selected_text () -{ - do_comment_selected_text (true); -} - -void -file_editor_tab::uncomment_selected_text () -{ - do_comment_selected_text (false); -} - -void -file_editor_tab::do_comment_selected_text (bool comment) -{ - if ( _edit_area->hasSelectedText() ) - { - int lineFrom, lineTo, colFrom, colTo, i; - _edit_area->getSelection (&lineFrom,&colFrom,&lineTo,&colTo); - if ( colTo == 0 ) // the beginning of last line is not selected - lineTo--; // stop at line above - _edit_area->beginUndoAction (); - for ( i=lineFrom; i<=lineTo; i++ ) - { - if ( comment ) - _edit_area->insertAt("%",i,0); - else - { - QString line(_edit_area->text(i)); - if ( line.startsWith("%") ) - { - _edit_area->setSelection(i,0,i,1); - _edit_area->removeSelectedText(); - } - } - } - _edit_area->endUndoAction (); - } -} - -void -file_editor_tab::find () -{ - find_dialog dialog (_edit_area); - dialog.exec (); + emit process_octave_code (QString ("cd \'%1\'\n%2\n") + .arg(path).arg (function_name)); + + // TODO: Sending a run event crashes for long scripts. Find out why. + // octave_link::post_event + // (this, &file_editor_tab::run_file_callback, _file_name.toStdString ())); } void -file_editor_tab::update_window_title (bool modified) -{ - QString title(_file_name); - if ( !_long_title ) - { - QFileInfo file(_file_name); - title = file.fileName(); - } - - if ( modified ) - { - emit file_name_changed (title.prepend("* ")); - } - else - emit file_name_changed (title); -} - -void -file_editor_tab::handle_copy_available(bool enableCopy) -{ - _copy_available = enableCopy; - emit editor_state_changed (); -} - -int -file_editor_tab::check_file_modified (const QString& msg, int cancelButton) +file_editor_tab::toggle_bookmark (const QWidget* ID) { - int decision = QMessageBox::Yes; - if (_edit_area->isModified ()) - { - // file is modified but not saved, ask user what to do - decision = QMessageBox::warning (this, - msg, - tr ("The file %1\n" - "has been modified. Do you want to save the changes?"). - arg (_file_name), - QMessageBox::Save, - QMessageBox::Discard, cancelButton ); - if (decision == QMessageBox::Save) - { - save_file (); - if (_edit_area->isModified ()) - { - // If the user attempted to save the file, but it's still - // modified, then probably something went wrong, so return - // cancel for cancel this operation or try to save files - // as if cancel not possible - if ( cancelButton ) - return (QMessageBox::Cancel); - else - save_file_as (); - } - } - } - return (decision); -} + if (ID != this) + return; -void -file_editor_tab::remove_bookmark () -{ - _edit_area->markerDeleteAll (bookmark); -} - -void -file_editor_tab::toggle_bookmark () -{ int line, cur; _edit_area->getCursorPosition (&line,&cur); if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) @@ -400,8 +377,11 @@ } void -file_editor_tab::next_bookmark() +file_editor_tab::next_bookmark (const QWidget* ID) { + if (ID != this) + return; + int line, cur, nextline; _edit_area->getCursorPosition (&line, &cur); if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) @@ -411,8 +391,11 @@ } void -file_editor_tab::previous_bookmark () +file_editor_tab::previous_bookmark (const QWidget* ID) { + if (ID != this) + return; + int line, cur, prevline; _edit_area->getCursorPosition (&line, &cur); if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) @@ -422,362 +405,12 @@ } void -file_editor_tab::remove_all_breakpoints () -{ - QFileInfo file_info (_file_name); - QString path = file_info.absolutePath (); - QString function_name = file_info.fileName (); - - // We have to cut off the suffix, because octave appends it. - function_name.chop (file_info.suffix ().length () + 1); - - bp_info info (path, function_name, 0); - - octave_link::post_event - (this, &file_editor_tab::remove_all_breakpoints_callback, info); -} - -void -file_editor_tab::toggle_breakpoint () -{ - int line, cur; - _edit_area->getCursorPosition (&line, &cur); - if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) - request_remove_breakpoint (line); - else - request_add_breakpoint (line); -} - -void -file_editor_tab::next_breakpoint () -{ - int line, cur, nextline; - _edit_area->getCursorPosition (&line, &cur); - if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) - line++; // we have a breakpoint here, so start search from next line - nextline = _edit_area->markerFindNext (line, (1 << breakpoint)); - _edit_area->setCursorPosition (nextline, 0); -} - -void -file_editor_tab::previous_breakpoint () -{ - int line, cur, prevline; - _edit_area->getCursorPosition (&line, &cur); - if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) - line--; // we have a breakpoint here, so start search from prev line - prevline = _edit_area->markerFindPrevious (line, (1 << breakpoint)); - _edit_area->setCursorPosition (prevline, 0); -} - -void -file_editor_tab::cut () -{ - _edit_area->cut (); -} - -void -file_editor_tab::copy () -{ - _edit_area->copy (); -} - -void -file_editor_tab::paste () -{ - _edit_area->paste (); -} - -void -file_editor_tab::undo () -{ - _edit_area->undo (); -} - -void -file_editor_tab::redo () -{ - _edit_area->redo (); -} - -void -file_editor_tab::set_debugger_position (int line) +file_editor_tab::remove_bookmark (const QWidget* ID) { - _edit_area->markerDeleteAll (debugger_position); - if (line > 0) - { - _edit_area->markerAdd (line, debugger_position); - } -} - -void -file_editor_tab::set_modified (bool modified) -{ - _edit_area->setModified (modified); -} - -bool -file_editor_tab::open_file (const QString& dir) -{ - QString openFileName; - QFileDialog fileDialog(this); - fileDialog.setNameFilter(SAVE_FILE_FILTER); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setDirectory(dir); - if (fileDialog.exec () == QDialog::Accepted) - { - openFileName = fileDialog.selectedFiles().at(0); - if (openFileName.isEmpty ()) - return false; - - return load_file(openFileName); - } - else - { - return false; - } -} - -bool -file_editor_tab::load_file(const QString& fileName, bool silent) -{ - if (!_file_editor->isVisible ()) - { - _file_editor->show (); - } - - QFile file (fileName); - if (!file.open (QFile::ReadOnly)) - { - if (silent==false) - QMessageBox::warning (this, tr ("Octave Editor"), - tr ("Could not open file %1 for read:\n%2.").arg (fileName). - arg (file.errorString ())); - return false; - } - - QTextStream in (&file); - QApplication::setOverrideCursor (Qt::WaitCursor); - _edit_area->setText (in.readAll ()); - QApplication::restoreOverrideCursor (); - - set_file_name (fileName); - update_window_title (false); // window title (no modification) - _edit_area->setModified (false); // loaded file is not modified yet - - return true; -} - -void -file_editor_tab::new_file () -{ - if (!_file_editor->isVisible ()) - { - _file_editor->show (); - } - - set_file_name (UNNAMED_FILE); - update_window_title (false); // window title (no modification) - _edit_area->setText (""); - _edit_area->setModified (false); // new file is not modified yet -} - -bool file_editor_tab::save_file() -{ - return save_file (_file_name); -} - -bool -file_editor_tab::save_file (const QString& saveFileName) -{ - // it is a new file with the name "" -> call saveFielAs - if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) - { - return save_file_as(); - } + if (ID != this) + return; - // remove the file to save from the tracker since we will change it on disk now - QStringList watched_files = _file_system_watcher.files(); - if (!watched_files.isEmpty ()) - _file_system_watcher.removePath(saveFileName); - - // open the file for writing - QFile file (saveFileName); - if (!file.open (QFile::WriteOnly)) - { - QMessageBox::warning (this, tr ("Octave Editor"), - tr ("Could not open file %1 for write:\n%2."). - arg (saveFileName).arg (file.errorString ())); - return false; - } - - // save the contents into the file - QTextStream out (&file); - QApplication::setOverrideCursor (Qt::WaitCursor); - out << _edit_area->text (); - QApplication::restoreOverrideCursor (); - file.close(); - - // save file name after closing file otherwise tracker will notice file change - set_file_name (saveFileName); - // set the window title to actual file name (not modified) - update_window_title (false); - // files is save -> not modified - _edit_area->setModified (false); - - return true; -} - -bool -file_editor_tab::save_file_as () -{ - QString saveFileName(_file_name); - QFileDialog fileDialog(this); - if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) - { - QString directory = QString::fromStdString - (octave_link::last_working_directory ()); - - if (directory.isEmpty ()) - { - directory = QDir::homePath (); - } - - fileDialog.setDirectory (directory); - } - else - { - fileDialog.selectFile (saveFileName); - } - fileDialog.setNameFilter (SAVE_FILE_FILTER); - fileDialog.setDefaultSuffix ("m"); - fileDialog.setAcceptMode (QFileDialog::AcceptSave); - fileDialog.setViewMode (QFileDialog::Detail); - - if (fileDialog.exec ()) - { - saveFileName = fileDialog.selectedFiles ().at (0); - if (saveFileName.isEmpty ()) - return false; - - return save_file (saveFileName); - } - - return false; -} - -void -file_editor_tab::run_file () -{ - if (_edit_area->isModified ()) - save_file(_file_name); - - QFileInfo file_info (_file_name); - QString path = file_info.absolutePath (); - QString current_path - = QString::fromStdString (octave_link::last_working_directory ()); - QString function_name = file_info.fileName (); - - // We have to cut off the suffix, because octave appends it. - function_name.chop (file_info.suffix ().length () + 1); - _file_editor->terminal ()->sendText (QString ("cd \'%1\'\n%2\n") - .arg(path).arg (function_name)); - // TODO: Sending a run event crashes for long scripts. Find out why. - // octave_link::post_event - // (this, &file_editor_tab::run_file_callback, _file_name.toStdString ())); -} - -void -file_editor_tab::file_has_changed (const QString&) -{ - if (QFile::exists (_file_name)) - { - // Prevent popping up multiple message boxes when the file has - // been changed multiple times. - static bool alreadyAsking = false; - if (!alreadyAsking) - { - alreadyAsking = true; - - int decision = - QMessageBox::warning (this, tr ("Octave Editor"), - tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?"). - arg (_file_name), QMessageBox::Yes, - QMessageBox::No); - - if (decision == QMessageBox::Yes) - { - load_file (_file_name); - } - - alreadyAsking = false; - } - } - else - { - int decision = - QMessageBox::warning (this, tr ("Octave Editor"), - tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?"). - arg (_file_name), QMessageBox::Save, - QMessageBox::Close); - if (decision == QMessageBox::Save) - { - if (!save_file_as ()) - { - set_file_name (UNNAMED_FILE); - update_window_title (true); // window title (no modification) - set_modified (true); - } - } - else - { - emit close_request (); - } - } -} - -void -file_editor_tab::notice_settings () -{ - QSettings *settings = resource_manager::get_settings (); - - if (settings==NULL) - return; // this shouldn't happen! - - _edit_area->setCaretLineVisible(settings->value ("editor/highlightCurrentLine",true).toBool ()); - - if (settings->value ("editor/codeCompletion",true).toBool ()) - _edit_area->setAutoCompletionThreshold (1); - else - _edit_area->setAutoCompletionThreshold (-1); - - QFont font( settings->value ("editor/fontName","Courier").toString () , - settings->value ("editor/fontSize",10).toInt () ); - if (settings->value ("editor/showLineNumbers",true).toBool ()) - { - _edit_area->setMarginLineNumbers (2, true); - _edit_area->setMarginsFont( font ); - QFontMetrics metrics( font ); - _edit_area->setMarginWidth(2, metrics.width("9999")); - } - else - { - _edit_area->setMarginLineNumbers (2, false); - _edit_area->setMarginWidth(2, 0); - } - - update_lexer (); - - _long_title = settings->value ("editor/longWindowTitle",false).toBool (); - - update_window_title (false); -} - -void -file_editor_tab::run_file_callback (void) -{ - // Maybe someday we will do something here? + _edit_area->markerDeleteAll (bookmark); } void @@ -831,3 +464,639 @@ if (intmap.size() > 0) _edit_area->markerDeleteAll (breakpoint); } + +void +file_editor_tab::request_add_breakpoint (int line) +{ + QFileInfo file_info (_file_name); + QString path = file_info.absolutePath (); + QString function_name = file_info.fileName (); + + // We have to cut off the suffix, because octave appends it. + function_name.chop (file_info.suffix ().length () + 1); + + bp_info info (path, function_name, line); + + octave_link::post_event + (this, &file_editor_tab::add_breakpoint_callback, info); +} + +void +file_editor_tab::request_remove_breakpoint (int line) +{ + QFileInfo file_info (_file_name); + QString path = file_info.absolutePath (); + QString function_name = file_info.fileName (); + + // We have to cut off the suffix, because octave appends it. + function_name.chop (file_info.suffix ().length () + 1); + + bp_info info (path, function_name, line); + + octave_link::post_event + (this, &file_editor_tab::remove_breakpoint_callback, info); +} + +void +file_editor_tab::toggle_breakpoint (const QWidget* ID) +{ + if (ID != this) + return; + + int line, cur; + _edit_area->getCursorPosition (&line, &cur); + if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) + request_remove_breakpoint (line); + else + request_add_breakpoint (line); +} + +void +file_editor_tab::next_breakpoint (const QWidget* ID) +{ + if (ID != this) + return; + + int line, cur, nextline; + _edit_area->getCursorPosition (&line, &cur); + if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) + line++; // we have a breakpoint here, so start search from next line + nextline = _edit_area->markerFindNext (line, (1 << breakpoint)); + _edit_area->setCursorPosition (nextline, 0); +} + +void +file_editor_tab::previous_breakpoint (const QWidget* ID) +{ + if (ID != this) + return; + + int line, cur, prevline; + _edit_area->getCursorPosition (&line, &cur); + if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) + line--; // we have a breakpoint here, so start search from prev line + prevline = _edit_area->markerFindPrevious (line, (1 << breakpoint)); + _edit_area->setCursorPosition (prevline, 0); +} + +void +file_editor_tab::remove_all_breakpoints (const QWidget* ID) +{ + if (ID != this) + return; + + QFileInfo file_info (_file_name); + QString path = file_info.absolutePath (); + QString function_name = file_info.fileName (); + + // We have to cut off the suffix, because octave appends it. + function_name.chop (file_info.suffix ().length () + 1); + + bp_info info (path, function_name, 0); + + octave_link::post_event + (this, &file_editor_tab::remove_all_breakpoints_callback, info); +} + +void +file_editor_tab::comment_selected_text (const QWidget* ID) +{ + if (ID != this) + return; + + do_comment_selected_text (true); +} + +void +file_editor_tab::uncomment_selected_text (const QWidget* ID) +{ + if (ID != this) + return; + + do_comment_selected_text (false); +} + +void +file_editor_tab::handle_find_dialog_finished (int) +{ + // Find dialog is going to hide. Save location of window for + // when it is reshown. + _find_dialog_geometry = _find_dialog->geometry (); + _find_dialog_is_visible = false; +} + +void +file_editor_tab::find (const QWidget* ID) +{ + if (ID != this) + return; + + // The find_dialog feature doesn't need a slot for return info. + // Rather than Qt::DeleteOnClose, let the find feature hang about + // in case it contains useful information like previous searches + // and so on. Perhaps one find dialog for the whole editor is + // better, but individual find dialogs has the nice feature of + // retaining position per file editor tabs, which can be undocked. + + if (!_find_dialog) + { + _find_dialog = new find_dialog (_edit_area); + connect (_find_dialog, SIGNAL (finished (int)), + this, SLOT (handle_find_dialog_finished (int))); + _find_dialog->setWindowModality (Qt::NonModal); + _find_dialog_geometry = _find_dialog->geometry (); + } + + if (!_find_dialog->isVisible ()) + { + _find_dialog->setGeometry (_find_dialog_geometry); + _find_dialog->show (); + _find_dialog_is_visible = true; + } + + _find_dialog->activateWindow (); +} + +void +file_editor_tab::do_comment_selected_text (bool comment) +{ + if ( _edit_area->hasSelectedText() ) + { + int lineFrom, lineTo, colFrom, colTo, i; + _edit_area->getSelection (&lineFrom,&colFrom,&lineTo,&colTo); + if ( colTo == 0 ) // the beginning of last line is not selected + lineTo--; // stop at line above + _edit_area->beginUndoAction (); + for ( i=lineFrom; i<=lineTo; i++ ) + { + if ( comment ) + _edit_area->insertAt("%",i,0); + else + { + QString line(_edit_area->text(i)); + if ( line.startsWith("%") ) + { + _edit_area->setSelection(i,0,i,1); + _edit_area->removeSelectedText(); + } + } + } + _edit_area->endUndoAction (); + } +} + +void +file_editor_tab::update_window_title (bool modified) +{ + QString title (""); + if (_file_name.isEmpty () || _file_name.at (_file_name.count () - 1) == '/') + title = UNNAMED_FILE; + else + title = _file_name; + if ( !_long_title ) + { + QFileInfo file(_file_name); + title = file.fileName(); + } + + if ( modified ) + { + emit file_name_changed (title.prepend("* ")); + } + else + emit file_name_changed (title); +} + +void +file_editor_tab::handle_copy_available(bool enableCopy) +{ + _copy_available = enableCopy; + emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name)); +} + +int +file_editor_tab::check_file_modified (const QString& msg, int cancelButton) +{ + int decision = QMessageBox::Yes; + if (_edit_area->isModified ()) + { + // File is modified but not saved, ask user what to do. The file + // editor tab can't be made parent because it may be deleted depending + // upon the response. Instead, change the _edit_area to read only. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Warning, tr ("Octave Editor"), + tr ("The file \'%1\' has been modified. Do you want to save the changes?"). + arg (_file_name), QMessageBox::Yes | QMessageBox::No, 0); + _edit_area->setReadOnly (true); + connect (msgBox, SIGNAL (finished (int)), + this, SLOT (handle_file_modified_answer (int))); + msgBox->setWindowModality (Qt::NonModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + return (QMessageBox::Cancel); + } + else + { + // Nothing was modified, just remove from editor. + emit tab_remove_request (); + } + + return (decision); +} + +void +file_editor_tab::handle_file_modified_answer (int decision) +{ + if (decision == QMessageBox::Yes) + { + // Save file, then remove from editor. + save_file (_file_name, true); + } + else if (decision == QMessageBox::No) + { + // User doesn't want to save, just remove from editor. + emit tab_remove_request (); + } + else + { + // User canceled, allow editing again. + _edit_area->setReadOnly (false); + } +} + +void +file_editor_tab::set_modified (bool modified) +{ + _edit_area->setModified (modified); +} + +QString +file_editor_tab::load_file(const QString& fileName) +{ + QFile file (fileName); + if (!file.open (QFile::ReadOnly)) + { + return file.errorString (); + } + + QTextStream in (&file); + QApplication::setOverrideCursor (Qt::WaitCursor); + _edit_area->setText (in.readAll ()); + QApplication::restoreOverrideCursor (); + + set_file_name (fileName); + update_window_title (false); // window title (no modification) + _edit_area->setModified (false); // loaded file is not modified yet + + return QString (); +} + +void +file_editor_tab::new_file () +{ + update_window_title (false); // window title (no modification) + _edit_area->setText (""); + _edit_area->setModified (false); // new file is not modified yet +} + +void +file_editor_tab::save_file (const QString& saveFileName, bool remove_on_success) +{ + // If it is a new file with no name, signal that saveFileAs + // should be performed. + if (saveFileName.isEmpty () || saveFileName.at (saveFileName.count () - 1) == '/') + { + save_file_as (remove_on_success); + return; + } + + // stop watching file + QStringList trackedFiles = _file_system_watcher.files (); + if (!trackedFiles.isEmpty ()) + _file_system_watcher.removePath (saveFileName); + + // open the file for writing + QFile file (saveFileName); + if (!file.open (QIODevice::WriteOnly)) + { + // Unsuccessful, begin watching file again if it was being + // watched previously. + if (trackedFiles.contains (saveFileName)) + _file_system_watcher.addPath (saveFileName); + + // Create a NonModal message about error. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Critical, tr ("Octave Editor"), + tr ("Could not open file %1 for write:\n%2."). + arg (saveFileName).arg (file.errorString ()), + QMessageBox::Ok, 0); + msgBox->setWindowModality (Qt::NonModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + return; + } + + // save the contents into the file + QTextStream out (&file); + QApplication::setOverrideCursor (Qt::WaitCursor); + out << _edit_area->text (); + QApplication::restoreOverrideCursor (); + file.close(); + + // save file name after closing file as set_file_name starts watching again + set_file_name (saveFileName); + // set the window title to actual file name (not modified) + update_window_title (false); + // files is save -> not modified + _edit_area->setModified (false); + + if (remove_on_success) + { + emit tab_remove_request (); + return; // Don't touch member variables after removal + } +} + +void +file_editor_tab::save_file_as (bool remove_on_success) +{ + // Simply put up the file chooser dialog box with a slot connection + // then return control to the system waiting for a file selection. + + // If the tab is removed in response to a QFileDialog signal, the tab + // can't be a parent. + QFileDialog* fileDialog; + if (remove_on_success) + { + // If tab is closed, "this" cannot be parent in which case modality + // has no effect. Disable editing instead. + _edit_area->setReadOnly (true); + fileDialog = new QFileDialog (); + } + else + fileDialog = new QFileDialog (this); + + if (!_file_name.isEmpty () && _file_name.at (_file_name.count () - 1) != '/') + { + fileDialog->selectFile (_file_name); + } + else + { + fileDialog->selectFile (""); + if (_file_name.isEmpty ()) + { + fileDialog->setDirectory (QDir::currentPath ()); + } + else + { + // The file name is actually the directory name from the + // constructor argument. + fileDialog->setDirectory (_file_name); + } + } + fileDialog->setNameFilter (SAVE_FILE_FILTER); + fileDialog->setDefaultSuffix ("m"); + fileDialog->setAcceptMode (QFileDialog::AcceptSave); + fileDialog->setViewMode (QFileDialog::Detail); + if (remove_on_success) + { + connect (fileDialog, SIGNAL (fileSelected (const QString&)), + this, SLOT (handle_save_file_as_answer_close (const QString&))); + connect (fileDialog, SIGNAL (rejected ()), + this, SLOT (handle_save_file_as_answer_cancel ())); + } + else + { + connect (fileDialog, SIGNAL (fileSelected (const QString&)), + this, SLOT (handle_save_file_as_answer (const QString&))); + } + fileDialog->setWindowModality (Qt::WindowModal); + fileDialog->setAttribute (Qt::WA_DeleteOnClose); + fileDialog->show (); +} + +void +file_editor_tab::message_duplicate_file_name (const QString& saveFileName) +{ + // Could overwrite the file here (and tell user the file was + // overwritten), but the user could have unintentionally + // selected the same name not intending to overwrite. + + // Create a NonModal message about error. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Critical, tr ("Octave Editor"), + tr ("File not saved! You've selected a file name\n\n %1\n\nwhich is the same as the current file name. Use ""Save"" to overwrite. (Could allow overwriting, with message, if that is what folks want.)"). + arg (saveFileName), + QMessageBox::Ok, 0); + msgBox->setWindowModality (Qt::NonModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); +} + +void +file_editor_tab::handle_save_file_as_answer (const QString& saveFileName) +{ + if (saveFileName == _file_name) + { + message_duplicate_file_name (saveFileName); + // Nothing done, allow editing again. + _edit_area->setReadOnly (false); + } + else + { + // Have editor check for conflict, do not delete tab after save. + emit editor_check_conflict_save (saveFileName, false); + } +} + +void +file_editor_tab::handle_save_file_as_answer_close (const QString& saveFileName) +{ + if (saveFileName == _file_name) + { + message_duplicate_file_name (saveFileName); + // Nothing done, allow editing again. + _edit_area->setReadOnly (false); + } + else + { + // Have editor check for conflict, delete tab after save. + emit editor_check_conflict_save (saveFileName, true); + } +} + +void +file_editor_tab::handle_save_file_as_answer_cancel () +{ + // User canceled, allow editing again. + _edit_area->setReadOnly (false); +} + +void +file_editor_tab::file_has_changed (const QString&) +{ + // Prevent popping up multiple message boxes when the file has + // been changed multiple times by temporarily removing from the + // file watcher. + QStringList trackedFiles = _file_system_watcher.files (); + if (!trackedFiles.isEmpty ()) + _file_system_watcher.removePath (_file_name); + + if (QFile::exists (_file_name)) + { + // Create a WindowModal message that blocks the edit area + // by making _edit_area parent. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Warning, tr ("Octave Editor"), + tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?"). + arg (_file_name), QMessageBox::Yes | QMessageBox::No, this); + connect (msgBox, SIGNAL (finished (int)), + this, SLOT (handle_file_reload_answer (int))); + msgBox->setWindowModality (Qt::WindowModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + } + else + { + // Create a WindowModal message that blocks the edit area + // by making _edit_area parent. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Warning, tr ("Octave Editor"), + tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?"). + arg (_file_name), QMessageBox::Save | QMessageBox::Close, this); + connect (msgBox, SIGNAL (finished (int)), + this, SLOT (handle_file_resave_answer (int))); + msgBox->setWindowModality (Qt::WindowModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + } +} + +void +file_editor_tab::notice_settings () +{ + QSettings *settings = resource_manager::get_settings (); + + if (settings==NULL) + return; // this shouldn't happen! + + _edit_area->setCaretLineVisible(settings->value ("editor/highlightCurrentLine",true).toBool ()); + + if (settings->value ("editor/codeCompletion",true).toBool ()) + _edit_area->setAutoCompletionThreshold (1); + else + _edit_area->setAutoCompletionThreshold (-1); + + QFont font( settings->value ("editor/fontName","Courier").toString () , + settings->value ("editor/fontSize",10).toInt () ); + if (settings->value ("editor/showLineNumbers",true).toBool ()) + { + _edit_area->setMarginLineNumbers (2, true); + _edit_area->setMarginsFont( font ); + QFontMetrics metrics( font ); + _edit_area->setMarginWidth(2, metrics.width("9999")); + } + else + { + _edit_area->setMarginLineNumbers (2, false); + _edit_area->setMarginWidth(2, 0); + } + + update_lexer (); + + _long_title = settings->value ("editor/longWindowTitle",false).toBool (); + + update_window_title (false); +} + +void +file_editor_tab::conditional_close (const QWidget* ID) +{ + if (ID != this) + return; + + close (); +} + +void +file_editor_tab::change_editor_state (const QWidget* ID) +{ + if (ID != this) + { + // Widget may be going out of focus. If so, record location. + if (_find_dialog) + { + if (_find_dialog->isVisible ()) + { + _find_dialog_geometry = _find_dialog->geometry (); + _find_dialog->hide (); + } + } + return; + } + + if (_find_dialog && _find_dialog_is_visible) + { + _find_dialog->setGeometry (_find_dialog_geometry); + _find_dialog->show (); + } + emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name)); +} + +void +file_editor_tab::file_name_query (const QWidget* ID) +{ + // A zero (null pointer) means that all file editor tabs + // should respond, otherwise just the desired file editor tab. + if (ID != this && ID != 0) + return; + + // Unnamed files shouldn't be transmitted. + if (!_file_name.isEmpty ()) + emit add_filename_to_list (_file_name); +} + +void +file_editor_tab::handle_file_reload_answer (int decision) +{ + if (decision == QMessageBox::Yes) + { // reload: file is readded to the file watcher in set_file_name () + load_file (_file_name); + } + else + { // do not reload: readd to the file watche + _file_system_watcher.addPath (_file_name); + } +} + +void +file_editor_tab::handle_file_resave_answer (int decision) +{ + if (decision == QMessageBox::Save) + { + save_file (_file_name); + } + else + { + if (close ()) + { + emit tab_remove_request (); + return; // Don't touch member variables after removal + } + } + + // Start watching file once again. + _file_system_watcher.addPath (_file_name); +} + +void +file_editor_tab::set_debugger_position (int line) +{ + _edit_area->markerDeleteAll (debugger_position); + if (line > 0) + { + _edit_area->markerAdd (line, debugger_position); + } +} + +#endif diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/m-editor/file-editor-tab.h --- a/libgui/src/m-editor/file-editor-tab.h Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/m-editor/file-editor-tab.h Thu Jan 03 13:36:55 2013 -0500 @@ -28,61 +28,89 @@ #include #include +#include "find-dialog.h" + class file_editor; class file_editor_tab : public QWidget { Q_OBJECT public: - file_editor_tab (file_editor *fileEditor); - bool copy_available (); + file_editor_tab (QString directory = ""); + ~file_editor_tab (); public slots: void update_window_title(bool modified); void handle_copy_available(bool enableCopy); void handle_margin_clicked (int line, int margin, Qt::KeyboardModifiers state); - void comment_selected_text (); - void uncomment_selected_text (); - void find (); - void remove_bookmark (); - void toggle_bookmark (); - void next_bookmark (); - void previous_bookmark (); - void remove_all_breakpoints (); - void toggle_breakpoint (); - void next_breakpoint (); - void previous_breakpoint (); - void cut (); - void copy (); - void paste (); - void undo (); - void redo (); + + /** Tells the editor tab to react on changed settings. */ + void notice_settings (); + /** Will initiate close if associated with the identifier tag. */ + void conditional_close (const QWidget* ID); + /** Change to a different editor tab by identifier tag. */ + void change_editor_state (const QWidget* ID); + /** Simply transmit file name. */ + void file_name_query (const QWidget* ID); + + void undo (const QWidget* ID); + void redo (const QWidget* ID); + void copy (const QWidget* ID); + void cut (const QWidget* ID); + void paste (const QWidget* ID); + void save_file (const QWidget* ID); + void save_file (const QWidget* ID, const QString& fileName, bool remove_on_success); + void save_file_as (const QWidget* ID); + void run_file (const QWidget* ID); + void toggle_bookmark (const QWidget* ID); + void next_bookmark (const QWidget* ID); + void previous_bookmark (const QWidget* ID); + void remove_bookmark (const QWidget* ID); + + void toggle_breakpoint (const QWidget* ID); + void next_breakpoint (const QWidget* ID); + void previous_breakpoint (const QWidget* ID); + void remove_all_breakpoints (const QWidget* ID); + + void comment_selected_text (const QWidget* ID); + void uncomment_selected_text (const QWidget* ID); + void find (const QWidget* ID); + void set_debugger_position (int line); void set_modified (bool modified = true); - bool open_file (const QString& dir = QString ()); - bool load_file (const QString& fileName, bool silent = false); + QString load_file (const QString& fileName); void new_file (); - bool save_file (); - bool save_file (const QString& saveFileName); - bool save_file_as(); - void run_file (); void file_has_changed (const QString& fileName); - QString get_file_name () const {return _file_name;} - - /** Tells the editor tab to react on changed settings. */ - void notice_settings (); signals: void file_name_changed (const QString& fileName); - void editor_state_changed (); - void close_request (); + void editor_state_changed (bool copy_available, const QString& fileName); + void tab_remove_request (); + void add_filename_to_list (const QString& fileName); + void mru_add_file (const QString& file_name); + void editor_check_conflict_save (const QString& saveFileName, bool remove_on_success); + void process_octave_code (const QString& command); protected: void closeEvent (QCloseEvent *event); void set_file_name (const QString& fileName); +private slots: + /** When user closes message box for reload question. */ + void handle_file_reload_answer (int decision); + /** When user closes message box for resave question. */ + void handle_file_resave_answer (int decision); + /** When user closes message box for modified question. */ + void handle_file_modified_answer (int decision); + /** When user closes find_dialog box. */ + void handle_find_dialog_finished (int decision); + /** When user closes QFileDialog box. */ + void handle_save_file_as_answer (const QString& fileName); + void handle_save_file_as_answer_close (const QString& fileName); + void handle_save_file_as_answer_cancel (); + private: struct bp_info @@ -96,6 +124,10 @@ int line; }; + void save_file (const QString& saveFileName, bool remove_on_success = false); + void save_file_as (bool remove_on_success = false); + void message_duplicate_file_name (const QString& fileName); + void update_lexer (); void request_add_breakpoint (int line); void request_remove_breakpoint (int line); @@ -108,7 +140,6 @@ void remove_breakpoint_callback (const bp_info& info); void remove_all_breakpoints_callback (const bp_info& info); - file_editor * _file_editor; QsciScintilla * _edit_area; QString _file_name; @@ -118,6 +149,10 @@ bool _copy_available; QFileSystemWatcher _file_system_watcher; + + find_dialog * _find_dialog; + bool _find_dialog_is_visible; + QRect _find_dialog_geometry; }; #endif // FILEEDITORTAB_H diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/m-editor/file-editor.cc --- a/libgui/src/m-editor/file-editor.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/m-editor/file-editor.cc Thu Jan 03 13:36:55 2013 -0500 @@ -24,6 +24,8 @@ #include #endif +#ifdef HAVE_QSCINTILLA + #include "file-editor.h" #include "resource-manager.h" #include @@ -35,46 +37,33 @@ #include #include -file_editor::file_editor (QTerminal *t, main_window *m) - : file_editor_interface (t, m) +#include "octave-link.h" + +file_editor::file_editor (QWidget *p) + : file_editor_interface (p) { + // Set current editing directory before construct because loaded + // files will change ced accordingly. + ced = QDir::currentPath (); + construct (); - _terminal = t; - _main_window = m; setVisible (false); } file_editor::~file_editor () { QSettings *settings = resource_manager::get_settings (); - QStringList sessionFileNames; + fetFileNames.clear (); if (settings->value ("editor/restoreSession",true).toBool ()) { - for (int n=0;n<_tab_widget->count();++n) - { - file_editor_tab* tab = dynamic_cast (_tab_widget->widget (n)); - if (!tab) - continue; - sessionFileNames.append (tab->get_file_name ()); - } + // Have all file editor tabs signal what their file names are. + emit fetab_file_name_query (0); } - settings->setValue ("editor/savedSessionTabs", sessionFileNames); + settings->setValue ("editor/savedSessionTabs", fetFileNames); settings->sync (); } -QTerminal * -file_editor::terminal () -{ - return _terminal; -} - -main_window * -file_editor::get_main_window () -{ - return _main_window; -} - QMenu * file_editor::debug_menu () { @@ -102,10 +91,14 @@ void file_editor::request_new_file () { - file_editor_tab *fileEditorTab = new file_editor_tab (this); + // New file isn't a file_editor_tab function since the file + // editor tab has yet to be created and there is no object to + // pass a signal to. Hence, functionality is here. + + file_editor_tab *fileEditorTab = new file_editor_tab (ced); if (fileEditorTab) { - add_file_editor_tab (fileEditorTab); + add_file_editor_tab (fileEditorTab, UNNAMED_FILE); fileEditorTab->new_file (); } } @@ -113,208 +106,313 @@ void file_editor::request_open_file () { - file_editor_tab *current_tab = active_editor_tab (); - int curr_tab_index = _tab_widget->currentIndex (); - file_editor_tab *fileEditorTab = new file_editor_tab (this); - if (fileEditorTab) + // Open file isn't a file_editor_tab function since the file + // editor tab has yet to be created and there is no object to + // pass a signal to. Hence, functionality is here. + + // Create a NonModal message. + QFileDialog* fileDialog = new QFileDialog (this); + fileDialog->setNameFilter (SAVE_FILE_FILTER); + fileDialog->setAcceptMode (QFileDialog::AcceptOpen); + fileDialog->setViewMode (QFileDialog::Detail); + fileDialog->setDirectory (ced); + connect (fileDialog, SIGNAL (fileSelected (const QString&)), + this, SLOT (request_open_file (const QString&))); + fileDialog->setWindowModality (Qt::NonModal); + fileDialog->setAttribute (Qt::WA_DeleteOnClose); + fileDialog->show (); +} + +void +file_editor::request_open_file (const QString& openFileName) +{ + if (openFileName.isEmpty ()) + { + // ?? Not sure this will happen. This routine isn't even called + // if the user hasn't selected a file. + } + else { - add_file_editor_tab (fileEditorTab); - QString dir = QDir::currentPath (); - // get the filename of the last active tab to open a new file from there - if (current_tab) - dir = QDir::cleanPath (current_tab->get_file_name ()); - if (!fileEditorTab->open_file (dir)) + // Have all file editor tabs signal what their file names are. + fetFileNames.clear (); + emit fetab_file_name_query (0); + + // Check whether this file is already open in the editor. + if (fetFileNames.contains (openFileName, Qt::CaseSensitive)) { - // If no file was loaded, remove the tab again. - _tab_widget->removeTab (_tab_widget->indexOf (fileEditorTab)); - // restore focus to previous tab - if (curr_tab_index>=0) - _tab_widget->setCurrentIndex (curr_tab_index); + // Create a NonModal message so nothing is blocked and + // bring the existing file forward. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Critical, tr ("Octave Editor"), + tr ("File %1 is already open in the editor."). + arg (openFileName), QMessageBox::Ok, 0); + msgBox->setWindowModality (Qt::NonModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + QFileInfo file(openFileName); + QString short_openFileName = file.fileName(); // get file name only + for(int i = 0; i < _tab_widget->count (); i++) + { // check whether tab title is file name (long or short) + if (_tab_widget->tabText (i) == openFileName || + _tab_widget->tabText (i) == short_openFileName) + { + _tab_widget->setCurrentIndex (i); + break; + } + } + return; + } + + file_editor_tab *fileEditorTab = new file_editor_tab (); + if (fileEditorTab) + { + QString result = fileEditorTab->load_file(openFileName); + if (result == "") + { + // Supply empty title then have the file_editor_tab update + // with full or short name. + add_file_editor_tab (fileEditorTab, ""); + fileEditorTab->update_window_title (false); + // file already loaded, add file to mru list here + handle_mru_add_file(QDir::cleanPath (openFileName)); + } + else + { + delete fileEditorTab; + // Create a NonModal message about error. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Critical, tr ("Octave Editor"), + tr ("Could not open file %1 for read:\n%2."). + arg (openFileName).arg (result), + QMessageBox::Ok, 0); + msgBox->setWindowModality (Qt::NonModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + } } } } +// open a file from the mru list void -file_editor::request_open_file (const QString& fileName, bool silent) +file_editor::request_mru_open_file () +{ + QAction *action = qobject_cast(sender ()); + if (action) + { + request_open_file (action->data ().toString ()); + } +} + + +void +file_editor::check_conflict_save (const QString& saveFileName, bool remove_on_success) { - if (!isVisible ()) + // Have all file editor tabs signal what their file names are. + fetFileNames.clear (); + emit fetab_file_name_query (0); + + // If one of those names matches the desired name, that's a conflict. + if (fetFileNames.contains (saveFileName, Qt::CaseSensitive)) { - show (); + // Note: to overwrite the contents of some other file editor tab + // with the same name requires identifying which file editor tab + // that is (not too difficult) then close that tab. Of course, + // that could trigger another dialog box if the file editor tab + // with the same name has modifications in it. This could become + // somewhat confusing to the user. For now, opt to do nothing. + + // Create a NonModal message about error. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Critical, tr ("Octave Editor"), + tr ("File not saved! You've selected a file name\n\n %1\n\nwhich is the same as an already open file in the editor. (Could allow overwriting, with message, if that is what folks want.)"). + arg (saveFileName), + QMessageBox::Ok, 0); + msgBox->setWindowModality (Qt::NonModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + + return; } - file_editor_tab *fileEditorTab = new file_editor_tab (this); - int curr_tab_index = _tab_widget->currentIndex (); - if (fileEditorTab) + QObject* saveFileObject = sender (); + QWidget* saveFileWidget = 0; + for(int i = 0; i < _tab_widget->count (); i++) { - add_file_editor_tab (fileEditorTab); - if (!fileEditorTab->load_file (fileName, silent)) + if (_tab_widget->widget (i) == saveFileObject) { - // If no file was loaded, remove the tab again. - _tab_widget->removeTab (_tab_widget->indexOf (fileEditorTab)); - // restore focus to previous tab - _tab_widget->setCurrentIndex (curr_tab_index); + saveFileWidget = _tab_widget->widget (i); + break; } } + if (!saveFileWidget) + { + // Create a NonModal message about error. + QMessageBox* msgBox = new QMessageBox ( + QMessageBox::Critical, tr ("Octave Editor"), + tr ("The associated file editor tab has disappeared. It was likely closed by some means."), + QMessageBox::Ok, 0); + msgBox->setWindowModality (Qt::NonModal); + msgBox->setAttribute (Qt::WA_DeleteOnClose); + msgBox->show (); + return; + } + + // Can save without conflict, have the file editor tab do so. + emit fetab_save_file (saveFileWidget, saveFileName, remove_on_success); } void file_editor::request_undo () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->undo (); + emit fetab_undo (_tab_widget->currentWidget ()); } void file_editor::request_redo () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->redo (); + emit fetab_redo (_tab_widget->currentWidget ()); } void file_editor::request_copy () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->copy (); + emit fetab_copy (_tab_widget->currentWidget ()); } void file_editor::request_cut () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->cut (); + emit fetab_cut (_tab_widget->currentWidget ()); } void file_editor::request_paste () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->paste (); + emit fetab_paste (_tab_widget->currentWidget ()); } void file_editor::request_save_file () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->save_file (); + emit fetab_save_file (_tab_widget->currentWidget ()); } void file_editor::request_save_file_as () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->save_file_as (); + emit fetab_save_file_as (_tab_widget->currentWidget ()); } void file_editor::request_run_file () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->run_file (); + emit fetab_run_file (_tab_widget->currentWidget ()); } void file_editor::request_toggle_bookmark () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->toggle_bookmark (); + emit fetab_toggle_bookmark (_tab_widget->currentWidget ()); } void file_editor::request_next_bookmark () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->next_bookmark (); + emit fetab_next_bookmark (_tab_widget->currentWidget ()); } void file_editor::request_previous_bookmark () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->previous_bookmark (); + emit fetab_previous_bookmark (_tab_widget->currentWidget ()); } void file_editor::request_remove_bookmark () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->remove_bookmark (); + emit fetab_remove_bookmark (_tab_widget->currentWidget ()); } void file_editor::request_toggle_breakpoint () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->toggle_breakpoint (); + emit fetab_toggle_breakpoint (_tab_widget->currentWidget ()); } void file_editor::request_next_breakpoint () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->next_breakpoint (); + emit fetab_next_breakpoint (_tab_widget->currentWidget ()); } void file_editor::request_previous_breakpoint () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->previous_breakpoint (); + emit fetab_previous_breakpoint (_tab_widget->currentWidget ()); } void file_editor::request_remove_breakpoint () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->remove_all_breakpoints (); + emit fetab_remove_all_breakpoints (_tab_widget->currentWidget ()); } void file_editor::request_comment_selected_text () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->comment_selected_text (); + emit fetab_comment_selected_text (_tab_widget->currentWidget ()); } void file_editor::request_uncomment_selected_text () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->uncomment_selected_text (); + emit fetab_uncomment_selected_text (_tab_widget->currentWidget ()); } void file_editor::request_find () { - file_editor_tab *_active_file_editor_tab = active_editor_tab (); - if (_active_file_editor_tab) - _active_file_editor_tab->find (); + emit fetab_find (_tab_widget->currentWidget ()); +} + +void +file_editor::handle_mru_add_file (const QString& file_name) +{ + _mru_files.removeAll (file_name); + _mru_files.prepend (file_name); + mru_menu_update (); +} + +void +file_editor::mru_menu_update () +{ + int num_files = qMin (_mru_files.size(), int (MaxMRUFiles)); + // configure and show active actions of mru-menu + for (int i = 0; i < num_files; ++i) + { + QString text = tr("&%1 %2"). + arg ((i+1) % int (MaxMRUFiles)).arg (_mru_files.at (i)); + _mru_file_actions[i]->setText (text); + _mru_file_actions[i]->setData (_mru_files.at (i)); + _mru_file_actions[i]->setVisible (true); + } + // hide unused mru-menu entries + for (int j = num_files; j < MaxMRUFiles; ++j) + _mru_file_actions[j]->setVisible (false); + // delete entries in string-list beyond MaxMRUFiles + while (_mru_files.size () > MaxMRUFiles) + _mru_files.removeLast (); + // save actual mru-list in settings + QSettings *settings = resource_manager::get_settings (); + // FIXME -- what should happen if settings is 0? + settings->setValue ("editor/mru_file_list",_mru_files); } void file_editor::handle_file_name_changed (const QString& fileName) { - QObject *senderObject = sender (); - file_editor_tab *fileEditorTab - = dynamic_cast (senderObject); + QObject *fileEditorTab = sender(); if (fileEditorTab) { for(int i = 0; i < _tab_widget->count (); i++) @@ -330,26 +428,72 @@ void file_editor::handle_tab_close_request (int index) { - file_editor_tab *fileEditorTab - = dynamic_cast (_tab_widget->widget (index)); + // Signal to the tabs a request to close whomever matches the identifying + // tag (i.e., unique widget pointer). The reason for this indirection is + // that it will enable a file editor widget to toss up a non-static + // dialog box and later signal that it wants to be removed. + QWidget *tabID = _tab_widget->widget (index); + emit fetab_close_request (tabID); +} + +void +file_editor::handle_tab_remove_request () +{ + QObject *fileEditorTab = sender(); if (fileEditorTab) - if (fileEditorTab->close ()) - { - _tab_widget->removeTab (index); - delete fileEditorTab; - } + { + for(int i = 0; i < _tab_widget->count (); i++) + { + if (_tab_widget->widget (i) == fileEditorTab) + { + _tab_widget->removeTab (i); + delete fileEditorTab; + } + } + } +} + +void +file_editor::handle_add_filename_to_list (const QString& fileName) +{ + fetFileNames.append (fileName); } void -file_editor::handle_tab_close_request () +file_editor::active_tab_changed (int index) +{ + emit fetab_change_request (_tab_widget->widget (index)); +} + +void +file_editor::handle_editor_state_changed (bool copy_available, const QString& file_name) { - file_editor_tab *fileEditorTab = dynamic_cast (sender ()); - if (fileEditorTab) - if (fileEditorTab->close ()) - { - _tab_widget->removeTab (_tab_widget->indexOf (fileEditorTab)); - delete fileEditorTab; - } + // In case there is some scenario where traffic could be coming from + // all the file editor tabs, just process info from the current active tab. + if (sender() == _tab_widget->currentWidget ()) + { + _copy_action->setEnabled (copy_available); + _cut_action->setEnabled (copy_available); + if (!file_name.isEmpty ()) + { + ced = QDir::cleanPath (file_name); + int lastslash = ced.lastIndexOf ('/'); + // Test against > 0 because if somehow the directory is "/" the + // slash should be retained. Otherwise, last slash is removed. + if (lastslash > 0 && lastslash != ced.count ()) + { + ced = ced.left (lastslash); + } + } + setFocusProxy (_tab_widget->currentWidget ()); + } +} + +void +file_editor::notice_settings () +{ + // Relay signal to file editor tabs. + emit fetab_settings_changed (); } // slot for signal that is emitted when floating property changes @@ -364,37 +508,6 @@ } void -file_editor::active_tab_changed (int) -{ - handle_editor_state_changed (); -} - -void -file_editor::handle_editor_state_changed () -{ - file_editor_tab *f = active_editor_tab (); - if (f) - { - bool copy_available = f->copy_available (); - _copy_action->setEnabled (copy_available); - _cut_action->setEnabled (copy_available); - setFocusProxy (f); - } -} - -void -file_editor::notice_settings () -{ - for(int i = 0; i < _tab_widget->count (); i++) - { - file_editor_tab *fileEditorTab - = dynamic_cast (_tab_widget->widget (i)); - if (fileEditorTab) - fileEditorTab->notice_settings (); - } -} - -void file_editor::construct () { QWidget *editor_widget = new QWidget (this); @@ -460,6 +573,16 @@ _run_action = new QAction (QIcon(":/actions/icons/artsbuilderexecute.png"), tr("Save File And Run"), _tool_bar); + // the mru-list and an empty array of actions + QSettings *settings = resource_manager::get_settings (); + // FIXME -- what should happen if settings is 0? + _mru_files = settings->value ("editor/mru_file_list").toStringList (); + for (int i = 0; i < MaxMRUFiles; ++i) + { + _mru_file_actions[i] = new QAction (this); + _mru_file_actions[i]->setVisible (false); + } + // some actions are disabled from the beginning _copy_action->setEnabled(false); _cut_action->setEnabled(false); @@ -505,6 +628,12 @@ fileMenu->addAction (save_action); fileMenu->addAction (save_as_action); fileMenu->addSeparator (); + QMenu *mru_file_menu = new QMenu (tr ("Open &Recent"), fileMenu); + for (int i = 0; i < MaxMRUFiles; ++i) + { + mru_file_menu->addAction (_mru_file_actions[i]); + } + fileMenu->addMenu (mru_file_menu); _menu_bar->addMenu (fileMenu); QMenu *editMenu = new QMenu (tr ("&Edit"), _menu_bar); @@ -589,6 +718,12 @@ SIGNAL (triggered ()), this, SLOT (request_uncomment_selected_text ())); connect (find_action, SIGNAL (triggered ()), this, SLOT (request_find ())); + // The actions of the mru file menu + for (int i = 0; i < MaxMRUFiles; ++i) + { + connect(_mru_file_actions[i], SIGNAL (triggered ()), this, SLOT (request_mru_open_file ())); + } + mru_menu_update (); connect (_tab_widget, SIGNAL (tabCloseRequested (int)), this, SLOT (handle_tab_close_request (int))); connect (_tab_widget, @@ -601,31 +736,88 @@ setWindowTitle ("Editor"); //restore previous session - QSettings *settings = resource_manager::get_settings (); if (settings->value ("editor/restoreSession",true).toBool ()) { QStringList sessionFileNames = settings->value("editor/savedSessionTabs", QStringList()).toStringList (); for (int n=0; n < sessionFileNames.count (); ++n) - request_open_file (sessionFileNames.at (n), true); + request_open_file (sessionFileNames.at (n)); } } void -file_editor::add_file_editor_tab (file_editor_tab *f) +file_editor::add_file_editor_tab (file_editor_tab *f, const QString &fn) { - _tab_widget->addTab (f, ""); - connect (f, SIGNAL (file_name_changed(QString)), - this, SLOT(handle_file_name_changed(QString))); - connect (f, SIGNAL (editor_state_changed ()), - this, SLOT (handle_editor_state_changed ())); - connect (f, SIGNAL (close_request ()), - this, SLOT (handle_tab_close_request ())); + _tab_widget->addTab (f, fn); + + // Signals from the file editor_tab + connect (f, SIGNAL (file_name_changed (const QString&)), + this, SLOT (handle_file_name_changed (const QString&))); + connect (f, SIGNAL (editor_state_changed (bool, const QString&)), + this, SLOT (handle_editor_state_changed (bool, const QString&))); + connect (f, SIGNAL (tab_remove_request ()), + this, SLOT (handle_tab_remove_request ())); + connect (f, SIGNAL (add_filename_to_list (const QString&)), + this, SLOT (handle_add_filename_to_list (const QString&))); + connect (f, SIGNAL (editor_check_conflict_save (const QString&, bool)), + this, SLOT (check_conflict_save (const QString&, bool))); + connect (f, SIGNAL (mru_add_file (const QString&)), + this, SLOT (handle_mru_add_file (const QString&))); + connect (f, SIGNAL (process_octave_code (const QString&)), + parent (), SLOT (handle_command_double_clicked (const QString&))); + + // Signals from the file_editor non-trivial operations + connect (this, SIGNAL (fetab_settings_changed ()), + f, SLOT (notice_settings ())); + connect (this, SIGNAL (fetab_close_request (const QWidget*)), + f, SLOT (conditional_close (const QWidget*))); + connect (this, SIGNAL (fetab_change_request (const QWidget*)), + f, SLOT (change_editor_state (const QWidget*))); + connect (this, SIGNAL (fetab_file_name_query (const QWidget*)), + f, SLOT (file_name_query (const QWidget*))); + connect (this, SIGNAL (fetab_save_file (const QWidget*, const QString&, bool)), + f, SLOT (save_file (const QWidget*, const QString&, bool))); + // Signals from the file_editor trivial operations + connect (this, SIGNAL (fetab_undo (const QWidget*)), + f, SLOT (undo (const QWidget*))); + connect (this, SIGNAL (fetab_redo (const QWidget*)), + f, SLOT (redo (const QWidget*))); + connect (this, SIGNAL (fetab_copy (const QWidget*)), + f, SLOT (copy (const QWidget*))); + connect (this, SIGNAL (fetab_cut (const QWidget*)), + f, SLOT (cut (const QWidget*))); + connect (this, SIGNAL (fetab_paste (const QWidget*)), + f, SLOT (paste (const QWidget*))); + connect (this, SIGNAL (fetab_save_file (const QWidget*)), + f, SLOT (save_file (const QWidget*))); + connect (this, SIGNAL (fetab_save_file_as (const QWidget*)), + f, SLOT (save_file_as (const QWidget*))); + connect (this, SIGNAL (fetab_run_file (const QWidget*)), + f, SLOT (run_file (const QWidget*))); + connect (this, SIGNAL (fetab_toggle_bookmark (const QWidget*)), + f, SLOT (toggle_bookmark (const QWidget*))); + connect (this, SIGNAL (fetab_next_bookmark (const QWidget*)), + f, SLOT (next_bookmark (const QWidget*))); + connect (this, SIGNAL (fetab_previous_bookmark (const QWidget*)), + f, SLOT (previous_bookmark (const QWidget*))); + connect (this, SIGNAL (fetab_remove_bookmark (const QWidget*)), + f, SLOT (remove_bookmark (const QWidget*))); + connect (this, SIGNAL (fetab_toggle_breakpoint (const QWidget*)), + f, SLOT (toggle_breakpoint (const QWidget*))); + connect (this, SIGNAL (fetab_next_breakpoint (const QWidget*)), + f, SLOT (next_breakpoint (const QWidget*))); + connect (this, SIGNAL (fetab_previous_breakpoint (const QWidget*)), + f, SLOT (previous_breakpoint (const QWidget*))); + connect (this, SIGNAL (fetab_remove_all_breakpoints (const QWidget*)), + f, SLOT (remove_all_breakpoints (const QWidget*))); + connect (this, SIGNAL (fetab_comment_selected_text (const QWidget*)), + f, SLOT (comment_selected_text (const QWidget*))); + connect (this, SIGNAL (fetab_uncomment_selected_text (const QWidget*)), + f, SLOT (uncomment_selected_text (const QWidget*))); + connect (this, SIGNAL (fetab_find (const QWidget*)), + f, SLOT (find (const QWidget*))); + _tab_widget->setCurrentWidget (f); } -file_editor_tab * -file_editor::active_editor_tab () -{ - return dynamic_cast (_tab_widget->currentWidget ()); -} +#endif diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/m-editor/file-editor.h --- a/libgui/src/m-editor/file-editor.h Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/m-editor/file-editor.h Thu Jan 03 13:36:55 2013 -0500 @@ -30,7 +30,6 @@ #include #include -#include "main-window.h" #include "file-editor-interface.h" #include "file-editor-tab.h" @@ -48,23 +47,49 @@ Q_OBJECT public: - file_editor (QTerminal *terminal, main_window *m); + file_editor (QWidget *p); ~file_editor (); void loadFile (const QString& fileName); - QTerminal * terminal (); - main_window * get_main_window (); - QMenu * debug_menu (); QToolBar * toolbar (); void handle_entered_debug_mode (); void handle_quit_debug_mode (); +signals: + void fetab_settings_changed (); + void fetab_close_request (const QWidget* ID); + void fetab_change_request (const QWidget* ID); + void fetab_file_name_query (const QWidget* ID); + // Save is a ping-pong type of communication + void fetab_save_file (const QWidget* ID, const QString& fileName, bool remove_on_success); + // No fetab_open, functionality in editor + // No fetab_new, functionality in editor + void fetab_undo (const QWidget* ID); + void fetab_redo (const QWidget* ID); + void fetab_copy (const QWidget* ID); + void fetab_cut (const QWidget* ID); + void fetab_paste (const QWidget* ID); + void fetab_save_file (const QWidget* ID); + void fetab_save_file_as (const QWidget* ID); + void fetab_run_file (const QWidget* ID); + void fetab_toggle_bookmark (const QWidget* ID); + void fetab_next_bookmark (const QWidget* ID); + void fetab_previous_bookmark (const QWidget* ID); + void fetab_remove_bookmark (const QWidget* ID); + void fetab_toggle_breakpoint (const QWidget* ID); + void fetab_next_breakpoint (const QWidget* ID); + void fetab_previous_breakpoint (const QWidget* ID); + void fetab_remove_all_breakpoints (const QWidget* ID); + void fetab_comment_selected_text (const QWidget* ID); + void fetab_uncomment_selected_text (const QWidget* ID); + void fetab_find (const QWidget* ID); + public slots: void request_new_file (); void request_open_file (); - void request_open_file (const QString& fileName, bool silent = false); + void request_mru_open_file (); void request_undo (); void request_redo (); @@ -90,19 +115,30 @@ void handle_file_name_changed (const QString& fileName); void handle_tab_close_request (int index); - void handle_tab_close_request (); + void handle_tab_remove_request (); + void handle_add_filename_to_list (const QString& fileName); void active_tab_changed (int index); - void handle_editor_state_changed (); + void handle_editor_state_changed (bool enableCopy, const QString& fileName); + void handle_mru_add_file (const QString& file_name); + void check_conflict_save (const QString& fileName, bool remove_on_success); + /** Slot when floating property changes */ void top_level_changed (bool floating); /** Tells the editor to react on changed settings. */ void notice_settings (); +private slots: + void request_open_file (const QString& fileName); + private: void construct (); - void add_file_editor_tab(file_editor_tab *f); - file_editor_tab *active_editor_tab(); + void add_file_editor_tab(file_editor_tab *f, const QString &fn); + void save_file_as (QWidget *fetabID = 0); + void mru_menu_update (); + + QStringList fetFileNames; + QString ced; QMenuBar * _menu_bar; QToolBar * _tool_bar; @@ -112,6 +148,11 @@ QAction * _run_action; QTabWidget * _tab_widget; int _marker_breakpoint; + + enum { MaxMRUFiles = 10 }; + QAction *_mru_file_actions[MaxMRUFiles]; + QStringList _mru_files; + }; #endif // FILEEDITORMDISUBWINDOW_H diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/m-editor/find-dialog.cc --- a/libgui/src/m-editor/find-dialog.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/m-editor/find-dialog.cc Thu Jan 03 13:36:55 2013 -0500 @@ -43,6 +43,8 @@ #include #endif +#ifdef HAVE_QSCINTILLA + #include #include #include "find-dialog.h" @@ -199,3 +201,5 @@ } // TODO: Show number of replaced strings } + +#endif diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/m-editor/lexer-octave-gui.cc --- a/libgui/src/m-editor/lexer-octave-gui.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/m-editor/lexer-octave-gui.cc Thu Jan 03 13:36:55 2013 -0500 @@ -24,6 +24,8 @@ #include #endif +#ifdef HAVE_QSCINTILLA + #include "lexer-octave-gui.h" #include #include @@ -175,3 +177,4 @@ return 0; } +#endif diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/main-window.cc --- a/libgui/src/main-window.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/main-window.cc Thu Jan 03 13:36:55 2013 -0500 @@ -68,8 +68,10 @@ if (_octave_qt_event_listener) delete _octave_qt_event_listener; +#ifdef HAVE_QSCINTILLA if (_file_editor) delete _file_editor; +#endif if (_terminal_dock_widget) delete _terminal_dock_widget; @@ -96,22 +98,28 @@ void main_window::new_file () { +#ifdef HAVE_QSCINTILLA _file_editor->request_new_file (); focus_editor (); +#endif } void main_window::open_file () { +#ifdef HAVE_QSCINTILLA _file_editor->request_open_file (); focus_editor (); +#endif } void main_window::open_file (const QString& file_name) { +#ifdef HAVE_QSCINTILLA _file_editor->request_open_file (file_name); focus_editor (); +#endif } void @@ -362,6 +370,7 @@ void main_window::focus_editor () { +#ifdef HAVE_QSCINTILLA if (!_file_editor->isVisible ()) { _file_editor->setVisible (true); @@ -370,6 +379,7 @@ _file_editor->setFocus (); _file_editor->activateWindow (); _file_editor->raise (); +#endif } void @@ -394,7 +404,9 @@ _debug_step_over->setEnabled (true); _debug_step_out->setEnabled (true); _debug_quit->setEnabled (true); +#ifdef HAVE_QSCINTILLA _file_editor->handle_entered_debug_mode (); +#endif } void @@ -406,7 +418,9 @@ _debug_step_over->setEnabled (false); _debug_step_out->setEnabled (false); _debug_quit->setEnabled (false); +#ifdef HAVE_QSCINTILLA _file_editor->handle_quit_debug_mode (); +#endif } void @@ -576,7 +590,9 @@ dummyWidget->hide (); setCentralWidget (dummyWidget); - _file_editor = new file_editor (_terminal, this); +#ifdef HAVE_QSCINTILLA + _file_editor = new file_editor (this); +#endif QMenu *file_menu = menuBar ()->addMenu (tr ("&File")); @@ -698,35 +714,47 @@ _debug_step_over = _debug_menu->addAction (QIcon (":/actions/icons/db_step.png"), tr ("Step")); _debug_step_over->setEnabled (false); +#ifdef HAVE_QSCINTILLA _file_editor->debug_menu ()->addAction (_debug_step_over); _file_editor->toolbar ()->addAction (_debug_step_over); +#endif _debug_step_over->setShortcut (Qt::Key_F10); _debug_step_into = _debug_menu->addAction (QIcon (":/actions/icons/db_step_in.png"), tr ("Step in")); _debug_step_into->setEnabled (false); +#ifdef HAVE_QSCINTILLA _file_editor->debug_menu ()->addAction (_debug_step_into); _file_editor->toolbar ()->addAction (_debug_step_into); +#endif _debug_step_into->setShortcut (Qt::Key_F11); _debug_step_out = _debug_menu->addAction (QIcon (":/actions/icons/db_step_out.png"), tr ("Step out")); _debug_step_out->setEnabled (false); +#ifdef HAVE_QSCINTILLA _file_editor->debug_menu ()->addAction (_debug_step_out); _file_editor->toolbar ()->addAction (_debug_step_out); +#endif _debug_step_out->setShortcut (Qt::ShiftModifier + Qt::Key_F11); _debug_continue = _debug_menu->addAction (QIcon (":/actions/icons/db_cont.png"), tr ("Continue")); _debug_continue->setEnabled (false); +#ifdef HAVE_QSCINTILLA _file_editor->debug_menu ()->addAction (_debug_continue); _file_editor->toolbar ()->addAction (_debug_continue); +#endif _debug_continue->setShortcut (Qt::Key_F5); _debug_menu->addSeparator (); +#ifdef HAVE_QSCINTILLA _file_editor->debug_menu ()->addSeparator (); +#endif _debug_quit = _debug_menu->addAction (QIcon (":/actions/icons/db_stop.png"), tr ("Exit Debug Mode")); _debug_quit->setEnabled (false); +#ifdef HAVE_QSCINTILLA _file_editor->debug_menu ()->addAction (_debug_quit); _file_editor->toolbar ()->addAction (_debug_quit); +#endif _debug_quit->setShortcut (Qt::ShiftModifier + Qt::Key_F5); //QMenu *parallelMenu = menuBar ()->addMenu (tr ("&Parallel")); @@ -866,10 +894,12 @@ _files_dock_widget, SLOT (setVisible (bool))); connect (_files_dock_widget, SIGNAL (active_changed (bool)), show_file_browser_action, SLOT (setChecked (bool))); +#ifdef HAVE_QSCINTILLA connect (show_editor_action, SIGNAL (toggled (bool)), _file_editor, SLOT (setVisible (bool))); connect (_file_editor, SIGNAL (active_changed (bool)), show_editor_action, SLOT (setChecked (bool))); +#endif connect (show_documentation_action, SIGNAL (toggled (bool)), _documentation_dock_widget, SLOT (setVisible (bool))); connect (_documentation_dock_widget, SIGNAL (active_changed (bool)), @@ -890,8 +920,10 @@ connect (reset_windows_action, SIGNAL (triggered ()), this, SLOT (reset_windows ())); +#ifdef HAVE_QSCINTILLA connect (this, SIGNAL (settings_changed ()), _file_editor, SLOT (notice_settings ())); +#endif connect (this, SIGNAL (settings_changed ()), _files_dock_widget, SLOT (notice_settings ())); connect (this, SIGNAL (settings_changed ()), @@ -941,7 +973,9 @@ addDockWidget (Qt::LeftDockWidgetArea, _workspace_view); addDockWidget (Qt::LeftDockWidgetArea, _history_dock_widget); addDockWidget (Qt::RightDockWidgetArea, _files_dock_widget); +#ifdef HAVE_QSCINTILLA addDockWidget (Qt::RightDockWidgetArea, _file_editor); +#endif addDockWidget (Qt::BottomDockWidgetArea, _terminal_dock_widget); addDockWidget (Qt::RightDockWidgetArea, _documentation_dock_widget); setStatusBar (_status_bar); diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/main-window.h --- a/libgui/src/main-window.h Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/main-window.h Thu Jan 03 13:36:55 2013 -0500 @@ -148,7 +148,9 @@ void exit_callback (void); QTerminal * _terminal; +#ifdef HAVE_QSCINTILLA file_editor_interface * _file_editor; +#endif QMenu * _debug_menu; QAction * _debug_continue; diff -r 2b6fe094e615 -r 1ca9beb2a194 libgui/src/symbol-information.cc --- a/libgui/src/symbol-information.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libgui/src/symbol-information.cc Thu Jan 03 13:36:55 2013 -0500 @@ -51,6 +51,7 @@ // for performance reasons. QString short_value_string; bool use_short_value_string = false; + if (ov.is_range ()) { use_short_value_string = true; @@ -58,8 +59,8 @@ Range r = ov.range_value (); double base = r.base (); - double increment = r.base (); - double limit = r.base (); + double increment = r.inc (); + double limit = r.limit (); std::stringstream buffer; @@ -72,16 +73,24 @@ } else if (ov.is_matrix_type () || ov.is_cell ()) { - if (ov.numel () > 10) - use_short_value_string = true; - } - else if (ov.is_string ()) - { - if (ov.string_value ().length () > 40) + if (ov.is_string ()) // a string? { - use_short_value_string = true; - short_value_string - = QString::fromStdString (ov.string_value ().substr (0, 40)); + if (ov.string_value ().length () > 30) + { + use_short_value_string = true; + short_value_string = QString ("\"") + + QString::fromStdString (ov.string_value ().substr (0, 30)) + + QString (" ... \""); + } + } + else // arrays and cell arrays + { + if (ov.numel () > 10) + { + use_short_value_string = true; + short_value_string = QString("..."); + // TODO: what kind of short version can be printed for arrays? + } } } diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/corefcn/__contourc__.cc --- a/libinterp/corefcn/__contourc__.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/corefcn/__contourc__.cc Thu Jan 03 13:36:55 2013 -0500 @@ -97,54 +97,87 @@ unsigned int start_edge, bool first, charMatrix& mark) { double px[4], py[4], pz[4], tmp; - unsigned int stop_edge, next_edge, pt[2]; - int next_r, next_c; + unsigned int stop_edge, pt[2]; + + // Continue while next facet is not done yet. + while (r >= 0 && c >= 0 && r < mark.rows () && c < mark.cols () + && mark(r, c) > 0) + { - //get x, y, and z - lvl for current facet - px[0] = px[3] = X(c); - px[1] = px[2] = X(c+1); + //get x, y, and z - lvl for current facet + px[0] = px[3] = X(c); + px[1] = px[2] = X(c+1); - py[0] = py[1] = Y(r); - py[2] = py[3] = Y(r+1); + py[0] = py[1] = Y(r); + py[2] = py[3] = Y(r+1); + + pz[3] = Z(r+1, c) - lvl; + pz[2] = Z(r+1, c + 1) - lvl; + pz[1] = Z(r, c+1) - lvl; + pz[0] = Z(r, c) - lvl; - pz[3] = Z(r+1, c) - lvl; - pz[2] = Z(r+1, c + 1) - lvl; - pz[1] = Z(r, c+1) - lvl; - pz[0] = Z(r, c) - lvl; + // Facet edge and point naming assignment. + // + // 0-----1 .-0-. + // | | | | + // | | 3 1 + // | | | | + // 3-----2 .-2-. - // Facet edge and point naming assignment. - // - // 0-----1 .-0-. - // | | | | - // | | 3 1 - // | | | | - // 3-----2 .-2-. + // Get mark value of current facet. + char id = static_cast (mark(r, c)); + + // Check startedge s. + if (start_edge == 255) + { + // Find start edge. + for (unsigned int k = 0; k < 4; k++) + if (static_cast (1 << k) & id) + start_edge = k; + } - // Get mark value of current facet. - char id = static_cast (mark(r, c)); + if (start_edge == 255) + break; + + // Decrease mark value of current facet for start edge. + mark(r, c) -= static_cast (1 << start_edge); - // Check startedge s. - if (start_edge == 255) - { - // Find start edge. - for (unsigned int k = 0; k < 4; k++) - if (static_cast (1 << k) & id) - start_edge = k; - } + // Next point (clockwise). + pt[0] = start_edge; + pt[1] = (pt[0] + 1) % 4; + + // Calculate contour segment start if first of contour. + if (first) + { + tmp = fabs (pz[pt[1]]) / fabs (pz[pt[0]]); - if (start_edge == 255) - return; + if (xisnan (tmp)) + ct_x = ct_y = 0.5; + else + { + ct_x = px[pt[0]] + (px[pt[1]] - px[pt[0]])/(1 + tmp); + ct_y = py[pt[0]] + (py[pt[1]] - py[pt[0]])/(1 + tmp); + } - // Decrease mark value of current facet for start edge. - mark(r, c) -= static_cast (1 << start_edge); + start_contour (lvl, ct_x, ct_y); + first = false; + } - // Next point (clockwise). - pt[0] = start_edge; - pt[1] = (pt[0] + 1) % 4; + // Find stop edge. + // FIXME -- perhaps this should use a while loop? + for (unsigned int k = 1; k <= 4; k++) + { + if (start_edge == 0 || start_edge == 2) + stop_edge = (start_edge + k) % 4; + else + stop_edge = (start_edge - k) % 4; - // Calculate contour segment start if first of contour. - if (first) - { + if (static_cast (1 << stop_edge) & id) + break; + } + + pt[0] = stop_edge; + pt[1] = (pt[0] + 1) % 4; tmp = fabs (pz[pt[1]]) / fabs (pz[pt[0]]); if (xisnan (tmp)) @@ -155,60 +188,25 @@ ct_y = py[pt[0]] + (py[pt[1]] - py[pt[0]])/(1 + tmp); } - start_contour (lvl, ct_x, ct_y); - } + // Add point to contour. + add_point (ct_x, ct_y); - // Find stop edge. - // FIXME -- perhaps this should use a while loop? - for (unsigned int k = 1; k <= 4; k++) - { - if (start_edge == 0 || start_edge == 2) - stop_edge = (start_edge + k) % 4; - else - stop_edge = (start_edge - k) % 4; - - if (static_cast (1 << stop_edge) & id) - break; - } - - pt[0] = stop_edge; - pt[1] = (pt[0] + 1) % 4; - tmp = fabs (pz[pt[1]]) / fabs (pz[pt[0]]); + // Decrease id value of current facet for start edge. + mark(r, c) -= static_cast (1 << stop_edge); - if (xisnan (tmp)) - ct_x = ct_y = 0.5; - else - { - ct_x = px[pt[0]] + (px[pt[1]] - px[pt[0]])/(1 + tmp); - ct_y = py[pt[0]] + (py[pt[1]] - py[pt[0]])/(1 + tmp); - } - - // Add point to contour. - add_point (ct_x, ct_y); - - // Decrease id value of current facet for start edge. - mark(r, c) -= static_cast (1 << stop_edge); + // Find next facet. + if (stop_edge == 0) + r--; + else if (stop_edge == 1) + c++; + else if (stop_edge == 2) + r++; + else if (stop_edge == 3) + c--; - // Find next facet. - next_c = c; - next_r = r; + // Go to next facet. + start_edge = (stop_edge + 2) % 4; - if (stop_edge == 0) - next_r--; - else if (stop_edge == 1) - next_c++; - else if (stop_edge == 2) - next_r++; - else if (stop_edge == 3) - next_c--; - - // Check if next facet is not done yet. - // Go to next facet. - if (next_r >= 0 && next_c >= 0 && next_r < mark.rows () - && next_c < mark.cols () && mark(next_r, next_c) > 0) - { - next_edge = (stop_edge + 2) % 4; - drawcn (X, Y, Z, lvl, next_r, next_c, ct_x, ct_y, next_edge, false, mark); } } diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/corefcn/svd.cc --- a/libinterp/corefcn/svd.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/corefcn/svd.cc Thu Jan 03 13:36:55 2013 -0500 @@ -421,3 +421,16 @@ return SET_INTERNAL_VARIABLE_CHOICES (svd_driver, driver_names); } + +/* +%!test +%! A = [1+1i, 1-1i, 0; 0, 2, 0; 1i, 1i, 1+2i]; +%! old_driver = svd_driver ("gesvd"); +%! [U1, S1, V1] = svd (A); +%! svd_driver ("gesdd"); +%! [U2, S2, V2] = svd (A); +%! assert (U1, U2, 5*eps); +%! assert (S1, S2, 5*eps); +%! assert (V1, V2, 5*eps); +%! svd_driver (old_driver); +*/ diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/dldfcn/convhulln.cc --- a/libinterp/dldfcn/convhulln.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/dldfcn/convhulln.cc Thu Jan 03 13:36:55 2013 -0500 @@ -179,7 +179,7 @@ { octave_idx_type j = 0; - if (! nonsimp_seen && ! facet->simplicial) + if (! (nonsimp_seen || facet->simplicial || qh hull_dim == 2)) { nonsimp_seen = true; @@ -313,4 +313,9 @@ %! h = sortrows (sort (h, 2), [1 2 3]); %! assert (h, [1 2 3;1 2 4; 1 3 4; 2 3 4]); %! assert (v, 8/3, 10*eps); + +%!testif HAVE_QHULL +%! triangle=[0 0; 1 1; 1 0; 1 2]; +%! h = convhulln (triangle); +%! assert (size (h), [3 2]); */ diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/octave-value/ov-cell.cc --- a/libinterp/octave-value/ov-cell.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/octave-value/ov-cell.cc Thu Jan 03 13:36:55 2013 -0500 @@ -1399,7 +1399,7 @@ s = struct (\"name\", @{\"Peter\", \"Hannah\", \"Robert\"@},\n\ \"age\", @{23, 16, 3@});\n\ c = struct2cell (s)\n\ - @result{} c = @{1x1x3 Cell Array@}\n\ + @result{} c = @{2x1x3 Cell Array@}\n\ c(1,1,:)(:)\n\ @result{}\n\ @{\n\ diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/octave-value/ov-ch-mat.cc --- a/libinterp/octave-value/ov-ch-mat.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/octave-value/ov-ch-mat.cc Thu Jan 03 13:36:55 2013 -0500 @@ -154,11 +154,17 @@ // The C++ standard guarantees cctype defines functions, not macros (and // hence macros *CAN'T* be defined if only cctype is included) so -// there's no need to fuck around. The exceptions are isascii and -// toascii, which are not C++. Oddly enough, all those character -// functions are int (*) (int), even in C++. Wicked! +// there's no need to fuck around. The exceptions are isascii and +// toascii, which are not C++. Oddly enough, all those character +// functions are int (*) (int), even in C++. Wicked! static inline int xisascii (int c) -{ return isascii (c); } +{ +#ifdef HAVE_ISASCII + return isascii (c); +#else + return (c >= 0x00 && c <= 0x7f); +#endif +} static inline int xtoascii (int c) { diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/octave-value/ov-java.cc --- a/libinterp/octave-value/ov-java.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/octave-value/ov-java.cc Thu Jan 03 13:36:55 2013 -0500 @@ -178,8 +178,6 @@ std::list java_opts; }; -static dim_vector compute_array_dimensions (JNIEnv* jni_env, jobject obj); - #ifdef __WIN32__ static std::string read_registry_string (const std::string& key, const std::string& value) @@ -726,8 +724,8 @@ jobjectArray_ref jobj (jni_env, reinterpret_cast (obj)); jclass_ref jcls (jni_env, jni_env->GetObjectClass (obj)); jclass_ref ccls (jni_env, jni_env->GetObjectClass (jcls)); - jmethodID isArray_ID = jni_env->GetMethodID (ccls, "isArray", "()Z"), - getComponentType_ID = jni_env->GetMethodID (ccls, "getComponentType", "()Ljava/lang/Class;"); + jmethodID isArray_ID = jni_env->GetMethodID (ccls, "isArray", "()Z"); + jmethodID getComponentType_ID = jni_env->GetMethodID (ccls, "getComponentType", "()Ljava/lang/Class;"); dim_vector dv (1, 1); int idx = 0; @@ -810,7 +808,8 @@ octave_value retval; jclass_ref rhsCls (jni_env); - jobject_ref resObj (jni_env), rhsObj (jni_env); + jobject_ref resObj (jni_env); + jobject_ref rhsObj (jni_env); jobject_ref java_idx (jni_env, make_java_index (jni_env, idx)); if (! error_state && unbox (jni_env, rhs, rhsObj, rhsCls)) @@ -839,15 +838,16 @@ { jclass_ref cls (jni_env, jni_env->GetObjectClass (jobj)); jclass_ref ccls (jni_env, jni_env->GetObjectClass (cls)); - jmethodID getMethods_ID = jni_env->GetMethodID (ccls, "getMethods", "()[Ljava/lang/reflect/Method;"), - getFields_ID = jni_env->GetMethodID (ccls, "getFields", "()[Ljava/lang/reflect/Field;"); - jobjectArray_ref mList (jni_env, reinterpret_cast (jni_env->CallObjectMethod (cls, getMethods_ID))), - fList (jni_env, reinterpret_cast (jni_env->CallObjectMethod (cls, getFields_ID))); - int mLen = jni_env->GetArrayLength (mList), fLen = jni_env->GetArrayLength (fList); - jclass_ref mCls (jni_env, jni_env->FindClass ("java/lang/reflect/Method")), - fCls (jni_env, jni_env->FindClass ("java/lang/reflect/Field")); - jmethodID m_getName_ID = jni_env->GetMethodID (mCls, "getName", "()Ljava/lang/String;"), - f_getName_ID = jni_env->GetMethodID (fCls, "getName", "()Ljava/lang/String;"); + jmethodID getMethods_ID = jni_env->GetMethodID (ccls, "getMethods", "()[Ljava/lang/reflect/Method;"); + jmethodID getFields_ID = jni_env->GetMethodID (ccls, "getFields", "()[Ljava/lang/reflect/Field;"); + jobjectArray_ref mList (jni_env, reinterpret_cast (jni_env->CallObjectMethod (cls, getMethods_ID))); + jobjectArray_ref fList (jni_env, reinterpret_cast (jni_env->CallObjectMethod (cls, getFields_ID))); + int mLen = jni_env->GetArrayLength (mList); + int fLen = jni_env->GetArrayLength (fList); + jclass_ref mCls (jni_env, jni_env->FindClass ("java/lang/reflect/Method")); + jclass_ref fCls (jni_env, jni_env->FindClass ("java/lang/reflect/Field")); + jmethodID m_getName_ID = jni_env->GetMethodID (mCls, "getName", "()Ljava/lang/String;"); + jmethodID f_getName_ID = jni_env->GetMethodID (fCls, "getName", "()Ljava/lang/String;"); for (int i = 0; i < mLen; i++) { @@ -1230,8 +1230,7 @@ { Matrix m = val.matrix_value (); jdoubleArray dv = jni_env->NewDoubleArray (m.length ()); - //for (int i = 0; i < m.length (); i++) - jni_env->SetDoubleArrayRegion (dv, 0, m.length (), m.fortran_vec ()); + jni_env->SetDoubleArrayRegion (dv, 0, m.length (), m.fortran_vec ()); jobj = dv; jcls = jni_env->GetObjectClass (jobj); } @@ -1410,38 +1409,6 @@ } } -DEFUN (__java_init__, , , - "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} java_init ()\n\ -Internal function used @strong{only} when debugging Java interface.\n\ -Function will directly call initialize_java() to create an instance of a JVM.\n\ -@end deftypefn") -{ - octave_value retval; - - retval = 0; - initialize_java (); - if (! error_state) - retval = 1; - - return retval; -} - -DEFUN (__java_exit__, , , - "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} java_exit ()\n\ -Internal function used @strong{only} when debugging Java interface.\n\ -Function will directly call terminate_jvm() to destroy the current JVM\n\ -instance.\n\ -@end deftypefn") -{ - octave_value retval; - - terminate_jvm (); - - return retval; -} - JNIEXPORT jboolean JNICALL Java_org_octave_Octave_call (JNIEnv *env, jclass, jstring funcName, jobjectArray argin, jobjectArray argout) @@ -1736,6 +1703,19 @@ return octave_value (""); } +void +octave_java::print (std::ostream& os, bool) const +{ + print_raw (os); + newline (os); +} + +void +octave_java::print_raw (std::ostream& os, bool) const +{ + os << ""; +} + octave_value octave_java::do_javaMethod (JNIEnv* jni_env, const std::string& name, const octave_value_list& args) @@ -1925,6 +1905,48 @@ // DEFUN blocks below must be outside of HAVE_JAVA block so that // documentation strings are always available, even when functions are not. +DEFUN (__java_init__, , , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} java_init ()\n\ +Internal function used @strong{only} when debugging Java interface.\n\ +Function will directly call initialize_java() to create an instance of a JVM.\n\ +@end deftypefn") +{ + +#ifdef HAVE_JAVA + octave_value retval; + + retval = 0; + + initialize_java (); + + if (! error_state) + retval = 1; + + return retval; +#else + error ("__java_init__: Octave was not compiled with Java interface"); + return octave_value (); +#endif +} + +DEFUN (__java_exit__, , , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} java_exit ()\n\ +Internal function used @strong{only} when debugging Java interface.\n\ +Function will directly call terminate_jvm() to destroy the current JVM\n\ +instance.\n\ +@end deftypefn") +{ +#ifdef HAVE_JAVA + terminate_jvm (); +#else + error ("__java_init__: Octave was not compiled with Java interface"); +#endif + + return octave_value (); +} + DEFUN (javaObject, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{jobj} =} javaObject (@var{classname})\n\ diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/octave-value/ov-java.h --- a/libinterp/octave-value/ov-java.h Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/octave-value/ov-java.h Thu Jan 03 13:36:55 2013 -0500 @@ -149,16 +149,9 @@ dim_vector dims (void) const; - void print (std::ostream& os, bool pr_as_read_syntax = false) const - { - os << ""; - newline(os); - } + void print (std::ostream& os, bool pr_as_read_syntax = false) const; - void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const - { - print(os, pr_as_read_syntax); - } + void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; octave_value_list subsref (const std::string& type, diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/octave.cc --- a/libinterp/octave.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/octave.cc Thu Jan 03 13:36:55 2013 -0500 @@ -657,6 +657,8 @@ { octave_process_command_line (argc, argv); + sysdep_init (); + install_defaults (); octave_initialize_interpreter (argc, argv, embedded); @@ -862,8 +864,6 @@ init_signals (); - sysdep_init (); - octave_ieee_init (); // The idea here is to force xerbla to be referenced so that we will diff -r 2b6fe094e615 -r 1ca9beb2a194 libinterp/template-inst/Array-jit.cc --- a/libinterp/template-inst/Array-jit.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/libinterp/template-inst/Array-jit.cc Thu Jan 03 13:36:55 2013 -0500 @@ -31,10 +31,15 @@ extern template class OCTAVE_API Array; -#include "pt-jit.h" +#include "jit-ir.h" NO_INSTANTIATE_ARRAY_SORT (jit_function); INSTANTIATE_ARRAY (jit_function, OCTINTERP_API); +#ifdef Cell_h +#error Must not include Cell.h in Array-jit.h +#error This causes problems on MSVC #endif + +#endif diff -r 2b6fe094e615 -r 1ca9beb2a194 liboctave/numeric/CmplxSVD.cc --- a/liboctave/numeric/CmplxSVD.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/liboctave/numeric/CmplxSVD.cc Thu Jan 03 13:36:55 2013 -0500 @@ -118,8 +118,7 @@ // // For Lapack 3.0, this problem seems to be fixed. - jobu = 'N'; - jobv = 'N'; + jobu = jobv = 'N'; ncol_u = nrow_vt = 1; break; @@ -142,21 +141,21 @@ Complex *vt = right_sm.fortran_vec (); - octave_idx_type lrwork = 5*max_mn; - - Array rwork (dim_vector (lrwork, 1)); - - // Ask ZGESVD what the dimension of WORK should be. + // Query ZGESVD for the correct dimension of WORK. octave_idx_type lwork = -1; Array work (dim_vector (1, 1)); octave_idx_type one = 1; - octave_idx_type m1 = std::max (m, one), nrow_vt1 = std::max (nrow_vt, one); + octave_idx_type m1 = std::max (m, one); + octave_idx_type nrow_vt1 = std::max (nrow_vt, one); if (svd_driver == SVD::GESVD) { + octave_idx_type lrwork = 5*max_mn; + Array rwork (dim_vector (lrwork, 1)); + F77_XFCN (zgesvd, ZGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), F77_CONST_CHAR_ARG2 (&jobv, 1), m, n, tmp_data, m1, s_vec, u, m1, vt, @@ -180,6 +179,14 @@ { assert (jobu == jobv); char jobz = jobu; + + octave_idx_type lrwork; + if (jobz == 'N') + lrwork = 7*min_mn; + else + lrwork = 5*min_mn*min_mn + 5*min_mn; + Array rwork (dim_vector (lrwork, 1)); + OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, 8*min_mn); F77_XFCN (zgesdd, ZGESDD, (F77_CONST_CHAR_ARG2 (&jobz, 1), diff -r 2b6fe094e615 -r 1ca9beb2a194 liboctave/numeric/dbleSVD.cc --- a/liboctave/numeric/dbleSVD.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/liboctave/numeric/dbleSVD.cc Thu Jan 03 13:36:55 2013 -0500 @@ -118,8 +118,7 @@ // // For Lapack 3.0, this problem seems to be fixed. - jobu = 'N'; - jobv = 'N'; + jobu = jobv = 'N'; ncol_u = nrow_vt = 1; break; @@ -142,14 +141,15 @@ double *vt = right_sm.fortran_vec (); - // Ask DGESVD what the dimension of WORK should be. + // Query DGESVD for the correct dimension of WORK. octave_idx_type lwork = -1; Array work (dim_vector (1, 1)); octave_idx_type one = 1; - octave_idx_type m1 = std::max (m, one), nrow_vt1 = std::max (nrow_vt, one); + octave_idx_type m1 = std::max (m, one); + octave_idx_type nrow_vt1 = std::max (nrow_vt, one); if (svd_driver == SVD::GESVD) { diff -r 2b6fe094e615 -r 1ca9beb2a194 liboctave/numeric/fCmplxSVD.cc --- a/liboctave/numeric/fCmplxSVD.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/liboctave/numeric/fCmplxSVD.cc Thu Jan 03 13:36:55 2013 -0500 @@ -120,8 +120,7 @@ // // For Lapack 3.0, this problem seems to be fixed. - jobu = 'N'; - jobv = 'N'; + jobu = jobv = 'N'; ncol_u = nrow_vt = 1; break; @@ -144,21 +143,21 @@ FloatComplex *vt = right_sm.fortran_vec (); - octave_idx_type lrwork = 5*max_mn; - - Array rwork (dim_vector (lrwork, 1)); - - // Ask ZGESVD what the dimension of WORK should be. + // Query CGESVD for the correct dimension of WORK. octave_idx_type lwork = -1; Array work (dim_vector (1, 1)); octave_idx_type one = 1; - octave_idx_type m1 = std::max (m, one), nrow_vt1 = std::max (nrow_vt, one); + octave_idx_type m1 = std::max (m, one); + octave_idx_type nrow_vt1 = std::max (nrow_vt, one); if (svd_driver == SVD::GESVD) { + octave_idx_type lrwork = 5*max_mn; + Array rwork (dim_vector (lrwork, 1)); + F77_XFCN (cgesvd, CGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), F77_CONST_CHAR_ARG2 (&jobv, 1), m, n, tmp_data, m1, s_vec, u, m1, vt, @@ -182,6 +181,14 @@ { assert (jobu == jobv); char jobz = jobu; + + octave_idx_type lrwork; + if (jobz == 'N') + lrwork = 5*min_mn; + else + lrwork = min_mn * std::max (5*min_mn+7, 2*max_mn+2*min_mn+1); + Array rwork (dim_vector (lrwork, 1)); + OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, 8*min_mn); F77_XFCN (cgesdd, CGESDD, (F77_CONST_CHAR_ARG2 (&jobz, 1), diff -r 2b6fe094e615 -r 1ca9beb2a194 liboctave/numeric/floatSVD.cc --- a/liboctave/numeric/floatSVD.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/liboctave/numeric/floatSVD.cc Thu Jan 03 13:36:55 2013 -0500 @@ -118,8 +118,7 @@ // // For Lapack 3.0, this problem seems to be fixed. - jobu = 'N'; - jobv = 'N'; + jobu = jobv = 'N'; ncol_u = nrow_vt = 1; break; @@ -142,14 +141,15 @@ float *vt = right_sm.fortran_vec (); - // Ask DGESVD what the dimension of WORK should be. + // Query SGESVD for the correct dimension of WORK. octave_idx_type lwork = -1; Array work (dim_vector (1, 1)); octave_idx_type one = 1; - octave_idx_type m1 = std::max (m, one), nrow_vt1 = std::max (nrow_vt, one); + octave_idx_type m1 = std::max (m, one); + octave_idx_type nrow_vt1 = std::max (nrow_vt, one); if (svd_driver == SVD::GESVD) { diff -r 2b6fe094e615 -r 1ca9beb2a194 liboctave/numeric/lo-specfun.cc --- a/liboctave/numeric/lo-specfun.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/liboctave/numeric/lo-specfun.cc Thu Jan 03 13:36:55 2013 -0500 @@ -46,10 +46,6 @@ #include "mx-inlines.cc" #include "lo-mappers.h" -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - #include "Faddeeva.hh" extern "C" diff -r 2b6fe094e615 -r 1ca9beb2a194 liboctave/numeric/oct-rand.cc --- a/liboctave/numeric/oct-rand.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/liboctave/numeric/oct-rand.cc Thu Jan 03 13:36:55 2013 -0500 @@ -427,7 +427,7 @@ if (use_old_generators) { double da = a; - double dretval; + double dretval = 0.0; switch (current_distribution) { case uniform_dist: diff -r 2b6fe094e615 -r 1ca9beb2a194 liboctave/numeric/randpoisson.c --- a/liboctave/numeric/randpoisson.c Tue Jan 01 19:54:15 2013 -0500 +++ b/liboctave/numeric/randpoisson.c Thu Jan 03 13:36:55 2013 -0500 @@ -422,7 +422,7 @@ double y, em, t; do { do { - y = tan(M_PI*RUNI); + y = tan (M_PI*RUNI); em = sq * y + lambda; } while (em < 0.0); em = floor (em); diff -r 2b6fe094e615 -r 1ca9beb2a194 m4/acinclude.m4 --- a/m4/acinclude.m4 Tue Jan 01 19:54:15 2013 -0500 +++ b/m4/acinclude.m4 Thu Jan 03 13:36:55 2013 -0500 @@ -1276,19 +1276,23 @@ dnl dnl Figure out the hardware-vendor-os info. dnl -dnl Hanging '])' in AC_MSG_WARN is for adding newline to output -dnl -AC_DEFUN([OCTAVE_HOST_TYPE], [ +AC_DEFUN([OCTAVE_CANONICAL_HOST], [ AC_CANONICAL_HOST if test -z "$host"; then - host=unknown + host=unknown-unknown-unknown + AC_MSG_WARN([configuring Octave for unknown system type]) fi canonical_host_type=$host - if test "$host" = unknown; then - AC_MSG_WARN([configuring Octave for unknown system type -]) + AC_SUBST(canonical_host_type) + if test -z "$host_cpu"; then + host_cpu=unknown fi - AC_SUBST(canonical_host_type) + if test -z "$host_vendor"; then + host_vendor=unknown + fi + if test -z "$host_os"; then + host_os=unknown + fi ]) dnl dnl Check for IEEE 754 data format. diff -r 2b6fe094e615 -r 1ca9beb2a194 scripts/io/importdata.m --- a/scripts/io/importdata.m Tue Jan 01 19:54:15 2013 -0500 +++ b/scripts/io/importdata.m Thu Jan 03 13:36:55 2013 -0500 @@ -19,9 +19,9 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {@var{A} =} importdata (@var{fname}) ## @deftypefnx {Function File} {@var{A} =} importdata (@var{fname}, @var{delimiter}) -## @deftypefnx {Function File} {@var{A} =} importdata (@var{fname}, @var{delimiter}, @var{header_rows}) -## @deftypefnx {Function File} {[@var{A}, @var{delimiter}] =} importdata (...) -## @deftypefnx {Function File} {[@var{A}, @var{delimiter}, @var{header_rows}] =} importdata (...) +## @deftypefnx {Function File} {@var{A} =} importdata (@var{fname}, @var{delimiter}, @var{header_rows}) +## @deftypefnx {Function File} {[@var{A}, @var{delimiter}] =} importdata (@dots{}) +## @deftypefnx {Function File} {[@var{A}, @var{delimiter}, @var{header_rows}] =} importdata (@dots{}) ## Importing data from file. ## ## Importing the contents of file @var{fname} into workspace. diff -r 2b6fe094e615 -r 1ca9beb2a194 scripts/io/strread.m --- a/scripts/io/strread.m Tue Jan 01 19:54:15 2013 -0500 +++ b/scripts/io/strread.m Thu Jan 03 13:36:55 2013 -0500 @@ -597,7 +597,8 @@ else if (! idg(ii) && ! isempty (strfind (fmt_words{ii-1}, "%s"))) ## Trailing literal. If preceding format == '%s' this is an error - warning ("Ambiguous '%s' specifier next to literal in column %d", icol); + warning ... + ("strread: ambiguous '%s' specifier next to literal in column %d", icol); elseif (idg(ii)) ## Current field = fixed width. Strip into icol, rest in icol+1 sw = regexp (fmt_words{ii}, '\d', "once"); @@ -797,8 +798,8 @@ %! str = sprintf ("%s %.6f %s\n", str, a(k), b(k)); %! endfor %! [aa, bb] = strread (str, "%f %s"); -%! assert (a, aa, 1e-6); -%! assert (cellstr (b), bb); +%! assert (aa, a, 1e-6); +%! assert (bb, cellstr (b)); %!test %! str = ""; @@ -808,7 +809,7 @@ %! str = sprintf ("%s %.6f %s\n", str, a(k), b(k)); %! endfor %! aa = strread (str, "%f %*s"); -%! assert (a, aa, 1e-6); +%! assert (aa, a, 1e-6); %!test %! str = sprintf ("/* this is\nacomment*/ 1 2 3"); diff -r 2b6fe094e615 -r 1ca9beb2a194 scripts/io/textscan.m --- a/scripts/io/textscan.m Tue Jan 01 19:54:15 2013 -0500 +++ b/scripts/io/textscan.m Thu Jan 03 13:36:55 2013 -0500 @@ -195,6 +195,7 @@ error ("textscan: character value required for EndOfLine"); endif else + if (! ischar (fid)) ## Determine EOL from file. Search for EOL candidates in first BUFLENGTH chars eol_srch_len = min (length (str), BUFLENGTH); ## First try DOS (CRLF) @@ -207,6 +208,9 @@ else eol_char = "\n"; endif + else + eol_char = "\n"; + endif ## Set up the default endofline param value args(end+1:end+2) = {"endofline", eol_char}; endif @@ -408,3 +412,88 @@ %! data = textscan(" 1. 1 \n 2 3\n", '%f %f'); %! assert (data{1}, [1; 2], 1e-15); %! assert (data{2}, [1; 3], 1e-15); + +%% Whitespace test (bug #37333) using delimiter ";" +%!test +%! tc = []; +%! tc{1, 1} = "C:/code;"; +%! tc{1, end+1} = "C:/code/meas;"; +%! tc{1, end+1} = " C:/code/sim;"; +%! tc{1, end+1} = "C:/code/utils;"; +%! string = [tc{:}]; +%! c = textscan (string, "%s", "delimiter", ";"); +%! for k = 1:numel (c{1}) +%! lh = c{1}{k}; +%! rh = tc{k}; +%! rh(rh == ";") = ""; +%! rh = strtrim (rh); +%! assert (strcmp (lh, rh)); +%! end + +%% Whitespace test (bug #37333), adding multipleDelimsAsOne true arg +%!test +%! tc = []; +%! tc{1, 1} = "C:/code;"; +%! tc{1, end+1} = " C:/code/meas;"; +%! tc{1, end+1} = "C:/code/sim;;"; +%! tc{1, end+1} = "C:/code/utils;"; +%! string = [tc{:}]; +%! c = textscan (string, "%s", "delimiter", ";", "multipleDelimsAsOne", 1); +%! for k = 1:numel (c{1}) +%! lh = c{1}{k}; +%! rh = tc{k}; +%! rh(rh == ";") = ""; +%! rh = strtrim (rh); +%! assert (strcmp (lh, rh)); +%! end + +%% Whitespace test (bug #37333), adding multipleDelimsAsOne false arg +%!test +%! tc = []; +%! tc{1, 1} = "C:/code;"; +%! tc{1, end+1} = " C:/code/meas;"; +%! tc{1, end+1} = "C:/code/sim;;"; +%! tc{1, end+1} = ""; +%! tc{1, end+1} = "C:/code/utils;"; +%! string = [tc{:}]; +%! c = textscan (string, "%s", "delimiter", ";", "multipleDelimsAsOne", 0); +%! for k = 1:numel (c{1}) +%! lh = c{1}{k}; +%! rh = tc{k}; +%! rh(rh == ";") = ""; +%! rh = strtrim (rh); +%! assert (strcmp (lh, rh)); +%! end + +%% Whitespace test (bug #37333) whitespace "" arg +%!test +%! tc = []; +%! tc{1, 1} = "C:/code;"; +%! tc{1, end+1} = " C:/code/meas;"; +%! tc{1, end+1} = "C:/code/sim;"; +%! tc{1, end+1} = "C:/code/utils;"; +%! string = [tc{:}]; +%! c = textscan (string, "%s", "delimiter", ";", "whitespace", ""); +%! for k = 1:numel (c{1}) +%! lh = c{1}{k}; +%! rh = tc{k}; +%! rh(rh == ";") = ""; +%! assert (strcmp (lh, rh)); +%! end + +%% Whitespace test (bug #37333), whitespace " " arg +%!test +%! tc = []; +%! tc{1, 1} = "C:/code;"; +%! tc{1, end+1} = " C:/code/meas;"; +%! tc{1, end+1} = "C:/code/sim;"; +%! tc{1, end+1} = "C:/code/utils;"; +%! string = [tc{:}]; +%! c = textscan (string, "%s", "delimiter", ";", "whitespace", " "); +%! for k = 1:numel (c{1}) +%! lh = c{1}{k}; +%! rh = tc{k}; +%! rh(rh == ";") = ""; +%! rh = strtrim (rh); +%! assert (strcmp (lh, rh)); +%! end diff -r 2b6fe094e615 -r 1ca9beb2a194 scripts/miscellaneous/orderfields.m --- a/scripts/miscellaneous/orderfields.m Tue Jan 01 19:54:15 2013 -0500 +++ b/scripts/miscellaneous/orderfields.m Thu Jan 03 13:36:55 2013 -0500 @@ -48,7 +48,7 @@ ## @} ## @end group ## @group -## t = struct ("d", @{@}, "c", @{@}, "b", "a", @{@}); +## t = struct ("d", @{@}, "c", @{@}, "b", @{@}, "a", @{@}); ## t2 = orderfields (s, t) ## @result{} t2 = ## @{ @@ -59,7 +59,7 @@ ## @} ## @end group ## @group -## t3 = orderfields (s, [3, 2, 4, 1]); +## t3 = orderfields (s, [3, 2, 4, 1]) ## @result{} t3 = ## @{ ## a = 1 diff -r 2b6fe094e615 -r 1ca9beb2a194 scripts/plot/__gnuplot_drawnow__.m --- a/scripts/plot/__gnuplot_drawnow__.m Tue Jan 01 19:54:15 2013 -0500 +++ b/scripts/plot/__gnuplot_drawnow__.m Thu Jan 03 13:36:55 2013 -0500 @@ -321,6 +321,7 @@ endif endif endif + fprintf (plot_stream, "set termoption dashed\n") else ## gnuplot will pick up the GNUTERM environment variable itself ## so no need to set the terminal type if not also setting the diff -r 2b6fe094e615 -r 1ca9beb2a194 src/Makefile.am --- a/src/Makefile.am Tue Jan 01 19:54:15 2013 -0500 +++ b/src/Makefile.am Thu Jan 03 13:36:55 2013 -0500 @@ -25,9 +25,10 @@ -I$(top_srcdir)/liboctave/array \ -I$(top_srcdir)/liboctave/cruft/misc \ -I$(top_srcdir)/liboctave/numeric \ + -I$(top_srcdir)/liboctave/system \ -I$(top_srcdir)/liboctave/util \ -I$(top_srcdir)/libinterp \ - -I$(top_builddir)/libinterp/interpfcn \ + -I$(top_builddir)/libinterp/interpfcn -I$(top_srcdir)/libinterp/interpfcn \ -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu AM_CFLAGS += $(WARN_CFLAGS) diff -r 2b6fe094e615 -r 1ca9beb2a194 src/main-cli.cc --- a/src/main-cli.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/src/main-cli.cc Thu Jan 03 13:36:55 2013 -0500 @@ -26,12 +26,15 @@ #include "defaults.h" #include "octave.h" +#include "sysdep.h" int main (int argc, char **argv) { octave_process_command_line (argc, argv); + sysdep_init (); + install_defaults (); octave_initialize_interpreter (argc, argv, 0); diff -r 2b6fe094e615 -r 1ca9beb2a194 src/main.cc --- a/src/main.cc Tue Jan 01 19:54:15 2013 -0500 +++ b/src/main.cc Thu Jan 03 13:36:55 2013 -0500 @@ -27,6 +27,7 @@ #include "defaults.h" #include "octave.h" #include "octave-gui.h" +#include "sysdep.h" int main (int argc, char **argv) @@ -35,6 +36,8 @@ octave_process_command_line (argc, argv); + sysdep_init (); + install_defaults (); if (octave_starting_gui ())