[3depict] 01/04: * Update to 0.0.17
D Haley
mycae-guest at moszumanska.debian.org
Sun Sep 28 15:46:52 UTC 2014
This is an automated email from the git hooks/post-receive script.
mycae-guest pushed a commit to branch master
in repository 3depict.
commit 06a21f13b28b411d6b2ee51ac2a1ace9c935d69d
Author: D Haley <mycae at gmx.com>
Date: Sun Sep 28 16:53:51 2014 +0200
* Update to 0.0.17
---
ChangeLog | 37 +
TODO | 16 +-
aclocal.m4 | 58 +-
config.h.in | 6 -
configure | 246 +-
configure.ac | 95 +-
data/naturalAbundance.xml | 16 +-
docs/developers/code-notes.txt | 5 -
docs/developers/filter-template.patch | 295 ++
docs/manual-latex/figures/Screenshot-thumb.png | Bin 0 -> 43986 bytes
docs/manual-latex/manual.blg | 2 +-
docs/manual-latex/manual.log | 30 +-
docs/manual-latex/manual.pdf | Bin 4517180 -> 4550865 bytes
docs/manual-latex/manual.tex | 6 +-
docs/web/about.html | 3 +
docs/web/compiling-OSX.html | 74 +
docs/web/compiling-cross.html | 56 +
docs/web/compiling-linux.html | 153 +
docs/web/compiling-macosx.html | 78 +
docs/web/compiling.html | 528 +---
docs/web/contact.html | 3 +-
docs/web/documentation.html | 25 +-
docs/web/download.html | 37 +-
docs/web/images/3Depict-icon.png | Bin 0 -> 9132 bytes
docs/web/images/Screenshot-thumb.png | Bin 0 -> 39680 bytes
docs/web/images/cu-ppt-cluster-analysis.png | Bin 0 -> 116809 bytes
docs/web/images/exportanimParamDialog.png | Bin 0 -> 89361 bytes
docs/web/images/laser-data1.png | Bin 0 -> 322814 bytes
docs/web/images/laser-data2.png | Bin 0 -> 193987 bytes
docs/web/images/resolution-example.png | Bin 0 -> 201393 bytes
docs/web/images/voxel-representations.png | Bin 0 -> 1034586 bytes
docs/web/index.html | 31 +-
docs/web/manual.html | 2 +-
docs/web/news.html | 35 +-
docs/web/questions.html | 25 +-
docs/web/rss.xml | 42 +-
docs/web/screenshots.html | 60 +
docs/web/videos.html | 37 +-
install-sh | 1 -
locales/de_DE/LC_MESSAGES/3Depict.mo | Bin 49844 -> 45179 bytes
packaging/RPM/3Depict-0.0.15-manual-pdf-loc.patch | 16 -
...t-path.patch => 3Depict-0.0.17-font-path.patch} | 8 +-
packaging/RPM/3Depict-0.0.17-manual-pdf-loc.patch | 16 +
packaging/RPM/3Depict-0.0.17-upstream.patch | 65 +
packaging/RPM/3Depict.spec | 14 +-
packaging/debian/3depict.install | 0
packaging/debian/changelog | 16 +-
packaging/debian/control | 2 +-
packaging/debian/copyright | 0
packaging/debian/patches/patch-caching-bug | 35 -
packaging/debian/patches/series | 2 -
packaging/debian/rules | 9 +-
packaging/deps/getDeps | 122 +-
packaging/mac/3package.sh | 18 +
packaging/mac/makeMacOSXApp | 2 +
packaging/makeTarball.sh | 21 +-
packaging/mingw-debian-cross/bootstrap.sh | 245 +-
.../mingw-debian-cross/patches/cmake-toolchain32 | 25 +
.../mingw-debian-cross/patches/cmake-toolchain64 | 24 +
.../patches/ftgl-mingw32-prototype | 0
.../patches/ftgl-override-configure | 0
.../patches/gettext-disable-tools | 0
.../patches/gettext-win32-prefix | 0
packaging/mingw-debian-cross/patches/glew-makefile | 31 +-
.../mingw-debian-cross/patches/glew-makefile.base | 27 +-
.../mingw-debian-cross/patches/gsl-config.patch | 0
.../mingw-debian-cross/patches/zlib-no-lc.patch | 0
packaging/mingw-debian-cross/windows-installer.nsi | 41 +-
src/3Depict.cpp | 108 +-
src/Makefile.am | 16 +-
src/Makefile.in | 74 +-
src/backend/APT/APTFileIO.cpp | 49 +-
src/backend/APT/APTFileIO.h | 7 +-
src/backend/APT/APTRanges.cpp | 58 +-
src/backend/APT/APTRanges.h | 12 +-
src/backend/APT/abundanceParser.cpp | 73 +
src/backend/APT/abundanceParser.h | 10 +-
src/backend/APT/ionhit.cpp | 6 +
src/backend/APT/ionhit.h | 2 +
src/backend/animator.cpp | 48 +-
src/backend/configFile.cpp | 10 +-
src/backend/filter.cpp | 188 +-
src/backend/filter.h | 115 +-
src/backend/filters/algorithms/K3DTree-mk2.cpp | 143 +-
src/backend/filters/algorithms/K3DTree-mk2.h | 19 +-
src/backend/filters/allFilter.h | 1 -
src/backend/filters/annotation.cpp | 247 +-
src/backend/filters/annotation.h | 2 +-
src/backend/filters/boundingBox.cpp | 106 +-
src/backend/filters/boundingBox.h | 2 +-
src/backend/filters/clusterAnalysis.cpp | 257 +-
src/backend/filters/clusterAnalysis.h | 3 +
src/backend/filters/compositionProfile.cpp | 280 +-
src/backend/filters/compositionProfile.h | 2 +-
src/backend/filters/dataLoad.cpp | 132 +-
src/backend/filters/dataLoad.h | 5 +-
src/backend/filters/externalProgram.cpp | 136 +-
src/backend/filters/filterCommon.cpp | 46 +-
src/backend/filters/filterCommon.h | 12 +-
src/backend/filters/ionClip.cpp | 139 +-
src/backend/filters/ionColour.cpp | 57 +-
src/backend/filters/ionColour.h | 2 +
src/backend/filters/ionDownsample.cpp | 88 +-
src/backend/filters/ionInfo.cpp | 76 +-
src/backend/filters/rangeFile.cpp | 266 +-
src/backend/filters/rangeFile.h | 4 +
src/backend/filters/spatialAnalysis.cpp | 815 ++++--
src/backend/filters/spatialAnalysis.h | 23 +-
src/backend/filters/spectrumPlot.cpp | 162 +-
src/backend/filters/spectrumPlot.h | 2 +-
src/backend/filters/transform.cpp | 144 +-
src/backend/filters/voxelise.cpp | 267 +-
src/backend/filters/voxelise.h | 2 +-
src/backend/filtertree.cpp | 91 +-
src/backend/filtertree.h | 8 +-
src/backend/filtertreeAnalyse.cpp | 5 +-
src/backend/plot.cpp | 1006 ++++---
src/backend/plot.h | 223 +-
src/backend/state.cpp | 154 +-
src/backend/state.h | 7 +-
src/backend/tree.hh | 0
src/backend/viscontrol.cpp | 257 +-
src/backend/viscontrol.h | 35 +-
src/common/array2D.h | 223 ++
src/common/basics.cpp | 411 ++-
src/common/basics.h | 176 +-
src/common/{translation.h => constants.cpp} | 39 +-
src/common/constants.h | 29 +-
src/common/stringFuncs.cpp | 77 +-
src/common/stringFuncs.h | 18 +-
src/common/translation.h | 5 -
src/gl/cameras.cpp | 99 +-
src/gl/cameras.h | 24 +-
src/gl/drawables.cpp | 334 ++-
src/gl/drawables.h | 223 +-
src/gl/glDebug.h | 37 +-
src/gl/scene.cpp | 118 +-
src/gl/scene.h | 8 +-
src/gl/textures.h | 9 +
src/gl/tr.cpp | 49 +-
src/gl/tr.h | 21 +
src/gui/dialogs/ExportPos.cpp | 36 +-
src/gui/dialogs/ExportRngDialog.cpp | 56 +-
src/gui/dialogs/StashDialog.cpp | 71 +-
src/gui/dialogs/StashDialog.h | 5 +-
src/gui/dialogs/animateFilterDialog.cpp | 174 +-
src/gui/dialogs/animateFilterDialog.h | 5 +-
.../animateSubDialogs/choiceKeyFrameDialog.cpp | 2 +-
.../animateSubDialogs/colourKeyFrameDialog.cpp | 36 +-
.../animateSubDialogs/stringKeyFrameDialog.cpp | 48 +-
src/gui/dialogs/autosaveDialog.cpp | 8 +-
src/gui/dialogs/filterErrorDialog.cpp | 10 +-
src/gui/dialogs/prefDialog.cpp | 290 +-
src/gui/dialogs/prefDialog.h | 9 +-
src/gui/dialogs/rangeEditDialog.cpp | 112 +-
src/gui/dialogs/rangeEditDialog.h | 2 +-
src/gui/dialogs/resolutionDialog.cpp | 42 +-
src/gui/glPane.cpp | 296 +-
src/gui/glPane.h | 9 +-
src/gui/glade-skeleton/animateFilterDialog.wxg | 0
.../animateSubDialogs/choiceKeyFrameDialog.wxg | 0
.../animateSubDialogs/colourChooserDialog.wxg | 0
.../animateSubDialogs/realKeyFrameDialog.wxg | 0
.../animateSubDialogs/stringKeyFrameDialog.wxg | 0
src/gui/glade-skeleton/autosaveDialog.wxg | 0
src/gui/glade-skeleton/errorDialog.wxg | 0
src/gui/glade-skeleton/mainWindow.wxg | 0
src/gui/glade-skeleton/preferencesDialog.wxg | 0
src/gui/glade-skeleton/resDialog.wxg | 0
src/gui/mainFrame.cpp | 1499 +++++-----
src/gui/mainFrame.h | 55 +-
src/gui/mathglPane.cpp | 296 +-
src/gui/mathglPane.h | 18 +-
src/testing/filtertesting.cpp | 31 +-
src/testing/mglTesting.cpp | 30 +-
src/testing/mglTesting.h | 18 +
src/testing/testing.cpp | 49 +-
src/testing/testing.h | 1 +
src/wx/propertyGridUpdater.cpp | 320 +++
src/wx/propertyGridUpdater.h | 43 +
src/wx/wxcommon.cpp | 112 +-
src/wx/wxcommon.h | 12 +-
src/wx/wxcomponents.cpp | 512 +---
src/wx/wxcomponents.h | 97 -
test/dogtail/test.py | 2 +-
translations/3Depict_base.pot | 2799 +++++++++---------
translations/3Depict_de_DE.mo | Bin 49844 -> 45179 bytes
translations/3Depict_de_DE.po | 2979 ++++++++++----------
translations/makeTranslations | 6 +-
189 files changed, 11057 insertions(+), 9676 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 42b3ac6..6f343ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+* 01 Sep 2014 : 0.0.17
+ Features
+ - Upgrade to wxWidgets 3 (wx3)
+ - Now using wx3 property grid. Property grid interaction
+ greatly improved.
+ - Categories collapsible
+ - file browse buttons
+ - One-click check buttons/dropdown
+ - Set (Subtraction/Union/Intersection) operations on points
+ - Can, eg load data from separate file after performing
+ operations on primary file
+
+
+ User Visible Changes
+ - Fix bug in left/right panel startup size setting
+ - Exporting images with colour bar now works correctly
+ - Cursor now shows OS' busy status during refresh
+ - Files no longer disappear from recent when loading
+ - Fix range propagation behaviour when using spatial analysis
+ - Clustering now supports cluster ID->value mode (Feature request)
+ - Status messages are now queued, so they won't be missed
+ - Fixed profile minimum events not working
+
+ Technical bugfixes/changes:
+ - wxWidgets < 2.9 (prior to 2010) no longer supported
+ - Remove 2.8 conditional code
+ - Mathgl < 2.0 (prior to 2011) no longer supported
+ - Remove 1.x conditional code
+ - Fix relatively frequent crashes when sampling data files
+ under parallel mode
+ - 2D plots (f(x,y) and scatter+size) now supported, but no
+ filter actually currently uses this
+ - All filter properties must have a group title
+ - Fix crash in mac OSX if expected data files not found
+ - Refactoring for filter caching and property setting
+ - Fix linker failure when using distcc
+
* 01 Mar 2014 : 0.0.16
Features:
- Added experimental LAWATAP (ATO) file support
diff --git a/TODO b/TODO
index d425a18..c648e05 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,16 @@
TODO List - worlds simplest bugtracking system
--Packaging--
+ * Update manual with
+ - cluster ID
+ - Set operations
--Main app--
To Implement:
== Next version ==
+ * Alpha blending on plane slice?
== Eventually ==
- * Support for XY scatter plots
- * Status bar message queue
* Voxel export dialog
* VTK voxel data export
* OPS and other 3DAP formats reader?
@@ -36,10 +38,9 @@ TODO List - worlds simplest bugtracking system
Outstanding bugs:
== Next release==
- * Colour bar drawing broken when tiling an output image
- * Fix voxelisation "filter" option
-
+
== Eventually==
+ * Fix voxelisation "filter" option
* Cluster filter wont save state correctly if parent
rangefile has disabled ions. It will output incorrect
number of enabled ions, and get wiped during next ::initFilter
@@ -68,7 +69,6 @@ TODO List - worlds simplest bugtracking system
* Pos limit loader could alter its behaviour when
sampling rates some percentage to be determined (load
file, skip buffer).
- * KD tree could implement proper range queries, eg bounds overlaps box
* Clustering could be paralellised, but is complex. Split & weld along KD tree lines using
cluster BB interactions.
* Examine performance characteristics of HULL_GRAB in ioninfo
@@ -80,9 +80,6 @@ TODO List - worlds simplest bugtracking system
-- Refactor/cleanup --
- * updateFilterPropertyGrid is in a bad location, need new
- file that knows about filters and wx at the same time,
- but is not viscontrol ;)
* Plotting code is a nightmare. Data model for plot.h is not
very well thought out, leading to large duplication, and elaborate special-case-ing
- Plots need log/non-log axes
@@ -91,7 +88,6 @@ TODO List - worlds simplest bugtracking system
- Plots need to be able to set strings/legends
- There is little diference between plot1D and plot2D, really.
* work out which inline FIXMEs and TODOs are still valid, and need attention
- * I have multiple colour classes floating about. might be an idea to unify them.
* K3DTree currently requires public access to members of boundcube
* Enums should be, where possible, moved into their relevant class' namespace
* Better error code behaviour for filters. There is a lot of needless duplication
diff --git a/aclocal.m4 b/aclocal.m4
index 7bf2270..170ae3e 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -180,6 +180,61 @@ else
fi[]dnl
])# PKG_CHECK_MODULES
+
+# PKG_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable pkgconfigdir as the location where a module
+# should install pkg-config .pc files. By default the directory is
+# $libdir/pkgconfig, but the default can be changed by passing
+# DIRECTORY. The user can override through the --with-pkgconfigdir
+# parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_INSTALLDIR
+
+
+# PKG_NOARCH_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable noarch_pkgconfigdir as the location where a
+# module should install arch-independent pkg-config .pc files. By
+# default the directory is $datadir/pkgconfig, but the default can be
+# changed by passing DIRECTORY. The user can override through the
+# --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_NOARCH_INSTALLDIR
+
+
+# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -------------------------------------------
+# Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])# PKG_CHECK_VAR
+
# Copyright (C) 2002-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
@@ -733,8 +788,7 @@ to "yes", and re-run configure.
END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
-fi
-])
+fi])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
diff --git a/config.h.in b/config.h.in
index 60472de..affad5d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -24,9 +24,6 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
-/* MathGL compilation OK */
-#undef HAVE_MGL
-
/* PNG compilation OK */
#undef HAVE_PNG
@@ -90,9 +87,6 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
-/* "Enable mgl1 support" */
-#undef USE_MGL1
-
/* "Enable mgl2 support" */
#undef USE_MGL2
diff --git a/configure b/configure
index 62f3ce3..045e12b 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for 3Depict 0.0.16.
+# Generated by GNU Autoconf 2.69 for 3Depict 0.0.17.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='3Depict'
PACKAGE_TARNAME='3depict'
-PACKAGE_VERSION='0.0.16'
-PACKAGE_STRING='3Depict 0.0.16'
+PACKAGE_VERSION='0.0.17'
+PACKAGE_STRING='3Depict 0.0.17'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -779,8 +779,6 @@ with_libqhull_flags
with_libqhull_link
with_libpng_flags
with_libpng_link
-enable_mgl2
-enable_mgl1
with_mgl_flags
with_mgl_libs
with_gsl_flags
@@ -791,6 +789,7 @@ enable_gsltest
with_intl_libs
enable_openmp_parallel
enable_debug_checks
+enable_ubsan
'
ac_precious_vars='build_alias
host_alias
@@ -1352,7 +1351,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures 3Depict 0.0.16 to adapt to many kinds of systems.
+\`configure' configures 3Depict 0.0.17 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1422,7 +1421,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of 3Depict 0.0.16:";;
+ short | recursive ) echo "Configuration of 3Depict 0.0.17:";;
esac
cat <<\_ACEOF
@@ -1436,11 +1435,10 @@ Optional Features:
do not reject slow dependency extractors
--disable-dependency-tracking
speeds up one-time build
- --enable-mgl2 Enable mathgl 2.x support
- --enable-mgl1 Enable mathgl 1.x support
--disable-gsltest Do not try to compile and run a test GSL program
--enable-openmp-parallel Enable OpenMP multi-CPU usage; requires GCC > 4.2 for parallel STL support
--disable-debug-checks Disable any debug checking, provides faster operation, but less information needed to debug internal problems, or to provide problem reports to developers
+ --disable-ubsan Disable undefined behaviour sanitizer. Only takes effect on certain ubsan supporting compilers. Useful for working around ubsan aborts that you cant fix (eg 3rd party libs
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1554,7 +1552,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-3Depict configure 0.0.16
+3Depict configure 0.0.17
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2194,52 +2192,6 @@ fi
} # ac_fn_cxx_check_header_mongrel
-# ac_fn_cxx_try_link LINENO
-# -------------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_cxx_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- test -x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_cxx_try_link
-
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -2364,7 +2316,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by 3Depict $as_me 0.0.16, which was
+It was created by 3Depict $as_me 0.0.17, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3227,7 +3179,7 @@ fi
# Define the identity of the package.
PACKAGE='3depict'
- VERSION='0.0.16'
+ VERSION='0.0.17'
cat >>confdefs.h <<_ACEOF
@@ -3319,7 +3271,6 @@ END
as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
fi
fi
-
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5372,7 +5323,7 @@ fi
if test "$WX_CONFIG_PATH" != "no" ; then
WX_VERSION=""
- min_wx_version=2.6.0
+ min_wx_version=2.9.0
if test -z "" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version" >&5
$as_echo_n "checking for wxWidgets version >= $min_wx_version... " >&6; }
@@ -5544,20 +5495,23 @@ fi
#Append the --gl-libs flag
-WX_LIBS="$WX_LIBS `$WX_CONFIG_PATH --gl-libs`"
+WX_LIBS="$WX_LIBS `$WX_CONFIG_PATH --libs gl,propgrid`"
WANT_WINDRES="no"
case "${host_os}" in
- *w64_mingw*)
+ *mingw*)
#wx-config is a little unreliable in cross-compile mode
# Manually append -DUNICODE to cppflags/cxxflags
WX_CXXFLAGS="$WX_CXXFLAGS -DUNICODE"
WX_CPPFLAGS="$WX_CPPFLAGS -DUNICODE"
- WANT_WINDRES="true"
+ WANT_WINDRES="yes"
;;
esac
- if test x$WANT_WINDRES= xtrue ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Want windres... $WANT_WINDRES" >&5
+$as_echo "Want windres... $WANT_WINDRES" >&6; }
+
+ if test x"$WANT_WINDRES" == "xyes" ; then
HAVE_WINDRES_TRUE=
HAVE_WINDRES_FALSE='#'
else
@@ -6800,20 +6754,6 @@ esac
CFLAGS_ORIG="$CFLAGS"
LDFLAGS_ORIG="$LDFLAGS"
-# Check whether --enable-mgl2 was given.
-if test "${enable_mgl2+set}" = set; then :
- enableval=$enable_mgl2;
-fi
-
-# Check whether --enable-mgl1 was given.
-if test "${enable_mgl1+set}" = set; then :
- enableval=$enable_mgl1;
-fi
-
-
-if test x"${enable_mgl2}" == x"yes" && test x"${enable_mgl1}" == x"yes"; then
- as_fn_error $? "\"Can specify mgl1, or mgl2 - not both\"" "$LINENO" 5
-fi
# Check whether --with-mgl-flags was given.
@@ -6841,8 +6781,6 @@ fi
LDFLAGS="$LDFLAGS $MGL_LIBS"
-#Note:
-# mathgl1.x uses mgl_c.h as c functions.
# mathgl2.x uses mgl_cf.h for c functions.
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
@@ -6850,11 +6788,10 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test x"${enable_mgl2}" == x"yes" ; then
$as_echo "#define USE_MGL2 1 " >>confdefs.h
- as_ac_Header=`$as_echo "ac_cv_header_"mgl2/mgl_cf.h"" | $as_tr_sh`
+as_ac_Header=`$as_echo "ac_cv_header_"mgl2/mgl_cf.h"" | $as_tr_sh`
ac_fn_cxx_check_header_mongrel "$LINENO" ""mgl2/mgl_cf.h"" "$as_ac_Header" "$ac_includes_default"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
@@ -6863,100 +6800,6 @@ else
fi
-else
- if test x"${enable_mgl1}" == x"yes" ; then
-
-$as_echo "#define USE_MGL1 0 " >>confdefs.h
-
- as_ac_Header=`$as_echo "ac_cv_header_"mgl/mgl_c.h"" | $as_tr_sh`
-ac_fn_cxx_check_header_mongrel "$LINENO" ""mgl/mgl_c.h"" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-
-else
- as_fn_error $? "\"mgl specified, but header mgl/mgl_c.h not found\"" "$LINENO" 5
-fi
-
-
- else
- #mgl2 is installed into different path (at least under debian)
- # /usr/include/mgl2/
- MGL_TEST_HEADERS="mgl2/mgl_cf.h mgl/mgl_c.h"
- for ac_header in $MGL_TEST_HEADERS
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- HAVE_MGL_H=1; break;
-fi
-
-done
-
-
- #check our set HAVE_MGL_H for *any* mglh
- if test $HAVE_MGL_H -ne 1 ; then :
- as_fn_error $? "\"MGL headers not found, looking for any of $MGL_TEST_HEADERS\"" "$LINENO" 5
-fi
-
- #Check MGL 2:
- if test x"$ac_cv_header_mgl2_mgl_cf_h" == x"yes" ; then :
- $as_echo "#define USE_MGL2 1" >>confdefs.h
-
-else
- USE_MGL2=0
-fi
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mgl_set_def_param in -lmgl" >&5
-$as_echo_n "checking for mgl_set_def_param in -lmgl... " >&6; }
-if ${ac_cv_lib_mgl_mgl_set_def_param+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lmgl -lmgl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char mgl_set_def_param ();
-int
-main ()
-{
-return mgl_set_def_param ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- ac_cv_lib_mgl_mgl_set_def_param=yes
-else
- ac_cv_lib_mgl_mgl_set_def_param=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mgl_mgl_set_def_param" >&5
-$as_echo "$ac_cv_lib_mgl_mgl_set_def_param" >&6; }
-if test "x$ac_cv_lib_mgl_mgl_set_def_param" = xyes; then :
-
-$as_echo "#define HAVE_MGL /**/" >>confdefs.h
-
-else
- as_fn_error $? "Required MathGL libraries not found" "$LINENO" 5
-fi
-
-
- fi
-fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -7298,6 +7141,15 @@ else
fi
+# Check whether --enable-ubsan was given.
+if test "${enable_ubsan+set}" = set; then :
+ enableval=$enable_ubsan; enable_no_ubsan="yes"
+else
+ enable_no_ubsan="no"
+fi
+
+
+
if test x"$enable_openmp_parallel" != x"" ;
then
@@ -7319,14 +7171,43 @@ then
- if test x"$GCC" = xyes; then
+ if test x"$GCC" = x"yes" ; then
# Strip optimsation flags from debug build
+ #--
CFLAGS=`echo "$CFLAGS" | sed -e 's/-O[0-9s]*//g'`
CXXFLAGS=`echo "$CXXFLAGS" | sed -e 's/-O[0-9s]*//g'`
CFLAGS="$CFLAGS -g"
CXXFLAGS="$CXXFLAGS -g"
+ #--
+
+ #Check for UbSan availability
+ #--
+ if test x"${enable_no_ubsan}" == x"no" ; then
+
+ USE_UBSAN="no"
+
+ case "${host_os}" in
+ *inux*)
+ GCC_VER=`gcc --version | head -n 1 | awk '{ print $(NF)}'`
+ case "${GCC_VER}" in
+ 4.9*)
+ USE_UBSAN="yes"
+ ;;
+ esac
+ ;;
+ esac
+
+ if test x"$USE_UBSAN" == x"yes" ; then
+ CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined -fsanitize=return -fsanitize=integer-divide-by-zero -fsanitize=vla-bound -fsanitize=null -fsanitize=signed-integer-overflow"
+ CXXFLAGS="$CXXFLAGS -fsanitize=address -fsanitize=undefined -fsanitize=return -fsanitize=integer-divide-by-zero -fsanitize=vla-bound -fsanitize=null -fsanitize=signed-integer-overflow"
+ LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=undefined -fsanitize=return "
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"Enabling Gcc-UbSan\"" >&5
+$as_echo "\"Enabling Gcc-UbSan\"" >&6; };
+ fi
+ fi
+ #--
fi
@@ -7337,6 +7218,13 @@ else
fi
fi
+if test x"$CXX" = xdistcc ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"Adding distcc link flags\"" >&5
+$as_echo "\"Adding distcc link flags\"" >&6; };
+ #Add -lstdc++ to libs for distcc
+ LIBS="$LIBS -lstdc++"
+fi
+
# Checks for typedefs, structures, and compiler characteristics.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
@@ -8126,7 +8014,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by 3Depict $as_me 0.0.16, which was
+This file was extended by 3Depict $as_me 0.0.17, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -8192,7 +8080,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-3Depict config.status 0.0.16
+3Depict config.status 0.0.17
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 4a35591..c38c1c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([3Depict], [0.0.16])
+AC_INIT([3Depict], [0.0.17])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_PROG_CXX
AC_PROG_CC
@@ -18,7 +18,7 @@ dnl Test for wx-widgets
dnl ----------
AM_OPTIONS_WXCONFIG
-AM_PATH_WXCONFIG(2.6.0, wxWin=1)
+AM_PATH_WXCONFIG(2.9.0, wxWin=1)
if test "$wxWin" != 1; then
AC_MSG_ERROR([
@@ -34,20 +34,22 @@ fi
#Append the --gl-libs flag
-WX_LIBS="$WX_LIBS `$WX_CONFIG_PATH --gl-libs`"
+WX_LIBS="$WX_LIBS `$WX_CONFIG_PATH --libs gl,propgrid`"
WANT_WINDRES="no"
case "${host_os}" in
- *w64_mingw*)
+ *mingw*)
#wx-config is a little unreliable in cross-compile mode
# Manually append -DUNICODE to cppflags/cxxflags
WX_CXXFLAGS="$WX_CXXFLAGS -DUNICODE"
WX_CPPFLAGS="$WX_CPPFLAGS -DUNICODE"
- WANT_WINDRES="true"
+ WANT_WINDRES="yes"
;;
esac
-AM_CONDITIONAL([HAVE_WINDRES], [ test x$WANT_WINDRES= xtrue ] )
+AC_MSG_RESULT([Want windres... $WANT_WINDRES])
+
+AM_CONDITIONAL([HAVE_WINDRES], [ test x"$WANT_WINDRES" == "xyes"] )
AC_SUBST(WX_LIBS)
@@ -280,14 +282,6 @@ dnl ----------
CFLAGS_ORIG="$CFLAGS"
LDFLAGS_ORIG="$LDFLAGS"
-AC_ARG_ENABLE(mgl2,
- [ --enable-mgl2 Enable mathgl 2.x support])
-AC_ARG_ENABLE(mgl1,
- [ --enable-mgl1 Enable mathgl 1.x support])
-
-if test x"${enable_mgl2}" == x"yes" && test x"${enable_mgl1}" == x"yes"; then
- AC_MSG_ERROR(["Can specify mgl1, or mgl2 - not both"])
-fi
AC_ARG_WITH(mgl-flags,
[ --with-mgl-flags=PATH : specify compiler flags for mathgl])
@@ -307,36 +301,10 @@ fi
AC_SUBST(MGL_LIBS)
LDFLAGS="$LDFLAGS $MGL_LIBS"
-#Note:
-# mathgl1.x uses mgl_c.h as c functions.
# mathgl2.x uses mgl_cf.h for c functions.
AC_LANG_PUSH([C++])
-if test x"${enable_mgl2}" == x"yes" ; then
- AC_DEFINE(USE_MGL2, 1 , ["Enable mgl2 support"])
- AC_CHECK_HEADER("mgl2/mgl_cf.h",[],[AC_MSG_ERROR(["mgl2 specified, but header mgl2/mgl_cf.h not found"])],[])
-else
- if test x"${enable_mgl1}" == x"yes" ; then
- AC_DEFINE(USE_MGL1, 0 , ["Enable mgl1 support"])
- AC_CHECK_HEADER("mgl/mgl_c.h",[],[AC_MSG_ERROR(["mgl specified, but header mgl/mgl_c.h not found"])],[])
- else
- #mgl2 is installed into different path (at least under debian)
- # /usr/include/mgl2/
- MGL_TEST_HEADERS="mgl2/mgl_cf.h mgl/mgl_c.h"
- AC_CHECK_HEADERS($MGL_TEST_HEADERS,[HAVE_MGL_H=1; break;], [])
-
- #check our set HAVE_MGL_H for *any* mglh
- AS_IF([ test $HAVE_MGL_H -ne 1 ] , [ AC_MSG_ERROR(["MGL headers not found, looking for any of $MGL_TEST_HEADERS"])])
-
- #Check MGL 2:
- AS_IF([ test x"$ac_cv_header_mgl2_mgl_cf_h" == x"yes" ], [ AC_DEFINE(USE_MGL2,1) ], [ USE_MGL2=0 ])
-
-
-
- AC_CHECK_LIB(mgl, mgl_set_def_param, [AC_DEFINE(HAVE_MGL,[],[MathGL compilation OK])] ,
- AC_MSG_ERROR([Required MathGL libraries not found]), -lmgl)
-
- fi
-fi
+AC_DEFINE(USE_MGL2, 1 , ["Enable mgl2 support"])
+AC_CHECK_HEADER("mgl2/mgl_cf.h",[],[AC_MSG_ERROR(["mgl2 specified, but header mgl2/mgl_cf.h not found"])],[])
AC_LANG_POP([C++])
@@ -408,6 +376,11 @@ AC_ARG_ENABLE(openmp-parallel,
AC_ARG_ENABLE(debug-checks,
[ --disable-debug-checks Disable any debug checking, provides faster operation, but less information needed to debug internal problems, or to provide problem reports to developers ],[enable_no_debug_checks="yes"],[enable_no_debug_checks="no"])
+AC_ARG_ENABLE(ubsan,
+ [ --disable-ubsan Disable undefined behaviour sanitizer. Only takes effect on certain ubsan supporting compilers. Useful for working around ubsan aborts that you cant fix (eg 3rd party libs ],
+ [ enable_no_ubsan="yes"],[enable_no_ubsan="no"])
+
+
if test x"$enable_openmp_parallel" != x"" ;
then
@@ -429,15 +402,43 @@ then
AC_SUBST(DEBUG_FLAGS)
- if test x"$GCC" = xyes; then
+ if test x"$GCC" = x"yes" ; then
# Strip optimsation flags from debug build
+ #--
changequote({,})
CFLAGS=`echo "$CFLAGS" | sed -e 's/-O[0-9s]*//g'`
CXXFLAGS=`echo "$CXXFLAGS" | sed -e 's/-O[0-9s]*//g'`
changequote([,])
CFLAGS="$CFLAGS -g"
CXXFLAGS="$CXXFLAGS -g"
-
+ #--
+
+ #Check for UbSan availability
+ #--
+ if test x"${enable_no_ubsan}" == x"no" ; then
+
+ USE_UBSAN="no"
+
+ case "${host_os}" in
+ *inux*)
+ GCC_VER=`gcc --version | head -n 1 | awk '{ print $(NF)}'`
+ case "${GCC_VER}" in
+ 4.9*)
+ USE_UBSAN="yes"
+ ;;
+ esac
+ ;;
+ esac
+
+ if test x"$USE_UBSAN" == x"yes" ; then
+ CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined -fsanitize=return -fsanitize=integer-divide-by-zero -fsanitize=vla-bound -fsanitize=null -fsanitize=signed-integer-overflow"
+ CXXFLAGS="$CXXFLAGS -fsanitize=address -fsanitize=undefined -fsanitize=return -fsanitize=integer-divide-by-zero -fsanitize=vla-bound -fsanitize=null -fsanitize=signed-integer-overflow"
+ LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=undefined -fsanitize=return "
+ AC_MSG_RESULT(["Enabling Gcc-UbSan"]);
+ fi
+ fi
+ #--
+
fi
else
@@ -447,6 +448,12 @@ else
fi
fi
+if test x"$CXX" = xdistcc ; then
+ AC_MSG_RESULT(["Adding distcc link flags"]);
+ #Add -lstdc++ to libs for distcc
+ LIBS="$LIBS -lstdc++"
+fi
+
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST
diff --git a/data/naturalAbundance.xml b/data/naturalAbundance.xml
index 7a371b0..b321d61 100644
--- a/data/naturalAbundance.xml
+++ b/data/naturalAbundance.xml
@@ -129,7 +129,7 @@ http://www.iupac.org/publications/pac/2003/7506/7506x0683.html
<mass value="15.9994" error="0.0003"/>
<isotope mass-number="16">
<mass value="15.9949146223" error="0.0000000025"/>
- <abundance value="0.99759" error="0.00016"/>
+ <abundance value="0.99757" error="0.00016"/>
</isotope>
<isotope mass-number="17">
<mass value="16.99913150" error="0.00000022"/>
@@ -267,7 +267,7 @@ http://www.iupac.org/publications/pac/2003/7506/7506x0683.html
<mass value="39.948" error="0.001"/>
<isotope mass-number="36">
<mass value="35.96754626" error="0.00000027"/>
- <abundance value="0.0003365" error="0.000030"/>
+ <abundance value="0.003365" error="0.000030"/>
</isotope>
<isotope mass-number="38">
<mass value="37.9627322" error="0.0000005"/>
@@ -328,7 +328,7 @@ http://www.iupac.org/publications/pac/2003/7506/7506x0683.html
<entry symbol="Sc" atomic-number="21">
<natural-abundance>
<mass value="44.955910" error="0.000008"/>
- <isotope mass-number="45">
+<isotope mass-number="45">
<mass value="44.9559102" error="0.0000012"/>
<abundance value="1" error="0"/>
</isotope>
@@ -353,6 +353,10 @@ http://www.iupac.org/publications/pac/2003/7506/7506x0683.html
<mass value="48.9478707" error="0.0000010"/>
<abundance value="0.0541" error="0.0002"/>
</isotope>
+ <isotope mass-number="50">
+ <mass value="49.9447912" error="0.0000010"/>
+ <abundance value="0.0518" error="0.0002"/>
+ </isotope>
</natural-abundance>
</entry>
<entry symbol="V" atomic-number="23">
@@ -445,7 +449,7 @@ http://www.iupac.org/publications/pac/2003/7506/7506x0683.html
</isotope>
<isotope mass-number="62">
<mass value="61.9283484" error="0.0000015"/>
- <abundance value="0.0036345" error="0.000017"/>
+ <abundance value="0.036345" error="0.000017"/>
</isotope>
<isotope mass-number="64">
<mass value="63.9279692" error="0.0000016"/>
@@ -732,7 +736,7 @@ http://www.iupac.org/publications/pac/2003/7506/7506x0683.html
</isotope>
<isotope mass-number="99">
<mass value="98.9059385" error="0.0000022"/>
- <abundance value=".01276" error="0.0014"/>
+ <abundance value=".1276" error="0.0014"/>
</isotope>
<isotope mass-number="100">
<mass value="99.9042189" error="0.0000022"/>
@@ -1024,7 +1028,7 @@ http://www.iupac.org/publications/pac/2003/7506/7506x0683.html
</isotope>
<isotope mass-number="135">
<mass value="134.905684" error="0.000003"/>
- <abundance value="0.000003" error="0.00012"/>
+ <abundance value="0.06592" error="0.00012"/>
</isotope>
<isotope mass-number="136">
<mass value="135.904571" error="0.000003"/>
diff --git a/docs/developers/code-notes.txt b/docs/developers/code-notes.txt
deleted file mode 100644
index 39213c2..0000000
--- a/docs/developers/code-notes.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-String comments that can be searched for in the code:
- COMPAT_BREAK : items that need to be changed at some point, but require a compatability break with earlier versions
- TODO : Deferred/nice-to-have/not-sure-about-fix items
- FIXME : Not nicely written bits of code, or known minor problems/failure edge cases.
-
diff --git a/docs/developers/filter-template.patch b/docs/developers/filter-template.patch
new file mode 100644
index 0000000..b86ee77
--- /dev/null
+++ b/docs/developers/filter-template.patch
@@ -0,0 +1,295 @@
+diff -r e500a2602f86 src/Makefile.am
+--- a/src/Makefile.am Sun Jul 20 15:44:52 2014 +0100
++++ b/src/Makefile.am Sun Jul 20 15:49:30 2014 +0100
+@@ -38,7 +38,7 @@
+ backend/filters/compositionProfile.cpp backend/filters/spatialAnalysis.cpp \
+ backend/filters/clusterAnalysis.cpp backend/filters/ionInfo.cpp \
+ backend/filters/annotation.cpp backend/filters/geometryHelpers.cpp \
+- backend/filters/algorithms/binomial.cpp
++ backend/filters/algorithms/binomial.cpp backend/filters/filterTemplate.cpp
+
+ FILTER_HEADER_FILES = backend/filters/allFilter.h backend/filters/filterCommon.h \
+ backend/filters/dataLoad.h backend/filters/ionDownsample.h \
+@@ -48,7 +48,7 @@
+ backend/filters/compositionProfile.h backend/filters/spatialAnalysis.h \
+ backend/filters/clusterAnalysis.h backend/filters/ionInfo.h \
+ backend/filters/annotation.h backend/filters/geometryHelpers.h \
+- backend/filters/algorithms/binomial.h
++ backend/filters/algorithms/binomial.h backend/filters/algorithms/filterTemplate.h
+
+ BACKEND_SOURCE_FILES = backend/animator.cpp backend/filtertreeAnalyse.cpp backend/filtertree.cpp \
+ backend/APT/ionhit.cpp backend/APT/APTFileIO.cpp backend/APT/APTRanges.cpp backend/APT/abundanceParser.cpp \
+diff -r e500a2602f86 src/backend/filter.cpp
+--- a/src/backend/filter.cpp Sun Jul 20 15:44:52 2014 +0100
++++ b/src/backend/filter.cpp Sun Jul 20 15:49:30 2014 +0100
+@@ -63,7 +63,8 @@
+ "clusteranalysis",
+ "voxelise",
+ "ioninfo",
+- "annotation"
++ "annotation",
++ "template"
+ };
+
+ size_t numElements(const vector<const FilterStreamData *> &v, unsigned int mask)
+diff -r e500a2602f86 src/backend/filter.h
+--- a/src/backend/filter.h Sun Jul 20 15:44:52 2014 +0100
++++ b/src/backend/filter.h Sun Jul 20 15:49:30 2014 +0100
+@@ -71,6 +71,7 @@
+ FILTER_TYPE_VOXELS,
+ FILTER_TYPE_IONINFO,
+ FILTER_TYPE_ANNOTATION,
++ FILTER_TYPE_TEMPLATE,
+ FILTER_TYPE_ENUM_END // not a filter. just end of enum
+ };
+
+diff -r e500a2602f86 src/backend/filters/allFilter.cpp
+--- a/src/backend/filters/allFilter.cpp Sun Jul 20 15:44:52 2014 +0100
++++ b/src/backend/filters/allFilter.cpp Sun Jul 20 15:49:30 2014 +0100
+@@ -104,6 +104,9 @@
+ case FILTER_TYPE_ANNOTATION:
+ f = new AnnotateFilter;
+ break;
++ case FILTER_TYPE_TEMPLATE:
++ f = new TemplateFilter;
++ break;
+ default:
+ ASSERT(false);
+ }
+diff -r e500a2602f86 src/backend/filters/allFilter.h
+--- a/src/backend/filters/allFilter.h Sun Jul 20 15:44:52 2014 +0100
++++ b/src/backend/filters/allFilter.h Sun Jul 20 15:49:30 2014 +0100
+@@ -32,6 +32,7 @@
+ #include "voxelise.h"
+ #include "ionInfo.h"
+ #include "annotation.h"
++#include "filterTemplate.h"
+
+ //!Returns true if the string is a valid filter name
+ bool isValidFilterName(const std::string &s);
+diff -r e500a2602f86 src/gui/mainFrame.cpp
+--- a/src/gui/mainFrame.cpp Sun Jul 20 15:44:52 2014 +0100
++++ b/src/gui/mainFrame.cpp Sun Jul 20 15:49:30 2014 +0100
+@@ -116,7 +116,7 @@
+ //MainFrame's constructor
+
+ //--- These settings must be modified concomitantly.
+-const unsigned int FILTER_DROP_COUNT=14;
++const unsigned int FILTER_DROP_COUNT=15;
+
+ const char * comboFilters_choices[FILTER_DROP_COUNT] =
+ {
+@@ -134,6 +134,7 @@
+ NTRANS("Range File"),
+ NTRANS("Spat. Analysis"),
+ NTRANS("Voxelisation"),
++ NTRANS("Template")
+ };
+
+ //Mapping between filter ID and combo position
+@@ -152,6 +153,7 @@
+ FILTER_TYPE_RANGEFILE,
+ FILTER_TYPE_SPATIAL_ANALYSIS,
+ FILTER_TYPE_VOXELS,
++ FILTER_TYPE_TEMPLATE,
+ };
+ //----
+
+diff -r 036cf664e28d docs/developers/filter-template.patch
+--- a/docs/developers/filter-template.patch Sun Aug 24 14:17:50 2014 +0100
++++ b/docs/developers/filter-template.patch Sun Aug 24 14:18:26 2014 +0100
+@@ -1,97 +0,0 @@
+-diff -r e500a2602f86 src/Makefile.am
+---- a/src/Makefile.am Sun Jul 20 15:44:52 2014 +0100
+-+++ b/src/Makefile.am Sun Jul 20 15:49:30 2014 +0100
+-@@ -38,7 +38,7 @@
+- backend/filters/compositionProfile.cpp backend/filters/spatialAnalysis.cpp \
+- backend/filters/clusterAnalysis.cpp backend/filters/ionInfo.cpp \
+- backend/filters/annotation.cpp backend/filters/geometryHelpers.cpp \
+-- backend/filters/algorithms/binomial.cpp
+-+ backend/filters/algorithms/binomial.cpp backend/filters/filterTemplate.cpp
+-
+- FILTER_HEADER_FILES = backend/filters/allFilter.h backend/filters/filterCommon.h \
+- backend/filters/dataLoad.h backend/filters/ionDownsample.h \
+-@@ -48,7 +48,7 @@
+- backend/filters/compositionProfile.h backend/filters/spatialAnalysis.h \
+- backend/filters/clusterAnalysis.h backend/filters/ionInfo.h \
+- backend/filters/annotation.h backend/filters/geometryHelpers.h \
+-- backend/filters/algorithms/binomial.h
+-+ backend/filters/algorithms/binomial.h backend/filters/algorithms/filterTemplate.h
+-
+- BACKEND_SOURCE_FILES = backend/animator.cpp backend/filtertreeAnalyse.cpp backend/filtertree.cpp \
+- backend/APT/ionhit.cpp backend/APT/APTFileIO.cpp backend/APT/APTRanges.cpp backend/APT/abundanceParser.cpp \
+-diff -r e500a2602f86 src/backend/filter.cpp
+---- a/src/backend/filter.cpp Sun Jul 20 15:44:52 2014 +0100
+-+++ b/src/backend/filter.cpp Sun Jul 20 15:49:30 2014 +0100
+-@@ -63,7 +63,8 @@
+- "clusteranalysis",
+- "voxelise",
+- "ioninfo",
+-- "annotation"
+-+ "annotation",
+-+ "template"
+- };
+-
+- size_t numElements(const vector<const FilterStreamData *> &v, unsigned int mask)
+-diff -r e500a2602f86 src/backend/filter.h
+---- a/src/backend/filter.h Sun Jul 20 15:44:52 2014 +0100
+-+++ b/src/backend/filter.h Sun Jul 20 15:49:30 2014 +0100
+-@@ -71,6 +71,7 @@
+- FILTER_TYPE_VOXELS,
+- FILTER_TYPE_IONINFO,
+- FILTER_TYPE_ANNOTATION,
+-+ FILTER_TYPE_TEMPLATE,
+- FILTER_TYPE_ENUM_END // not a filter. just end of enum
+- };
+-
+-diff -r e500a2602f86 src/backend/filters/allFilter.cpp
+---- a/src/backend/filters/allFilter.cpp Sun Jul 20 15:44:52 2014 +0100
+-+++ b/src/backend/filters/allFilter.cpp Sun Jul 20 15:49:30 2014 +0100
+-@@ -104,6 +104,9 @@
+- case FILTER_TYPE_ANNOTATION:
+- f = new AnnotateFilter;
+- break;
+-+ case FILTER_TYPE_TEMPLATE:
+-+ f = new TemplateFilter;
+-+ break;
+- default:
+- ASSERT(false);
+- }
+-diff -r e500a2602f86 src/backend/filters/allFilter.h
+---- a/src/backend/filters/allFilter.h Sun Jul 20 15:44:52 2014 +0100
+-+++ b/src/backend/filters/allFilter.h Sun Jul 20 15:49:30 2014 +0100
+-@@ -32,6 +32,7 @@
+- #include "voxelise.h"
+- #include "ionInfo.h"
+- #include "annotation.h"
+-+#include "filterTemplate.h"
+-
+- //!Returns true if the string is a valid filter name
+- bool isValidFilterName(const std::string &s);
+-diff -r e500a2602f86 src/gui/mainFrame.cpp
+---- a/src/gui/mainFrame.cpp Sun Jul 20 15:44:52 2014 +0100
+-+++ b/src/gui/mainFrame.cpp Sun Jul 20 15:49:30 2014 +0100
+-@@ -116,7 +116,7 @@
+- //MainFrame's constructor
+-
+- //--- These settings must be modified concomitantly.
+--const unsigned int FILTER_DROP_COUNT=14;
+-+const unsigned int FILTER_DROP_COUNT=15;
+-
+- const char * comboFilters_choices[FILTER_DROP_COUNT] =
+- {
+-@@ -134,6 +134,7 @@
+- NTRANS("Range File"),
+- NTRANS("Spat. Analysis"),
+- NTRANS("Voxelisation"),
+-+ NTRANS("Template")
+- };
+-
+- //Mapping between filter ID and combo position
+-@@ -152,6 +153,7 @@
+- FILTER_TYPE_RANGEFILE,
+- FILTER_TYPE_SPATIAL_ANALYSIS,
+- FILTER_TYPE_VOXELS,
+-+ FILTER_TYPE_TEMPLATE,
+- };
+- //----
+-
+diff -r 036cf664e28d src/Makefile.am
+--- a/src/Makefile.am Sun Aug 24 14:17:50 2014 +0100
++++ b/src/Makefile.am Sun Aug 24 14:18:26 2014 +0100
+@@ -38,7 +38,7 @@
+ backend/filters/compositionProfile.cpp backend/filters/spatialAnalysis.cpp \
+ backend/filters/clusterAnalysis.cpp backend/filters/ionInfo.cpp \
+ backend/filters/annotation.cpp backend/filters/geometryHelpers.cpp \
+- backend/filters/algorithms/binomial.cpp
++ backend/filters/algorithms/binomial.cpp backend/filters/filterTemplate.cpp
+
+ FILTER_HEADER_FILES = backend/filters/allFilter.h backend/filters/filterCommon.h \
+ backend/filters/dataLoad.h backend/filters/ionDownsample.h \
+@@ -48,7 +48,7 @@
+ backend/filters/compositionProfile.h backend/filters/spatialAnalysis.h \
+ backend/filters/clusterAnalysis.h backend/filters/ionInfo.h \
+ backend/filters/annotation.h backend/filters/geometryHelpers.h \
+- backend/filters/algorithms/binomial.h
++ backend/filters/algorithms/binomial.h backend/filters/algorithms/filterTemplate.h
+
+ BACKEND_SOURCE_FILES = backend/animator.cpp backend/filtertreeAnalyse.cpp backend/filtertree.cpp \
+ backend/APT/ionhit.cpp backend/APT/APTFileIO.cpp backend/APT/APTRanges.cpp backend/APT/abundanceParser.cpp \
+diff -r 036cf664e28d src/backend/filter.cpp
+--- a/src/backend/filter.cpp Sun Aug 24 14:17:50 2014 +0100
++++ b/src/backend/filter.cpp Sun Aug 24 14:18:26 2014 +0100
+@@ -63,7 +63,8 @@
+ "clusteranalysis",
+ "voxelise",
+ "ioninfo",
+- "annotation"
++ "annotation",
++ "template"
+ };
+
+ size_t numElements(const vector<const FilterStreamData *> &v, unsigned int mask)
+diff -r 036cf664e28d src/backend/filter.h
+--- a/src/backend/filter.h Sun Aug 24 14:17:50 2014 +0100
++++ b/src/backend/filter.h Sun Aug 24 14:18:26 2014 +0100
+@@ -71,6 +71,7 @@
+ FILTER_TYPE_VOXELS,
+ FILTER_TYPE_IONINFO,
+ FILTER_TYPE_ANNOTATION,
++ FILTER_TYPE_TEMPLATE,
+ FILTER_TYPE_ENUM_END // not a filter. just end of enum
+ };
+
+diff -r 036cf664e28d src/backend/filters/allFilter.cpp
+--- a/src/backend/filters/allFilter.cpp Sun Aug 24 14:17:50 2014 +0100
++++ b/src/backend/filters/allFilter.cpp Sun Aug 24 14:18:26 2014 +0100
+@@ -104,6 +104,9 @@
+ case FILTER_TYPE_ANNOTATION:
+ f = new AnnotateFilter;
+ break;
++ case FILTER_TYPE_TEMPLATE:
++ f = new TemplateFilter;
++ break;
+ default:
+ ASSERT(false);
+ }
+diff -r 036cf664e28d src/backend/filters/allFilter.h
+--- a/src/backend/filters/allFilter.h Sun Aug 24 14:17:50 2014 +0100
++++ b/src/backend/filters/allFilter.h Sun Aug 24 14:18:26 2014 +0100
+@@ -32,6 +32,7 @@
+ #include "voxelise.h"
+ #include "ionInfo.h"
+ #include "annotation.h"
++#include "filterTemplate.h"
+
+ //!Returns true if the string is a valid filter name
+ bool isValidFilterName(const std::string &s);
+diff -r 036cf664e28d src/gui/mainFrame.cpp
+--- a/src/gui/mainFrame.cpp Sun Aug 24 14:17:50 2014 +0100
++++ b/src/gui/mainFrame.cpp Sun Aug 24 14:18:26 2014 +0100
+@@ -121,7 +121,7 @@
+ //MainFrame's constructor
+
+ //--- These settings must be modified concomitantly.
+-const unsigned int FILTER_DROP_COUNT=14;
++const unsigned int FILTER_DROP_COUNT=15;
+
+ const char * comboFilters_choices[FILTER_DROP_COUNT] =
+ {
+@@ -139,6 +139,7 @@
+ NTRANS("Range File"),
+ NTRANS("Spat. Analysis"),
+ NTRANS("Voxelisation"),
++ NTRANS("Template")
+ };
+
+ //Mapping between filter ID and combo position
+@@ -157,6 +158,7 @@
+ FILTER_TYPE_RANGEFILE,
+ FILTER_TYPE_SPATIAL_ANALYSIS,
+ FILTER_TYPE_VOXELS,
++ FILTER_TYPE_TEMPLATE,
+ };
+ //----
+
diff --git a/docs/manual-latex/figures/Screenshot-thumb.png b/docs/manual-latex/figures/Screenshot-thumb.png
new file mode 100644
index 0000000..ad53949
Binary files /dev/null and b/docs/manual-latex/figures/Screenshot-thumb.png differ
diff --git a/docs/manual-latex/manual.blg b/docs/manual-latex/manual.blg
index 6f03a0c..2d3519b 100644
--- a/docs/manual-latex/manual.blg
+++ b/docs/manual-latex/manual.blg
@@ -1,4 +1,4 @@
-This is BibTeX, Version 0.99d (TeX Live 2013/Debian)
+This is BibTeX, Version 0.99d (TeX Live 2014/Debian)
Capacity: max_strings=35307, hash_size=35307, hash_prime=30011
The top-level auxiliary file: manual.aux
The style file: unsrt.bst
diff --git a/docs/manual-latex/manual.log b/docs/manual-latex/manual.log
index 6eb8f8e..38771a5 100644
--- a/docs/manual-latex/manual.log
+++ b/docs/manual-latex/manual.log
@@ -1,10 +1,10 @@
-This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/Debian) (format=pdflatex 2014.4.17) 17 APR 2014 22:03
+This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014/Debian) (preloaded format=pdflatex 2014.6.29) 2 AUG 2014 00:59
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**manual.tex
(./manual.tex
-LaTeX2e <2011/06/27>
+LaTeX2e <2014/05/01>
Babel <3.9k> and hyphenation patterns for 2 languages loaded.
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
@@ -28,10 +28,10 @@ Package: fullpage 1999/02/23 1.1 (PWD)
\FP at margin=\skip43
)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty
-Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
+Package: graphicx 2014/04/25 v1.0g Enhanced LaTeX Graphics (DPC,SPQR)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty
-Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
+Package: keyval 2014/05/08 v1.15 key=value parser (DPC)
\KV at toks@=\toks14
)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty
@@ -555,13 +555,12 @@ Package pdftex.def Info: ./figures/externalProgBash.png used on input line 1601
[47 <./figures/externalProgBash.png>]
LaTeX Font Info: Try loading font information for OMS+cmtt on input line 165
8.
+LaTeX Font Info: No file OMScmtt.fd. on input line 1658.
-(/usr/share/texmf/tex/latex/R/tex/latex/omscmtt.fd
-File: omscmtt.fd
-)
-LaTeX Font Info: Font shape `OMS/cmtt/m/n' in size <10> not available
-(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 1658.
+LaTeX Font Warning: Font shape `OMS/cmtt/m/n' undefined
+(Font) using `OMS/cmsy/m/n' instead
+(Font) for symbol `textbraceleft' on input line 1658.
<./figures/externalProgCpp.png, id=1502, 2123.935pt x 839.135pt>
File: ./figures/externalProgCpp.png Graphic file (type png)
@@ -583,6 +582,9 @@ Package rerunfilecheck Info: File `manual.out' has not changed.
(rerunfilecheck) Checksum: 5D9DF5F8101C21D1BE54E57385EA4596;5634.
+LaTeX Font Warning: Some font shapes were not available, defaults substituted.
+
+
LaTeX Warning: There were undefined references.
@@ -591,10 +593,10 @@ LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 1911.
)
Here is how much of TeX's memory you used:
- 5708 strings out of 495028
- 87083 string characters out of 6181497
- 165098 words of memory out of 5000000
- 8634 multiletter control sequences out of 15000+600000
+ 5698 strings out of 495021
+ 86846 string characters out of 6181344
+ 165106 words of memory out of 5000000
+ 8630 multiletter control sequences out of 15000+600000
13156 words of font info for 46 fonts, out of 8000000 for 9000
14 hyphenation exceptions out of 8191
29i,11n,28p,1058b,447s stack positions out of 5000i,500n,10000p,200000b,80000s
@@ -615,7 +617,7 @@ re/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb></usr/share/texl
ive/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt10.pfb></usr/share/texlive/te
xmf-dist/fonts/type1/public/amsfonts/cm/cmtt12.pfb></usr/share/texlive/texmf-di
st/fonts/type1/public/amsfonts/cm/cmtt8.pfb>
-Output written on manual.pdf (59 pages, 4517180 bytes).
+Output written on manual.pdf (59 pages, 4550865 bytes).
PDF statistics:
1660 PDF objects out of 1728 (max. 8388607)
1281 compressed objects within 13 object streams
diff --git a/docs/manual-latex/manual.pdf b/docs/manual-latex/manual.pdf
index b81c71a..fef3e72 100644
Binary files a/docs/manual-latex/manual.pdf and b/docs/manual-latex/manual.pdf differ
diff --git a/docs/manual-latex/manual.tex b/docs/manual-latex/manual.tex
index 5f4f518..26d9ee5 100644
--- a/docs/manual-latex/manual.tex
+++ b/docs/manual-latex/manual.tex
@@ -40,7 +40,7 @@
\begin{minipage}{0.3\textwidth}
\begin{flushright} \large
\emph{Version:} \\
- 0.0.16, Apr 2014\end{flushright}
+ 0.0.17, Sep 2014\end{flushright}
\end{minipage}
\vfill
@@ -53,7 +53,7 @@
\tableofcontents
\clearpage
\pagenumbering{arabic}
-\title{3Depict -- Valued point cloud visualisation and analysis}
+\title{3Depict -- Visualisation and Analysis for Atom Probe}
\widowpenalty = 10000
@@ -62,7 +62,7 @@
\section{Foreword}
\subsection{Introduction}
-\emph{3Depict} is an open source computer program designed for the analysis of point clouds with an associated scalar value. The program is designed around interactive data analysis, with a view to combine rapid feedback, ease of use and flexibility in a single system. At time of writing, \emph{3Depict} is in the so-called ``alpha'' prototyping stage, and should be used where helpful, but may contain rough-edges.
+\emph{3Depict} is an open source computer program designed for the analysis of point clouds with an associated scalar value. The software is designed around interactive data analysis, with a view to combine rapid feedback, ease of use and flexibility in a single system. At time of writing, \emph{3Depict} is in the so-called ``alpha'' prototyping stage, and should be used where helpful, but may contain rough-edges.
\emph{3Depict} is designed purely for post-processing of 3D point data, and was originally primarily targeted to users of Atom Probe Tomography. Other users (\emph{e.g.} in astronomical, geospatial or digital preservation fields) may find the program useful, and are encouraged to seek assistance.
diff --git a/docs/web/about.html b/docs/web/about.html
index 5bbb4a1..e2e973f 100644
--- a/docs/web/about.html
+++ b/docs/web/about.html
@@ -7,6 +7,9 @@
<title>About 3Depict </title>
<link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="icon" type="image/png" href="favicon.png"/>
+
+
</head>
<body>
diff --git a/docs/web/compiling-OSX.html b/docs/web/compiling-OSX.html
new file mode 100644
index 0000000..56dc075
--- /dev/null
+++ b/docs/web/compiling-OSX.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+
+<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<link rel="icon" type="image/png" href="favicon.png"/>
+
+<title>compiling.html</title></head><body>
+<div id="header">
+<h1>3Depict - Valued point cloud visualisation and analysis</h1>
+<ul id="nav">
+ <li><a href="index.html">Home</a></li>
+ <li><a href="download.html">Download</a></li>
+ <li><a href="questions.html">Questions</a></li>
+ <li><a href="documentation.html">Documentation</a></li>
+ <li><a href="contact.html">Contact</a></li>
+ <li><a href="about.html">About</a></li>
+</ul>
+</div>
+
+<div id="left">
+<div class="box">
+<h2>Get the code</h2>
+<p> <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code for the latest version of 3Depict for your platform.</p> Alternately, download the latest <a href="http://sourceforge.net/p/threedepict/code/ci/default/tree/">development version</a>.
+</div>
+<div class="box">
+<h3>Stuck on how to compile?</h3>
+Try asking for help on the <a href="https://sourceforge.net/apps/phpbb/threedepict/">forums</a>
+<p></p>
+</div>
+<center>
+<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=341003&type=2" alt="SourceForge.net Logo" border="0" height="37"/></a>
+</center>
+</div>
+<div id="content">
+<div id="right">
+
+<h1> Preface </h1>
+
+Mac OSX is currently a "contributed" build platform, and thus the build systems are more rough than for other systems. Some scripts are provided to smooth the process, however these may be out of date. The developers cannot continuously build this platform, as it is against the OSX licence to run OSX on virtual machines. Cross-compilation is not readily feasible either. If you can assist in building for this platform, please <a href="contact.html">contact us</a>.
+
+<h1>Compiling</h1>
+
+Mac OS does not have a proper package management system. You need XCode installed (<a href="http://developer.apple.com/mac/library/documentation/Xcode/Conceptual/XcodeCoexistence/Contents/Resources/en.lproj/Basics/Basics.html">here</a>). For the latest version of OSX for some reason this is not quite free, and you now are required to use the app store or something to get this or build gcc yourself (somehow) it appears. So we can't easily automate this procedure for you.
+
+Considering GCC (the bit we need) is completely free (GPL), it is unclear what the deal is here. To make matters more complex, there are <i>two</i> compilers (clang & GCC) and <i>two</i> standard libraries (libstdc++ and libc++), all of which are incompatible with the alternate. This means you must compile everything with the same compiler the whole time - read <a href="https://trac.macports.org/wiki/UsingTheRightCompiler">here</a> for how to do this (macports & local). Check to mak [...]
+
+Note that at time of writing the wxWidgets version provided with XCode is several years out-of-date and won't work. Please don't try to use any of the built-in libraries provided with XCode - firstly, you cannot mix and match library linkage, it simply won't work (crashes) and secondly they are all very out of date. In fact, using XCode at all is highly discouraged, due to its poor portability, and the difficultly scripting solutions and debugging problems.
+
+<br/>
+
+There is an automatic dependency grabbing script in the 3Depict source
+code under the "deps" folder. Run that (ensure you are connected to the
+Internet) to automatically download, build and install all the software
+dependencies. If it does not work, this is a bug, so let us know.<br/>
+
+<br/>
+To run the script, simply open terminal.app, navigate to the "packaging/deps" folder containing "getDeps", then type:<br/>
+<br/>
+<span style="font-family: monospace;">$ ./getDeps</span><br/>
+
+<br/>
+This will check your system for a compiler, and then will proceed to download and install the needed components in an automatic fashion. The compilation process can take several hours.<br/>
+<br/>
+
+<h2>Packaging</2>
+Due to some design decisions under OSX, programs cannot be directly run, but first must be packaged. Attempts to run programs without creating the <a href="http://wiki.wxwidgets.org/WxMac-specific_topics#Building_a_MacOSX_application_bundle">".app package"</a> (actually a folder with metadata), will cause the program to function incorrectly (eg user input will be ignored).
+
+To aid compilation and packaging, use the "3package.sh" script in the "packaging/mac" folder. Execute this to build and package the program. In this way, a .app package should be built and ready for use.
+
+</div></div>
+
+</body></html>
diff --git a/docs/web/compiling-cross.html b/docs/web/compiling-cross.html
new file mode 100644
index 0000000..e8bb836
--- /dev/null
+++ b/docs/web/compiling-cross.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+
+<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<link rel="icon" type="image/png" href="favicon.png"/>
+
+<title>compiling.html</title></head><body>
+<div id="header">
+<h1>3Depict - Valued point cloud visualisation and analysis</h1>
+<ul id="nav">
+ <li><a href="index.html">Home</a></li>
+ <li><a href="download.html">Download</a></li>
+ <li><a href="questions.html">Questions</a></li>
+ <li><a href="documentation.html">Documentation</a></li>
+ <li><a href="contact.html">Contact</a></li>
+ <li><a href="about.html">About</a></li>
+</ul>
+</div>
+
+<div id="left">
+<div class="box">
+<h2>Get the code</h2>
+<p> <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code for the latest version of 3Depict for your platform.</p> Alternately, download the latest <a href="http://sourceforge.net/p/threedepict/code/ci/default/tree/">development version</a>.
+</div>
+<div class="box">
+<h3>Stuck on how to compile?</h3>
+Try asking for help on the <a href="https://sourceforge.net/apps/phpbb/threedepict/">forums</a>
+<p></p>
+</div>
+<center>
+<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=341003&type=2" alt="SourceForge.net Logo" border="0" height="37"/></a>
+</center>
+</div>
+<div id="content">
+<div id="right">
+
+<h1>Cross Compilation</h1>
+
+<p>Compiling under windows is quite tricky. Compiling for windows under a Linux environment is significantly easier. Easier still, we have automated the procedure to build windows executables via a technique known as <a href="https://en.wikipedia.org/wiki/Cross_compiler">Cross compiling</a>. This technique is used for the official 3Depict builds.</p>
+
+<p>To run the cross compilation script, you must first have an installed Debian-like Linux system. We recommend "Debian", however you can probably use Linux Mint or Ubuntu. We have not tried these. </p>
+
+<p>For windows users, you can install a <a href="http://www.brianlinkletter.com/installing-debian-linux-in-a-virtualbox-virtual-machine/">virtual machine</a> to do the trick, then start the build. Make sure you allocate lots of RAM and disk space (>8GB ram or swap needed, >10GB disk space recommended), to ensure the build works. On older machines, you may need to <a href="http://www.sysprobs.com/disable-enable-virtualization-technology-bios">enable</a> virtual machine access in the <a hr [...]
+
+
+<h1> Procedure</h1>
+<p>Having downloaded the source code, copy the <span style="font-family: monospace;">./packaging/mingw-debian-cross/</span> folder to your home directory, eg <span style="font-family: monospace;">/home/user/mingw-debian-cross/</span>. Once done, create a folder called <span style="font-family: monospace;">code</span> inside <span style="font-family: monospace;">mingw-debian-cross/</span>. This is case sensitive. Copy the <span style="font-family: monospace;">3Depict</span> folder into th [...]
+
+<p>Now run the <span style="font-family: monospace;">bootstrap.sh</span> script to execute the cross-compilation - the process can take several hours on a standard system to execute a full build. On the first run you will be asked whether you wish to compile for 32 or 64 bit windows. Once complete, you will be given a 3Depict-VERSION-BIT.exe file that you can use under windows. </p>
+
+To get the file out of your virtual machine, we recommend using a USB key. Plug the USB key in, then select it in your virtual machine, and copy the file over. It is possible to also do this by drag and drop onto your desktop, but you need to enable the virtual machine's <a href="http://www.virtualbox.org/manual/ch04.html">guest additions</a>. This can be a tricky process in itself, so it is not recommended. Many other methods of copying the file are possible, but not discussed here.</p>
+</div></div>
+
+</body></html>
diff --git a/docs/web/compiling-linux.html b/docs/web/compiling-linux.html
new file mode 100644
index 0000000..eb1ee82
--- /dev/null
+++ b/docs/web/compiling-linux.html
@@ -0,0 +1,153 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+
+<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<link rel="icon" type="image/png" href="favicon.png"/>
+
+<title>compiling.html</title></head><body>
+<div id="header">
+<h1>3Depict - Valued point cloud visualisation and analysis</h1>
+<ul id="nav">
+ <li><a href="index.html">Home</a></li>
+ <li><a href="download.html">Download</a></li>
+ <li><a href="questions.html">Questions</a></li>
+ <li><a href="documentation.html">Documentation</a></li>
+ <li><a href="contact.html">Contact</a></li>
+ <li><a href="about.html">About</a></li>
+</ul>
+</div>
+
+<div id="left">
+<div class="box">
+<h2>Get the code</h2>
+<p> <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code for the latest version of 3Depict for your platform.</p> Alternately, download the latest <a href="http://sourceforge.net/p/threedepict/code/ci/default/tree/">development version</a>.
+</div>
+<div class="box">
+<h3>Stuck on how to compile?</h3>
+Try asking for help on the <a href="https://sourceforge.net/apps/phpbb/threedepict/">forums</a>
+<p></p>
+</div>
+<center>
+<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=341003&type=2" alt="SourceForge.net Logo" border="0" height="37"/></a>
+</center>
+</div>
+<div id="content">
+<div id="right">
+
+<h1>Compiling for Linux</h1>
+
+
+<p>
+
+
+In the following instructions, <span style="text-decoration: underline; font-family: monospace;">$</span> and <span style="text-decoration: underline; font-family: monospace;">#</span> indicate to enter command at a command prompt, as either a normal user or as an <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Root_user">administrator</a>. Do not type the <span style="font-family: monospace;">$</span> or <span style="font-family: monospace;">#</span> when entering the commands. [...]
+</p>
+<p>
+If there are any problems or flaws with the instructions, please <a href="contact.html">contact the author</a>.
+</p>
+
+<h2> Installing dependencies</h2>
+<h3>Automatic dependancy retrieval</h3>
+<p>
+An experimental script "getDeps" is supplied in the <i>packaging/deps/</i> folder. Run this script to automatically detect your platform and download and install the required dependencies.</p>
+
+<p>
+Alternately, use the following instructions:</p>
+
+
+<h3>Debian and derivatives</h3>
+Debian Linux and its derivatives (Linux Mint, Ubuntu, etc), can use the following procedure.
+To build 3Depict, you need to install the following packages:
+<ul>
+<li>build-essential</li>
+<li>libwxgtk2.8-dev</li>
+<li>libmgl-dev</li>
+<li>libxml2-dev</li>
+<li>libftgl-dev</li>
+<li>libqhull-dev</li>
+</ul>
+
+
+This can be done through the command line (below), or using the gui (synaptic package manager)<br/>
+
+<br/>
+
+<span style="text-decoration: underline; font-family: monospace;">$</span><span style="font-family: monospace;"> sudo apt-get build-dep 3depict </span><br/>
+
+
+
+<h3>Fedora/RedHat:</h3>
+
+<ul>
+<li>"Development Tools" group package</li>
+<li>mathgl-devel</li>
+<li>libxml2-devel</li>
+<li>ftgl-devel</li>
+<li>wxgtk-devel</li>
+<li>qhull-devel</li>
+
+</ul>
+
+
+This can be done through either the command line, or through the GUI <br/>
+
+<br/>
+
+
+<span style="text-decoration: underline; font-family: monospace;">$</span><span style="font-family: monospace;"> yum groupinstall "Development Tools"</span><br/>
+
+<span style="text-decoration: underline; font-family: monospace;">$</span><span style="font-family: monospace;"> yum install mathgl-devel libxml2-devel ftgl-devel wxgtk-devel qhull-devel</span><br/>
+<br/>
+
+<h3>OpenSuse:</h3>
+<i>These instructions may be slightly out of date</i>
+<ul>
+<li>wxGTK-devel</li>
+<li>libxml2-devel</li>
+<li>ftgl-devel</li>
+<li>qhull-devel</li>
+</ul>
+
+
+This can be done either through the graphical interface (YaST) or at the command line.<br/>
+
+<br/>
+
+
+<span style="font-family: monospace;"> $ zypper install -t devel_C_C++</span><br/>
+
+<span style="font-family: monospace;"> $ zypper install wxGTK-devel libxml2-devel ftgl-devel qhull-devel</span><br/>
+
+ <br/>
+
+Unfortunately, mathgl is not available as a pre-built package for Suse.
+You must therefore download and install it manually from the mathgl
+website:<br/>
+
+<ul>
+<li><a href="http://mathgl.sourceforge.net/">http://mathgl.sourceforge.net/</a></li>
+</ul>
+
+</ul>
+
+
+<h2> Compiling</h2>
+<p>
+To compile 3Depict, ensure you have installed all the required dependencies (above), then use the following commands in the 3Depict/ directory:</p>
+
+<p>
+<span style="font-family: monospace;"> $ ./configure</span> <br/><br/> Optionally, you may use <span style="font-family: monospace;">--enable-openmp-parallel</span> or <span style="font-family: monospace;">--disable-debug-checks</span> to enable parallelism or disable debug checks respectively. <br/>
+<span style="font-family: monospace;"> $ make</span><br/>to build 3depict.<br/><br/>
+
+Once built, you can install the program with:
+<span style="font-family: monospace;">make install</span></p>
+
+
+<h2> Compiling under eclipse</h2>
+Although not officially supported, some users report being able to compile 3Depict under the eclipse IDE. You can read more about the method on the <a href="http://sourceforge.net/apps/phpbb/threedepict/viewtopic.php?f=1&t=26">forums</a>.
+
+
+</div></div>
+</body></html>
diff --git a/docs/web/compiling-macosx.html b/docs/web/compiling-macosx.html
new file mode 100644
index 0000000..1db56a9
--- /dev/null
+++ b/docs/web/compiling-macosx.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+
+<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<link rel="icon" type="image/png" href="favicon.png"/>
+
+<title>compiling.html</title></head><body>
+<div id="header">
+<h1>3Depict - Valued point cloud visualisation and analysis</h1>
+<ul id="nav">
+ <li><a href="index.html">Home</a></li>
+
+ <li><a href="download.html">Download</a></li>
+ <li><a href="questions.html">Questions</a></li>
+ <li><a href="documentation.html">Documentation</a></li>
+ <li><a href="contact.html">Contact</a></li>
+ <li><a href="about.html">About</a></li>
+</ul>
+</div>
+
+<div id="left">
+<div class="box">
+<h2>Get the code</h2>
+<p> <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code for the latest version of 3Depict for your platform.</p> Alternately, download the latest <a href="http://sourceforge.net/p/threedepict/code/ci/default/tree/">development version</a>.
+</div>
+<div class="box">
+<h3>Stuck on how to compile?</h3>
+
+Try asking for help on the <a href="https://sourceforge.net/apps/phpbb/threedepict/">forums</a>
+<p></p>
+</div>
+<center>
+<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=341003&type=2" alt="SourceForge.net Logo" border="0" height="37"/></a>
+</center>
+</div>
+<div id="content">
+<div id="right">
+
+<h1> Preface </h1>
+
+Mac OSX is currently a "contributed" build platform, and thus the build systems are more rough than for other systems. Some scripts are provided to smooth the process, however these may be out of date. The developers cannot continuously build this platform, as it is against the OSX licence to run OSX on virtual machines. Cross-compilation is not readily feasible either. If you can assist in building for this platform, please <a href="contact.html">contact us</a>.
+
+
+<h1>Compiling</h1>
+<h2>Dependencies</h2>
+Mac OS does not have a proper package management system. You need XCode installed (<a href="http://developer.apple.com/mac/library/documentation/Xcode/Conceptual/XcodeCoexistence/Contents/Resources/en.lproj/Basics/Basics.html">here</a>). For the latest version of OSX for some reason this is not quite free, and you now are required to use the app store or something to get this or build gcc yourself (somehow) it appears. So we can't easily automate this procedure for you.
+
+Considering GCC (the bit we need) is completely free (GPL), it is unclear what the deal is here.
+
+Note that at time of writing the wxWidgets version provided with XCode is several years out-of-date and won't work. Please don't try to use any of the built-in libraries provided with XCode - firstly, you cannot mix and match library linkage, it simply won't work (crashes) and secondly they are all very out of date.
+
+<br/>
+
+There is an automatic dependency grabbing script in the 3Depict source
+code under the "deps" folder. Run that (ensure you are connected to the
+Internet) to automatically download, build and install all the software
+dependencies. If it does not work, this is a bug, so let us know.<br/>
+
+<br/>
+To run the script, simply open terminal.app, navigate to the "packaging/deps" folder containing "getDeps", then type:<br/>
+<br/>
+<span style="font-family: monospace;">$ ./getDeps</span><br/>
+
+<br/>
+This will check your system for a compiler, and then will proceed to download and install the needed components in an automatic fashion. The compilation process can take several hours.<br/>
+<br/>
+
+<h2>Building and Packaging</h2>
+Due to some design decisions under OSX, programs cannot be directly run, but first must be packaged. Attempts to run programs without creating the ".app package" (actually a folder with metadata), will cause the program to function incorrectly (eg user input will be ignored).
+
+To aid compilation and packaging, use the "3package.sh" script in the "packaging/mac" folder. Execute this to build and package the program. In this way, a .app package should be built and ready for use.
+
+</div></div>
+
+</body></html>
+
diff --git a/docs/web/compiling.html b/docs/web/compiling.html
index 822623d..ecad8f9 100644
--- a/docs/web/compiling.html
+++ b/docs/web/compiling.html
@@ -4,6 +4,7 @@
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"/>
<link rel="stylesheet" href="style.css" type="text/css"/>
+<link rel="icon" type="image/png" href="favicon.png"/>
<title>compiling.html</title></head><body>
<div id="header">
@@ -20,8 +21,8 @@
<div id="left">
<div class="box">
-<h2> Latest version: 0.0.13</h2>
-<p> <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code for the latest version of 3Depict for your platform</p>
+<h2>Get the code</h2>
+<p> <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code for the latest version of 3Depict for your platform.</p> Alternately, download the latest <a href="http://sourceforge.net/p/threedepict/code/ci/default/tree/">development version</a>.
</div>
<div class="box">
<h3>Stuck on how to compile?</h3>
@@ -49,39 +50,14 @@ this is a limited and typically slow method of communication.<br/>
Looking for an easier install? <a href="download.html">Check</a> to see if your platform is supported. If it is not supported, you can <a href="contact.html">contact the author</a> for other options.<br/><br/>
<hr/>
-<h2>Getting started<br/>
-
-
-</h2>
-
-This project uses <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Autotools">autotools</a> to manage system configuration and program
-dependency information, so if you know what that means and you are
-running Linux, just do as per normal after installing dependencies
-(.<span style="font-family: monospace;">/configure && make && make install</span>). <br/>
-<br/>
-Due to a missing build environment, building under
-windows is highly complicated, and more thoroughly documented <a href="#windows">below</a>.<br/>
-<br/>
-
-
-Direct <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Software_library">Dependencies</a>: <br/>
-
-<ul>
-<li><a href="http://sourceforge.net/projects/ftgl/">ftgl</a></li>
-<li><a href="http://freetype.org/">freetype2</a></li>
-<li><a href="http://www.xmlsoft.org/">libxml2</a></li>
-<li><a href="http://mathgl.sourceforge.net/">mathgl</a></li>
-<li><a href="http://wxwidgets.org/">wxwidgets</a></li>
-<li><a href="http://www.gnu.org/software/gettext/">gettext</a></li>
-<li><a href="http://www.qhull.org/">qhull</a></li>
-</ul>
-
+<h2>Getting started</h2>
There are two main stages to compiling, <br/>
<ul>
-<li>setting up your computer to be able to build, and </li><li>actually building the program.</li>
+<li>setting up your computer to be able to build, and
+</li><li>actually building the program.</li>
</ul>
@@ -89,503 +65,27 @@ There are two main stages to compiling, <br/>
In the following instructions, <span style="text-decoration: underline; font-family: monospace;">$</span> and <span style="text-decoration: underline; font-family: monospace;">#</span> indicate to enter command at a command prompt, as either a normal user or as an <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Root_user">administrator</a>. Do not type the <span style="font-family: monospace;">$</span> or <span style="font-family: monospace;">#</span> when entering the commands. [...]
<br/>
-If there are any problems or flaws with the instructions, please <a href="contact.html">contact the author</a><br/><br/>
+If there are any problems or flaws with the instructions, please <a href="contact.html">contact the author</a>
<h2>Get the code</h2>
-Either <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code (<a href="https://secure.wikimedia.org/wikipedia/en/wiki/Tar.gz">.tar.gz</a> file ), or grab the <a href="http://mercurial.selenic.com">mercurial</a> repository using this clone command, or by opening the URL in your graphical mercurial client (the URL is the bit at the right)
-<br/>
-<br/>
-<span style="font-family: monospace;">$ hg clone http://threedepict.hg.sourceforge.net:8000/hgroot/threedepict/threedepict</span>
-<br/>
-<br/>
-You should then install the following packages (this requires administrative rights to your machine).:<br/>
-<br/>
-
-
-<h2>Setting up</h2>
-<h3>Debian/Ubuntu:</h3>
-<ul>
-<li>build-essential</li><li>libwxgtk2.8-dev</li><li>libmgl-dev</li><li>libxml2-dev</li><li>libftgl-dev</li><li>libqhull-dev</li>
-</ul>
-
-
-This can be done through the command line (below), or using the gui (synaptic package manager)<br/>
-
-<br/>
-
-<span style="text-decoration: underline; font-family: monospace;">$</span><span style="font-family: monospace;"> sudo apt-get build-dep 3depict </span><br/>
-
-
-<h3>Fedora/RedHat:</h3>
-
-<ul>
-<li>"Development Tools" group package</li><li>mathgl-devel</li><li>libxml2-devel</li><li>ftgl-devel</li><li>wxgtk-devel</li><li>qhull-devel</li>
-</ul>
-
-
-This can be done through either the command line, or through the GUI <br/>
-
-<br/>
-
-
-<span style="text-decoration: underline; font-family: monospace;">$</span><span style="font-family: monospace;"> yum groupinstall "Development Tools"</span><br/>
-
-<span style="text-decoration: underline; font-family: monospace;">$</span><span style="font-family: monospace;"> yum install mathgl-devel libxml2-devel ftgl-devel wxgtk-devel qhull-devel</span><br/>
-<br/>
-
-<h3>OpenSuse:</h3>
-
-<ul>
-<li>wxGTK-devel</li><li>libxml2-devel</li><li>ftgl-devel</li><li>qhull-devel</li>
-</ul>
-
-
-
-This can be done either through the graphical interface (YaST) or at the command line.<br/>
-
-<br/>
-
-
-<span style="font-family: monospace;"> $ zypper install -t devel_C_C++</span><br/>
-
-<span style="font-family: monospace;"> $ zypper install wxGTK-devel libxml2-devel ftgl-devel qhull-devel</span><br/>
-
- <br/>
-
-Unfortunately, mathgl is not available as a pre-built package for Suse.
-You must therefore download and install it manually from the mathgl
-website:<br/>
-
-<ul>
-<li><a href="http://mathgl.sourceforge.net/">http://mathgl.sourceforge.net/</a></li>
-</ul>
-
-<h4> Cross compiling</h4>
-There is a cross compilation script available (0.0.13) in the packaging/mingw-debian-cross/ folder of the <a href="http://threedepict.hg.sourceforge.net/hgweb/threedepict/threedepict/summary">code repository</a>. This can be used to build 3Depict for windows platforms using a Debian or Debian-like host. The cross-compilation script is experimental, but will get you most of the way to a cross compiled version. The script will download, patch and build all the neccessary dependencies auto [...]
-
-<br/>
-
-
-<h3>Mac OS X</h3>
-
-Mac OS does not have a proper package management system. You need XCode installed (<a href="http://developer.apple.com/mac/library/documentation/Xcode/Conceptual/XcodeCoexistence/Contents/Resources/en.lproj/Basics/Basics.html">here</a>). For the latest version of Snow Leopard for some reason this is not free, and you now are required to use the app store or something to get this or build gcc yourself (somehow) it appears. Considering GCC (the bit we need) is completely free (GPL), it is [...]
-Note that at time of writing the wxWidgets version provided with XCode is several years out-of-date and probably won't work. Please don't try to use any of the built-in libraries provided with XCode - you cannot mix and match library linkage, it simply won't work (crashes). There are some <a href="#Extra_notes_for_Mac_OSX">post-compile notes</a>, which <span style="font-weight: bold; font-style: italic;">must</span> be followed to build a usable program.<br/>
-
-<br/>
-
-There is an automatic dependency grabbing script in the 3Depict source
-code under the "deps" folder. Run that (ensure you are connected to the
-Internet) to automatically download, build and install all the software
-dependencies. If it does not work, this is a bug, so let me know. <br/>
-<br/>
-To run the script, simply open terminal.app, navigate to the correct folder containing "getDeps", then type:<br/>
-<br/>
-<span style="font-family: monospace;">$ ./getDeps</span><br/>
-
-<br/>
-This will check your system for a compiler, and then will proceed to download and install the needed components in an automatic fashion.<br/>
-<br/>
-
-
-<h3><a name="From_Source_setup"></a>From Source (All other platforms)</h3>
-For platforms not listed above (including windows), dependency source
-compiling is the way to go if you don't have pre-built versions
-available. Compiling from source is tricky, can fail due to version
-mismatch, can break your current computer install, and is only
-recommended for advanced users with a programming background. <br/>
-
-<br/>
-
-You must first install GCC for your platform, and be able to compile a
-basic "hello world" program. Other compilers might work, but I cannot
-tell you how to do this. If you don't know what that means, you may
-need to seek assistance from someone who does. Ask your local computer-y
-person.<br/>
-
-<br/>
-
-If your platform provides any of the following libraries in an easy to
-install fashion, use that, but don't forget to install the development
-components, if you choose this route. Otherwise, just follow the
-below instructions.<br/>
-
-<br/>
-
-Install the development headers for your platform. Windows needs
-MinGW/MSYS or TDM-GCC/MSYS (unless you know better), some instructions are <a href="http://wiki.wxwindows.org/HowTo:_Install_MSYS_and_MinGW_for_use_with_Eclipse_CDT#MSYS_installation">here</a>, and my notes are below. Otherwise, you are largely <a href="https://www.google.com/">on your own</a>. Cygwin is <span style="font-style: italic;">not</span> recommended, as OpenGL may not work in the final program (without X11). Feel free to <a href="contact.html">ask for help</a>.<br/>
-
-
-
-
-
-<h4>wxWidgets<br/>
-</h4>
-
-<ul>
- <li>Download the latest wxWidgets source code from <a href="http://www.wxwidgets.org/">http://www.wxwidgets.org/</a></li><li>Then extract the tarball/zip/whatever</li><li>Compile this with the following console command:<ul><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> ./configure --with-opengl --enable-unicode</span></li><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> make</span></li></ul></li><l [...]
-</ul>
-
-
-<h4>LibPNG <br/>
-</h4>
-
-<ul>
-<li>Download the latest libPNG (Unless running mac) <a href="http://www.libpng.org/pub/png/libpng.html">http://www.libpng.org/pub/png/libpng.html</a><ul><li>Copy the correct makefile to the base directory</li><li>Mac OSX : move scripts/makefile.darwin to the libpng dir, and rename it makefile</li><li>Windows: Not sure. I had to do a lot of fiddling to get this to
-work. Essentially I pulled a makefile from the msysPORT code, and then
-converted it from patch format to a usable makefile. I suggest looking
-on the interwebs for instructions.</li></ul></li><li>Other platforms: move scripts/makefile.gcc to the libpng dir and rename it makefile</li><ul><li> Compile it with<span style="font-family: monospace;"> <span style="text-decoration: underline;">$</span> make</span></li><li> Install it with<span style="font-family: monospace;"> <span style="text-decoration: underline;">#</span> make install </span><br/>
-
-
- </ul>
- </li>
-</ul>
-
-<h4> Freetype</h4>
-
-<ul>
-<li>Download the latest freetype source code: <a href="http://www.freetype.org/">http://www.freetype.org/</a></li><li>Compile with</li><ul><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> ./configure<br/>
- </span></li><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> make</span></li></ul><li> Install (as administrator)</li><ul><li><span style="font-family: monospace;"><span style="text-decoration: underline;">#</span> make install</span></li></ul>
-</ul>
-
-
-<h4> FTGL<br/>
-</h4>
-
-<ul>
-<li>Download the latest FTGL source code from <a href="http://sourceforge.net/projects/ftgl/">http://sourceforge.net/projects/ftgl/</a></li><li>Compile with</li><ul><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> ./configure <br/>
- </span></li><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> make</span></li></ul><li> Install (as administrator)</li><ul><li><span style="font-family: monospace;"><span style="text-decoration: underline;">#</span> make install</span></li></ul>
-</ul>
-
-
-
-<h4>libxml2</h4>
-
-<ul>
-<li>Download the latest libxml2 <a href="http://www.xmlsoft.org/">http://www.xmlsoft.org/</a></li><li>Compile with</li><ul><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> ./configure <br/>
-</span></li><li><span style="font-family: monospace;"><span style="text-decoration: underline;">$</span> make</span></li></ul><li> Install (as administrator)</li><ul><li><span style="font-family: monospace;"><span style="text-decoration: underline;">#</span> make install</span></li></ul>
-</ul>
-
-
-<h4>MathGL</h4>
-
-
-<ul>
-<li>Download the latest mathgl <a href="http://mathgl.sourceforge.net/">http://mathgl.sourceforge.net/</a></li><li>Compile this with:</li><ul style="font-family: monospace;"><li>$ ./configure --disable-gsl</li></ul><ul style="font-family: monospace;"><li>$ make</li></ul><li>Install with</li><ul><li style="font-family: monospace;"># make install</li></ul>
-</ul>
-
-
-
-<h2><a name="3Depict_Compilation"></a>3Depict Compilation</h2>
-
-
-Run the "configure" script (as a normal user) with:<br/>
-
-
-<br/>
-
-<span style="font-family: monospace;">$ ./configure</span><br/>
-
-<br/>
-
-This script works out some of the specifics of your system. If it
-fails, saying that it cannot locate ftgl, and you know you have the
-headers and libraries installed, simply pass the directory for ftgl
-with --with-ftgl-prefix=(wherever, for example /usr/ if ftgl is
-installed in /usr/include and /usr/libs). A full list of possible
-options (there are many) is available with:<br/>
-<br/>
-
-<span style="font-family: monospace;">$ ./configure --help</span>
-
-<br/>
-<br/>
-
-
-build the project (again normal user) with:<br/>
-
-
-<br/>
-
-<span style="font-family: monospace;">$ make</span><br/>
-
+Either <a href="https://sourceforge.net/projects/threedepict/files/">Download</a> the source code (<a href="https://secure.wikimedia.org/wikipedia/en/wiki/Tar.gz">.tar.gz</a> file), or grab the <a href="http://mercurial.selenic.com">mercurial</a> repository using this clone command, or by opening the URL in your graphical mercurial client (the URL is the bit at the right).
<br/>
-
-to run the program:<br/>
-
-
-<br/>
-
-<span style="font-family: monospace;">$ ./src/3Depict</span><br/>
-
<br/>
-
-you can optionally install it (Excluding mac OS) with:<br/>
-
-<br/>
-
-<span style="font-family: monospace;"># make install</span><br/>
-
-<h3><a name="Extra_notes_for_Mac_OSX"></a>Extra notes for Mac OSX<br/>
-
-</h3>
-
-To build a .app package (required to interact with the program), you need to run <br/>
-
+<span style="font-family: monospace;">$ hg clone http://hg.code.sf.net/p/threedepict/code/ 3Depict</span>
<br/>
-<span style="font-family: monospace;">$ makeMacOSXPackage</span><br/>
-
-<br/>
-
-You can even move this ".app" package to other computers (with the same OSX version), and it should work there. <br/>
-<br/>
-<h2><a href="windows"></a> Compile notes for windows </h2>
-<p><i>
-THese notes are a little outdated as of April 2013 - you may find some of the program versions have changed. Most of the notes should still be valid. However, this is not how 3Depict is built for windows - we use the cross-compile method instead. This has been scripted and is much easier, but requires a Debian or Debian-like installation (we recommend using VirtualBox). If you still want to compile under normal windows, then read on.
-</i>
-</p>
-<p> Before I post the full notes, this is very, very detailed and technical. But it means I have this working, and down to a fine art. Its a rough ride.</p>
-<p>
-You will need the 7zip file manager program or winrar to be able to open tar/gz files, as windows does not support this filetype, nor recognises it in the "web search" facility. (Its a standard gzip + archive file, note to windows devs : see <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Tgz">wikipedia on tar-gz</a>)</p>
-<p>
-This worked under windows 7. It probably works elsewhere too. Maybe. I *really* recommend using ubuntu or something; then you don't have to go through all these hoops.
-</p>
-<br/>
-Files required to set up dependencies:
+<h2>Compiling for your platform</h2>
+To compile, you must first have a working compilation environment. This is diferent for each system. Follow these notes to set up your environment for your system
<ul>
-<li>MSYS-1.0.11.exe</li>
-<li>tdm-gcc-4.5.1.exe</li>
-<li>lpng143.zip</li>
-<li>freetype-2.3.12.tar.gz</li>
-<li>gsl-1.14.tar.gz</li>
-<li>zlib-1.2.5.tar.gz</li>
-<li>libxml2-2.7.7.tar.gz</li>
-<li>ftgl-2.1.3~rc5.tar.gz</li>
-<li>mathgl-1.10.2.1.tar.gz</li>
-<li>wxMSW-2.8.11.zip</li>
+<li><a href="compiling-linux.html">Linux</a> - this is the recommended system for compiling, as it is the easiest to work with.</li>
+<li><a href="compiling-cross.html">Windows via Debian Linux</a> - this is the recommended method for building windows executables. We <b>do not</b> recommend building under windows directly, as it is very complicated.</li>
+<li><a href="compiling-macosx.html">Mac OSX</a> - Rough guide for OSX compilation.
</ul>
-<br/>
-<h3>Setting up dependencies</h3>
-<ul>
-<li>
-Installed TDM-GCC-4.51 (32bit) (all defaults +openmp)
-</li>
-<li>
- Installed MSYS-1.0.11
-<ul>
-<li>
- - Said "yes" to "have mingw installed (c:/MinGW32/)
-</li>
-</ul>
-</li>
-<li>
-Use console provided by the big blue "m(sys)" shortcut now on desktop to do most of the following
-</li>
-<li>
-Checked that<span style="font-family: monospace;">gcc --version</span> worked (should now spit out something like "gcc.exe (tdm-1) 4.5.1")
-</li>
-</ul>
-<h4>wxWidgets</h4>
-<ul>
-<li>
-Extracted wxMSW-2.8.11.zip to C:</li>
-<li>
-ran <span style="font-family: monospace;">./configure --with-opengl --enable-unicode</span> inside c:\wxMSW-2.8.11\
-</li>
-<li>
-ran <span style="font-family: monospace;">make</span>. This will take a long time to run. (make can of course be sped up on multi-cpu systems with <span style="font-family: monospace;">make -j(#CPU)</span> (eg <span style="font-family: monospace;">make -j4</span>) to enable parallel compilation
-</li>
-<li>
- Checked that the openGL wxWidgets sample works.
-<ul>
-<li>
- <span style="font-family: monospace;">cd samples/opengl</span></li>
- <li>
- <span style="font-family: monospace;">make</span></li>
- <li>
- Ran samples/opengl/cube/cube.exe</li>
- <li>
- Copied dlls that it complained about when double clicking the icon to the exe folder.
- (wxbase28u_gcc_custom.dll,wxmsw28u_core_gcc_custom.dll,wxmsw28u_gl_gcc_custom.dll)</li>
- <li>
- Ran samples/opengl/cube/cube.exe</li>
- <li>
- Saw cube. OpenGL must therefore work.
- </li>
- </ul>
-</li>
-<li>
- Ran <span style="font-family: monospace;">make install</span>
-</li>
-</ul>
-<h4>zlib</h4>
-<ul>
-<li>
- ran <span style="font-family: monospace;">make -f win32/Makefile.gcc</span>
-</li>
-<li>
- Copied .h to C:\MinGW32\include\
-</li>
-<li>
- Copied zlib1.dll,libz.a,libzdll.a to C:\MinGW32\lib\
-</li>
-</ul>
-
-<h4>libpng</h4>
-<ul>
-<li>
- depends upon zlib, so do zlib first
-</li>
-<li>
- ran <span style="font-family: monospace;">make-f scripts/makefile.gcc</span>
-</li>
-<li>
- Copied .h to C:\MinGW32\include\
-</li>
-<li>
- Copied libpng.a to c:\MinGW32\lib\
-</li>
-</ul>
-<h4>libxml2</h4>
-<ul>
-<li>
- Ran<span style="font-family: monospace;"> ./configure</span>
- <li>
- -- Failure on libtoolT (I ignored this).
- </li>
- </li>
-<li>
- Ran make
-</li>
-<li>
-- Failed on testThreads.c. In that file, on line 110:
-<span style="font-family: monospace;"> tid[i]= (pthread_t)-1; </span> should be
-<span style="font-family: monospace;">
-<pre>
- tid[i].p= NULL;
- tid[i].x=-1;
-</pre>
-</span>
-
- as pthread_t is a struct under windows ( see <a href="http://sourceware.org/pthreads-win32/faq.html">Pthreads faq</a>, Q11)
- looking in pthread.h:
-<span style="font-family: monospace;">
-<pre>
- typedef struct {
- void p; /* Pointer to actual object */
- unsigned int x; /* Extra information - reuse count etc */
- } ptw32_handle_t;
-</pre>
- </li>
-<li>
- Ran <span style="font-family: monospace;">make install</span>
-</li>
-</ul>
-<h4>libfreetype</h4>
-<ul>
-<li>
- Ran <span style="font-family: monospace;">./configure</span>
-</li>
-<li>
- Ran <span style="font-family: monospace;">make</span>
-</li>
-<li>
- Ran <span style="font-family: monospace;">make install</span>
-</li>
-</ul>
-<h4>ftgl</h4>
-<ul>
-<li>
- Edited configure
- <ul>
-<li>
- --found "-lgl" replaced with "-lopengl32".
- </li>
- <li>
- -- found "-lGLU" replaced with "-lGLU32"
- </li>
- <li>
- --openGL and GLU tests are broken. in "configure" replace char glBegin() with #include <GL/gl.h> and char gluNewTess (); with #include <GL/glu.h>, then remove the "return" specification from the function call. This will allow the GL and GLU tests to succeed.
- </li>
- </ul>
-</li>
-<li>
- Ran <span style="font-family: monospace;">./configure</span></li>
-<li>
- <span style="font-family: monospace;">Make</span></li>
-<li>
- <span style="font-family: monospace;">make install</span> (this installs into /usr/local/, which is not preferable, really)
- </li>
- </ul>
-<h4>GSL</h4>
-<ul>
-<li> Ran <span style="font-family: monospace;">./configure</span></li>
-<li> Ran <span style="font-family: monospace;">make</span></li>
-<li> ran <span style="font-family: monospace;">make install</span></li>
-</ul>
-
-<h4>Mathgl</h4>
-<ul>
-<li>
-(Depends GSL, do that before this)
- Ran <span style="font-family: monospace;">./configure</span>
-</li>
-<li>
- Ran Make
- <ul>
- <li>
- This failed in the utils dir. libpng is unable to see libz for whatever reason. Does not bode well, but it was in the utils section, which I don't need, so I ignored it.
- </li>
- </ul>
-</li>
-<li>
- Entered the "mgl" directory & ran <span style="font-family: monospace;">make install</span>
-</li>
-<li>
- Entered the "include" directory & ran <span style="font-family: monospace;">make install</span>
-</li>
-</ul>
-<h4>3Depict</h4>
-<ul>
-
-<li>
- Ran <span style="font-family: monospace;"> export CFLAGS="-I/c/msys/1.0/local/include" && export LDFLAGS="-L/c/msys/1.0/local/lib" && ./configure --with-libqhull-link="-L/c/msys/1.0/local/lib/ -lqhull" --with-libpng-link="-lpng -lz" </span>
- <ul>
- <li>
- For an explanation as to why this "export" business is needed, see <a href="http://www.mingw.org/wiki/IncludePathHOWTO">this mingw faq</a>. </li><li>
- -- This won't build with parallelism; you have to add <span style="font-family: monospace;">--enable-openmp-parallel </span> , however some versions of GCC do not like this, so I left it off by default. If you get errors about <span style="font-family: monospace;">undefined __sync_compare_and_swap_4 </span>(or similar) you can either 1) Alter your optimisation level 2) rebuild with -march=i686 3) modify the files it complains from, and build only those files without paralellism (modi [...]
- These settings will enable slow debug checking. To turn off debug checking add <span style="font-family: monospace;">--enable-no-debug-checks</span> after configure, as in <span style="font-family: monospace;">./configure --enable-no-debug-checks</span>. Full information is available in <span style="font-family: monospace;">./configure --help</span>.
- </li>
- </ul>
-</li>
-<li>
- Ran <span style="font-family: monospace;">make</span>
-</li>
-<li>
- Modified pngread.h to remove windows specific path
-</li>
-<li>
- Modified c:\msys\1.0\include\mgl\mgl_data.h to add #undef NO_GSL immediately before #ifndef NO_GSL
-</li>
-<li>
- Re-ran <span style="font-family: monospace;">make</span> -- this generates the "exe" file.
-</li>
-
-<li>
-Double clicked program
-
-<ul>
-<li>
- -- Put missing DLL it complained about in the same dir. Kept doing this until it stopped whinging about dlls
-</li>
-</ul>
-</li>
-</ul>
</div></div>
</body></html>
diff --git a/docs/web/contact.html b/docs/web/contact.html
index cbd3254..123de14 100644
--- a/docs/web/contact.html
+++ b/docs/web/contact.html
@@ -8,6 +8,7 @@
<title>Contact 3Depict</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="icon" type="image/png" href="favicon.png"/>
</head>
@@ -46,7 +47,7 @@ You can post messages to the <a href="https://sourceforge.net/apps/phpbb/threede
<h2>Email</h2>
<form id="emf-form" enctype="multipart/form-data" method="post" action="http://www.emailmeform.com/builder/form/ff3Jr0WI55h54"><table style="text-align:left;" cellpadding="2" cellspacing="0" border="0" bgcolor="transparent"><tr><td style="" colspan="2"></td></tr><tr valign="top"><td style="" ><font face="Verdana" size="2" color="#000000"><b>Name</b></font><span style="color:red;"><small>*</small></span></td></tr><tr><td style=""><input id="element_0" name="element_0" value="" size="30" c [...]
<p>
-If you need to attach an image, you can do so using an image upload service, such as <a href="http://imagepaste.nullnetwork.net/">Nullnetwork's image paste bin</a>, provided the images are < 1MB in size.
+If you need to attach an image, you can do so using an image upload service, such as <a href="http://imagebin.ca/">Imagebin.ca</a>.
</p>
</div>
</div>
diff --git a/docs/web/documentation.html b/docs/web/documentation.html
index bb29cc4..25c4fa2 100644
--- a/docs/web/documentation.html
+++ b/docs/web/documentation.html
@@ -5,9 +5,8 @@
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Documentation</title>
<meta name="description" content="Documentation for 3Depict" />
-
-
- <link rel="stylesheet" href="style.css" type="text/css" meda="screen"></head><body>
+ <link rel="icon" type="image/png" href="favicon.png"/>
+ <link rel="stylesheet" href="style.css" type="text/css" meda="screen"></head><body>
<div id="header">
<h1>3Depict - Valued point cloud visualisation and analysis</h1>
<ul id="nav">
@@ -42,6 +41,13 @@ PDF Manual <a href="manual.pdf">here</a>. There is an <a href="manual/manual.htm
<h2>Screencasts</h2>
+
+New features 0.0.14 (July 2013):<br>
+<center>
+<video src="3Depict-0.0.14-screencast.ogg" controls="controls" type='video/ogg; codecs="theora, vorbis"'></video><br></small>
+<small><a href="3Depict-0.0.14-screencast.ogg">download video</a></small>
+</center>
+
<p>
Animation and composition profiles in 3Depict 0.0.13 (Apr, 2013):<br>
<center>
@@ -49,11 +55,6 @@ Animation and composition profiles in 3Depict 0.0.13 (Apr, 2013):<br>
<small><a href="33Depict-0.0.13-sphere_comp_and_animate-screencast.ogg">download video</a></small>
</center>
-A short demo of 3Depict 0.0.8 (Oct, 2011):<br>
-<center>
-<video src="3Depict-0.0.8-screencast.ogg" controls="controls" type='video/ogg; codecs="theora, vorbis"'></video><br></small>
-<small><a href="3Depict-0.0.8-screencast.ogg">download video</a></small>
-</center>
<center>
@@ -83,8 +84,12 @@ Some sample datasets are listed below, and whilst not very interesting can be us
</p>
<h2> Programmer's Reference</h2>
-<p>
-3Depict has <a href="doxygen/main.html">documentation</a> regarding the program structure available. This is automatically generated using the <a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a> "Doxyfile" in the source tarball. The documentation provides data such as call and inheritance diagrams, hyperlinked function declarations and descriptions, and provides a useful "first glance" reference for working with the code. For a full program overview, try looking at the <a href=" [...]
+<h3> Compilation instructions</h3>
+
+For programmers, and advanced users, instructions on how to compile 3Depict from source are available <a href="compiling.html">here</a>. The procedure can be a bit tricky though.
+
+<h3> Program structure</h3>
+3Depict has <a href="doxygen/index.html">documentation</a> regarding the program structure available. This is automatically generated using the <a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a> "Doxyfile" in the source tarball. The documentation provides data such as call and inheritance diagrams, hyperlinked function declarations and descriptions, and provides a useful "first glance" reference for working with the code. For a full program overview, try looking at the <a href= [...]
</p>
diff --git a/docs/web/download.html b/docs/web/download.html
index e04aae3..18f6646 100644
--- a/docs/web/download.html
+++ b/docs/web/download.html
@@ -3,9 +3,10 @@
<meta name="description" content="Download 3Depict" />
-
-
- <link rel="stylesheet" href="style.css" type="text/css" meda="screen"></head><body>
+ <link rel="icon" type="image/png" href="favicon.png"/>
+ <link rel="stylesheet" href="style.css" type="text/css" meda="screen">
+
+</head><body>
<div id="header">
<h1>3Depict - Valued point cloud visualisation and analysis</h1>
<ul id="nav">
@@ -20,7 +21,7 @@
<div id="left">
<div class="box">
- <h2> Latest version: 0.0.13</h2>
+ <h2> Latest version: 0.0.16</h2>
</div>
<div class="box">
@@ -35,7 +36,9 @@ how</p>
<div id="content">
<div id="right">
<h1>Download</h1>
-<p> Remeber that 3Depict is currently in the <i>0.0.blah</i> series (early development). This is alpha software, and provided on a best-effort basis. If you find bugs in the software, please <a href="contact.html">let us know</a> and they will be fixed!</p>
+<p> Remember that 3Depict is currently in the <i>0.0.blah</i> series (early development). This is alpha software, and provided on a best-effort basis. If you find bugs in the software, please <a href="contact.html">let us know</a> and they will be fixed! Older releases are available in both source and binary (executable) form from our <a href="https://sourceforge.net/projects/threedepict/files/">files page</a>. </p>
+
+<p> Don't forget - support is available on our <a href="https://sourceforge.net/apps/phpbb/threedepict/index.php">forums</a>, or <a href="contact.html">by email!</a></p>
<h2>Select your system:</h2>
<ul>
@@ -67,10 +70,11 @@ how</p>
</ul>
<h3><a name="Mac_OS_X"></a>Mac OS X </h3>
+<p><i>The following versions are quite old now. We are looking for help with the OSX version, please see the <a href="https://sourceforge.net/apps/phpbb/threedepict/viewtopic.php?f=1&t=39">forum</a> thread!</i></p>
<ul>
- <li>10.7 "Lion" </li>
+ <li>10.7 "Lion" (0.0.13)</li>
<ul>
- <li><a href="https://sourceforge.net/projects/threedepict/files/3Depict-0.0.13-mac10.7.5.pkg/download">64 bit Intel</a> <br>
+ <li><a href="https://sourceforge.net/projects/threedepict/files/3Depict-0.0.13-10.7.pkg/download">64 bit Intel</a> <br>
</ul>
</li>
@@ -78,20 +82,29 @@ how</p>
<ul>
<li><a href="https://sourceforge.net/projects/threedepict/files/3Depict-0.0.10-mac10.6.dmg/download">32 bit Intel</a> <br>
</ul>
-
</li>
</ul>
-<h3><a name="Windows"></a>Windows (0.0.11)</h3>
+<h3><a name="Windows"></a>Windows </h3>
+<small>how to tell if you want the 32 or 64 bit version : <a href="http://windows.microsoft.com/en-US/windows-vista/32-bit-and-64-bit-Windows-frequently-asked-questions">see here</a></small>. If you are still unsure, try the 64 bit version, then if it doesn't work, use the 32 bit one.
+
+
<ul>
- <li><a href="http://sourceforge.net/projects/threedepict/files/3Depict-0.0.11-win32.exe/download">32 Bit version</a> (works on 64 bit too, just slower, and can't use as much RAM). XP Users - <a href="https://sourceforge.net/apps/phpbb/threedepict/viewtopic.php?f=1&t=13">Note</a>
+ <li>0.0.16 :<a href="http://sourceforge.net/projects/threedepict/files/3Depict-0.0.16-win32.exe/download">32 Bit version</a>
+ </li>
+<li>0.0.16: <a href="http://sourceforge.net/projects/threedepict/files/3Depict-0.0.16-win64.exe/download">64 Bit version</a>
</li>
</ul>
+
+
+<p>
+
+</p>
<h3><a name="Other_systems"></a>Other systems</h3>
<ul>
<li>Binaries (executables) not available for your system, sorry. You
-will have to <a href="compiling.html">compile from source</a>. The current compressed source archive is <a href="http://sourceforge.net/projects/threedepict/files/0.0.12/3Depict-0.0.12.tar.gz/download">3Depict 0.0.12</a>.</li>
- <li>Older releases are avaialable in both source and binary (excecutable) form from our <a href="https://sourceforge.net/projects/threedepict/files/">sourceforge files page</a>. </li>
+will have to <a href="compiling.html">compile from source</a>. The current compressed source archive is <a href="http://sourceforge.net/projects/threedepict/files/0.0.16/3Depict-0.0.16.tar.gz/download">3Depict 0.0.16</a>.</li>
+
</ul>
<br>
</div>
diff --git a/docs/web/images/3Depict-icon.png b/docs/web/images/3Depict-icon.png
new file mode 100644
index 0000000..650ac31
Binary files /dev/null and b/docs/web/images/3Depict-icon.png differ
diff --git a/docs/web/images/Screenshot-thumb.png b/docs/web/images/Screenshot-thumb.png
new file mode 100644
index 0000000..c109dcc
Binary files /dev/null and b/docs/web/images/Screenshot-thumb.png differ
diff --git a/docs/web/images/cu-ppt-cluster-analysis.png b/docs/web/images/cu-ppt-cluster-analysis.png
new file mode 100644
index 0000000..7144eaa
Binary files /dev/null and b/docs/web/images/cu-ppt-cluster-analysis.png differ
diff --git a/docs/web/images/exportanimParamDialog.png b/docs/web/images/exportanimParamDialog.png
new file mode 100644
index 0000000..29e94d2
Binary files /dev/null and b/docs/web/images/exportanimParamDialog.png differ
diff --git a/docs/web/images/laser-data1.png b/docs/web/images/laser-data1.png
new file mode 100644
index 0000000..82dbb0c
Binary files /dev/null and b/docs/web/images/laser-data1.png differ
diff --git a/docs/web/images/laser-data2.png b/docs/web/images/laser-data2.png
new file mode 100644
index 0000000..b27c76f
Binary files /dev/null and b/docs/web/images/laser-data2.png differ
diff --git a/docs/web/images/resolution-example.png b/docs/web/images/resolution-example.png
new file mode 100644
index 0000000..94e2338
Binary files /dev/null and b/docs/web/images/resolution-example.png differ
diff --git a/docs/web/images/voxel-representations.png b/docs/web/images/voxel-representations.png
new file mode 100644
index 0000000..db4a452
Binary files /dev/null and b/docs/web/images/voxel-representations.png differ
diff --git a/docs/web/index.html b/docs/web/index.html
index adebc5b..465eb32 100644
--- a/docs/web/index.html
+++ b/docs/web/index.html
@@ -8,6 +8,7 @@
<title>3Depict Home</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="icon" type="image/png" href="favicon.png"/>
</head>
@@ -26,14 +27,18 @@
<div id="left">
<div class="box">
-<h2> Latest version: 0.0.13</h2>
+<h2> Latest version: 0.0.16</h2>
<p><a href="download.html">Download</a> the latest version of 3Depict for your platform</p>
</div>
<div class="box">
<b>Questions?</b> Ask on the <a href="http://sourceforge.net/apps/phpbb/threedepict/">forum</a>
<br/>
+<br/>
+<b>Quick Peek?</b>: See some <a href="screenshots.html">Screenshots</a>
+
</div>
+
<center>
<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=341003&type=2" alt="SourceForge.net Logo" border="0" height="37" width="125" align="middle"/></a><br/>
<small><a href="http://sourceforge.net/projects/threedepict/">SF project page</a></small>
@@ -58,24 +63,25 @@ interact with and analyse point based datasets. <br/>
<h3>
News:
</h3>
-
<ul>
- <li><i>15th Apr. 2013: </i> 3Depict 0.0.13 windows installers <a href="download.html">uploaded</a>.</li>
- <li><i>13th Apr. 2013: </i> 3Depict 0.0.13 mac OSX 10.7 ("Lion") <a href="download.html">uploaded</a>.</li>
- <li><i>12th Apr. 2013: </i> 3Depict 0.0.13 source code uploaded</li>
-
- <li>Older news <a href="news.html">here</a>
+ <li><i>24th Apr. 2014: </i> The console-only <i>Posgen</i> project, which covers atom probe data automation, has had its 0.0.1 release! <a href="http://apttools.sourceforge.net/">Check it out</a>!
+ <li><i>21th Apr. 2014: </i> 0.0.16 installers for windows 32 and 64 bit ready for <a href="download.html">download</a>!</li>
+ <li><i>17st Apr. 2014: </i> 3Depict 0.0.16 released. As previously mentioned, we have experimental LAWATAP ato file support, and have improved overall program stability and appearance. Check the complete <a href="changelog.txt">changelog</a>!</li>
+ <li><i>6th Apr. 2014</i> Source code repository has been updated for upcoming 0.0.16. You can see the upcoming features for 3Depict in the source-code repository's <a href="http://sourceforge.net/p/threedepict/code/ci/f03a128c15bc422c6ba5fc38245f77ee1248c19e/tree/ChangeLog">changelog</a>. Notably, experimental ATO file support (please submit samples!) has been added, and many plot area improvements have been made</li>
+
+ <li>Older news <a href="news.html">here</a>,</li>
</ul>
<h3>
-New features in 0.0.13:
+Enhancements in 0.0.16:
</h3>
<ul>
- <li>Spherical composition profiles</li>
- <li>1D "axial" distribution functions, for measuring inter-atomic distance profiles</li>
-
-
+ <li>Experimental LAWATAP (.ATO) support. We need sample files to ensure this works for everyone, so please send them!</li>
+ <li>Animation is saved/restored</li>
+ <li>Filter tree interaction improved</li>
+ <li>Min-count mode for composition profiles</li>
+ <li>Automated GUI interaction checker</li>
<li> and more. Full details in the <a href="changelog.txt">Changelog</a></li>
</ul>
@@ -146,6 +152,7 @@ of how much you have </a><br/>
</ul>
</li>
+ <li> Most, but not all state files can be transmitted between differing 3Depict versions</li>
</ul>
</div>
diff --git a/docs/web/manual.html b/docs/web/manual.html
index ec5e9e6..ab8db9a 100644
--- a/docs/web/manual.html
+++ b/docs/web/manual.html
@@ -8,7 +8,7 @@
<title>3Depict Home</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
-
+ <link rel="icon" type="image/png" href="favicon.png"/>
</head>
<body>
<div id="left">
diff --git a/docs/web/news.html b/docs/web/news.html
index e016dff..7791976 100644
--- a/docs/web/news.html
+++ b/docs/web/news.html
@@ -8,7 +8,7 @@
<title>3Depict Home</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
-
+ <link rel="icon" type="image/png" href="favicon.png"/>
</head>
<body>
@@ -30,15 +30,34 @@
<div id="right">
<h2> News Archive </h2>
<p>
+<h3> 2013</h3>
+<ul>
+ <li><i>25th Jan. 2014: </i> <a href="http://sourceforge.net/apps/phpbb/threedepict/viewtopic.php?f=1&t=38">Bugs</a> were introduced in the uploaded versions of 0.0.15, which caused the filter system to function incorrectly. This has been fixed, and the installers updated. If you downloaded 0.0.15 previously, please <a href="download.html">re-download</a> the latest installer (windows: 0.0.15-1).</li>
+ <li><i>1st Dec. 2013: </i> 3Depict 0.0.15 installers for windows 32 and 64 bit <a href="download.html">uploaded</a>. The current windows installers now use multiple CPUs for many filters - go faster!</li>
+ <li><i>1st Dec. 2013: </i> 3Depict 0.0.15 released! New features include a range editor, binomial randomness testing, and enhanced support for ENV and RRNG files. More details in the <a href="changelog.txt">Changelog</a>. Platform builds available soon.</li>
+
+ <li><i>29th Aug. 2013: </i> Some reports of windows versions of 0.0.14 not working for some systems, whilst 0.0.13 works. If this affects you, please <a href="https://sourceforge.net/apps/phpbb/threedepict/viewtopic.php?f=1&t=33">post on the forum</a>.</li>
+ <li><i>21st Jul. 2013: </i> Windows installers <a href="download.html">uploaded</a>.</li>
+ <li><i>20th Jul. 2013: </i> 3Depict 0.0.14 source code uploaded. Various platform releases to follow shortly. </li>
+
+ <li><i>6th Jul. 2013: </i> 3Depict 0.0.14's <a href="http://sourceforge.net/p/threedepict/code/ci/default/tree/">source code</a> is now ready for testing. New <a href="http://sourceforge.net/p/threedepict/code/ci/default/tree/ChangeLog">features</a> include slice voxel visualisation, improved rangefile support and performance improvements. Advanced users can <a href="compiling.html">build a copy</a>. We plan to finalise the release in ~3 weeks.</li>
+
+ <li><i>15th Apr. 2013: </i> 3Depict 0.0.13 windows installers <a href="download.html">uploaded</a>.</li>
+ <li><i>13th Apr. 2013: </i> 3Depict 0.0.13 mac OSX 10.7 ("Lion") <a href="download.html">uploaded</a>.</li>
+
+ <li><i>12th Apr. 2013: </i> 3Depict 0.0.13 source code uploaded</li>
+</ul>
+
<h3> 2012</h3>
<ul>
- <li><i>24 Nov. 2012: 0.0.12 released - the source code has been uploaded, with various platform builds to follow shortly. This release focussed on a new feature - filter animation, as well as improved stability and decreased resource consumption. As usual, check the <a href="changelog.txt">Changelog</a> for more info!</i></li>
- <li><i>29 Oct. 2012: We are finalising the current code for release of 0.0.12 in ~6 weeks. We need people to test the program, do translation and provide feedback - if you can help out, please <a href="contact.html">contact us</a>!</i></li>
- <li><i>20 Jul. 2012: We have received unconfirmed reports that some users on Windows XP may experience startup problems with 3Depict. If this affects you, please <a href="https://sourceforge.net/apps/phpbb/threedepict/viewtopic.php?f=1&t=13">report it</a>.</i></li>
- <li><i>17th Jul. 2012: Windows and Mac 10.7 installers uploaded for 3Depict 0.0.11.</i></li>
- <li><i>16th Jul. 2012: 3Depict 0.0.11 source code uploaded. Installers for various platforms (linux,mac,windows) to follow soon.</i></li>
- <li><i>28th Jun. 2012: 3Depict 0.0.10 mac 10.6 (snow leopard) installer uploaded.</i></li>
- <li><i>10th Apr. 2012: 3Depict 0.0.10 mac 10.7 (lion) installer uploaded.</i></li>
+
+ <li><i>24 Nov. 2012:</i> 0.0.12 released - the source code has been uploaded, with various platform builds to follow shortly. This release focussed on a new feature - filter animation, as well as improved stability and decreased resource consumption. As usual, check the <a href="changelog.txt">Changelog</a> for more info!</i></li>
+ <li><i>29th Oct. 2012:</i> We are finalising the current code for release of 0.0.12 in ~6 weeks. We need people to test the program, do translation and provide feedback - if you can help out, please <a href="contact.html">contact us</a>!</i></li>
+ <li><i>20th Jul. 2012:</i> We have received unconfirmed reports that some users on Windows XP may experience startup problems with 3Depict. If this affects you, please <a href="https://sourceforge.net/apps/phpbb/threedepict/viewtopic.php?f=1&t=13">report it</a>.</i></li>
+ <li><i>17th Jul. 2012:</i> Windows and Mac 10.7 installers uploaded for 3Depict 0.0.11.</i></li>
+ <li><i>16th Jul. 2012:</i> 3Depict 0.0.11 source code uploaded. Installers for various platforms (linux,mac,windows) to follow soon.</i></li>
+ <li><i>28th Jun. 2012:</i> 3Depict 0.0.10 mac 10.6 (snow leopard) installer uploaded.</i></li>
+ <li><i>10th Apr. 2012:</i> 3Depict 0.0.10 mac 10.7 (lion) installer uploaded.</i></li>
<li><i>1st Apr. 2012:</i> 3Depict 0.0.10 windows installer uploaded.</li>
<li><i>31st Mar. 2012:</i> 3Depict 0.0.10 source code uploaded. Builds for various platforms to follow. This version mostly is directed at bug fixes and improved program structure.</li>
<li><i>25th Mar. 2012:</i> We are close to releasing 0.0.10, and we would like to have better native language support - we have added French and Spanish using <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Translation_memory">translation memory</a>, but it still needs human review. If you can check translations in these languages - please consider doing so <a href="https://www.transifex.net/projects/p/3depict/">here</a>.</li>
diff --git a/docs/web/questions.html b/docs/web/questions.html
index d3c105b..94c3e73 100644
--- a/docs/web/questions.html
+++ b/docs/web/questions.html
@@ -8,6 +8,7 @@
<title>3Depict Frequent Questions</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="icon" type="image/png" href="favicon.png"/>
</head>
@@ -43,7 +44,7 @@ You can help, even without programming; Alternately, if you know how to program
<li>Are there any instruction manuals?</li>
<ul>
<li>Yes, you can download one from the <a href="documentation.html">documentation
-page.</a>
+page.</a> If you are new to 3Depict, but not atom probe, you might want to read the "quick start" section in the manual.
</li>
</ul>
</ul>
@@ -60,17 +61,16 @@ page.</a>
</ul>
</ul>
</ul>
+
<ul>
- <li>I'm running Debian/Mint/Ubuntu, and getting a crash on startup: "Floating point exception"</li>
- <ul>
- <li>We left some strict debugging in for some of the deb packages, which converts a minor problem into a major one, but only on some machines (we are not sure why). To solve this, you need to update to 0.0.8 or later. We have <a href="https://launchpad.net/~tehuser/+archive/ppa">set up a PPA</a> for Ubuntu users.</li>
- </ul>
-</ul>
-<ul>
- <li>I'm running Mac OSX, and when trying to update to the new version, I get the error "A newer version of this software already exists on this disk"</li>
+ <li>How do I cite this program?</li>
<ul>
- <li>This was due to us not specifying a version number in some early releases. Go to spotlight, then type "terminal", and open Terminal.app. Now cut and paste the following command into the terminal to remove the old version data. <p><span style="font-family: monospace;">sudo rm /private/var/db/receipts/net.sourceforge.threedepict.3Depict.pkg.plist /private/var/db/receipts/net.sourceforge.3Depict.pkg.plist
-</span></p> don't forget to press enter. You will be prompted for your password for this action.</li>
+ <li>We get this one more than we thought too. Just make sure the URL and the version number of the program you were using is included. Here is a bibtex entry you can modify : <br/><code> @Misc{,<br/>
+ Title = {3Depict - Valued point cloud visualisation and analysis},<br/>
+ Note = {[Online; Accessed : D-Month-YEAR ]},<br/>
+ Comment = {Please use \usepackageurl with latex, to display URL in citation},<br/>
+ Url = {http://threedepict.sourceforge.net}<br/>
+} </code> </li>
</ul>
</ul>
@@ -99,7 +99,7 @@ too.</li>
</ul>
<ul>
- <li><a href="http://imagepaste.nullnetwork.net/">Upload a nice screenshot online</a>, then send us a link. </li>
+ <li>Upload a nice screenshot online, then send us a link. </li>
<li>Report bugs, or </li>
</ul>
<ul>
@@ -151,6 +151,7 @@ computational skill and more importantly, familiarity with the code.</li>
<ul>
<li>Firstly, make sure you are familiar with C++ and compiling projects with multiple source files. Then, the best thing to do is to <a href="compiling.html">compile</a> the latest source code (.tar.gz file). This is by far the easiest under Linux, then Mac, and most difficult under windows, due to dependencies. If needed, you can run a <a href="http://www.virtualbox.org">virtual machine</a>. Now, once done, you can make your changes as you like - there is a section in the manual descri [...]
</ul>
+
</ul>
<ul>
@@ -164,7 +165,7 @@ computational skill and more importantly, familiarity with the code.</li>
<ul>
<li>Well,
try to <a href="contact.html">contact the authors</a>. These questions were written in a
-speculative fashion, and are not technically "frequently asked".</li>
+speculative fashion, and are not technically "frequently asked". There are some older questions written up <a href="questions/oldquestions.html">here</a>, for which the answers are now a bit obsolete.</li>
</ul>
</ul>
</div>
diff --git a/docs/web/rss.xml b/docs/web/rss.xml
index 9c0d622..9c275d8 100644
--- a/docs/web/rss.xml
+++ b/docs/web/rss.xml
@@ -6,12 +6,48 @@
<title>3Depict releases</title>
<description>3Depict release data</description>
<link>http://threedepict.sourceforge.net/</link>
- <lastBuildDate>Sat, 24 Nov 2012 00:00:00 +0000 </lastBuildDate>
- <pubDate>Fri, 12 Apr 2013 00:00:00 +0000 </pubDate>
+ <lastBuildDate>Sun, 01 Dec 2013 00:00:00 +0000 </lastBuildDate>
+ <pubDate>Sun, 01 Dec 2013 00:00:00 +0000 </pubDate>
+
+
+ <item>
+ <title>0.0.16</title>
+ <description>source,win32,win64</description>
+
+
+ <link>http://threedepict.sourceforge.net/changelog.txt</link>
+ <guid>http://sourceforge.net/projects/threedepict/files/0.0.16/3Depict-0.0.16.tar.gz/download</guid>
+
+ <pubDate>Sun, 17 Apr 2014 00:00:00 +0000 </pubDate>
+ </item>
+
+
+ <item>
+ <title>0.0.15</title>
+ <description>source,win32,win64,macosx10.7</description>
+
+
+ <link>http://threedepict.sourceforge.net/changelog.txt</link>
+ <guid>http://sourceforge.net/projects/threedepict/files/0.0.15/3Depict-0.0.15.tar.gz/download</guid>
+
+ <pubDate>Sun, 01 Dec 2013 00:00:00 +0000 </pubDate>
+ </item>
+
+ <item>
+ <title>0.0.14</title>
+ <description>win32,win64,source</description>
+
+
+ <link>http://threedepict.sourceforge.net/changelog.txt</link>
+ <guid>http://sourceforge.net/projects/threedepict/files/0.0.14/3Depict-0.0.14.tar.gz/download</guid>
+
+ <pubDate>Sun, 21 Jul 2013 00:00:00 +0000 </pubDate>
+ </item>
+
<item>
<title>0.0.13</title>
- <description>macosx10.7,source</description>
+ <description>win32,win64,macosx10.7,source</description>
<link>http://threedepict.sourceforge.net/changelog.txt</link>
diff --git a/docs/web/screenshots.html b/docs/web/screenshots.html
new file mode 100644
index 0000000..8f55f8e
--- /dev/null
+++ b/docs/web/screenshots.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta content="text/html; charset=utf-8" http-equiv="content-type" />
+ <meta name="description" content="Point cloud visualisation and analysis. Useful for atom probe, lidar, and more sciencey/data-ey things"/>
+
+ <title>3Depict Screenshots </title>
+ <link rel="stylesheet" href="style.css" type="text/css"/>
+ <link rel="icon" type="image/png" href="favicon.png"/>
+</head>
+<body>
+<div id="header">
+<h1>3Depict - Valued point cloud visualisation and analysis</h1>
+<ul id="nav">
+ <li><a href="index.html">Home</a></li>
+ <li><a href="download.html">Download</a></li>
+ <li><a href="questions.html">Questions</a></li>
+ <li><a href="documentation.html">Documentation</a></li>
+ <li><a href="contact.html">Contact</a></li>
+ <li><a href="about.html">About</a></li>
+</ul>
+</div>
+
+<div id="left">
+<div class="box">
+<h2>Have a neat image?</h2>
+<p>You should <a href="contact.html">let us know</a>, so we can add it!</p>
+</div>
+</div>
+
+
+<div id="content">
+<div id="right">
+<p>
+<center>
+<h3>Cluster analysis of Cu Precipitates in Steel</h3>
+<img src="images/cu-ppt-cluster-analysis.png"/><br/>
+<small>Courtesy, Dr. P. Styman, <a href="http://www-fim.materials.ox.ac.uk">University of Oxford, Dept. Materials</a></small>
+<br/>
+<br/>
+
+<h3>"Ladybug" robotics project data visualisation</h3>
+<img src="images/laser-data1.png"/>
+<br/>
+<br/>
+<img src="images/laser-data2.png"/>
+<br/>
+<br/>
+<hr width="35%"/>
+<h3>Atom probe data analysis</h3>
+<img src="images/resolution-example.png"/>
+</div>
+</div>
+
+
+
+</center>
+</p>
+</body></html>
diff --git a/docs/web/videos.html b/docs/web/videos.html
index 1780c31..bfe8732 100644
--- a/docs/web/videos.html
+++ b/docs/web/videos.html
@@ -5,8 +5,7 @@
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Documentation</title>
<meta name="description" content="Documentation for 3Depict" />
-
-
+ <link rel="icon" type="image/png" href="favicon.png"/>
<link rel="stylesheet" href="style.css" type="text/css" meda="screen"></head><body>
<div id="header">
<h1>3Depict - Valued point cloud visualisation and analysis</h1>
@@ -23,7 +22,29 @@
<div id="content">
<div id="right"><br>
+
+A short demo of 3Depict 0.0.8 (Oct, 2011):<br>
+<center>
+<video src="3Depict-0.0.8-screencast.ogg" controls="controls" type='video/ogg; codecs="theora, vorbis"'></video><br></small>
+<small><a href="3Depict-0.0.8-screencast.ogg">download video</a></small>
+</center>
+
<p>
+New in 0.0.4 (Jan, 2011) :<br>
+<center>
+<video src="3Depict-0.0.4-screencast.ogg" controls="controls" type='video/ogg; codecs="theora, vorbis"'></video><br>
+<small><a href="3Depict-0.0.4-screencast.ogg">download video</a></small>
+</center>
+
+
+
+New in 0.0.3 (Nov, 2010) :<br>
+<center>
+<video src="3Depict-0.0.3-screencast.ogg" controls="controls" type='video/ogg; codecs="theora, vorbis"'></video><br>
+<small><a href="3Depict-0.0.3-screencast.ogg">download video</a></small>
+</center>
+
+
New in 0.0.2 (Sep, 2010) :<br>
<center>
<video src="3Depict-0.0.2-screencast.ogg" controls="controls" type='video/ogg; codecs="theora, vorbis"'></video><br>
@@ -31,6 +52,18 @@ New in 0.0.2 (Sep, 2010) :<br>
</center>
<p>
+A short demo of 3Depict 0.0.1 (Aug, 2010):<br>
+<center>
+<video src="3Depict-0.0.1-screencast.ogg" controls="controls" type='video/ogg; codecs="theora, vorbis"'></video><br><small>
+<a href="3Depict-0.0.1-screencast.ogg">download video</a>
+</center>
+
+<center>
+<br>
+<br>
+Can't see the videos above? You can download the video using the links above, we recommend the <a href="http://www.videolan.org/vlc/">VideoLan Client</a> player for playing the downloaded files. <br> If you want in-browser playback, you might need to install <a href="http://xiph.org/quicktime/">XiphQT</a> (mac, safari) or <a href="http://xiph.org/dshow/">Xiph Directshow</a> (windows, IE). Alternately, you should be able to view this without downloading any plugins under the <a href="htt [...]
+</center>
+
</div>
</div>
</body>
diff --git a/install-sh b/install-sh
old mode 100644
new mode 100755
index 0bd91ae..e69de29
--- a/install-sh
+++ b/install-sh
@@ -1 +0,0 @@
-install-sh
diff --git a/locales/de_DE/LC_MESSAGES/3Depict.mo b/locales/de_DE/LC_MESSAGES/3Depict.mo
index cf1c383..36291f1 100644
Binary files a/locales/de_DE/LC_MESSAGES/3Depict.mo and b/locales/de_DE/LC_MESSAGES/3Depict.mo differ
diff --git a/packaging/RPM/3Depict-0.0.15-manual-pdf-loc.patch b/packaging/RPM/3Depict-0.0.15-manual-pdf-loc.patch
deleted file mode 100644
index 8eb261f..0000000
--- a/packaging/RPM/3Depict-0.0.15-manual-pdf-loc.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-diff -r 1b997a96b779 src/gui/mainFrame.cpp
---- src/gui/mainFrame.cpp Sat Mar 23 17:50:44 2013 +0000
-+++ src/gui/mainFrame.cpp Sat Mar 23 17:56:36 2013 +0000
-@@ -2546,9 +2546,9 @@
- string s;
- s=locateDataFile("3Depict-manual.pdf");
-
-- //Also Debian makes us use the lowercase "D", so check there too.
-- if(!s.size())
-- s=locateDataFile("3depict-manual.pdf");
-+ //Also Fedora has diff dir
-+ if(!wxFileExists(wxStr(s)))
-+ s="/usr/share/doc/3Depict-0.0.8/3Depict-0.0.8-manual.pdf";
-
-
- //If we found it, use the default program associated with that data file
diff --git a/packaging/RPM/3Depict-0.0.15-font-path.patch b/packaging/RPM/3Depict-0.0.17-font-path.patch
similarity index 83%
rename from packaging/RPM/3Depict-0.0.15-font-path.patch
rename to packaging/RPM/3Depict-0.0.17-font-path.patch
index 3c13891..02f52fc 100644
--- a/packaging/RPM/3Depict-0.0.15-font-path.patch
+++ b/packaging/RPM/3Depict-0.0.17-font-path.patch
@@ -1,7 +1,7 @@
-diff -r 1b997a96b779 src/wxcomponents.cpp
---- src/wx/wxcomponents.cpp Sat Mar 23 17:50:44 2013 +0000
-+++ src/wx/wxcomponents.cpp Sat Mar 23 17:56:14 2013 +0000
-@@ -857,16 +857,17 @@
+diff -r 7abb69436c2b src/wx/wxcomponents.cpp
+--- src/wx/wxcomponents.cpp Sat Aug 02 05:39:24 2014 -0400
++++ src/wx/wxcomponents.cpp Sat Aug 02 05:40:51 2014 -0400
+@@ -547,16 +547,17 @@
//(Oh look Ma, I'm autoconf!)
const char *dirs[] = { ".",
diff --git a/packaging/RPM/3Depict-0.0.17-manual-pdf-loc.patch b/packaging/RPM/3Depict-0.0.17-manual-pdf-loc.patch
new file mode 100644
index 0000000..31178af
--- /dev/null
+++ b/packaging/RPM/3Depict-0.0.17-manual-pdf-loc.patch
@@ -0,0 +1,16 @@
+diff -r 7abb69436c2b src/gui/mainFrame.cpp
+--- src/gui/mainFrame.cpp Sat Aug 02 05:39:24 2014 -0400
++++ src/gui/mainFrame.cpp Sat Aug 02 05:40:32 2014 -0400
+@@ -2840,9 +2840,9 @@
+ string s;
+ s=locateDataFile("3Depict-manual.pdf");
+
+- //Also Debian makes us use the lowercase "D", so check there too.
+- if(!s.size())
+- s=locateDataFile("3depict-manual.pdf");
++ //Also Fedora has diff dir
++ if(!wxFileExists(s))
++ s="/usr/share/doc/3Depict-0.0.8/3Depict-0.0.8-manual.pdf";
+
+ //FIXME: under windows, currently we use "manual.pdf"
+ if(!s.size())
diff --git a/packaging/RPM/3Depict-0.0.17-upstream.patch b/packaging/RPM/3Depict-0.0.17-upstream.patch
new file mode 100644
index 0000000..c82d579
--- /dev/null
+++ b/packaging/RPM/3Depict-0.0.17-upstream.patch
@@ -0,0 +1,65 @@
+diff -r 7372047ee6f9 src/common/basics.cpp
+--- src/common/basics.cpp Sun Aug 03 16:58:06 2014 -0400
++++ src/common/basics.cpp Sun Aug 03 17:01:04 2014 -0400
+@@ -1471,6 +1471,21 @@
+ return 0;
+ }
+
++bool isNotDirectory(const char *filename)
++{
++ struct stat statbuf;
++
++ if(stat(filename,&statbuf) == -1)
++ return false;
++
++ return (statbuf.st_mode !=S_IFDIR);
++}
++
++bool rmFile(const std::string &filename)
++{
++ return remove(filename.c_str()) == 0;
++}
++
+ #ifdef DEBUG
+ bool isValidXML(const char *filename)
+ {
+@@ -1503,27 +1518,6 @@
+ return true;
+ }
+
+-#if !defined(__WIN32__) && !defined(__WIN64)
+
+-bool isNotDirectory(const char *filename)
+-{
+- struct stat statbuf;
+-
+- if(stat(filename,&statbuf) == -1)
+- return false;
+-
+- return (statbuf.st_mode !=S_IFDIR);
+-}
+-
+-bool rmFile(const std::string &filename)
+-{
+- return remove(filename.c_str()) == 0;
+-}
+-#elif defined(__WIN32) || defined(__WIN64)
+-bool rmFile(const std::string &filename)
+-{
+- return DeleteFile((const wchar_t*)filename.c_str()) == 0;
+-}
+-#endif
+
+ #endif
+diff -r 7372047ee6f9 src/gl/tr.cpp
+--- src/gl/tr.cpp Sun Aug 03 16:58:06 2014 -0400
++++ src/gl/tr.cpp Sun Aug 03 17:01:04 2014 -0400
+@@ -63,7 +63,7 @@
+ #include "common/assertion.h"
+
+ #include <math.h>
+-
++#include <stdlib.h>
+
+ #ifdef WIN32
+ #include <windows.h>
diff --git a/packaging/RPM/3Depict.spec b/packaging/RPM/3Depict.spec
index 7d943cf..8d2780b 100644
--- a/packaging/RPM/3Depict.spec
+++ b/packaging/RPM/3Depict.spec
@@ -1,5 +1,5 @@
Name: 3Depict
-Version: 0.0.16
+Version: 0.0.17
Release: 1%{?dist}
Summary: Valued 3D point cloud visualization and analysis
Group: Applications/Engineering
@@ -36,8 +36,7 @@ BuildRequires: qhull-devel
Patch0: %{name}-%{version}-manual-pdf-loc.patch
#Fedora specific font dir
Patch1: %{name}-%{version}-font-path.patch
-#Upstream patches from 0.0.15 release tarball
-Patch2: %{name}-0.0.15-upstream.patch
+
%description
This software is designed to help users visualize and analyze 3D point clouds
@@ -51,7 +50,6 @@ useful for general scalar valued point data purposes.
%patch0
%patch1
-%patch2
%build
%configure --disable-debug-checks --enable-openmp-parallel --enable-mgl2
@@ -112,7 +110,13 @@ rm -rf %{buildroot}
%changelog
-* Sun Apr 06 2014 D Haley <mycae(a!t)gmx.com> - 0.0.16-1
+* Sat Aug 02 2014 D Haley <mycae(a!t)gmx.com> - 0.0.17-1
+- Update to 0.0.17
+
+* Fri Jun 06 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.0.16-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Sat Apr 26 2014 D Haley <mycae(a!t)gmx.com> - 0.0.16-1
- Update to 0.0.16
* Wed Feb 12 2014 D Haley <mycae(a!t)gmx.com> - 0.0.15-4
diff --git a/packaging/debian/3depict.install b/packaging/debian/3depict.install
old mode 100644
new mode 100755
diff --git a/packaging/debian/changelog b/packaging/debian/changelog
index 2b680f4..b44a057 100644
--- a/packaging/debian/changelog
+++ b/packaging/debian/changelog
@@ -1,8 +1,20 @@
-3depict (0.0.16-1) UNRELEASED; urgency=medium
+3depict (0.0.17-1) UNRELEASED; urgency=medium
+
+ * Update to upstream 0.0.17
+
+ -- D Haley <mycae at gmx.com> Sun, 03 Aug 2014 23:11:45 +0100
+
+3depict (0.0.16-2) unstable; urgency=medium
+
+ * Add wx 3.0 startup patch (Closes: #746609)
+
+ -- D Haley <mycae at gmx.com> Mon, 09 Jun 2014 22:54:00 +0100
+
+3depict (0.0.16-1) unstable; urgency=medium
* Update to upstream 0.0.16
- -- D Haley <mycae at gmx.com> Sun, 06 Apr 2014 23:11:51 +0100
+ -- D Haley <mycae at gmx.com> Thu, 24 Apr 2014 00:56:00 +0100
3depict (0.0.15-3) unstable; urgency=medium
diff --git a/packaging/debian/control b/packaging/debian/control
old mode 100644
new mode 100755
index 86e3834..b770948
--- a/packaging/debian/control
+++ b/packaging/debian/control
@@ -3,7 +3,7 @@ Section: science
Priority: optional
Maintainer: Debian Science Maintainers <debian-science-maintainers at lists.alioth.debian.org>
Uploaders: D Haley <mycae at gmx.com>
-Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), libgl1-mesa-dev | libgl-dev, libpng-dev | libpng15-dev, libqhull-dev, libwxgtk2.8-dev, libftgl-dev, libxml2-dev, libmgl-dev (>= 2.0)
+Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), libgl1-mesa-dev | libgl-dev, libpng-dev | libpng15-dev, libqhull-dev, libwxgtk3.0-dev, libftgl-dev, libxml2-dev, libmgl-dev (>= 2.0), automake
Standards-Version: 3.9.5
Homepage: http://threedepict.sourceforge.net/index.html
Vcs-Git: git://anonscm.debian.org/debian-science/packages/3depict.git
diff --git a/packaging/debian/copyright b/packaging/debian/copyright
old mode 100644
new mode 100755
diff --git a/packaging/debian/patches/patch-caching-bug b/packaging/debian/patches/patch-caching-bug
deleted file mode 100644
index 0b845b4..0000000
--- a/packaging/debian/patches/patch-caching-bug
+++ /dev/null
@@ -1,35 +0,0 @@
-Bug fix for 0.0.15, from upstream : http://hg.code.sf.net/p/threedepict/code/rev/7fba7ef21117
---- 3depict-0.0.16.orig/src/backend/filters/ionColour.cpp
-+++ 3depict-0.0.16/src/backend/filters/ionColour.cpp
-@@ -82,7 +82,7 @@
- if(cacheOK)
- {
- ASSERT(filterOutputs.size());
-- propagateStreams(dataIn,getOut,STREAM_TYPE_IONS,false);
-+ propagateStreams(dataIn,getOut,getRefreshBlockMask(),true);
-
- propagateCache(getOut);
-
---- 3depict-0.0.16.orig/src/backend/filters/rangeFile.cpp
-+++ 3depict-0.0.16/src/backend/filters/rangeFile.cpp
-@@ -107,7 +107,7 @@
- //We don't cache anything but our modification
- //to the ion stream data types. so we propagate
- //these.
-- propagateStreams(dataIn,getOut,STREAM_TYPE_IONS,false);
-+ propagateStreams(dataIn,getOut,getRefreshBlockMask(),true);
-
- return 0;
- }
---- 3depict-0.0.16.orig/src/backend/filters/transform.cpp
-+++ 3depict-0.0.16/src/backend/filters/transform.cpp
-@@ -189,7 +189,8 @@
- //use the cached copy if we have it.
- if(cacheOK)
- {
-- propagateStreams(dataIn,getOut, STREAM_TYPE_IONS,false);
-+ //Propagate non-ion-types into output
-+ propagateStreams(dataIn,getOut, getRefreshBlockMask(),true);
- propagateCache(getOut);
- return 0;
- }
diff --git a/packaging/debian/patches/series b/packaging/debian/patches/series
index 90196aa..a50b6d2 100644
--- a/packaging/debian/patches/series
+++ b/packaging/debian/patches/series
@@ -1,4 +1,2 @@
debian-desktop-naming.patch
lowercase-textdomain.patch
-FTGL-lowercase.patch
-patch-caching-bug
diff --git a/packaging/debian/rules b/packaging/debian/rules
index 867f70e..7de271f 100755
--- a/packaging/debian/rules
+++ b/packaging/debian/rules
@@ -1,10 +1,12 @@
#!/usr/bin/make -f
%:
- dh $@ --parallel
+ dh $@ --parallel
override_dh_auto_configure:
- dh_auto_configure -- --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --enable-openmp-parallel --disable-debug-checks --with-libpng-link="-lpng" --with-libpng-flags="-L/lib" --with-ftgl-prefix="/usr" --enable-mgl2
+ LDFLAGS="$(LDFLAGS) -Wl,--as-needed" dh_auto_configure -- --prefix=/usr \
+ --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info \
+ --enable-openmp-parallel --disable-debug-checks --with-libpng-link="-lpng" --with-libpng-flags="-L/lib" --with-ftgl-prefix="/usr"
override_dh_clean:
@@ -20,6 +22,7 @@ override_dh_clean:
dh_clean
+
override_dh_auto_install:
dh_auto_install
@@ -27,7 +30,7 @@ override_dh_auto_install:
mv $(CURDIR)/debian/3depict/usr/bin/3Depict $(CURDIR)/debian/3depict/usr/bin/3depict
mkdir -p $(CURDIR)/debian/3depict/usr/share/doc/3depict/
- echo "Copyright" `date +%Y`" D Haley <mycae at yahoo.com>" > $(CURDIR)/debian/3depict/usr/share/doc/3depict/copyright
+ echo "Copyright 2013 D Haley <mycae at yahoo.com>" > $(CURDIR)/debian/3depict/usr/share/doc/3depict/copyright
echo "See /usr/share/common-licenses/GPL-1 for copyright info" >> $(CURDIR)/debian/3depict/usr/share/doc/3depict/copyright
#Install files that cannot be handled by .install due to rename
diff --git a/packaging/deps/getDeps b/packaging/deps/getDeps
index 438605f..aa6866a 100755
--- a/packaging/deps/getDeps
+++ b/packaging/deps/getDeps
@@ -49,9 +49,9 @@ function setMacDeps {
#Dependency ID, URL and name
DEPIDS=( 0)
DEPNAMES=( mathgl)
- DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%202.1.3/mathgl-2.1.3.1.tar.gz/download)
- DEPFILENAMES=( mathgl-2.1.3.1.tar.gz)
- DEPMDSUM=( 1476ea6fd32938ab221fe169025747ed)
+ DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%202.2.2/mathgl-2.2.2.1.tar.gz/download)
+ DEPFILENAMES=( mathgl-2.2.2.1.tar.gz)
+ DEPMDSUM=( cdee2784ce2f18ab9014bbd204b8589f)
}
@@ -100,18 +100,18 @@ function installMacPorts {
function setSuseDeps {
DEPIDS=( 0)
DEPNAMES=( mathgl)
- DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%201.11.2/mathgl-1.11.2.tar.gz/download)
- DEPFILENAMES=( mathgl-1.11.2.tar.gz)
- DEPMDSUM=( acd33e68911d9506f60d769dce23f95e)
+ DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%202.2.2/mathgl-2.2.2.1.tar.gz/download)
+ DEPFILENAMES=( mathgl-2.2.2.1.tar.gz)
+ DEPMDSUM=( cdee2784ce2f18ab9014bbd204b8589f)
}
-function setCentOS5Deps {
+function setCentOS6Deps {
DEPIDS=( 0)
DEPNAMES=( mathgl)
- DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%201.11.2/mathgl-1.11.2.tar.gz/download)
- DEPFILENAMES=( mathgl-1.11.2.tar.gz)
- DEPMDSUM=( acd33e68911d9506f60d769dce23f95e)
+ DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%202.2.2/mathgl-2.2.2.1.tar.gz/download)
+ DEPFILENAMES=( mathgl-2.2.2.1.tar.gz)
+ DEPMDSUM=( cdee2784ce2f18ab9014bbd204b8589f)
}
@@ -228,7 +228,7 @@ function handleLinuxDistro()
elif [ x$DISTRIBUTOR == x"Fedora" ] ; then
LINUXDISTRO="RedhatLike"
elif [ x$DISTRIBUTOR == x"CentOS" ] ; then
- LINUXDISTRO="RedhatLike"
+ LINUXDISTRO="CentOS6"
elif [ x`echo $DISTRIBUTOR | grep -i redhat` != x"" ] ; then
LINUXDISTRO="RedhatLike"
else
@@ -269,30 +269,43 @@ function handleLinuxDistro()
RedhatLike)
echo "System appears to be redhat like"
- sudo yum groupinstall "Development Tools" && sudo yum install yum-utils && sudo yum-builddep 3Depict
+ sudo yum groupinstall "Development Tools"
+ if [ $? -ne 0 ] ; then
+ echo "Yum installation failed"
+ exit 1
+ fi
+ sudo yum install yum-utils
if [ $? -ne 0 ] ; then
- echo "Failed to install build dependencies"
+ echo "Yum installation failed"
+ exit 1
+ fi
+ sudo yum-builddep 3Depict
+ if [ $? -ne 0 ] ; then
+ echo "Yum installation failed"
exit 1
- else
- echo "All done."
- exit 0
fi
;;
CentOS6)
echo "System appears to be CentOS6-like?"
- sudo yum groupinstall "Development Tools" && sudo yum install yum-utils && sudo yum install libxml2-devel ftgl-devel wxgtk-devel qhull-devel mathgl-devel
+ sudo yum groupinstall "Development Tools" && sudo yum install yum-utils libxml2-devel wxGTK-devel gsl-devel rpmdevtools
+ if [ $? -ne 0 ] ; then
+ echo "Yum installation failed"
+ exit 1
+ fi
+
echo " OK, so this gets tricky. Centos doesn't ship mathgl. So we have to grab it from fedora's Git repository, and build the RPM, the install that."
echo "Getting mgl dependencies"
- sudo yum install gsl-devel libpng-devel libtool-ltdl-devel libtool swig freeglut-devel hdf-devel \
- hdf5-static libjpeg-devel libtiff-devel fltk-devel qt4-devel wxGTK-devel giflib-devel \
- autoconf automake libtool info texi2html texinfo-tex
- if [ $? -eq 0 ] ; then
+ sudo yum install gsl-devel libpng-devel libtool-ltdl-devel libtool swig freeglut-devel \
+ libjpeg-devel libtiff-devel qt4-devel wxGTK-devel giflib-devel \
+ info texi2html texinfo-tex cmake libXmu-devel lua-devel python-devel
+ echo "Return code :" $?
+ if [ $? -ne 0 ] ; then
echo "Yum installation failed"
exit 1
fi
@@ -300,24 +313,25 @@ function handleLinuxDistro()
if [ x`which git` == x"" ] ; then
echo "Installing git...."
sudo yum install git
- if [ $? -eq 0 ] ; then
+ if [ $? -ne 0 ] ; then
echo "Yum git installation failed"
exit 1
fi
fi
+
+ if [ ! -d mathgl ] ; then
- git clone git://pkgs.fedoraproject.org/mathgl.git
- if [ $? -eq 0 ] ; then
- echo "git clone failed - couldn't retreive mathgl spec and patch data"
- exit 1
- elif [ ! -f mathgl ] ; then
- echo "Git clone succeded, but couldn't locate checkout dir, \"mathgl\""
- exit 1
+ git clone git://pkgs.fedoraproject.org/mathgl.git
+ if [ $? -ne 0 ] ; then
+ echo "git clone failed - couldn't retreive mathgl spec and patch data"
+ exit 1
+ elif [ ! -d mathgl ] ; then
+ echo "Git clone succeded, but couldn't locate checkout dir, \"mathgl\""
+ exit 1
+ fi
fi
cd mathgl
- # We want this version
- git checkout 152ad15
if [ $? -ne 0 ] ; then
echo "Something went wrong when trying to check out the version of the repository we wanted"
@@ -335,33 +349,28 @@ function handleLinuxDistro()
cp mathgl.spec ~/rpmbuild/SPECS/
cp *patch ~/rpmbuild/SOURCES/
- MATHGLVER=1.11.2
+ MATHGLVER=2.2.2.1
setCentOS6Deps
pushd ~/rpmbuild/SOURCES/
runDownloads
checkHashes
- mv sources/mathgl-${MATHGLVER}.tar..gz .
- popd
-
- pushd ~/rpmbuild/SPEC/
- rpmbuild -ba mathgl.spec
-
- if [ $? -ne 0 ] ; then
- echo "Runing RPMBuild failed - but we are close to getting mathgl installed, so please fix rpmbuild, and run rpmbuild -ba mathgl.spec from ~/rpmbuild/SPEC/"
- exit 1
- fi
+ mv sources/mathgl-${MATHGLVER}.tar.gz .
popd
-
- ARCH=`uname -m`
- pushd ~/rpmbuild/RPMS/${ARCH}/
- rpm -i mathgl-${MATHGLVER}*rpm
-
- if [ $? -ne 0 ] ; then
- echo "So we built the RPMs OK, but for some reason we cannot isntall them. Not sure whats going on here. Aborting."
- exit 1
- fi
- popd
+ #HACK : Strip out the optional buildrequires from the spec file
+ for i in hdf-devel hdf5-static fltk-devel qtwebkit-devel libharu-devel octave-devel openmpi-deve mpich-devel
+ do
+ sed -i "s/$i//" ~/rpmbuild/SPECS/mathgl.spec
+ done
+
+ sed -i 's/^\s*BuildRequires:\s*$//' ~/rpmbuild/SPECS/mathgl.spec
+
+ echo "---------------- NOTICE ----------------"
+ echo " CentOS is missing most of the optional dependencies for mathgl. "
+ echo " this script cannot do the work required to install mathgl. "
+ echo " An RPM \"Spec\" file has been left in ~/rpmbuild/SPECS/"
+ echo " go there, tweak that file and use \"rpmbuild -ba mathgl.spec\" to build it."
+ echo " This is not straightforwards - work is needed to make centos and mathgl play nice"
exit 0;
;;
SuseLike)
@@ -481,7 +490,7 @@ case $OS_NAME in
HASH_SUM=`md5 sources/$j | awk {'sub(/^.*= [ \t]*/, "", $0); print $0;'}`
;;
*)
- HASH_SUM=`md5sum sources/$j | awk {'sub(/^.*= [ \t]*/, "", $0); print $0;'}`
+ HASH_SUM=`md5sum sources/$j | awk {'sub(/^.*= [ \t]*/, "", $0); print $0;'} | awk '{print $1}'`
;;
esac
@@ -750,12 +759,13 @@ do
#patch mgl/mgl_export.cpp < ../../sources/mgl_export.patch
#After upgrade to 1.5.13, this patch required.
#patch mgl/mgl_data_png.cpp < ../../sources/mgl_data_png.patch
- patch src/obj.cpp < ../../patches/macosx/mathgl2/diff-obj.c.patch
- patch src/prc/writePRC.h < ../../patches/macosx/mathgl2/diff-prc-writePRC.h.patch
+ #patch src/obj.cpp < ../../patches/macosx/mathgl2/diff-obj.c.patch
+ #patch src/prc/writePRC.h < ../../patches/macosx/mathgl2/diff-prc-writePRC.h.patch
+ cmake .
+ patch ./CMakeCache.txt < ../../../../patches/0.0.17/macosx/mathgl2/CMakeCache.txt.patch
fi
#./configure --disable-gsl $PNGLIBS
cmake .
- cmake .
if [ $? -ne 0 ] ; then
diff --git a/packaging/mac/3package.sh b/packaging/mac/3package.sh
index 4d9b529..7fee2f3 100755
--- a/packaging/mac/3package.sh
+++ b/packaging/mac/3package.sh
@@ -45,6 +45,24 @@ if [ x`grep ${INFO_PLIST} -Depict` != x"" ] ; then
exit 1
fi
+#ensure that we have some .vfm files in here
+if [ x`find ./ -name \*.vfm` == x"" ] ; then
+ echo "No VFM files (mathgl fonts) found!"
+ exit 1
+fi
+
+#ensure that we have some .pdf files in here
+if [ x`find ./ -name \*.pdf` == x"" ] ; then
+ echo "No PDF files (manual) found!"
+ exit 1
+fi
+
+#ensure that some .mo (translation files) are here
+if [ x`find ./ -name \*.mo` == x"" ] ; then
+ echo "No mo files (translations) found!"
+ exit 1
+fi
+
#--
ARCHIVE_FILENAME=`echo "${BUILT_PROGRAMS_DIR}/${PROGRAM_NAME}-${VERSION}-${MAC_OS_VER}.pkg"`
diff --git a/packaging/mac/makeMacOSXApp b/packaging/mac/makeMacOSXApp
index 054b4b8..0fe5b5d 100755
--- a/packaging/mac/makeMacOSXApp
+++ b/packaging/mac/makeMacOSXApp
@@ -34,6 +34,7 @@ if [ $1 = '--update-config=yes' ]; then
make clean
fi
+read -p "have you changed the makefile?" yn
make -j8
@@ -51,6 +52,7 @@ cp data/textures/tex-source/3Depict-icon.icns ./3Depict.app/Contents/Resources/3
touch ./3Depict.app/Contents/PkgInfo
touch ./3Depict.app/Contents/info.plist
#copy textures
+cp ./data/* ./3Depict.app/Contents/Resources/
cp ./data/textures/* ./3Depict.app/Contents/Resources/textures/
cp ./data/textures/tex-source/3Depict-icon.icns ./3Depict.app/Contents/Resources
diff --git a/packaging/makeTarball.sh b/packaging/makeTarball.sh
index 6b3c18e..6d58c6f 100755
--- a/packaging/makeTarball.sh
+++ b/packaging/makeTarball.sh
@@ -75,6 +75,9 @@ fi
#Various release-time checks
#----
+
+echo "--------- RUNNING SANITY CHECKS -------"
+
#Check version
VER=`ls 3depict-*gz | sed 's/^3depict-\([0-9\.]*\).tar.gz$/\1/' `
echo "Version is apparently :" $VER
@@ -90,8 +93,8 @@ if [ x"`grep $VER ChangeLog`" == x"" ] ; then
echo " WARNING: Program version not set to match between configure.ac. and ChangeLog">> $MSG_FILE
fi
-if [ x"`grep PROGRAM_VERSION src/common/basics.cpp | grep $VER`" == x"" ] ; then
- echo " WARNING: Program version not set to match between configure.ac. and basics.cpp">> $MSG_FILE
+if [ x"`grep PROGRAM_VERSION src/common/constants.cpp | grep $VER`" == x"" ] ; then
+ echo " WARNING: Program version not set to match between configure.ac. and constants.cpp">> $MSG_FILE
fi
#Check version number in deb & rpm
@@ -151,9 +154,17 @@ if [ x"$SOMEFILES" != x"" ] ; then
fi
#Check that PDF manual is built
-if [ ! -f docs/manual-latex/manual.pdf ] ; then
+PDF_FILE=docs/manual-latex/manual.pdf
+if [ ! -f ] ; then
echo " WARNING : PDF manual was not found -- has it been compiled?" >> $MSG_FILE
echo "$FILES" >> $MSG_FILE
+else
+ #Check PDF is actually a pdf
+ if [ x"`file $PDF_FILE | grep "PDF document" `" == x"" ] ; then
+ echo " WARNING : PDF manual found, but does not appear to be a valid PDF?" >> $MSG_FILE
+ echo "$FILES" >> $MSG_FILE
+
+ fi
fi
#Check for outstanding mercurial changes
@@ -170,9 +181,9 @@ fi
#Run licensecheck over files, if available
if [ x`which licensecheck` != x"" ] ; then
- LIC_CHECK_OUT=`licensecheck -r --ignore ".*\.(sh|sci|py|tex)$" | grep -v "GPL (v3 or later)" | grep -v "GENERATED FILE" `
+ LIC_CHECK_OUT=`licensecheck -r --ignore=".*\.(sh|sci|py|tex)$" . | grep -v "GPL (v[23] or later)" | grep -v "GENERATED FILE" | grep -v "MPL" | grep -v "tarball/"`
- if [ x$LIC_CHECK_OUT != x"" ] ; then
+ if [ x"$LIC_CHECK_OUT" != x"" ] ; then
echo "WARNING:" $LIC_CHECK_OUT >> $MSG_FILE
fi
fi
diff --git a/packaging/mingw-debian-cross/bootstrap.sh b/packaging/mingw-debian-cross/bootstrap.sh
index 0a7acf7..1529e17 100755
--- a/packaging/mingw-debian-cross/bootstrap.sh
+++ b/packaging/mingw-debian-cross/bootstrap.sh
@@ -36,6 +36,19 @@ fi
if [ $HOST_VAL != "x86_64-w64-mingw32" ] && [ $HOST_VAL != i686-w64-mingw32 ] ; then
echo "Unknown HOST_VAL"
exit 1
+else
+ case $HOST_VAL in
+ x86_64-w64-mingw32)
+ BITS_VAL=64
+ ;;
+ i686-w64-mingw32)
+ BITS_VAL=32
+ ;;
+ *)
+ echo "Should not have got here - bug!"
+ exit 1
+ ;;
+ esac
fi
#----
@@ -58,9 +71,8 @@ if [ `id -u` -eq 0 ]; then
echo " If you know what you are doing, you can disable this check, but be aware you _can_ break your system by doing this."
exit 1;
fi
-#1) Filezilla wxwidgets patch for 64 bit support under mingw
#2) own patch for fixing wx-config's lack of sysroot support
-PATCHES_WXWIDGETS_PRE="wxWidgets-2.8.12-mingw64-1.patch configure-wxbool-patch"
+PATCHES_WXWIDGETS_PRE=""
PATCHES_WXWIDGETS_POST="wx-config-sysroot.patch"
#1) Zlib no longer needs to explicitly link libc, and will fail if it tries
PATCHES_ZLIB="zlib-no-lc.patch"
@@ -75,8 +87,7 @@ PATCHES_GETTEXT="gettext-disable-tools" #gettext-win32-prefix
PATCHES_GLEW="glew-makefile.base"
-#Disable broken build for "widgets" directory, which we don't need
-PATCHES_MATHGL="mathgl-disable-widgets"
+PATCHES_MATHGL=""
PATCH_LIST="$PATCHES_WXWIDGETS_PRE $PATCHES_WXWIDGETS_POST $PATCHES_GSL $PATCHES_ZLIB $PATCHES_LIBPNG $PATCHES_GETTEXT $PATCHES_FTGL $PATCHES_GLEW $PATCHES_MATHGL $PATCHES_FTGL_POSTCONF"
@@ -123,7 +134,7 @@ function install_mingw()
GET_PACKAGES="";
for i in $MINGW_PACKAGES
do
- if [ x`apt-cache pkgnames --installed $i` != x"$i" ] ; then
+ if [ x`dpkg --get-selections | grep ^$i | awk '{print $1}' ` != x"$i" ] ; then
GET_PACKAGES="$GET_PACKAGES $i";
fi
done
@@ -139,7 +150,7 @@ function grabDeps()
{
pushd deps 2>/dev/null
- DEB_PACKAGES="expat freetype ftgl gettext gsl libpng libxml2 mathgl qhull tiff wxwidgets2.8 zlib glew"
+ DEB_PACKAGES="expat freetype ftgl gettext gsl libpng libxml2 mathgl qhull tiff wxwidgets3.0 zlib glew"
if [ x$DIST_NAME == x"Ubuntu" ] || [ x$DIST_NAME == x"LinuxMint" ] ; then
LIBJPEGNAME="libjpeg6b"
else
@@ -163,6 +174,13 @@ function grabDeps()
if [ x"$GET_PACKAGES" != x"" ] ; then
apt-get source $GET_PACKAGES
+ if [ $? -ne 0 ] ; then
+ echo "Package retrieval failed"
+ echo "apt-get source failed... Maybe check internet connection, then try updating package database, then re-run?"
+ echo " other possibilities could include, eg, that the required package is not available in the debian archive.."
+ exit 1
+ fi
+
for i in $GET_PACKAGES
do
grep -v $i ../build-status > tmp
@@ -174,11 +192,7 @@ function grabDeps()
done
fi
-
- if [ $? -ne 0 ] ; then
- echo "apt-get source failed... Maybe check internet connection, then try updating package database, then re-run?"
- exit 1
- fi
+
#Move debian stuff into packages folder
if [ x"$GET_PACKAGES" != x"" ] ; then
@@ -350,7 +364,7 @@ function build_glew()
fi
#Perform dynamic modification of patch
- if [ x`grep patches/glew-makefile.base HOST_VAL` == x"" || x`grep patches/glew-makefile.base BASEDIR` == x"" ] ; then
+ if [ x"`grep HOST_VAL patches/glew-makefile.base`" == x"" -o x"`grep BASEDIR patches/glew-makefile.base`" == x"" ] ; then
echo "patches/glew-makefile did not contain replacement keywords"
exit 1
fi
@@ -383,6 +397,10 @@ function build_glew()
popd >/dev/null
popd >/dev/null
+ #remove static library, as this can be incorrectly caught by linker
+ # leading to confusing messages
+ rm ${BASE}/lib/libglew*.a
+
echo "glew" >> $BUILD_STATUS_FILE
}
@@ -596,14 +614,18 @@ function build_qhull()
make clean
- ./configure --host=$HOST_VAL --enable-shared --disable-static --prefix=/ || { echo "qhull configure failed"; exit 1; }
+ sed -i "s/ gcc$/${HOST_VAL}-gcc/" Makefile
+ sed -i "s/ g++$/${HOST_VAL}-g++/" Makefile
- make -j $NUM_PROCS || { echo "qhull build failed"; exit 1; }
-
+ make SO="dll" -j $NUM_PROCS
+ find ./ -name \*dll -exec cp {} ${BASE}/bin/
+ make SO="dll" -j $NUM_PROCS || { echo "qhull build failed"; exit 1; }
make install DESTDIR="$BASE"|| { echo "qhull install failed"; exit 1; }
popd >/dev/null
popd >/dev/null
+
+ ln -s ${BASE}/include/libqhull ${BASE}/include/qhull
FIX_LA_FILE_ARG=libqhull
fix_la_file
@@ -729,7 +751,21 @@ function build_wx()
pushd ./bin/
unlink wx-config
- ln -s `find ${BASE}/lib/wx/config/ -name \*release-2.8` wx-config
+
+
+ #Search for the wx-config file. It get installed into /lib/wx, but has
+ # unusual naming conventions
+ WX_CONFIG_FILE=`find ${BASE}/lib/wx/config/ -type f -executable -name \*release-\*`
+ if [ x$WX_CONFIG_FILE == x"" ] ; then
+ WX_CONFIG_FILE=`find ${BASE}/lib/wx/config/ -type f -executable -name \*-unicode-\*`
+ fi
+
+ if [ x$WX_CONFIG_FILE == x"" ] ; then
+ echo "Couldn't find the wx-config script."
+ exit 1
+ fi
+
+ cp $WX_CONFIG_FILE wx-config
APPLY_PATCH_ARG=$PATCHES_WXWIDGETS_POST
PATCH_LEVEL=0
applyPatches
@@ -738,7 +774,7 @@ function build_wx()
popd
pushd ./lib/
- ln -s wx-2.8/wx/ wx
+ ln -s wx-3.0/wx/ wx
popd
@@ -766,7 +802,7 @@ function build_freetype()
pushd freetype-[0-9]*
make clean
- ./configure --host=$HOST_VAL --enable-shared --disable-static --prefix=/ || { echo "freetype configure failed"; exit 1; }
+ ./configure --host=$HOST_VAL --enable-shared --disable-static --without-png --prefix=/ || { echo "freetype configure failed"; exit 1; }
make -j $NUM_PROCS || { echo "freetype build failed"; exit 1; }
@@ -882,27 +918,28 @@ function build_mathgl()
APPLY_PATCH_ARG=$PATCHES_MATHGL
applyPatches
- libtoolize --copy --force
- aclocal
- automake --add-missing
+ #Strip invalid linker flags from cmake's link instructions
+ rm CMakeCache.txt
+ #Strip invalid linker flags from cmake's link instructions
+ find ./ -name link.txt -exec sed -i 's/-Wl,-z,relro//' {} \;
+ cmake -DCMAKE_TOOLCHAIN_FILE=../../patches/cmake-toolchain$BITS_VAL
+ #Strip invalid linker flags from cmake's link instructions
+ find ./ -name link.txt -exec sed -i 's/-Wl,-z,relro//' {} \;
- autoreconf
- LIBS="${LIBS} -lz" ./configure --host=$HOST_VAL --disable-gsl --disable-pthread --enable-shared --disable-static --prefix=/ || { echo "mathgl configure failed"; exit 1; }
- #RPATH disable hack
- sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
- sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
+ cmake -DCMAKE_TOOLCHAIN_FILE=../../patches/cmake-toolchain$BITS_VAL
- #Hack to fix mathgl's libpng dll search
- mkdir -p $BASE/lib/.libs/
- ln -s $BASE/lib/libpng.dll $BASE/lib/.libs/libpng.dll.a
+ make -j $NUM_PROCS
- make -j $NUM_PROCS || { echo "mathgl build failed"; exit 1; }
-
- make install DESTDIR="$BASE"|| { echo "mathgl install failed"; exit 1; }
-
- #DLL needs to be copied into lib manually
+ if [ x"`find ./ -name \*dll`" == x"" ] ; then
+ echo "Did cmake fail to make a DLL? Cmake rarely builds cleanly, but I should be able to find the DLL..."
+ exit 1
+ fi
+
cp -p .libs/${NAME}-[0-9]*.dll $BASE/lib/
+
+ cp -R include/mgl2 ${BASE}/include
+ ln -s ${BASE}/include/mgl2 ${BASE}/include/mgl
popd >/dev/null
popd >/dev/null
@@ -956,6 +993,12 @@ function build_ftgl()
#MAkefile refers to ECHO variable for reporting completion, which does not exist
sed -i 's/ECHO_C =/ECHO=echo/' Makefile
+ sed -i "s at -I//@-I${BASE}/@" Makefile
+ sed -i 's/ECHO_C =/ECHO=echo/' Makefile
+
+ #HACK - find all -I// and -L// and replace them with something sane
+ find ./ -name Makefile -exec sed -i "s at -I//@-I${BASE}/@" {} \;
+ find ./ -name Makefile -exec sed -i "s at -L//@-L${BASE}/@" {} \;
make -j $NUM_PROCS || { echo "ftgl build failed"; exit 1; }
@@ -1058,34 +1101,66 @@ function build_3Depict()
CONF_FLAG="--host=$HOST_VAL"
if [ $IS_RELEASE -ne 0 ] ; then
- CONF_FLAG="$CONF_FLAG --disable-debug-checks"
+ CONF_FLAG="$CONF_FLAG --disable-debug-checks --enable-openmp-parallel"
fi
- CFLAGS="$CFLAGS -DUNICODE" CPPFLAGS="${CPPFLAGS} -DUNICODE" ./configure $CONF_FLAG
+ FTGL_CFLAGS="-I${BASE}/include/freetype/" CFLAGS="$CFLAGS -DUNICODE" CPPFLAGS="${CPPFLAGS} -DUNICODE" ./configure $CONF_FLAG
if [ $? -ne 0 ] ; then
echo "Failed 3Depict configure"
exit 1
fi
- #HACK - strip all makefiles of -D_GLIBCXX_DEBUG
- # mingw & GLIBCXX_DEBG don't play nice
- find ./ -name Makefile -exec sed -i 's/-D_GLIBCXX_DEBUG//g' {} \;
+ #sanity check that windres is activated
+ if [ x`grep HAVE_WINDRES_TRUE config.log | grep '#' ` != x"" ] ; then
+ echo "Windres appears to be commented out. Shouldn't be for windows builds"
+ exit 1
+ fi
+
+ #Check that wx's manifest matches our arch
+ MANIFEST=`find ../../include/ -name wx.manifest`
+ if [ x"$MANIFEST" == x"" ] ; then
+ echo "Didnt' find manifest!"
+ exit 1
+ fi
+ case $BITS_VAL in
+ 32)
+ MANIFEST_TARG=x86
+ MANIFEST_NOT=amd64
+ ;;
+ 64)
+ MANIFEST_TARG=amd64
+ MANIFEST_NOT=x86
+ ;;
+ esac
+
+ if [ x"`grep -i $MANIFEST_TARG $MANIFEST`" == x"" ] ; then
+ echo "Manifest arch does not match!"
+ echo " file examined: $MANIFEST"
+ echo " Expected :" $MANIFEST_TARG
+ exit 1
+ fi
+
+ if [ x"`grep -i $MANIFEST_NOT $MANIFEST`" != x"" ] ; then
+ echo "Manifest arch does not match!"
+ echo " file examined: $MANIFEST"
+ echo " This should be missing, but isnt:" $MANIFEST_NOT
+ exit 1
+ fi
+ #HACK - strip all makefiles of -D_GLIBCXX_DEBUG
+ # mingw & GLIBCXX_DEBG don't play nice
+ find ./ -name Makefile -exec sed -i 's/-D_GLIBCXX_DEBUG//g' {} \;
+ #HACK - find all -I// and -L// and replace them with something sane
+ find ./ -name Makefile -exec sed -i "s at -I//@-I${BASE}/@" {} \;
+ find ./ -name Makefile -exec sed -i "s at -L//@-L${BASE}/@" {} \;
+
make -j$NUM_PROCS
if [ $? -ne 0 ] ; then
echo "Failed 3Depict build"
exit 1
fi
- if [ $IS_RELEASE -ne 0 ] ; then
- #Sanity check that we are actually in debug mode
- TEST_FLAG=`./3Depict --help 2>&1 | grep "\-\-test"`
- if [ x"$TEST_FLAG" != x"" ] ; then
- echo "3Depict\'s Unit tests available, but should not be, when in release mode"
- exit 1
- fi
- fi
#if the locales are missing, try to rebuild them
@@ -1117,10 +1192,6 @@ function make_package()
pushd ./code/3Depict 2> /dev/null
NSI_FILE=./windows-installer.nsi
- if [ ! -f $NSI_FILE ] ; then
- echo "NSI file missing whilst trying to build package"
- exit 1;
- fi
#copy as needed
# Due to debian bug : #704828, makensis cannot correctly handle symlinks,
@@ -1129,9 +1200,28 @@ function make_package()
cp ./packaging/mingw-debian-cross/windows-installer.nsi .
fi
+
+ if [ ! -f $NSI_FILE ] ; then
+ echo "NSI file missing whilst trying to build package"
+ exit 1;
+ fi
+
+ #Check NSI file has PROGRAMFILES / PROGRAMFILES64 set
+ if [ x"`grep PROGRAMFILES64 $NSI_FILE`" == x"" -a $BITS_VAL == 64 ] ; then
+ echo "NSI file should contain PROGRAMFILES64 output path."
+ exit 1;
+ else
+ if [ x"`grep PROGRAMFILES64 $NSI_FILE`" != x"" -a $BITS_VAL == 32 ] ; then
+ echo "NSI file contained 64 bit install dir, but this is 32"
+ exit 1;
+ fi
+ fi
+
+
+
echo -n " Copying dll files... "
- SYSTEM_DLLS="(ADVAPI32.dll|COMCTL32.DLL|COMDLG32.DLL|GDI32.dll|KERNEL32.dll|ole32.dll|OLEAUT32.dll|RPCRT4.dll|SHELL32.DLL|USER32.dll|WINMM.DLL|WINSPOOL.DRV|WSOCK32.DLL|GLU32.dll|OPENGL32.dll|msvcrt.dll)"
+ SYSTEM_DLLS="(ADVAPI32.dll|COMCTL32.DLL|COMDLG32.DLL|GDI32.dll|KERNEL32.dll|ole32.dll|OLEAUT32.dll|RPCRT4.dll|SHELL32.DLL|USER32.dll|WINMM.DLL|WINSPOOL.DRV|WSOCK32.DLL|GLU32.dll|OPENGL32.dll|msvcrt.dll|WS2_32.dll)"
DLL_FILES=`${HOST_VAL}-objdump -x src/3Depict.exe | grep 'DLL Name:' | awk '{print $3}' | egrep -i -v ${SYSTEM_DLLS}`
FOUND_DLLS=""
@@ -1152,7 +1242,7 @@ function make_package()
for i in $DLL_FILES
do
HAVE_DLL=0
- for j in ${BASE}/lib/ ${BASE}/bin/ $SYS_DIR
+ for j in ${BASE}/lib/ ${BASE}/bin/ $SYS_DIR /usr/${HOST_VAL}/lib/
do
FIND_RES=`find $j -name $i | head -n 1`
if [ x$FIND_RES != x"" ] ; then
@@ -1185,24 +1275,23 @@ function make_package()
popd > /dev/null
fi
- if [ x"`cat windows-installer.nsi | grep INSERT_DLLS_HERE`" == x"" ] || [ x"`cat windows-installer.nsi | grep INSERT_UNINST_DLLS_HERE`" == x"" ] ; then
- echo "DLL insertion/removal tokens not found. Was looking for INSERT_DLLS_HERE and INSERT_UNINST_DLLS_HERE"
- exit 1
- fi
-
-
- #Check that each file in the data/textures/ dir is listed in the NSI file
- FILE_MISSED=0
- for i in data/textures/*png
+ #Check for differeent DLL types (eg 32/64)
+ DLL_FILE_OUT="";
+ for i in $FOUND_DLLS
do
- FILE_GREP=`grep "data\\textures\\$i" windows-installer.nsi`
- if [ x${FILE_GREP} == x"" ] ; then
- echo "MISSING FILE: " $i
- FILE_MISSED=1
+ J=`file $i | awk -F: '{print $2}' | sed 's/\s*//'`
+ if [ x"$DLL_FILE_OUT" == x"" ] ; then
+ DLL_FILE_OUT=$j
+ else
+ if [ x"$DLL_FILE_OUT" != x"$j" ] ; then
+ echo "DLL Mismatched file info. $i"
+ exit 1
+ fi
fi
done
- if [ $FILE_MISSED -ne 0 ] ; then
+ if [ x"`cat windows-installer.nsi | grep INSERT_DLLS_HERE`" == x"" ] || [ x"`cat windows-installer.nsi | grep INSERT_UNINST_DLLS_HERE`" == x"" ] ; then
+ echo "DLL insertion/removal tokens not found. Was looking for INSERT_DLLS_HERE and INSERT_UNINST_DLLS_HERE"
exit 1
fi
@@ -1224,15 +1313,20 @@ function make_package()
makensis `basename $NSI_FILE` || { echo "makensis failed" ; exit 1; }
+ echo "-------------------"
+ VERSION=`cat $NSI_FILE | grep "define PRODUCT_VERSION " | awk '{print $3}' | sed s/\"//g | sed s/\s*$//`
if [ $IS_RELEASE -ne 0 ] ; then
- VERSION=`cat $NSI_FILE | grep "define PRODUCT_VERSION " | awk '{print $3}' | sed s/\"//g | sed s/\s*$//`
+ echo "Release mode enabled:"
TARGET_FILE=3Depict-$VERSION-$HOST_EXT.exe
- mv Setup.exe $TARGET_FILE
- echo "-------------------"
- echo "File written to : `pwd`/$TARGET_FILE"
- echo "-------------------"
+ else
+ echo "Release mode disabled:"
+ TARGET_FILE=3Depict-${VERSION}-${HOST_EXT}-debug.exe
fi
+ mv Setup.exe $TARGET_FILE
+ echo "File written to : `pwd`/$TARGET_FILE"
+ echo "-------------------"
+
popd > /dev/null
}
@@ -1258,7 +1352,7 @@ case ${HOST_VAL} in
HOST_EXT="win64"
;;
i686-w64-mingw32)
- MINGW_PACKAGES="gcc-mingw32"
+ MINGW_PACKAGES="gcc-mingw-w64-i686 g++-mingw-w64-i686"
HOST_EXT="win32"
;;
*)
@@ -1303,10 +1397,11 @@ build_expat
build_freetype
build_libiconv
build_gettext
-build_mathgl
build_ftgl
build_glew
-build_wx # I'm not sure I've done this 100% right. Check wx-config output
+
+build_mathgl
+build_wx
build_3Depict
diff --git a/packaging/mingw-debian-cross/patches/cmake-toolchain32 b/packaging/mingw-debian-cross/patches/cmake-toolchain32
new file mode 100644
index 0000000..4fd462e
--- /dev/null
+++ b/packaging/mingw-debian-cross/patches/cmake-toolchain32
@@ -0,0 +1,25 @@
+# this one is important
+SET(CMAKE_SYSTEM_NAME Windows)
+#this one not so much
+SET(CMAKE_SYSTEM_VERSION 1)
+
+# specify the cross compiler
+#SET(CMAKE_CXX_COMPILER CXX_REPLACE)
+#SET(CMAKE_C_COMPILER C_REPLACE)
+SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
+SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
+SET(CMAKE_RC_COMPILER /usr/bin/i686-w64-mingw32-windres)
+# where is the target environment
+#SET(CMAKE_FIND_ROOT_PATH PWD_REPLACE)
+SET(CMAKE_FIND_ROOT_PATH /home/pcuser/mingw32/)
+
+SET(ZLIB_LIBRARY -lz)
+SET(PNG_LIBRARY -lpng)
+
+set(CMAKE_SHARED_LINKER_FLAGS " -Wl,--no-undefined -L/home/pcuser/mingw32/lib/")
+
+# search for programs in the build host directories
+#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+# for libraries and headers in the target directories
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/packaging/mingw-debian-cross/patches/cmake-toolchain64 b/packaging/mingw-debian-cross/patches/cmake-toolchain64
new file mode 100644
index 0000000..4d7d2f4
--- /dev/null
+++ b/packaging/mingw-debian-cross/patches/cmake-toolchain64
@@ -0,0 +1,24 @@
+# this one is important
+SET(CMAKE_SYSTEM_NAME Windows)
+#this one not so much
+SET(CMAKE_SYSTEM_VERSION 1)
+
+# specify the cross compiler
+#SET(CMAKE_CXX_COMPILER CXX_REPLACE)
+#SET(CMAKE_C_COMPILER C_REPLACE)
+SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
+SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
+SET(CMAKE_RC_COMPILER /usr/bin/x86_64-w64-mingw32-windres)
+# where is the target environment
+#SET(CMAKE_FIND_ROOT_PATH PWD_REPLACE)
+SET(CMAKE_FIND_ROOT_PATH /home/pcuser/mingw64/)
+
+SET(ZLIB_LIBRARY -lz)
+SET(PNG_LIBRARY -lpng)
+
+
+# search for programs in the build host directories
+#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+# for libraries and headers in the target directories
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/packaging/mingw-debian-cross/patches/ftgl-mingw32-prototype b/packaging/mingw-debian-cross/patches/ftgl-mingw32-prototype
old mode 100755
new mode 100644
diff --git a/packaging/mingw-debian-cross/patches/ftgl-override-configure b/packaging/mingw-debian-cross/patches/ftgl-override-configure
old mode 100755
new mode 100644
diff --git a/packaging/mingw-debian-cross/patches/gettext-disable-tools b/packaging/mingw-debian-cross/patches/gettext-disable-tools
old mode 100755
new mode 100644
diff --git a/packaging/mingw-debian-cross/patches/gettext-win32-prefix b/packaging/mingw-debian-cross/patches/gettext-win32-prefix
old mode 100755
new mode 100644
diff --git a/packaging/mingw-debian-cross/patches/glew-makefile b/packaging/mingw-debian-cross/patches/glew-makefile
old mode 100755
new mode 100644
index bb5c626..2d4985b
--- a/packaging/mingw-debian-cross/patches/glew-makefile
+++ b/packaging/mingw-debian-cross/patches/glew-makefile
@@ -1,6 +1,7 @@
---- a/Makefile 2013-07-07 15:37:19.000000000 +0200
-+++ b/Makefile 2013-07-07 15:44:55.000000000 +0200
-@@ -28,19 +28,12 @@
+diff -r 9bbbd8b43e5b Makefile
+--- a/Makefile Sun Jun 29 17:24:13 2014 +0100
++++ b/Makefile Sun Jun 29 17:25:52 2014 +0100
+@@ -28,19 +28,13 @@
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
## THE POSSIBILITY OF SUCH DAMAGE.
@@ -10,26 +11,28 @@
SHELL = /bin/sh
-SYSTEM ?= $(shell config/config.guess | cut -d - -f 3 | sed -e 's/[0-9\.]//g;')
-SYSTEM.SUPPORTED = $(shell test -f config/Makefile.$(SYSTEM) && echo 1)
-+SYSTEM = i686-w64-mingw32
++SYSTEM = x86_64-w64-mingw32
-ifeq ($(SYSTEM.SUPPORTED), 1)
-include config/Makefile.$(SYSTEM)
-else
-$(error "Platform '$(SYSTEM)' not supported")
-endif
--
+
-GLEW_DEST ?= /usr
-+GLEW_DEST ?= /home/pcuser/mingw32
- BINDIR ?= $(GLEW_DEST)/bin
- LIBDIR ?= $(GLEW_DEST)/lib
- INCDIR ?= $(GLEW_DEST)/include/GL
---- a/config/Makefile.mingw 2013-07-07 15:43:48.000000000 +0200
-+++ b/config/Makefile.mingw 2013-07-07 15:47:32.000000000 +0200
++GLEW_DEST ?= /home/pcuser/mingw64
+ BINDIR ?= $(GLEW_DEST)/bin
+ LIBDIR ?= $(GLEW_DEST)/lib
+ INCDIR ?= $(GLEW_DEST)/include/GL
+diff -r 9bbbd8b43e5b config/Makefile.mingw
+--- a/config/Makefile.mingw Sun Jun 29 17:24:13 2014 +0100
++++ b/config/Makefile.mingw Sun Jun 29 17:25:52 2014 +0100
@@ -1,7 +1,4 @@
NAME = glew32
--CC = gcc
-# use gcc for linking, with ld it does not work
--LD = gcc
+-CC := gcc
+-LD := gcc
+ LN :=
CFLAGS.SO = -DGLEW_BUILD
- LDFLAGS.GL = -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
+ LDFLAGS.GL = -lopengl32 -lgdi32 -luser32 -lkernel32
LDFLAGS.EXTRA = -L/mingw/lib
diff --git a/packaging/mingw-debian-cross/patches/glew-makefile.base b/packaging/mingw-debian-cross/patches/glew-makefile.base
index 4262a54..ae6b8d2 100644
--- a/packaging/mingw-debian-cross/patches/glew-makefile.base
+++ b/packaging/mingw-debian-cross/patches/glew-makefile.base
@@ -1,6 +1,7 @@
---- a/Makefile 2013-07-07 15:37:19.000000000 +0200
-+++ b/Makefile 2013-07-07 15:44:55.000000000 +0200
-@@ -28,19 +28,12 @@
+diff -r 9bbbd8b43e5b Makefile
+--- a/Makefile Sun Jun 29 17:24:13 2014 +0100
++++ b/Makefile Sun Jun 29 17:25:52 2014 +0100
+@@ -28,19 +28,13 @@
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
## THE POSSIBILITY OF SUCH DAMAGE.
@@ -17,19 +18,21 @@
-else
-$(error "Platform '$(SYSTEM)' not supported")
-endif
--
+
-GLEW_DEST ?= /usr
+GLEW_DEST ?= BASEDIR
- BINDIR ?= $(GLEW_DEST)/bin
- LIBDIR ?= $(GLEW_DEST)/lib
- INCDIR ?= $(GLEW_DEST)/include/GL
---- a/config/Makefile.mingw 2013-07-07 15:43:48.000000000 +0200
-+++ b/config/Makefile.mingw 2013-07-07 15:47:32.000000000 +0200
+ BINDIR ?= $(GLEW_DEST)/bin
+ LIBDIR ?= $(GLEW_DEST)/lib
+ INCDIR ?= $(GLEW_DEST)/include/GL
+diff -r 9bbbd8b43e5b config/Makefile.mingw
+--- a/config/Makefile.mingw Sun Jun 29 17:24:13 2014 +0100
++++ b/config/Makefile.mingw Sun Jun 29 17:25:52 2014 +0100
@@ -1,7 +1,4 @@
NAME = glew32
--CC = gcc
-# use gcc for linking, with ld it does not work
--LD = gcc
+-CC := gcc
+-LD := gcc
+ LN :=
CFLAGS.SO = -DGLEW_BUILD
- LDFLAGS.GL = -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
+ LDFLAGS.GL = -lopengl32 -lgdi32 -luser32 -lkernel32
LDFLAGS.EXTRA = -L/mingw/lib
diff --git a/packaging/mingw-debian-cross/patches/gsl-config.patch b/packaging/mingw-debian-cross/patches/gsl-config.patch
old mode 100755
new mode 100644
diff --git a/packaging/mingw-debian-cross/patches/zlib-no-lc.patch b/packaging/mingw-debian-cross/patches/zlib-no-lc.patch
old mode 100755
new mode 100644
diff --git a/packaging/mingw-debian-cross/windows-installer.nsi b/packaging/mingw-debian-cross/windows-installer.nsi
index 0d9e106..77b2fb8 100755
--- a/packaging/mingw-debian-cross/windows-installer.nsi
+++ b/packaging/mingw-debian-cross/windows-installer.nsi
@@ -2,7 +2,7 @@
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "3Depict"
-!define PRODUCT_VERSION "0.0.16"
+!define PRODUCT_VERSION "0.0.17"
!define PRODUCT_PUBLISHER "D. Haley, A. Ceguerra"
!define PRODUCT_WEB_SITE "http://threedepict.sourceforge.net"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\3Depict.exe"
@@ -12,6 +12,8 @@
SetCompressor /FINAL /SOLID lzma
SetCompressorDictSize 64
+!include "x64.nsh"
+
; MUI 1.67 compatible ------
!include "MUI.nsh"
@@ -42,7 +44,7 @@ SetCompressorDictSize 64
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "Setup.exe"
-InstallDir "$PROGRAMFILES\3Depict"
+InstallDir "$PROGRAMFILES64\3Depict"
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails show
ShowUnInstDetails show
@@ -55,7 +57,6 @@ Section "3Depict program" SEC01
;INSERT_DLLS_HERE
CreateDirectory "$SMPROGRAMS\3Depict"
- CreateDirectory "$SMPROGRAMS\3Depict\textures"
CreateShortCut "$SMPROGRAMS\3Depict\3Depict.lnk" "$INSTDIR\3Depict.exe"
CreateShortCut "$DESKTOP\3Depict.lnk" "$INSTDIR\3Depict.exe"
@@ -124,43 +125,29 @@ FunctionEnd
Section Uninstall
Delete "$INSTDIR\${PRODUCT_NAME}.url"
- Delete "$INSTDIR\textures\uninst.exe"
+ Delete "$INSTDIR\uninst.exe"
- Delete "$INSTDIR\textures\animProgress0.png"
- Delete "$INSTDIR\textures\animProgress1.png"
- Delete "$INSTDIR\textures\animProgress2.png"
- Delete "$INSTDIR\textures\scroll_wheel_mouse.png"
- Delete "$INSTDIR\textures\rotateArrow.png"
- Delete "$INSTDIR\textures\Right_clicked_mouse.png"
- Delete "$INSTDIR\textures\Right-arrow.png"
- Delete "$INSTDIR\textures\middle_clicked_mouse.png"
- Delete "$INSTDIR\textures\Left_clicked_mouse.png"
- Delete "$INSTDIR\textures\Left-Right-arrow.png"
- Delete "$INSTDIR\textures\keyboard-tab.png"
- Delete "$INSTDIR\textures\keyboard-shift.png"
- Delete "$INSTDIR\textures\keyboard-ctrl.png"
- Delete "$INSTDIR\textures\keyboard-command.png"
- Delete "$INSTDIR\textures\keyboard-alt.png"
- Delete "$INSTDIR\textures\enlarge.png"
+ RMDir /r "$INSTDIR\textures"
+ RMDir "$INSTDIR\textures"
+ RMDir /r "$INSTDIR\locales"
+ RMDir "$INSTDIR\locales"
- Delete "3Depict.xpm"
- Delete "atomic-mass-table.dtd"
- Delete "naturalAbundance.xml"
- Delete "startup-tips.txt"
+ Delete "$INSTDIR\3Depict.xpm"
+ Delete "$INSTDIR\atomic-mass-table.dtd"
+ Delete "$INSTDIR\naturalAbundance.xml"
+ Delete "$INSTDIR\startup-tips.txt"
Delete "$INSTDIR\3Depict.exe"
Delete "$INSTDIR\manual.pdf"
- RMDir /r "$INSTDIR\locales\*.*"
- RMDir "$INSTDIR\locales"
;This is a token that should be replaced with the DLLS to uninstall
;INSERT_UNINST_DLLS_HERE
- Delete "$INSTDIR\uninst.exe"
Delete "$SMPROGRAMS\3Depict\Uninstall.lnk"
Delete "$SMPROGRAMS\3Depict\Website.lnk"
+ Delete "$SMPROGRAMS\3Depict\manual.pdf"
Delete "$DESKTOP\3Depict.lnk"
Delete "$SMPROGRAMS\3Depict\3Depict.lnk"
RMDir "$SMPROGRAMS\3Depict"
diff --git a/src/3Depict.cpp b/src/3Depict.cpp
index 1c66435..a1df700 100644
--- a/src/3Depict.cpp
+++ b/src/3Depict.cpp
@@ -42,17 +42,18 @@ private:
MainWindowFrame* MainFrame ;
wxArrayString commandLineFiles;
wxLocale* usrLocale;
- //long language;
-
- //void initLanguageSupport();
+ long language;
+ void initLanguageSupport();
+ //Don't load the main window, as debugging was in progress
+ bool dontLoad;
public:
threeDepictApp() ;
- ~threeDepictApp() { if(usrLocale) delete usrLocale;}
bool OnInit();
virtual void OnInitCmdLine(wxCmdLineParser& parser);
+ virtual int OnExit();
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
int FilterEvent(wxEvent &event);
@@ -70,27 +71,14 @@ public:
//Command line parameter table
static const wxCmdLineEntryDesc g_cmdLineDesc [] =
{
-#if wxCHECK_VERSION(2,9,0)
{ wxCMD_LINE_SWITCH, ("h"), ("help"), ("displays this message"),
wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_PARAM, NULL, NULL, ("inputfile"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE},
-#else
- { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxNTRANS("displays this message"),
- wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
- { wxCMD_LINE_PARAM, NULL, NULL, wxNTRANS("inputfile"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE},
-#endif
//Unit testing system
#ifdef DEBUG
-#if wxCHECK_VERSION(2,9,0)
{ wxCMD_LINE_SWITCH, ("t"), ("test"), ("Run debug unit tests, returns nonzero on test failure, zero on success.\n\t\t"
"XML files may be passed to run , instead of default tests"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_SWITCH},
-#else
- { wxCMD_LINE_SWITCH, wxT("t"), wxT("test"),
- wxNTRANS("Run debug unit tests, returns nonzero on test failure, zero on success.\n\t\t"
- "XML files may be passed to run, instead of default tests"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_SWITCH},
-#endif
#endif
-
{ wxCMD_LINE_NONE,NULL,NULL,NULL,wxCMD_LINE_VAL_NONE,0 }
};
@@ -118,22 +106,31 @@ IMPLEMENT_APP(threeDepictApp)
threeDepictApp::threeDepictApp()
{
MainFrame=0;usrLocale=0;
+ dontLoad=false;
#ifndef DEBUG
-#if wxCHECK_VERSION(2,9,0)
//Wx 2.9 and up now has assertions auto-enabled.
//Disable for release builds
wxSetAssertHandler(NULL);
#endif
-#endif
}
+int threeDepictApp::OnExit()
+{
+ if(usrLocale)
+ delete usrLocale;
+
+ //libxml2 by default seems to leak memory, unless you call this function
+ xmlCleanupParser();
+
+ return wxApp::OnExit();
+}
-/*void threeDepictApp::initLanguageSupport()
+void threeDepictApp::initLanguageSupport()
{
language = wxLANGUAGE_DEFAULT;
// load language if possible, fall back to English otherwise
- if(false)// (wxLocale::IsAvailable(language))
+ if(wxLocale::IsAvailable(language))
{
//Wx 2.9 and above are now unicode, so locale encoding
//conversion is deprecated.
@@ -152,7 +149,7 @@ threeDepictApp::threeDepictApp()
usrLocale->AddCatalogLookupPathPrefix(paths->GetResourcesDir());
usrLocale->AddCatalogLookupPathPrefix ( wxT ( "locales" ) );
#endif
- usrLocale->AddCatalog(wxCStr(PROGRAM_NAME));
+ usrLocale->AddCatalog((PROGRAM_NAME));
@@ -210,7 +207,7 @@ threeDepictApp::threeDepictApp()
language = wxLANGUAGE_ENGLISH;
}
}
-*/
+
//Catching key events globally.
int threeDepictApp::FilterEvent(wxEvent& event)
{
@@ -283,9 +280,9 @@ void threeDepictApp::OnInitCmdLine(wxCmdLineParser& parser)
{
wxString name,version,preamble;
- name=wxCStr(PROGRAM_NAME);
+ name=(PROGRAM_NAME);
name=name+ wxT(" ");
- version=wxCStr(PROGRAM_VERSION);
+ version=(PROGRAM_VERSION);
version+=wxT("\n");
preamble=wxT("Copyright (C) 2013 3Depict team\n");
@@ -318,7 +315,7 @@ bool threeDepictApp::OnCmdLineParsed(wxCmdLineParser& parser)
if( !f.FileExists() )
{
cerr << "Unable to locate file:" << strFile << endl;
- continue;
+ return false;
}
cerr << "Loading :" << strFile << endl ;
@@ -328,7 +325,7 @@ bool threeDepictApp::OnCmdLineParsed(wxCmdLineParser& parser)
if(!visControl.loadState(strFile.c_str(),cerr,false,true))
{
cerr << "Error loading state file:" << endl;
- exit(1);
+ return false;
}
//Run a refresh over the filter tree as a test
@@ -343,7 +340,7 @@ bool threeDepictApp::OnCmdLineParsed(wxCmdLineParser& parser)
if(!testFilterTree(f))
{
cerr << "Failed loading :" << strFile << " , aborting" << endl;
- exit(1);
+ return false;
}
}
@@ -352,8 +349,8 @@ bool threeDepictApp::OnCmdLineParsed(wxCmdLineParser& parser)
}
- cerr << "Test XML File(s) Loaded OK" << endl;
- exit(0);
+ cerr << "Test XML File(s) Loaded OK" << endl;
+ dontLoad=true;
}
else
{
@@ -361,29 +358,30 @@ bool threeDepictApp::OnCmdLineParsed(wxCmdLineParser& parser)
if(!runUnitTests())
{
cerr << "Unit tests failed" <<endl;
- exit(1);
+ return false;
}
else
{
cerr << "Unit tests succeeded!" <<endl;
- exit(0);
+ dontLoad=true;
}
}
}
+ else
#endif
-
- for(unsigned int ui=0;ui<parser.GetParamCount();ui++)
{
- wxFileName f;
- f.Assign(parser.GetParam(ui));
+ for(unsigned int ui=0;ui<parser.GetParamCount();ui++)
+ {
+ wxFileName f;
+ f.Assign(parser.GetParam(ui));
- if( f.FileExists() )
- commandLineFiles.Add(f.GetFullPath());
- else
- std::cerr << TRANS("File : ") << stlStr(f.GetFullPath()) << TRANS(" does not exist. Skipping") << std::endl;
+ if( f.FileExists() )
+ commandLineFiles.Add(f.GetFullPath());
+ else
+ std::cerr << TRANS("File : ") << stlStr(f.GetFullPath()) << TRANS(" does not exist. Skipping") << std::endl;
+ }
}
-
return true;
}
@@ -411,13 +409,25 @@ void threeDepictApp::MacReopenFile(const wxString &filename)
bool threeDepictApp::OnInit()
{
- //initLanguageSupport();
+ initLanguageSupport();
//Set the gettext language
//Register signal handler for backtraces
if (!wxApp::OnInit())
- return false;
+ return false;
+
+ //if we ran the debug code, don't load the main window
+ if(dontLoad)
+ {
+ OnExit();
+ //FIXME: This causes wx to shutdown incorrectly, but gives us the return code
+ // - I can't seem to simultaneously set the return code and
+ // abort the init.
+ exit(0);
+
+ return false;
+ }
//Need to seed random number generator for entire program
srand (time(NULL));
@@ -429,10 +439,6 @@ bool threeDepictApp::OnInit()
wxInitAllImageHandlers();
MainFrame = new MainWindowFrame(NULL, ID_MAIN_WINDOW, wxEmptyString,wxDefaultPosition,wxDefaultSize);
- if(!MainFrame->initOK())
- return false;
-
-
SetTopWindow(MainFrame);
#if defined(DEBUG) && defined(__linux__)
@@ -457,11 +463,17 @@ bool threeDepictApp::OnInit()
MainFrame->Show();
-
+
+ MainFrame->checkShowTips();
+ MainFrame->checkReloadAutosave();
+
+
if(commandLineFiles.GetCount())
MainFrame->SetCommandLineFiles(commandLineFiles);
MainFrame->fixSplitterWindow();
+
+ MainFrame->finaliseStartup();
return true;
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 9ca6bb9..68011aa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
MSYS_PATH=/c/msys/1.0/local/include/
%.rc.o:
- $(WX_RESCOMP) $^ -o $@
+ $(WX_RESCOMP) $^ -o $@ 3Depict.rc
3Depict_LDFLAGS=$(LDFLAGS) $(FT_LDFLAGS) $(GSL_LIBS) $(MGL_LIBS)
@@ -20,9 +20,11 @@ MSYS_PATH=/c/msys/1.0/local/include/
bin_PROGRAMS= 3Depict
#------- Common header files for all sub-modules
-COMMON_SOURCE_FILES = common/pngread.c common/stringFuncs.cpp common/xmlHelper.cpp common/colourmap.cpp common/voxels.cpp common/mathfuncs.cpp common/basics.cpp common/assertion.cpp
+COMMON_SOURCE_FILES = common/pngread.c common/stringFuncs.cpp common/constants.cpp common/xmlHelper.cpp\
+ common/colourmap.cpp common/voxels.cpp common/mathfuncs.cpp common/basics.cpp common/assertion.cpp
COMMON_HEADER_FILES = common/pngread.h common/stringFuncs.h common/constants.h common/xmlHelper.h common/colourmap.h \
- common/mathfuncs.h common/basics.h common/translation.h common/endianTest.h common/assertion.h common/voxels.h
+ common/mathfuncs.h common/basics.h common/translation.h common/endianTest.h common/assertion.h common/voxels.h \
+ common/array2D.h
#-----------
@@ -36,7 +38,7 @@ FILTER_FILES = backend/filters/allFilter.cpp backend/filters/filterCommon.cpp \
backend/filters/compositionProfile.cpp backend/filters/spatialAnalysis.cpp \
backend/filters/clusterAnalysis.cpp backend/filters/ionInfo.cpp \
backend/filters/annotation.cpp backend/filters/geometryHelpers.cpp \
- backend/filters/algorithms/binomial.cpp
+ backend/filters/algorithms/binomial.cpp
FILTER_HEADER_FILES = backend/filters/allFilter.h backend/filters/filterCommon.h \
backend/filters/dataLoad.h backend/filters/ionDownsample.h \
@@ -46,7 +48,7 @@ FILTER_HEADER_FILES = backend/filters/allFilter.h backend/filters/filterCommon.h
backend/filters/compositionProfile.h backend/filters/spatialAnalysis.h \
backend/filters/clusterAnalysis.h backend/filters/ionInfo.h \
backend/filters/annotation.h backend/filters/geometryHelpers.h \
- backend/filters/algorithms/binomial.h
+ backend/filters/algorithms/binomial.h
BACKEND_SOURCE_FILES = backend/animator.cpp backend/filtertreeAnalyse.cpp backend/filtertree.cpp \
backend/APT/ionhit.cpp backend/APT/APTFileIO.cpp backend/APT/APTRanges.cpp backend/APT/abundanceParser.cpp \
@@ -94,8 +96,8 @@ DIALOG_HEADER_FILES = gui/dialogs/ExportPos.h gui/dialogs/ExportRngDialog.h gui/
GUI_SOURCE_FILES=gui/mainFrame.cpp gui/mathglPane.cpp gui/cropPanel.cpp gui/glPane.cpp $(DIALOG_SOURCE_FILES)
GUI_HEADER_FILES=gui/mainFrame.h gui/mathglPane.h gui/cropPanel.h gui/art.h gui/glPane.h $(DIALOG_HEADER_FILES)
-BASE_SOURCE_FILES= 3Depict.cpp testing/testing.cpp wx/wxcommon.cpp wx/wxcomponents.cpp winconsole.cpp
-BASE_HEADER_FILES= testing/testing.h wx/wxcommon.h wx/wxcomponents.h winconsole.h
+BASE_SOURCE_FILES= 3Depict.cpp testing/testing.cpp wx/wxcommon.cpp wx/wxcomponents.cpp winconsole.cpp wx/propertyGridUpdater.cpp
+BASE_HEADER_FILES= testing/testing.h wx/wxcommon.h wx/wxcomponents.h winconsole.h wx/propertyGridUpdater.h
TEST_SOURCE_FILES = testing/mglTesting.cpp
TEST_HEADER_FILES = testing/mglTesting.h
diff --git a/src/Makefile.in b/src/Makefile.in
index 0fc9cfb..54a2a60 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -100,7 +100,8 @@ am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am__3Depict_SOURCES_DIST = 3Depict.cpp testing/testing.cpp \
wx/wxcommon.cpp wx/wxcomponents.cpp winconsole.cpp \
- testing/testing.h wx/wxcommon.h wx/wxcomponents.h winconsole.h \
+ wx/propertyGridUpdater.cpp testing/testing.h wx/wxcommon.h \
+ wx/wxcomponents.h winconsole.h wx/propertyGridUpdater.h \
gui/mainFrame.cpp gui/mathglPane.cpp gui/cropPanel.cpp \
gui/glPane.cpp gui/dialogs/ExportPos.cpp \
gui/dialogs/ExportRngDialog.cpp gui/dialogs/prefDialog.cpp \
@@ -166,19 +167,20 @@ am__3Depict_SOURCES_DIST = 3Depict.cpp testing/testing.cpp \
gl/textures.cpp gl/select.cpp gl/cameras.cpp gl/isoSurface.cpp \
gl/tr.cpp gl/scene.h gl/drawables.h gl/effect.h gl/textures.h \
gl/select.h gl/cameras.h gl/isoSurface.h gl/tr.h gl/glDebug.h \
- common/pngread.c common/stringFuncs.cpp common/xmlHelper.cpp \
- common/colourmap.cpp common/voxels.cpp common/mathfuncs.cpp \
- common/basics.cpp common/assertion.cpp common/pngread.h \
- common/stringFuncs.h common/constants.h common/xmlHelper.h \
- common/colourmap.h common/mathfuncs.h common/basics.h \
- common/translation.h common/endianTest.h common/assertion.h \
- common/voxels.h testing/mglTesting.cpp testing/mglTesting.h \
- 3Depict.rc
+ common/pngread.c common/stringFuncs.cpp common/constants.cpp \
+ common/xmlHelper.cpp common/colourmap.cpp common/voxels.cpp \
+ common/mathfuncs.cpp common/basics.cpp common/assertion.cpp \
+ common/pngread.h common/stringFuncs.h common/constants.h \
+ common/xmlHelper.h common/colourmap.h common/mathfuncs.h \
+ common/basics.h common/translation.h common/endianTest.h \
+ common/assertion.h common/voxels.h common/array2D.h \
+ testing/mglTesting.cpp testing/mglTesting.h 3Depict.rc
am__dirstamp = $(am__leading_dot)dirstamp
am__objects_1 = 3Depict-3Depict.$(OBJEXT) \
testing/3Depict-testing.$(OBJEXT) \
wx/3Depict-wxcommon.$(OBJEXT) \
- wx/3Depict-wxcomponents.$(OBJEXT) 3Depict-winconsole.$(OBJEXT)
+ wx/3Depict-wxcomponents.$(OBJEXT) 3Depict-winconsole.$(OBJEXT) \
+ wx/3Depict-propertyGridUpdater.$(OBJEXT)
am__objects_2 =
am__objects_3 = gui/dialogs/3Depict-ExportPos.$(OBJEXT) \
gui/dialogs/3Depict-ExportRngDialog.$(OBJEXT) \
@@ -237,6 +239,7 @@ am__objects_8 = gl/3Depict-scene.$(OBJEXT) \
gl/3Depict-tr.$(OBJEXT)
am__objects_9 = common/3Depict-pngread.$(OBJEXT) \
common/3Depict-stringFuncs.$(OBJEXT) \
+ common/3Depict-constants.$(OBJEXT) \
common/3Depict-xmlHelper.$(OBJEXT) \
common/3Depict-colourmap.$(OBJEXT) \
common/3Depict-voxels.$(OBJEXT) \
@@ -481,9 +484,12 @@ MSYS_PATH = /c/msys/1.0/local/include/
$(GLU_LIBS) $(QHULL_LIBS) $(PNG_LIBS) $(am__append_2)
#------- Common header files for all sub-modules
-COMMON_SOURCE_FILES = common/pngread.c common/stringFuncs.cpp common/xmlHelper.cpp common/colourmap.cpp common/voxels.cpp common/mathfuncs.cpp common/basics.cpp common/assertion.cpp
+COMMON_SOURCE_FILES = common/pngread.c common/stringFuncs.cpp common/constants.cpp common/xmlHelper.cpp\
+ common/colourmap.cpp common/voxels.cpp common/mathfuncs.cpp common/basics.cpp common/assertion.cpp
+
COMMON_HEADER_FILES = common/pngread.h common/stringFuncs.h common/constants.h common/xmlHelper.h common/colourmap.h \
- common/mathfuncs.h common/basics.h common/translation.h common/endianTest.h common/assertion.h common/voxels.h
+ common/mathfuncs.h common/basics.h common/translation.h common/endianTest.h common/assertion.h common/voxels.h \
+ common/array2D.h
#-----------
@@ -498,7 +504,7 @@ FILTER_FILES = backend/filters/allFilter.cpp backend/filters/filterCommon.cpp \
backend/filters/compositionProfile.cpp backend/filters/spatialAnalysis.cpp \
backend/filters/clusterAnalysis.cpp backend/filters/ionInfo.cpp \
backend/filters/annotation.cpp backend/filters/geometryHelpers.cpp \
- backend/filters/algorithms/binomial.cpp
+ backend/filters/algorithms/binomial.cpp
FILTER_HEADER_FILES = backend/filters/allFilter.h backend/filters/filterCommon.h \
backend/filters/dataLoad.h backend/filters/ionDownsample.h \
@@ -508,7 +514,7 @@ FILTER_HEADER_FILES = backend/filters/allFilter.h backend/filters/filterCommon.h
backend/filters/compositionProfile.h backend/filters/spatialAnalysis.h \
backend/filters/clusterAnalysis.h backend/filters/ionInfo.h \
backend/filters/annotation.h backend/filters/geometryHelpers.h \
- backend/filters/algorithms/binomial.h
+ backend/filters/algorithms/binomial.h
BACKEND_SOURCE_FILES = backend/animator.cpp backend/filtertreeAnalyse.cpp backend/filtertree.cpp \
backend/APT/ionhit.cpp backend/APT/APTFileIO.cpp backend/APT/APTRanges.cpp backend/APT/abundanceParser.cpp \
@@ -553,8 +559,8 @@ DIALOG_HEADER_FILES = gui/dialogs/ExportPos.h gui/dialogs/ExportRngDialog.h gui/
GUI_SOURCE_FILES = gui/mainFrame.cpp gui/mathglPane.cpp gui/cropPanel.cpp gui/glPane.cpp $(DIALOG_SOURCE_FILES)
GUI_HEADER_FILES = gui/mainFrame.h gui/mathglPane.h gui/cropPanel.h gui/art.h gui/glPane.h $(DIALOG_HEADER_FILES)
-BASE_SOURCE_FILES = 3Depict.cpp testing/testing.cpp wx/wxcommon.cpp wx/wxcomponents.cpp winconsole.cpp
-BASE_HEADER_FILES = testing/testing.h wx/wxcommon.h wx/wxcomponents.h winconsole.h
+BASE_SOURCE_FILES = 3Depict.cpp testing/testing.cpp wx/wxcommon.cpp wx/wxcomponents.cpp winconsole.cpp wx/propertyGridUpdater.cpp
+BASE_HEADER_FILES = testing/testing.h wx/wxcommon.h wx/wxcomponents.h winconsole.h wx/propertyGridUpdater.h
TEST_SOURCE_FILES = testing/mglTesting.cpp
TEST_HEADER_FILES = testing/mglTesting.h
#-----------
@@ -661,6 +667,8 @@ wx/3Depict-wxcommon.$(OBJEXT): wx/$(am__dirstamp) \
wx/$(DEPDIR)/$(am__dirstamp)
wx/3Depict-wxcomponents.$(OBJEXT): wx/$(am__dirstamp) \
wx/$(DEPDIR)/$(am__dirstamp)
+wx/3Depict-propertyGridUpdater.$(OBJEXT): wx/$(am__dirstamp) \
+ wx/$(DEPDIR)/$(am__dirstamp)
gui/$(am__dirstamp):
@$(MKDIR_P) gui
@: > gui/$(am__dirstamp)
@@ -868,6 +876,8 @@ common/3Depict-pngread.$(OBJEXT): common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/3Depict-stringFuncs.$(OBJEXT): common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
+common/3Depict-constants.$(OBJEXT): common/$(am__dirstamp) \
+ common/$(DEPDIR)/$(am__dirstamp)
common/3Depict-xmlHelper.$(OBJEXT): common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/3Depict-colourmap.$(OBJEXT): common/$(am__dirstamp) \
@@ -943,6 +953,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/3Depict-assertion.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/3Depict-basics.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/3Depict-colourmap.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/3Depict-constants.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/3Depict-mathfuncs.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/3Depict-pngread.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/3Depict-stringFuncs.Po at am__quote@
@@ -974,6 +985,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at gui/dialogs/animateSubDialogs/$(DEPDIR)/3Depict-stringKeyFrameDialog.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at testing/$(DEPDIR)/3Depict-mglTesting.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at testing/$(DEPDIR)/3Depict-testing.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at wx/$(DEPDIR)/3Depict-propertyGridUpdater.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at wx/$(DEPDIR)/3Depict-wxcommon.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at wx/$(DEPDIR)/3Depict-wxcomponents.Po at am__quote@
@@ -1093,6 +1105,20 @@ wx/3Depict-wxcomponents.obj: wx/wxcomponents.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -c -o 3Depict-winconsole.obj `if test -f 'winconsole.cpp'; then $(CYGPATH_W) 'winconsole.cpp'; else $(CYGPATH_W) '$(srcdir)/winconsole.cpp'; fi`
+wx/3Depict-propertyGridUpdater.o: wx/propertyGridUpdater.cpp
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -MT wx/3Depict-propertyGridUpdater.o -MD -MP -MF wx/$(DEPDIR)/3Depict-propertyGridUpdater.Tpo -c -o wx/3Depict-propertyGridUpdater.o `test -f 'wx/propertyGridUpdater.cpp' || echo '$(srcdir)/'`wx/propertyGridUpdater.cpp
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) wx/$(DEPDIR)/3Depict-propertyGridUpdater.Tpo wx/$(DEPDIR)/3Depict-propertyGridUpdater.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx/propertyGridUpdater.cpp' object='wx/3Depict-propertyGridUpdater.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -c -o wx/3Depict-propertyGridUpdater.o `test -f 'wx/propertyGridUpdater.cpp' || echo '$(srcdir)/'`wx/propertyGridUpdater.cpp
+
+wx/3Depict-propertyGridUpdater.obj: wx/propertyGridUpdater.cpp
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -MT wx/3Depict-propertyGridUpdater.obj -MD -MP -MF wx/$(DEPDIR)/3Depict-propertyGridUpdater.Tpo -c -o wx/3Depict-propertyGridUpdater.obj `if test -f 'wx/propertyGridUpdater.cpp'; then $(CYGPATH_W) 'wx/propertyGridUpdater.cpp'; else $(CYGPATH_W) '$(srcdir)/wx/propertyGridUpdater.cpp'; fi`
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) wx/$(DEPDIR)/3Depict-propertyGridUpdater.Tpo wx/$(DEPDIR)/3Depict-propertyGridUpdater.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx/propertyGridUpdater.cpp' object='wx/3Depict-propertyGridUpdater.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -c -o wx/3Depict-propertyGridUpdater.obj `if test -f 'wx/propertyGridUpdater.cpp'; then $(CYGPATH_W) 'wx/propertyGridUpdater.cpp'; else $(CYGPATH_W) '$(srcdir)/wx/propertyGridUpdater.cpp'; fi`
+
gui/3Depict-mainFrame.o: gui/mainFrame.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -MT gui/3Depict-mainFrame.o -MD -MP -MF gui/$(DEPDIR)/3Depict-mainFrame.Tpo -c -o gui/3Depict-mainFrame.o `test -f 'gui/mainFrame.cpp' || echo '$(srcdir)/'`gui/mainFrame.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) gui/$(DEPDIR)/3Depict-mainFrame.Tpo gui/$(DEPDIR)/3Depict-mainFrame.Po
@@ -1919,6 +1945,20 @@ common/3Depict-stringFuncs.obj: common/stringFuncs.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -c -o common/3Depict-stringFuncs.obj `if test -f 'common/stringFuncs.cpp'; then $(CYGPATH_W) 'common/stringFuncs.cpp'; else $(CYGPATH_W) '$(srcdir)/common/stringFuncs.cpp'; fi`
+common/3Depict-constants.o: common/constants.cpp
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -MT common/3Depict-constants.o -MD -MP -MF common/$(DEPDIR)/3Depict-constants.Tpo -c -o common/3Depict-constants.o `test -f 'common/constants.cpp' || echo '$(srcdir)/'`common/constants.cpp
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/3Depict-constants.Tpo common/$(DEPDIR)/3Depict-constants.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/constants.cpp' object='common/3Depict-constants.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -c -o common/3Depict-constants.o `test -f 'common/constants.cpp' || echo '$(srcdir)/'`common/constants.cpp
+
+common/3Depict-constants.obj: common/constants.cpp
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -MT common/3Depict-constants.obj -MD -MP -MF common/$(DEPDIR)/3Depict-constants.Tpo -c -o common/3Depict-constants.obj `if test -f 'common/constants.cpp'; then $(CYGPATH_W) 'common/constants.cpp'; else $(CYGPATH_W) '$(srcdir)/common/constants.cpp'; fi`
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/3Depict-constants.Tpo common/$(DEPDIR)/3Depict-constants.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common/constants.cpp' object='common/3Depict-constants.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -c -o common/3Depict-constants.obj `if test -f 'common/constants.cpp'; then $(CYGPATH_W) 'common/constants.cpp'; else $(CYGPATH_W) '$(srcdir)/common/constants.cpp'; fi`
+
common/3Depict-xmlHelper.o: common/xmlHelper.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(3Depict_CXXFLAGS) $(CXXFLAGS) -MT common/3Depict-xmlHelper.o -MD -MP -MF common/$(DEPDIR)/3Depict-xmlHelper.Tpo -c -o common/3Depict-xmlHelper.o `test -f 'common/xmlHelper.cpp' || echo '$(srcdir)/'`common/xmlHelper.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) common/$(DEPDIR)/3Depict-xmlHelper.Tpo common/$(DEPDIR)/3Depict-xmlHelper.Po
@@ -2245,7 +2285,7 @@ uninstall-am: uninstall-binPROGRAMS
%.rc.o:
- $(WX_RESCOMP) $^ -o $@
+ $(WX_RESCOMP) $^ -o $@ 3Depict.rc
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/backend/APT/APTFileIO.cpp b/src/backend/APT/APTFileIO.cpp
index d37984e..c3b7cad 100644
--- a/src/backend/APT/APTFileIO.cpp
+++ b/src/backend/APT/APTFileIO.cpp
@@ -22,6 +22,8 @@
#include "../../common/stringFuncs.h"
#include "../../common/translation.h"
+
+
#include <cstring>
#include <new>
@@ -35,7 +37,18 @@ using std::make_pair;
const size_t PROGRESS_REDUCE=5000;
+
//---------
+const char *TEXT_LOAD_ERR_STRINGS[] = { "",
+ NTRANS("Error opening file"),
+ NTRANS("Only found header, no data"),
+ NTRANS("Unable to reopen file after first scan"),
+ NTRANS("Error whilst reading file contents"),
+ NTRANS("Unexpected file format"),
+ NTRANS("Unexpected file format"),
+ NTRANS("Insufficient memory to continue"),
+ };
+
const char *POS_ERR_STRINGS[] = { "",
NTRANS("Memory allocation failure on POS load"),
NTRANS("Error opening pos file"),
@@ -43,6 +56,7 @@ const char *POS_ERR_STRINGS[] = { "",
NTRANS("Pos file size appears to have non-integer number of entries"),
NTRANS("Error reading from pos file (after open)"),
NTRANS("Error - Found NaN in pos file"),
+ NTRANS("Error - Found Inf in pos file"),
NTRANS("Pos load aborted by interrupt.")
};
//---------
@@ -56,7 +70,6 @@ enum
TEXT_ERR_REOPEN,
TEXT_ERR_READ_CONTENTS,
TEXT_ERR_FORMAT,
- TEXT_ERR_NUM_FIELDS,
TEXT_ERR_ALLOC_FAIL,
TEXT_ERR_ENUM_END //not an error, just end of enum
};
@@ -95,10 +108,11 @@ const char *LAWATAP_ATO_ERR_STRINGS[] = { "",
};
//---------
-unsigned int LimitLoadPosFile(unsigned int inputnumcols, unsigned int outputnumcols, unsigned int index[], vector<IonHit> &posIons,const char *posFile, size_t limitCount,
+unsigned int LimitLoadPosFile(unsigned int inputnumcols, unsigned int outputnumcols, const unsigned int index[], vector<IonHit> &posIons,const char *posFile, size_t limitCount,
unsigned int &progress, bool (*callback)(bool),bool strongSampling)
{
+
//Function is only defined for 4 columns here.
ASSERT(outputnumcols == 4);
//buffersize must be a power of two and at least outputnumcols*sizeof(float)
@@ -187,9 +201,10 @@ unsigned int LimitLoadPosFile(unsigned int inputnumcols, unsigned int outputnumc
}
- //sort again
- GreaterWithCallback<size_t> g(callback,PROGRESS_REDUCE);
- std::sort(ionsToLoad.begin(),ionsToLoad.end(),g);
+ //sort again
+ //NOTE: I tried to use a functor here to get progress
+ // It was not stable with parallel sort
+ std::sort(ionsToLoad.begin(),ionsToLoad.end());
unsigned int curProg = PROGRESS_REDUCE;
@@ -228,7 +243,14 @@ unsigned int LimitLoadPosFile(unsigned int inputnumcols, unsigned int outputnumc
delete[] buffer2;
return POS_NAN_LOAD_ERROR;
}
-
+
+ if(posIons[ui].hasInf())
+ {
+ delete[] buffer;
+ delete[] buffer2;
+ return POS_INF_LOAD_ERROR;
+ }
+
pointCount++;
if(!curProg--)
{
@@ -253,7 +275,7 @@ unsigned int LimitLoadPosFile(unsigned int inputnumcols, unsigned int outputnumc
}
unsigned int GenericLoadFloatFile(unsigned int inputnumcols, unsigned int outputnumcols,
- unsigned int index[], vector<IonHit> &posIons,const char *posFile,
+ const unsigned int index[], vector<IonHit> &posIons,const char *posFile,
unsigned int &progress, bool (*callback)(bool))
{
ASSERT(outputnumcols==4); //Due to ionHit.setHit
@@ -369,6 +391,14 @@ unsigned int GenericLoadFloatFile(unsigned int inputnumcols, unsigned int output
delete[] buffer2;
return POS_NAN_LOAD_ERROR;
}
+
+ if(hit.hasInf())
+ {
+ delete[] buffer;
+ delete[] buffer2;
+ return POS_INF_LOAD_ERROR;
+ }
+
posIons[ionP] = hit;
ionP++;
@@ -408,7 +438,6 @@ unsigned int limitLoadTextFile(unsigned int maxCols,
vector<vector<float> > &data,const char *textFile, const char *delim, const size_t limitCount,
unsigned int &progress, bool (*callback)(bool),bool strongRandom)
{
-
ASSERT(maxCols);
ASSERT(textFile);
@@ -575,11 +604,11 @@ unsigned int limitLoadTextFile(unsigned int maxCols,
return TEXT_ERR_ALLOC_FAIL;
}
+ (*callback)(true);
//Sort the data such that we are going to
//always jump forwards in the file; better disk access and whatnot.
- GreaterWithCallback<size_t> g(callback,PROGRESS_REDUCE);
- std::sort(dataToLoad.begin(),dataToLoad.end(),g);
+ std::sort(dataToLoad.begin(),dataToLoad.end());
//OK, so we have a list of newlines
//that we can use as entry points for random seek.
diff --git a/src/backend/APT/APTFileIO.h b/src/backend/APT/APTFileIO.h
index b2b00c2..e743b9c 100644
--- a/src/backend/APT/APTFileIO.h
+++ b/src/backend/APT/APTFileIO.h
@@ -39,6 +39,8 @@ extern const char *ION_TEXT_ERR_STRINGS[];
extern const char *LAWATAP_ATO_ERR_STRINGS[];
+extern const char *TEXT_LOAD_ERR_STRINGS[];
+
//!Errors that can be encountered when openning pos files
enum posErrors
{
@@ -48,6 +50,7 @@ enum posErrors
POS_SIZE_MODULUS_ERR,
POS_READ_FAIL,
POS_NAN_LOAD_ERROR,
+ POS_INF_LOAD_ERROR,
POS_ABORT_FAIL,
POS_ERR_FINAL // Not actually an error, but tells us where the end of the num is.
};
@@ -62,11 +65,11 @@ enum posErrors
* */
//!Load a pos file into a T of IonHits
unsigned int GenericLoadFloatFile(unsigned int inputnumcols, unsigned int outputnumcols,
- unsigned int index[], vector<IonHit> &posIons,const char *posFile,
+ const unsigned int index[], vector<IonHit> &posIons,const char *posFile,
unsigned int &progress, bool (*callback)(bool));
-unsigned int LimitLoadPosFile(unsigned int inputnumcols, unsigned int outputnumcols, unsigned int index[],
+unsigned int LimitLoadPosFile(unsigned int inputnumcols, unsigned int outputnumcols, const unsigned int index[],
vector<IonHit> &posIons,const char *posFile, size_t limitCount,
unsigned int &progress, bool (*callback)(bool),bool strongRandom);
diff --git a/src/backend/APT/APTRanges.cpp b/src/backend/APT/APTRanges.cpp
index 9f45a8d..c8b06eb 100644
--- a/src/backend/APT/APTRanges.cpp
+++ b/src/backend/APT/APTRanges.cpp
@@ -40,7 +40,8 @@ using std::accumulate;
//Arbitrary maximum range file line size
const size_t MAX_LINE_SIZE = 16536;
-
+//Arbitrary maximum range file size, in bytes
+const size_t MAX_RANGEFILE_SIZE = 20*1024*1024;
const char *rangeErrStrings[] =
{
"",
@@ -62,6 +63,7 @@ const char *rangeErrStrings[] =
NTRANS("Range file appears to be inconsistent (eg, overlapping ranges)"),
NTRANS("No ion name mapping found for multiple ion."),
NTRANS("Polyatomic extension range matches multiple masses in first section"),
+ NTRANS("Range file is exceedingly large. Refusing to open"),
};
const char *RANGE_EXTS[] = { "rng",
@@ -470,17 +472,16 @@ unsigned int RangeFile::write(std::ostream &f, size_t format) const
for(size_t ui=0;ui<ranges.size();ui++)
{
+ ColourRGBA tmpRgba;
+ tmpRgba.fromRGBf(colours[ui]);
std::string colString;
- genColString((unsigned char)colours[ui].red*255,
- (unsigned char)colours[ui].green*255,
- (unsigned char)colours[ui].blue*255,colString);
-
+ colString = tmpRgba.rgbString();
//strip leading #
colString=colString.substr(1);
ASSERT(colString.size() == 6);
//FIXME: This is incomplete. we need to break the species apart into its
- // compponents, then decide to use the Element:count notation, or the Name:species notation
+ // components, then decide to use the Element:count notation, or the Name:species notation
string strName;
strName=ionNames[ionIDs[ui]].first;
if(elementSet.find(strName) != elementSet.end())
@@ -492,6 +493,8 @@ unsigned int RangeFile::write(std::ostream &f, size_t format) const
}
else
{
+ //Difference is we have to use the "Name" parameter if not in set
+
f << "Range" << ui+1 <<"="
<< ranges[ui].first << " " << ranges[ui].second <<
" " << "Name:" << strName << ":1" <<
@@ -531,6 +534,12 @@ void RangeFile::clear()
unsigned int RangeFile::open(const char *rangeFilename, unsigned int fileFormat)
{
+ size_t fileSize;
+ getFilesize(rangeFilename,fileSize);
+
+ if(fileSize > MAX_RANGEFILE_SIZE)
+ return RANGE_ERR_FILESIZE;
+
FILE *fpRange;
fpRange=fopen(rangeFilename,"r");
if (fpRange== NULL)
@@ -594,10 +603,17 @@ unsigned int RangeFile::open(const char *rangeFilename, unsigned int fileFormat)
bool RangeFile::openGuessFormat(const char *rangeFilename)
{
- unsigned int assumedFileFormat;
-
+ //Check the filesize before attempting to guess the format
+ size_t fileSize;
+ getFilesize(rangeFilename,fileSize);
+ if(fileSize > MAX_RANGEFILE_SIZE)
+ {
+ errState=RANGE_ERR_FILESIZE;
+ return false;
+ }
//Try to auto-detect the filetype
+ unsigned int assumedFileFormat;
assumedFileFormat=detectFileType(rangeFilename);
if(assumedFileFormat < RANGE_FORMAT_END_OF_ENUM)
@@ -1715,8 +1731,9 @@ unsigned int RangeFile::openENV(FILE *fpRange)
//There should be more data following the range information.
// if not, this is not really an env file
if(feof(fpRange))
+ {
return RANGE_ERR_FORMAT;
-
+ }
return 0;
}
@@ -1829,10 +1846,10 @@ unsigned int RangeFile::openRRNG(FILE *fpRange)
basicIonNames.push_back(split[1]);
if (basicIonNames.size() > numBasicIons)
- {
- delete[] inBuffer;
- return RANGE_ERR_FORMAT;
- }
+ {
+ delete[] inBuffer;
+ return RANGE_ERR_FORMAT;
+ }
}
else
{
@@ -1996,13 +2013,16 @@ unsigned int RangeFile::openRRNG(FILE *fpRange)
//which requires a leading #,
//in lowercase
value = string("#") + lowercase(value);
- unsigned char r,g,b,a;
-
- parseColString(value,r,g,b,a);
+ ColourRGBA tmpRgba;
+ if(!tmpRgba.parse(value))
+ {
+ delete[] inBuffer;
+ return RANGE_ERR_FORMAT;
+ }
- col.red = (float)r/255.0f;
- col.green=(float)g/255.0f;
- col.blue=(float)b/255.0f;
+ col.red = (float)tmpRgba.r()/255.0f;
+ col.green=(float)tmpRgba.g()/255.0f;
+ col.blue=(float)tmpRgba.b()/255.0f;
}
else
{
diff --git a/src/backend/APT/APTRanges.h b/src/backend/APT/APTRanges.h
index 35b8946..a08ba92 100644
--- a/src/backend/APT/APTRanges.h
+++ b/src/backend/APT/APTRanges.h
@@ -24,6 +24,7 @@
#include "backend/APT/ionhit.h"
+#include "common/basics.h"
enum{
RANGE_ERR_OPEN =1,
@@ -44,16 +45,10 @@ enum{
RANGE_ERR_DATA_INCONSISTENT,
RANGE_ERR_DATA_NOMAPPED_IONNAME,
RANGE_ERR_NONUNIQUE_POLYATOMIC,
+ RANGE_ERR_FILESIZE,
RANGE_ERR_ENUM_END
};
-//!Data holder for colour as float
-typedef struct RGBf
-{
- float red;
- float green;
- float blue;
-} RGBf;
//Number of elements stored in the table
const unsigned int NUM_ELEMENTS=119;
@@ -64,6 +59,7 @@ enum{ RANGE_FORMAT_ORNL,
RANGE_FORMAT_RRNG,
RANGE_FORMAT_END_OF_ENUM //not a format, just end of enumueration.
};
+
//!Data storage and retrieval class for various range files
class RangeFile
{
@@ -132,7 +128,7 @@ class RangeFile
RangeFile();
const RangeFile& operator=(const RangeFile &other);
- //!Open a specified range file
+ //!Open a specified range file, returns zero on success, nonzero on failure
unsigned int open(const char *rangeFile, unsigned int format=RANGE_FORMAT_ORNL);
//!Open a specified range file - returns true on success
bool openGuessFormat(const char *rangeFile);
diff --git a/src/backend/APT/abundanceParser.cpp b/src/backend/APT/abundanceParser.cpp
index 49f5aac..fba3917 100644
--- a/src/backend/APT/abundanceParser.cpp
+++ b/src/backend/APT/abundanceParser.cpp
@@ -353,3 +353,76 @@ void AbundanceData::getSymbolIndices(const vector<string> &symbols,vector<size_t
indices[ui]=symbolIndex(symbols[ui].c_str());
}
+
+#ifdef DEBUG
+
+#include <set>
+
+using std::set;
+
+void AbundanceData::checkErrors() const
+{
+ //Ensure all isotopes sum to 1-ish
+ // Rounding errors limit our correctness here.
+ for(size_t ui=0;ui<isotopeData.size();ui++)
+ {
+ if(!isotopeData[ui].size())
+ continue;
+
+ float sum;
+ sum=0.0f;
+ for(size_t uj=0; uj<isotopeData[ui].size();uj++)
+ {
+ sum+=isotopeData[ui][uj].abundance;
+ }
+
+ ASSERT(fabs(sum -1.0f) < 0.000001);
+
+ }
+
+
+ //Ensure Ti has 5 isotopes (original data file was missing)
+ ASSERT(isotopeData[symbolIndex("Ti")].size() == 5);
+
+ //Enusre all isotopes are uniquely numbered
+ // - loop over each atom
+ for(size_t ui=0;ui<isotopeData.size();ui++)
+ {
+ //now ovre each isotope
+ std::set<size_t> uniqNums;
+ uniqNums.clear();
+ for(size_t uj=0; uj<isotopeData[ui].size();uj++)
+ {
+ ASSERT(uniqNums.find(isotopeData[ui][uj].massNumber) == uniqNums.end());
+ uniqNums.insert(isotopeData[ui][uj].massNumber);
+
+ }
+ }
+}
+
+bool AbundanceData::runUnitTests(const char *tableFile)
+{
+ AbundanceData massTable;
+ TEST(massTable.open(tableFile) == 0,"load table");
+ //FIXME: Getting the isotope dis
+
+ size_t ironIndex=massTable.symbolIndex("Fe");
+ TEST(ironIndex != (size_t)-1,"symbol lookup");
+
+ //Generate the mass peak dist for iron
+ vector<size_t> elements;
+ vector<size_t> concentrations;
+ elements.push_back(ironIndex);
+ concentrations.push_back(1);
+
+ std::vector<std::pair<float,float> > massDist;
+ massTable.generateIsotopeDist(elements,concentrations,massDist);
+
+ TEST(massDist.size() == 4, "Iron has 4 isotopes");
+
+ massTable.checkErrors();
+
+ return true;
+
+}
+#endif
diff --git a/src/backend/APT/abundanceParser.h b/src/backend/APT/abundanceParser.h
index 0eb2289..8111c15 100644
--- a/src/backend/APT/abundanceParser.h
+++ b/src/backend/APT/abundanceParser.h
@@ -50,7 +50,7 @@ class AbundanceData
{
enum
{
- ABUNDANCE_ERR_BAD_DOC,
+ ABUNDANCE_ERR_BAD_DOC=1,
ABUNDANCE_ERR_NO_CONTEXT,
ABUNDANCE_ERROR_BAD_VALUE,
ABUNDANCE_ERROR_FAILED_VALIDATION,
@@ -68,6 +68,9 @@ class AbundanceData
// this is esentially a lookup (isotope # -> atom #)
std::vector<size_t> atomicNumber;
+ //Check the abundance table for inconsistenceis
+ void checkErrors() const;
+
public:
//!Attempt to open the abundance data file, return 0 on success
size_t open(const char *file, bool strict=false);
@@ -94,6 +97,11 @@ class AbundanceData
void generateSingleAtomDist(size_t atomIdx, unsigned int repeatCount, std::vector<std::pair<float,float> > &massDist,size_t solutionCharge=1) const;
const ISOTOPE_DATA &isotope(size_t elementIdx, size_t isotopeIdx) const;
+
+#ifdef DEBUG
+ //Run the unit esting code
+ static bool runUnitTests(const char *tableFile);
+#endif
};
#endif
diff --git a/src/backend/APT/ionhit.cpp b/src/backend/APT/ionhit.cpp
index dcd2e59..f45f890 100644
--- a/src/backend/APT/ionhit.cpp
+++ b/src/backend/APT/ionhit.cpp
@@ -176,6 +176,12 @@ bool IonHit::hasNaN()
std::isnan(pos[1]) || std::isnan(pos[2]));
}
+bool IonHit::hasInf()
+{
+ return (std::isinf(massToCharge) || std::isinf(pos[0]) ||
+ std::isinf(pos[1]) || std::isinf(pos[2]));
+}
+
void IonHit::getCentroid(const std::vector<IonHit> &points,Point3D ¢roid)
{
centroid=Point3D(0,0,0);
diff --git a/src/backend/APT/ionhit.h b/src/backend/APT/ionhit.h
index e90947a..e8cc552 100644
--- a/src/backend/APT/ionhit.h
+++ b/src/backend/APT/ionhit.h
@@ -50,6 +50,8 @@ class IonHit
inline const Point3D &getPosRef() const {return pos;};
//returns true if any of the 4 data pts are NaN
bool hasNaN();
+ //returns true if any of the 4 data pts are +-inf
+ bool hasInf();
#ifdef __LITTLE_ENDIAN__
void switchEndian();
diff --git a/src/backend/animator.cpp b/src/backend/animator.cpp
index e69ce06..cde1f99 100644
--- a/src/backend/animator.cpp
+++ b/src/backend/animator.cpp
@@ -536,29 +536,11 @@ std::string InterpData::getInterpolatedData(const vector<pair<size_t,
//Parse the colour start and end strings
//---------
- float colStart[4];
- float colEnd[4];
+ ColourRGBA tmpCol[2];
- unsigned char r,g,b,alpha;
- ASSERT(parseColString(keyData[0].second,r,g,b,alpha));
- ASSERT(parseColString(keyData[1].second,r,g,b,alpha));
-
- parseColString(keyData[0].second,r,g,b,alpha);
- alpha=255;
-
- colStart[0] = r/255.0f;
- colStart[1] = g/255.0f;
- colStart[2] = b/255.0f;
- colStart[3] = alpha/255.0f;
-
-
- parseColString(keyData[1].second,r,g,b,alpha);
-
-
- colEnd[0] = r/255.0f;
- colEnd[1] = g/255.0f;
- colEnd[2] = b/255.0f;
- colEnd[3] = alpha/255.0f;
+
+ tmpCol[0].parse(keyData[0].second);
+ tmpCol[1].parse(keyData[1].second);
//---------
@@ -576,23 +558,11 @@ std::string InterpData::getInterpolatedData(const vector<pair<size_t,
}
//interpolate the colour value
- unsigned char colInterp[4];
- for(size_t ui=0; ui<4;ui++)
- {
- float tmp;
- tmp=(interpLinearRamp(startF,endF,frame,
- colStart[ui],colEnd[ui])*255.0f);
-
- tmp = std::min(tmp,255.0f);
- tmp=std::max(tmp,0.0f);
-
- colInterp[ui] = (unsigned char)tmp;
- }
-
- std::string s;
- genColString(colInterp[0],colInterp[1],colInterp[2],
- colInterp[3],s);
- return s;
+ ColourRGBAf interpCol;
+ float delta;
+ delta = (frame - startF )/ (endF - startF);
+ interpCol=tmpCol[0].toRGBAf().interpolate(delta,tmpCol[1].toRGBAf());
+ return interpCol.toColourRGBA().rgbaString();
}
case INTERP_LIST:
{
diff --git a/src/backend/configFile.cpp b/src/backend/configFile.cpp
index 1bdea7e..b962cdc 100644
--- a/src/backend/configFile.cpp
+++ b/src/backend/configFile.cpp
@@ -521,7 +521,7 @@ nodeptrEndJump:
bool ConfigFile::createConfigDir()
{
- wxString filePath = wxStr(getConfigDir());
+ wxString filePath = (getConfigDir());
//Create the folder if it does not exist
if(!wxDirExists(filePath))
@@ -540,14 +540,8 @@ bool ConfigFile::createConfigDir()
std::string ConfigFile::getConfigDir()
{
-#if wxCHECK_VERSION(2,9,0)
wxStandardPaths &paths = wxStandardPaths::Get();
- wxString filePath = paths.GetDocumentsDir()+wxCStr("/.")+wxCStr(PROGRAM_NAME);
-#else
- wxStandardPaths *paths = new wxStandardPaths;
- wxString filePath = paths->GetDocumentsDir()+wxCStr("/.")+wxCStr(PROGRAM_NAME);
- delete paths;
-#endif
+ wxString filePath = paths.GetDocumentsDir()+("/.")+(PROGRAM_NAME);
return stlStr(filePath);
}
diff --git a/src/backend/filter.cpp b/src/backend/filter.cpp
index fc58788..8f0f15b 100644
--- a/src/backend/filter.cpp
+++ b/src/backend/filter.cpp
@@ -17,6 +17,7 @@
*/
#include "filter.h"
+#include "plot.h"
#include "common/stringFuncs.h"
#include "common/translation.h"
@@ -42,6 +43,7 @@ bool Filter::strongRandom= false;
const char *STREAM_NAMES[] = { NTRANS("Ion"),
NTRANS("Plot"),
+ NTRANS("2D Plot"),
NTRANS("Draw"),
NTRANS("Range"),
NTRANS("Voxel")};
@@ -64,60 +66,89 @@ const char *FILTER_NAMES[] = { "posload",
"annotation"
};
-void updateFilterPropertyGrid(wxCustomPropGrid *g, const Filter *f)
+size_t numElements(const vector<const FilterStreamData *> &v, unsigned int mask)
{
+ size_t nE=0;
+ for(unsigned int ui=0;ui<v.size();ui++)
+ {
+ if((v[ui]->getStreamType() & mask))
+ nE+=v[ui]->getNumBasicObjects();
+ }
+
+ return nE;
+}
+
- ASSERT(f);
- ASSERT(g);
+template<>
+bool Filter::applyPropertyNow(bool &prop, const std::string &val, bool &needUp)
+{
+ needUp=false;
+ bool tmp;
+ if(!boolStrDec(val,tmp))
+ return false;
- FilterPropGroup p;
- f->getProperties(p);
-#ifdef DEBUG
- //If debugging, test self consistency
- p.checkConsistent();
-#endif
- g->clearKeys();
- g->setNumGroups(p.numGroups());
+ //return true, as technically, we did something OK
+ // but erasing the cache, and re-setting the value is pointless
+ if(tmp == prop)
+ return true;
+
+ prop=tmp;
+ clearCache();
+
+ needUp=true;
+ return true;
+}
+
+template<>
+bool Filter::applyPropertyNow(Point3D &prop, const std::string &val, bool &needUp)
+{
+ needUp=false;
+ Point3D newPt;
+ if(!newPt.parse(val))
+ return false;
- //Create the keys to add to the grid
- for(size_t ui=0;ui<p.numGroups();ui++)
- {
- vector<FilterProperty> propGrouping;
- p.getGroup(ui,propGrouping);
+ //return true, as technically, we did something OK
+ // but erasing the cache, and re-setting the value is pointless
+ if(newPt== prop)
+ return true;
+
+ prop=newPt;
+ clearCache();
+ needUp=true;
+ return true;
+}
- for(size_t uj=0;uj<propGrouping.size();uj++)
- {
- g->addKey(propGrouping[uj].name,ui,
- propGrouping[uj].key,
- propGrouping[uj].type,
- propGrouping[uj].data,
- propGrouping[uj].helpText);
- }
+template<>
+bool Filter::applyPropertyNow(std::string &prop, const std::string &val, bool &needUp)
+{
+ needUp=false;
- //Set the name that is to be displayed for this grouping
- // of properties
- std::string title;
- p.getGroupTitle(ui,title);
- g->setGroupName(ui,title);
- }
+ //return true, as it is technically ok that we did this
+ if(val == prop)
+ return true;
- //Let the property grid layout what it needs to
- g->propertyLayout();
+ prop=val;
+ clearCache();
+ needUp=true;
+ return true;
}
-size_t numElements(const vector<const FilterStreamData *> &v, unsigned int mask)
+void Filter::cacheAsNeeded(FilterStreamData *stream)
{
- size_t nE=0;
- for(unsigned int ui=0;ui<v.size();ui++)
+ if(cache)
{
- if((v[ui]->getStreamType() & mask))
- nE+=v[ui]->getNumBasicObjects();
+ stream->cached=1;
+ filterOutputs.push_back(stream);
+ cacheOK=true;
+ }
+ else
+ {
+ stream->cached=0;
}
-
- return nE;
}
+
#ifdef DEBUG
bool FilterProperty::checkSelfConsistent() const
{
@@ -143,8 +174,8 @@ bool FilterProperty::checkSelfConsistent() const
}
case PROPERTY_TYPE_COLOUR:
{
- unsigned char r,g,b,a;
- if(!parseColString(data,r,g,b,a))
+ ColourRGBA rgba;
+ if(!rgba.parse(data))
return false;
break;
@@ -225,6 +256,16 @@ void FilterPropGroup::getGroup(size_t targetGroup, vector<FilterProperty> &vec)
#endif
}
+bool FilterPropGroup::hasGroup(size_t targetGroup) const
+{
+ for(size_t ui=0;ui<keyGroupings.size();ui++)
+ {
+ if(keyGroupings[ui].second==targetGroup)
+ return true;
+ }
+
+ return false;
+}
void FilterPropGroup::getGroupTitle(size_t group, std::string &s) const
{
ASSERT(group < groupNames.size());
@@ -282,6 +323,12 @@ void FilterPropGroup::checkConsistent() const
//Check that the group names are the same as the number of groups
ASSERT(groupNames.size() ==groupCount);
+
+ //check that each group ahas a name
+ for(size_t ui=0;ui<groupNames.size(); ui++)
+ {
+ ASSERT(!groupNames[ui].empty())
+ }
}
#endif
@@ -320,7 +367,7 @@ void DrawStreamData::checkSelfConsistent() const
#endif
PlotStreamData::PlotStreamData() : r(1.0f),g(0.0f),b(0.0f),a(1.0f),
- plotStyle(PLOT_TRACE_LINES), logarithmic(false) , useDataLabelAsYDescriptor(true),
+ plotStyle(PLOT_LINE_LINES), logarithmic(false) , useDataLabelAsYDescriptor(true),
index((unsigned int)-1)
{
streamType=STREAM_TYPE_PLOT;
@@ -422,7 +469,7 @@ void PlotStreamData::checkSelfConsistent() const
ASSERT(!(regionID.size() && !regionParent));
//Must have valid trace style
- ASSERT(plotStyle<PLOT_TRACE_ENDOFENUM);
+ ASSERT(plotStyle<PLOT_TYPE_ENUM_END);
//Must have valid error bar style
ASSERT(errDat.mode<PLOT_ERROR_ENDOFENUM);
@@ -433,7 +480,36 @@ void PlotStreamData::checkSelfConsistent() const
}
#endif
+Plot2DStreamData::Plot2DStreamData()
+{
+ streamType=STREAM_TYPE_PLOT2D;
+}
+
+size_t Plot2DStreamData::getNumBasicObjects() const
+{
+ if(xyData.size())
+ return xyData.size();
+ else if (scatterData.size())
+ return scatterData.size();
+ else
+ ASSERT(false);
+
+ return 0;
+}
+
#ifdef DEBUG
+
+void Plot2DStreamData::checkSelfConsistent() const
+{
+ //only using scatter or xy, not both
+ ASSERT(!(xyData.empty() && scatterData.empty()));
+
+ //no intensity without data
+ if(scatterData.empty())
+ ASSERT(scatterIntensity.empty());
+
+ ASSERT(plotType < PLOT_TYPE_ENUM_END);
+}
void RangeStreamData::checkSelfConsistent() const
{
if(!rangeFile)
@@ -450,6 +526,10 @@ FilterStreamData::FilterStreamData() : parent(0),cached((unsigned int)-1)
{
}
+FilterStreamData::FilterStreamData(const Filter *theParent) : parent(theParent),cached((unsigned int)-1)
+{
+}
+
IonStreamData::IonStreamData() : representationType(ION_REPRESENT_POINTS),
r(1.0f), g(0.0f), b(0.0f), a(1.0f),
ionSize(2.0f), valueType("Mass-to-Charge (amu/e)")
@@ -457,6 +537,14 @@ IonStreamData::IonStreamData() : representationType(ION_REPRESENT_POINTS),
streamType=STREAM_TYPE_IONS;
}
+IonStreamData::IonStreamData(const Filter *f) : FilterStreamData(f), representationType(ION_REPRESENT_POINTS),
+ r(1.0f), g(0.0f), b(0.0f), a(1.0f),
+ ionSize(2.0f), valueType("Mass-to-Charge (amu/e)")
+{
+ streamType=STREAM_TYPE_IONS;
+}
+
+
void IonStreamData::clear()
{
data.clear();
@@ -505,11 +593,22 @@ VoxelStreamData::VoxelStreamData() : representationType(VOXEL_REPRESENT_POINTCLO
streamType=STREAM_TYPE_VOXEL;
}
+VoxelStreamData::VoxelStreamData(const Filter *f) : FilterStreamData(f), representationType(VOXEL_REPRESENT_POINTCLOUD),
+ r(1.0f),g(0.0f),b(0.0f),a(0.3f), splatSize(2.0f),isoLevel(0.5f)
+{
+ streamType=STREAM_TYPE_VOXEL;
+}
+
RangeStreamData::RangeStreamData() : rangeFile(0)
{
streamType = STREAM_TYPE_RANGE;
}
+RangeStreamData::RangeStreamData(const Filter *f) : FilterStreamData(f), rangeFile(0)
+{
+ streamType = STREAM_TYPE_RANGE;
+}
+
bool RangeStreamData::save(const char *filename, size_t format) const
{
return !rangeFile->write(filename,format);
@@ -517,6 +616,7 @@ bool RangeStreamData::save(const char *filename, size_t format) const
Filter::Filter() : cache(true), cacheOK(false)
{
+ COMPILE_ASSERT( THREEDEP_ARRAYSIZE(STREAM_NAMES) == NUM_STREAM_TYPES);
for(unsigned int ui=0;ui<NUM_STREAM_TYPES;ui++)
numStreamsLastRefresh[ui]=0;
}
@@ -597,7 +697,7 @@ void Filter::propagateCache(vector<const FilterStreamData *> &getOut) const
}
void Filter::propagateStreams(const vector<const FilterStreamData *> &dataIn,
- vector<const FilterStreamData *> &dataOut,size_t mask,bool invertMask) const
+ vector<const FilterStreamData *> &dataOut,size_t mask,bool invertMask)
{
//Propagate any inputs that we don't normally block
if(invertMask)
diff --git a/src/backend/filter.h b/src/backend/filter.h
index bdc09cc..81eb9cc 100644
--- a/src/backend/filter.h
+++ b/src/backend/filter.h
@@ -33,6 +33,8 @@ class RangeFileFilter;
#include "gl/drawables.h"
#include "common/voxels.h"
+#include "common/stringFuncs.h"
+#include "common/array2D.h"
//ifdef inclusion as there is some kind of symbol clash...
#ifdef ATTRIBUTE_PRINTF
@@ -45,6 +47,7 @@ class RangeFileFilter;
#endif
+#include <wx/propgrid/propgrid.h>
const unsigned int NUM_CALLBACK=50000;
@@ -79,15 +82,16 @@ extern const char *FILTER_NAMES[];
//the number of stream types that we can have.
//Current bitmask using functions are
// VisController::safeDeleteFilterList
-const unsigned int NUM_STREAM_TYPES=5;
+const unsigned int NUM_STREAM_TYPES=6;
const unsigned int STREAMTYPE_MASK_ALL= ((1<<(NUM_STREAM_TYPES)) -1 ) & 0x000000FF;
enum
{
STREAM_TYPE_IONS=1,
STREAM_TYPE_PLOT=2,
- STREAM_TYPE_DRAW=4,
- STREAM_TYPE_RANGE=8,
- STREAM_TYPE_VOXEL=16
+ STREAM_TYPE_PLOT2D=4,
+ STREAM_TYPE_DRAW=8,
+ STREAM_TYPE_RANGE=16,
+ STREAM_TYPE_VOXEL=32
};
@@ -147,14 +151,10 @@ enum
//---
//
-//Forward dec.
-class wxCustomPropGrid;
-
//!Return the number of elements in a vector of filter data - i.e. the sum of the number of objects within each stream. Only masked streams (STREAM_TYPE_*) will be counted
size_t numElements(const vector<const FilterStreamData *> &vm, unsigned int mask=STREAMTYPE_MASK_ALL);
-void updateFilterPropertyGrid(wxCustomPropGrid *g, const Filter *f);
//!Abstract base class for data types that can propagate through filter system
class FilterStreamData
@@ -171,6 +171,7 @@ class FilterStreamData
unsigned int cached;
FilterStreamData();
+ FilterStreamData(const Filter *);
virtual ~FilterStreamData() {};
virtual size_t getNumBasicObjects() const =0;
//!Returns an integer unique to the class to identify type (yes rttid...)
@@ -197,6 +198,9 @@ class FilterProperty
size_t key;
//!Property data
std::string data;
+ //!Secondary property data
+ // - eg for file, contains wildcard mask for filename
+ std::string dataSecondary;
//!name of property
std::string name;
@@ -243,6 +247,9 @@ class FilterPropGroup
//!Grab all properties from the specified group
void getGroup(size_t group, vector<FilterProperty> &groupVec) const;
+
+ //Confirm a particular group exists
+ bool hasGroup(size_t group) const;
//!Get the nth key
const FilterProperty &getNthProp(size_t nthProp) const { return properties[nthProp];};
@@ -257,6 +264,7 @@ class IonStreamData : public FilterStreamData
{
public:
IonStreamData();
+ IonStreamData(const Filter *f);
void clear();
//Sample the data vector to the specified fraction
@@ -285,6 +293,7 @@ class VoxelStreamData : public FilterStreamData
{
public:
VoxelStreamData();
+ VoxelStreamData( const Filter *f);
size_t getNumBasicObjects() const { return data.getSize();};
void clear();
@@ -302,6 +311,7 @@ class PlotStreamData : public FilterStreamData
{
public:
PlotStreamData();
+ PlotStreamData(const Filter *f);
bool save(const char *filename) const;
@@ -360,6 +370,43 @@ class PlotStreamData : public FilterStreamData
};
+//!2D Plotting data
+class Plot2DStreamData : public FilterStreamData
+{
+ public:
+ Plot2DStreamData();
+ Plot2DStreamData(const Filter *f);
+
+ //erase plot contents
+ void clear() {xyData.clear();};
+
+ size_t getNumBasicObjects() const;
+ //title for data
+ std::string dataLabel;
+ //Label for X, Y axes
+ std::string xLabel,yLabel;
+
+ unsigned int plotType;
+
+ //!Structured XY data pairs for plotting curve
+ Array2D<float> xyData;
+ //Only rqeuired for xy plots
+ float xMin,xMax,yMin,yMax;
+
+ //!Unstructured XY points
+ vector<pair<float,float> > scatterData;
+ //optional intensity data for scatter plots
+ vector<float> scatterIntensity;
+
+
+ //!Parent filter index
+ unsigned int index;
+
+#ifdef DEBUG
+ void checkSelfConsistent() const;
+#endif
+};
+
//!Drawable objects, for 3D decoration.
class DrawStreamData: public FilterStreamData
{
@@ -368,6 +415,7 @@ class DrawStreamData: public FilterStreamData
vector<DrawableObj *> drawables;
//!constructor
DrawStreamData(){ streamType=STREAM_TYPE_DRAW;};
+ DrawStreamData(const Filter *f){ streamType=STREAM_TYPE_DRAW;};
//!Destructor
~DrawStreamData();
//!Returns 0, as this does not store basic object types -- i.e. is not for data storage per se.
@@ -397,6 +445,7 @@ class RangeStreamData : public FilterStreamData
//!constructor
RangeStreamData();
+ RangeStreamData(const Filter *f);
//!Destructor
~RangeStreamData() {};
//!save the range data to a file
@@ -443,12 +492,23 @@ class Filter
bool (*callback)(bool),size_t totalDataSize=(size_t)-1);
//!Propagate the given input data to an output vector
- void propagateStreams(const vector<const FilterStreamData *> &dataIn,
- vector<const FilterStreamData *> &dataOut,size_t mask=STREAMTYPE_MASK_ALL,bool invertMask=false) const;
+ static void propagateStreams(const vector<const FilterStreamData *> &dataIn,
+ vector<const FilterStreamData *> &dataOut,size_t mask=STREAMTYPE_MASK_ALL,bool invertMask=false) ;
//!Propagate the cache into output
void propagateCache(vector<const FilterStreamData *> &dataOut) const;
+ //Set a property, without any checking of the new value
+ // -clears cache on change
+ // - and skipping if no actual change between old and new prop
+ // returns true if change applied OK.
+ template<class T>
+ bool applyPropertyNow(T &oldProp,const std::string &newVal, bool &needUp);
+
+
+ //place a stream object into the filter cache, if required
+ // does not place object into filter output - you need to do that yourself
+ void cacheAsNeeded(FilterStreamData *s);
public:
Filter() ;
virtual ~Filter();
@@ -605,6 +665,41 @@ class Filter
};
+//Template specialisations & def for applyPropertyNow
+//--
+template<>
+bool Filter::applyPropertyNow(Point3D &prop, const std::string &val, bool &needUp);
+
+template<>
+bool Filter::applyPropertyNow(bool &prop, const std::string &val, bool &needUp);
+
+template<>
+bool Filter::applyPropertyNow(std::string &prop, const std::string &val, bool &needUp);
+
+template<class T>
+bool Filter::applyPropertyNow(T &prop, const std::string &val, bool &needUp)
+{
+ // no update initially needed
+ needUp=false;
+
+ //convert to type T
+ std::string s;
+ s=stripWhite(val);
+ T tmp;
+ if(stream_cast(tmp,s))
+ return false;
+
+ //return true, as it is technically ok that we assign to self.
+ // needUp however stays false, as the property is the same.
+ if(tmp == prop)
+ return true;
+
+ prop=tmp;
+ clearCache();
+ needUp=true;
+ return true;
+}
+//--
//!Class that tracks the progress of scene updates
class ProgressData
diff --git a/src/backend/filters/algorithms/K3DTree-mk2.cpp b/src/backend/filters/algorithms/K3DTree-mk2.cpp
index 61fa062..84ca087 100644
--- a/src/backend/filters/algorithms/K3DTree-mk2.cpp
+++ b/src/backend/filters/algorithms/K3DTree-mk2.cpp
@@ -106,7 +106,7 @@ size_t K3DTreeMk2::size() const
return indexedPoints.size();
}
-bool K3DTreeMk2::build()
+bool K3DTreeMk2::build(bool wantCallback)
{
const size_t PROGRESS_REDUCE=5000;
@@ -263,7 +263,7 @@ bool K3DTreeMk2::build()
}
}
- if(!(numSeen%PROGRESS_REDUCE) && progress)
+ if(wantCallback && !(numSeen%PROGRESS_REDUCE) && progress)
{
*progress= (unsigned int)((float)numSeen/(float)nodes.size()*100.0f);
@@ -377,8 +377,10 @@ void K3DTreeMk2::dump(std::ostream &strm, size_t depth, size_t offset) const
}
size_t K3DTreeMk2::findNearestUntagged(const Point3D &searchPt,
- const BoundCube &domainCube, bool shouldTag)
+ const BoundCube &domainCube, bool shouldTag, size_t pseudoRoot)
{
+ //Tree must be built!
+ ASSERT(treeRoot < nodes.size() && maxDepth <=nodes.size())
enum { NODE_FIRST_VISIT, //First visit is when you descend the tree
NODE_SECOND_VISIT, //Second visit is when you come back from ->Left()
NODE_THIRD_VISIT // Third visit is when you come back from ->Right()
@@ -410,10 +412,16 @@ size_t K3DTreeMk2::findNearestUntagged(const Point3D &searchPt,
stackTop=0;
//Start at median of array, which is top of tree,
- //by definition
- curNode=treeRoot;
+ //by definition, unless an alternative entry point is given
+ size_t startNode;
+ if(pseudoRoot==(size_t) -1)
+ startNode=treeRoot;
+ else
+ startNode=pseudoRoot;
- //check root node
+ curNode=startNode;
+
+ //check start node
if(!nodes[curNode].tagged)
{
float tmpDistSqr;
@@ -611,7 +619,7 @@ size_t K3DTreeMk2::findNearestUntagged(const Point3D &searchPt,
//Keep going until we meet the root nde for the third time (one left, one right, one finish)
- }while(!(curNode== treeRoot && visit== NODE_THIRD_VISIT));
+ }while(!(curNode== startNode && visit== NODE_THIRD_VISIT));
if(bestPoint != (size_t) -1)
nodes[bestPoint].tagged|=shouldTag;
@@ -621,19 +629,20 @@ size_t K3DTreeMk2::findNearestUntagged(const Point3D &searchPt,
void K3DTreeMk2::getTreesInSphere(const Point3D &pt, float sqrDist, const BoundCube &domainCube,
- vector<pair<size_t,size_t> > &contigousBlocks ) const
+ vector<pair<size_t,size_t> > &contiguousBlocks ) const
{
using std::queue;
using std::pair;
using std::make_pair;
+ if(treeRoot == (size_t) -1)
+ return;
+
queue<int> nodeQueue;
queue<int> axisQueue;
queue<BoundCube> boundQueue;
queue<pair<int,int> > limitQueue;
- if(treeRoot == (size_t) -1)
- return;
nodeQueue.push(treeRoot);
@@ -662,7 +671,7 @@ void K3DTreeMk2::getTreesInSphere(const Point3D &pt, float sqrDist, const BoundC
{
//We are? Interesting. We must be a contiguous block from our lower
//to upper limits
- contigousBlocks.push_back(limitQueue.front());
+ contiguousBlocks.push_back(limitQueue.front());
}
else if(tmpCube.intersects(pt,sqrDist))
{
@@ -716,6 +725,64 @@ void K3DTreeMk2::getTreesInSphere(const Point3D &pt, float sqrDist, const BoundC
}
+size_t K3DTreeMk2::getBoxInTree(const BoundCube &box) const
+{
+ ASSERT(treeRoot !=(size_t)-1);
+
+ BoundCube curB;
+ curB=treeBounds;
+ int curNode=treeRoot;
+ int curAxis=0;
+
+ //user-supplied box can overlap tree area (and thus not contain the box, by loop test)
+ // intersect the box with the tree bounds, such that it fits
+ BoundCube subBox;
+ subBox = curB.makeUnion(box);
+
+ //If our box-to-find fits inside the current bounds,
+ // keep refining our search area
+ while(curB.contains(subBox))
+ {
+ //Check for the tree's split axis
+ float axisPosition;
+ axisPosition= indexedPoints[curNode].first[curAxis];
+ switch(box.segmentTriple(curAxis,axisPosition))
+ {
+ //query axis is below box - move lower bound up, by searching right child
+ case 0:
+ {
+ curB.setBound(curAxis, 0,axisPosition);
+ if(nodes[curNode].childRight == (size_t) -1)
+ return curNode;
+ curNode=nodes[curNode].childRight;
+ break;
+ }
+ //intersects
+ case 1:
+ //Nothing we can do any more - return current node as new pseudo-root
+ return curNode;
+ //query axis is above target box - move upper bound down, and refine along left child
+ case 2:
+ {
+ curB.setBound(curAxis,1,axisPosition);
+ if(nodes[curNode].childLeft == (size_t) -1)
+ return curNode;
+ curNode=nodes[curNode].childLeft;
+ break;
+ }
+ default:
+ ASSERT(false);
+
+ }
+
+ curAxis++;
+ curAxis%=3;
+ }
+
+
+ return curNode;
+}
+
size_t K3DTreeMk2::tagCount() const
{
size_t count=0;
@@ -742,3 +809,57 @@ void K3DTreeMk2::clearAllTags()
for(size_t ui=0;ui<nodes.size();ui++)
nodes[ui].tagged=false;
}
+
+
+#ifdef DEBUG
+
+
+
+bool K3DMk2Tests()
+{
+ vector<Point3D> pts;
+
+ K3DTreeMk2 tree;
+
+ //First test with single point
+ //--
+ pts.push_back(Point3D(0,0,0));
+ tree.resetPts(pts,false);
+
+ //build, but do not give progress
+ tree.build(false);
+
+ Point3D searchPt=Point3D(1,0,0);
+ BoundCube dummyCube;
+ tree.getBoundCube(dummyCube);
+
+ size_t resultIdx;
+
+ resultIdx=tree.findNearestUntagged(searchPt,dummyCube,false);
+ //Only one point to find - should find it
+ TEST(resultIdx == 0,"K3D Mk2, single point test");
+
+ //Get the contiguous nodes
+ BoundCube testBox;
+ testBox.setBounds(Point3D(-2,-2,-2),Point3D(2,2,2));
+
+ TEST(tree.getBoxInTree(testBox) == 0,"subtree test");
+ //---
+
+ //Now, try adding more points
+ //---
+ pts.push_back(Point3D(1,1,1));
+ pts.push_back(Point3D(1.1,0.9,0.95));
+
+ tree.resetPts(pts,false);
+ tree.build(false);
+
+ testBox.setBounds(Point3D(1.05,0.5,0.5),Point3D(1.5,1.5,1.5));
+ TEST(tree.getBoxInTree(testBox)==2,"subtree test pt2");
+ //---
+
+ return true;
+
+}
+
+#endif
diff --git a/src/backend/filters/algorithms/K3DTree-mk2.h b/src/backend/filters/algorithms/K3DTree-mk2.h
index 94f3038..1379ae7 100644
--- a/src/backend/filters/algorithms/K3DTree-mk2.h
+++ b/src/backend/filters/algorithms/K3DTree-mk2.h
@@ -103,7 +103,7 @@ class K3DTreeMk2
* previously set by "resetPts". returns false if callback returns
* false;
*/
- bool build();
+ bool build(bool wantCallback=true);
void getBoundCube(BoundCube &b);
@@ -114,9 +114,11 @@ class K3DTreeMk2
//Find the nearest "untagged" point's internal index.
- //Mark the found point as "tagged" in the tree. Returns -1 on failure (no untagged points)
+ //Mark the found point as "tagged" in the tree. Returns -1 on failure (no untagged points)
+ // optionaly, a sub-root branch of the tree can be specified, eg based upon range query,
+ // in order to speed up search
size_t findNearestUntagged(const Point3D &queryPt,
- const BoundCube &b, bool tag=true);
+ const BoundCube &b, bool tag=true,size_t pseudoRoot=(size_t)-1);
//!Get the contigous node IDs for a subset of points in the tree that are contained
@@ -128,6 +130,11 @@ class K3DTreeMk2
void getTreesInSphere(const Point3D &pt, float sqrDist, const BoundCube &domainCube,
std::vector<std::pair<size_t,size_t> > &contigousBlocks ) const;
+ //!Get the smallest contigous bounds that will contain a box.
+ // - new sub-tree root is returned.
+ // function may only be called if tree is initalised
+ size_t getBoxInTree(const BoundCube &box) const;
+
//Obtain a point from its internal index
const Point3D *getPt(size_t index) const ;
@@ -157,4 +164,10 @@ class K3DTreeMk2
void clearAllTags();
};
+
+#ifdef DEBUG
+//KD tree internal unit tests
+// - return true on OK, false on fail
+bool K3DMk2Tests();
+#endif
#endif
diff --git a/src/backend/filters/allFilter.h b/src/backend/filters/allFilter.h
index ed8a140..68f356f 100644
--- a/src/backend/filters/allFilter.h
+++ b/src/backend/filters/allFilter.h
@@ -33,7 +33,6 @@
#include "ionInfo.h"
#include "annotation.h"
-
//!Returns true if the string is a valid filter name
bool isValidFilterName(const std::string &s);
diff --git a/src/backend/filters/annotation.cpp b/src/backend/filters/annotation.cpp
index 8563a4a..6f0d4b6 100644
--- a/src/backend/filters/annotation.cpp
+++ b/src/backend/filters/annotation.cpp
@@ -76,7 +76,7 @@ const char *annotationModeStrings[] =
AnnotateFilter::AnnotateFilter() : annotationMode(ANNOTATION_TEXT),
position(Point3D(0,0,0)), target(Point3D(1,0,0)), upVec(Point3D(0,0,1)),
acrossVec(Point3D(0,1,0)), textSize(1.0f), annotateSize(1.0f),
- sphereMarkerSize(1.5f),r(0),g(0),b(1),a(1),active(true),showAngleText(true),
+ sphereMarkerSize(1.5f),rgba(0,0,1), active(true),showAngleText(true),
reflexAngle(true), angleFormatPreDecimal(0),angleFormatPostDecimal(0),
linearFixedTicks(true),linearMeasureTicks(10),linearMeasureSpacing(10.0f),
fontSizeLinearMeasure(5)
@@ -93,9 +93,6 @@ AnnotateFilter::AnnotateFilter() : annotationMode(ANNOTATION_TEXT),
annotateSize=1;
sphereMarkerSize=1.5;
- //Set the colour to default blue
- r=g=0;b=a=1.0;
-
active=true;
showAngleText=true;
@@ -129,11 +126,7 @@ Filter *AnnotateFilter::cloneUncached() const
p->annotateSize=annotateSize;
p->sphereMarkerSize=sphereMarkerSize;
- p->r=r;
- p->g=g;
- p->b=b;
- p->a=a;
-
+ p->rgba=rgba;
p->active=active;
p->showAngleText=showAngleText;
@@ -185,7 +178,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
dt->setString(annotateText);
dt->setOrigin(position);
dt->setUp(upVec);
- dt->setColour(r,g,b,a);
+ dt->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dt->setTextDir(acrossVec);
dt->setSize((unsigned int)textSize);
@@ -215,7 +208,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
dv->setOrigin(position);
dv->setVector(target-position);
dv->setArrowSize(annotateSize);
- dv->setColour(r,g,b,a);
+ dv->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dv->setLineSize(lineSize);
dv->canSelect=true;
@@ -253,7 +246,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
dS=new DrawSphere;
dS->setOrigin(anglePos[ui]);
dS->setRadius(sphereMarkerSize);
- dS->setColour(r,g,b,a);
+ dS->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dS->canSelect=true;
dS->wantsLight=true;
@@ -283,14 +276,14 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
dv=new DrawVector;
dv->setOrigin(anglePos[0]);
dv->setVector(anglePos[1]-anglePos[0]);
- dv->setColour(r,g,b,a);
+ dv->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dv->setDrawArrow(false);
d->drawables.push_back(dv);
dv=new DrawVector;
dv->setOrigin(anglePos[0]);
dv->setVector(anglePos[2]-anglePos[0]);
- dv->setColour(r,g,b,a);
+ dv->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dv->setDrawArrow(false);
d->drawables.push_back(dv);
@@ -376,7 +369,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
//Use user-specifications for colour,
//size and orientation
dt->setUp(upVec);
- dt->setColour(r,g,b,a);
+ dt->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dt->setTextDir(acrossVec);
dt->setSize((unsigned int)textSize);
@@ -391,7 +384,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
dv = new DrawVector;
dv->setOrigin(position);
- dv->setColour(r,g,b,a);
+ dv->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dv->setVector(target-position);
dv->setDrawArrow(false);
@@ -424,7 +417,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
//Create the tick that will be added to the drawables
dT = new DrawGLText(getDefaultFontFile().c_str(),FTGL_POLYGON);
- dT->setColour(r,g,b,a);
+ dT->setColour(rgba.r(),rgba.g() ,rgba.b(),rgba.a());
dT->setOrigin(measureNormal*tickSpacings[ui] + position);
dT->setUp(upVec);
dT->setTextDir(acrossVec);
@@ -446,7 +439,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
dS = new DrawSphere;
dS->setRadius(sphereMarkerSize);
dS->setOrigin(position);
- dS->setColour(r,g,b,a);
+ dS->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dS->canSelect=true;
dS->wantsLight=true;
@@ -479,7 +472,7 @@ unsigned int AnnotateFilter::refresh(const std::vector<const FilterStreamData *>
dS->setRadius(sphereMarkerSize);
dS->setOrigin(target);
- dS->setColour(r,g,b,a);
+ dS->setColour(rgba.r(),rgba.g(),rgba.b(),rgba.a());
dS->canSelect=true;
dS->wantsLight=true;
@@ -550,6 +543,7 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Type or style of annotation");
p.type=PROPERTY_TYPE_CHOICE;
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Mode"));
curGroup++;
switch(annotationMode)
@@ -617,6 +611,8 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_TARGET;
p.helpText=TRANS("3D Position to which arrow points");
propertyList.addProperty(p,curGroup);
+
+ propertyList.setGroupTitle(curGroup,TRANS("Positioning"));
curGroup++;
@@ -667,6 +663,7 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Text of annotation");
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Options"));
curGroup++;
stream_cast(tmpStr,textSize);
@@ -725,6 +722,7 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Location of second non-central vertex");
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Positioning"));
curGroup++;
stream_cast(tmpStr,acrossVec);
@@ -746,7 +744,7 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_REFLEXIVE;
p.name=TRANS("Reflexive");
- p.data=reflexAngle? "1":"0";
+ p.data=boolStrEnc(reflexAngle);
p.type=PROPERTY_TYPE_BOOL;
p.helpText=TRANS("Measure interor (enabled) or exterior angle (disabled)");
propertyList.addProperty(p,curGroup);
@@ -754,7 +752,7 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
p.name=TRANS("Show Angle");
- p.data=showAngleText? "1":"0";
+ p.data=boolStrEnc(showAngleText);
p.type=PROPERTY_TYPE_BOOL;
p.key=KEY_ANGLE_TEXT_VISIBLE;
p.helpText=TRANS("Display angle text (when enabled)");
@@ -848,11 +846,8 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Relative size of annotation text");
propertyList.addProperty(p,curGroup);
-
- if(linearFixedTicks)
- tmpStr="1";
- else
- tmpStr="0";
+
+ tmpStr=boolStrEnc(linearFixedTicks);
p.key=KEY_LINEAR_FIXED_TICKS;
p.name=TRANS("Fixed ticks");
p.data=tmpStr;
@@ -897,15 +892,13 @@ void AnnotateFilter::getProperties(FilterPropGroup &propertyList) const
}
- genColString((unsigned char)(r*255.0),(unsigned char)(g*255.0),
- (unsigned char)(b*255),(unsigned char)(a*255),tmpStr);
p.key=KEY_COLOUR;
p.name=TRANS("Colour");
- p.data=tmpStr;
+ p.data=rgba.toColourRGBA().rgbString();
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Colour for ruler and ticks");
propertyList.addProperty(p,curGroup);
-
+ propertyList.setGroupTitle(curGroup,TRANS("Appearance"));
}
bool AnnotateFilter::setProperty( unsigned int key,
@@ -916,23 +909,8 @@ bool AnnotateFilter::setProperty( unsigned int key,
{
case KEY_ENABLE:
{
- bool tmpV;
-
- if( value == "1")
- tmpV=true;
- else if(value == "0")
- tmpV=false;
- else
- {
- ASSERT(false);
+ if(!applyPropertyNow(active,value,needUpdate))
return false;
- }
-
- if(tmpV!=active)
- {
- active=tmpV;
- needUpdate=true;
- }
break;
}
case KEY_MODE:
@@ -1031,109 +1009,53 @@ bool AnnotateFilter::setProperty( unsigned int key,
}
case KEY_POSITION:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(position,value,needUpdate))
return false;
-
- if(!(position == newPt))
- {
- position=newPt;
- needUpdate=true;
- }
-
break;
}
case KEY_TARGET:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(target,value,needUpdate))
return false;
-
- if(!(target== newPt))
- {
- target=newPt;
- needUpdate=true;
- }
-
break;
}
case KEY_ANGLE_POS_ZERO:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(anglePos[0],value,needUpdate))
return false;
-
- if(!(anglePos[0]== newPt))
- {
- anglePos[0]=newPt;
- needUpdate=true;
- }
break;
}
case KEY_ANGLE_POS_ONE:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(anglePos[1],value,needUpdate))
return false;
-
- if(!(anglePos[1]== newPt))
- {
- anglePos[1]=newPt;
- needUpdate=true;
- }
break;
}
case KEY_ANGLE_POS_TWO:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(anglePos[2],value,needUpdate))
return false;
-
- if(!(anglePos[2]== newPt))
- {
- anglePos[2]=newPt;
- needUpdate=true;
- }
break;
}
case KEY_ARROW_SIZE:
{
- float tmp;
- if(stream_cast(tmp,value))
+ if(!applyPropertyNow(annotateSize,value,needUpdate))
return false;
-
- if(tmp!=annotateSize)
- {
- annotateSize=tmp;
- needUpdate=true;
- }
-
break;
}
case KEY_ANNOTATE_TEXT:
{
- if(value!=annotateText)
- {
- needUpdate=true;
- annotateText=value;
- }
-
+ if(!applyPropertyNow(annotateText,value,needUpdate))
+ return false;
break;
}
case KEY_COLOUR:
{
- unsigned char newR,newG,newB,newA;
-
- parseColString(value,newR,newG,newB,newA);
-
- if(newB != b || newR != r ||
- newG !=g || newA != a)
+ ColourRGBA tmpRgba;
+ tmpRgba.parse(value);
+ if(tmpRgba != rgba)
{
- r=(float)newR/255.0;
- g=(float)newG/255.0;
- b=(float)newB/255.0;
- a=(float)newA/255.0;
-
+ rgba = tmpRgba.toRGBAf();
needUpdate=true;
}
else
@@ -1155,41 +1077,20 @@ bool AnnotateFilter::setProperty( unsigned int key,
}
case KEY_REFLEXIVE:
{
- bool tmp;
- tmp=(value=="1");
-
- if(tmp==reflexAngle)
+ if(!applyPropertyNow(reflexAngle,value,needUpdate))
return false;
-
- reflexAngle=tmp;
-
- needUpdate=true;
break;
}
case KEY_SPHERE_ANGLE_SIZE:
{
- float tmp;
- stream_cast(tmp,value);
-
- if(tmp == sphereMarkerSize)
+ if(!applyPropertyNow(sphereMarkerSize,value,needUpdate))
return false;
-
- sphereMarkerSize=tmp;
- needUpdate=true;
-
break;
}
case KEY_ANGLE_TEXT_VISIBLE:
{
- bool tmp;
- tmp=(value=="1");
-
- if(tmp == showAngleText)
+ if(!applyPropertyNow(showAngleText,value,needUpdate))
return false;
-
- showAngleText=tmp;
- needUpdate=true;
-
break;
}
@@ -1230,60 +1131,26 @@ bool AnnotateFilter::setProperty( unsigned int key,
case KEY_LINEAR_FONTSIZE:
{
- unsigned int tmp;
- stream_cast(tmp,value);
-
- if(tmp == fontSizeLinearMeasure)
+ if(!applyPropertyNow(fontSizeLinearMeasure,value,needUpdate))
return false;
-
- fontSizeLinearMeasure=tmp;
- needUpdate=true;
break;
}
case KEY_LINEAR_FIXED_TICKS:
{
- bool tmpTicks;
-
- if(value == "0")
- tmpTicks=false;
- else if(value =="1")
- tmpTicks=true;
- else
- return false;
-
- if(tmpTicks == linearFixedTicks)
+ if(!applyPropertyNow(linearFixedTicks,value,needUpdate))
return false;
-
- needUpdate=true;
- linearFixedTicks=tmpTicks;
break;
-
}
case KEY_LINEAR_NUMTICKS:
{
- unsigned int tmp;
- if(stream_cast(tmp,value))
+ if(!applyPropertyNow(linearMeasureTicks,value,needUpdate))
return false;
-
- if(tmp == linearMeasureTicks)
- return false;
-
- linearMeasureTicks=tmp;
- needUpdate=true;
-
break;
}
case KEY_LINEAR_TICKSPACING:
{
- float tmp;
- stream_cast(tmp,value);
-
- if(tmp == linearMeasureSpacing)
+ if(!applyPropertyNow(linearMeasureSpacing,value,needUpdate))
return false;
-
- linearMeasureSpacing=tmp;
- needUpdate=true;
-
break;
}
case KEY_LINESIZE:
@@ -1339,10 +1206,7 @@ bool AnnotateFilter::writeState(std::ostream &f,unsigned int format, unsigned in
//DEPRECATE: rename this element. It has been repurposed.
f << tabs(depth+1) << "<sphereanglesize value=\""<<sphereMarkerSize<< "\"/>" << endl;
f << tabs(depth+1) << "<linesize value=\""<<lineSize<< "\"/>" << endl;
- std::string colourString;
- genColString((unsigned char)(r*255),(unsigned char)(g*255),
- (unsigned char)(b*255),(unsigned char)(a*255),colourString);
- f << tabs(depth+1) << "<colour value=\""<<colourString<< "\"/>" << endl;
+ f << tabs(depth+1) << "<colour value=\""<< rgba.toColourRGBA().rgbaString() << "\"/>" << endl;
f << tabs(depth+1) << "<active value=\""<<(active? "1" : "0")<< "\"/>" << endl;
f << tabs(depth+1) << "<showangletext value=\""<<(showAngleText ? "1" : "0")<< "\"/>" << endl;
@@ -1462,41 +1326,36 @@ bool AnnotateFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFile
return false;
if(lineSize<0.0f)
return false;
+
+ //TODO: we have a standardised parsexmlColour func, use it
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"colour","value"))
return false;
- unsigned char rc,gc,bc,ac;
- if(!parseColString(tmpStr,rc,gc,bc,ac))
+ ColourRGBA tmpRgba;
+
+ if(!tmpRgba.parse(tmpStr))
return false;
- r=(float)(rc)/255.0f;
- g=(float)(gc)/255.0f;
- b=(float)(bc)/255.0f;
- a=(float)(ac)/255.0f;
+ rgba=tmpRgba.toRGBAf();
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"active","value"))
return false;
- if(!(tmpStr=="0" || tmpStr=="1"))
+ if(!boolStrDec(tmpStr,active))
return false;
- active = (tmpStr=="1");
-
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"showangletext","value"))
return false;
- if(!(tmpStr=="0" || tmpStr=="1"))
+ if(!boolStrDec(tmpStr,showAngleText))
return false;
- showAngleText = (tmpStr=="1");
-
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"reflexangle","value"))
return false;
- if(!(tmpStr=="0" || tmpStr=="1"))
+ if(!boolStrDec(tmpStr,reflexAngle))
return false;
- reflexAngle = (tmpStr=="1");
if(!XMLGetNextElemAttrib(nodePtr,angleFormatPreDecimal,"angleformat","predecimal"))
return false;
diff --git a/src/backend/filters/annotation.h b/src/backend/filters/annotation.h
index dbed5dc..ce99959 100644
--- a/src/backend/filters/annotation.h
+++ b/src/backend/filters/annotation.h
@@ -48,7 +48,7 @@ class AnnotateFilter : public Filter
float textSize,annotateSize,sphereMarkerSize,lineSize;
//Annotation colour
- float r,g,b,a;
+ ColourRGBAf rgba;
//Disable/enable annotation
bool active;
diff --git a/src/backend/filters/boundingBox.cpp b/src/backend/filters/boundingBox.cpp
index e729479..4180090 100644
--- a/src/backend/filters/boundingBox.cpp
+++ b/src/backend/filters/boundingBox.cpp
@@ -62,8 +62,7 @@ const char *BOUND_STYLE[] =
BoundingBoxFilter::BoundingBoxFilter() : isVisible(true), boundStyle(BOUND_STYLE_TICKS),
- fixedNumTicks(true), fontSize(5), rLine(0.0f), gLine(0.0f), bLine(1.0f), aLine(1.0f),
- lineWidth(2.0f), threeDText(true)
+ fixedNumTicks(true), fontSize(5), lineColour(0,0,1.0f), lineWidth(2.0f), threeDText(true)
{
for(unsigned int ui=0;ui<3;ui++)
{
@@ -71,7 +70,6 @@ BoundingBoxFilter::BoundingBoxFilter() : isVisible(true), boundStyle(BOUND_STYLE
tickSpacing[ui]=5.0f;
}
-
cacheOK=false;
cache=false;
}
@@ -90,10 +88,6 @@ Filter *BoundingBoxFilter::cloneUncached() const
p->boundStyle=boundStyle;
- p->rLine=rLine;
- p->gLine=gLine;
- p->bLine=bLine;
- p->aLine=aLine;
p->threeDText=threeDText;
p->lineWidth=lineWidth;
@@ -119,7 +113,7 @@ void BoundingBoxFilter::drawTicks(const BoundCube &bTotal, DrawStreamData *d) co
//Add the rectangle drawable
DrawRectPrism *dP = new DrawRectPrism;
dP->setAxisAligned(bTotal);
- dP->setColour(rLine,gLine,bLine,aLine);
+ dP->setColour(lineColour.r(),lineColour.g(),lineColour.b(),lineColour.a());
dP->setLineWidth(lineWidth);
d->drawables.push_back(dP);
@@ -185,7 +179,8 @@ void BoundingBoxFilter::drawTicks(const BoundCube &bTotal, DrawStreamData *d) co
dV->setDrawArrow(false);
dV->setOrigin(tickPosition);
dV->setVector(tickVector);
- dV->setColour(rLine,gLine,bLine,aLine);
+ dV->setColour(lineColour.r(),lineColour.g(),
+ lineColour.b(), lineColour.a());
d->drawables.push_back(dV);
@@ -206,7 +201,8 @@ void BoundingBoxFilter::drawTicks(const BoundCube &bTotal, DrawStreamData *d) co
dT->setString(buffer);
dT->setSize(fontSize);
- dT->setColour(rLine,gLine,bLine,aLine);
+ dT->setColour(lineColour.r(),lineColour.g(),
+ lineColour.b(),lineColour.a());
dT->setOrigin(tickPosition + tickVector*2);
dT->setUp(Point3D(0,0,1));
dT->setTextDir(textVector);
@@ -226,7 +222,8 @@ void BoundingBoxFilter::drawTicks(const BoundCube &bTotal, DrawStreamData *d) co
//Handle "0" text value
dT->setString("0");
- dT->setColour(rLine,gLine,bLine,aLine);
+ dT->setColour(lineColour.r(),lineColour.g(),
+ lineColour.b(),lineColour.a());
dT->setSize(fontSize);
dT->setOrigin(tickOrigin+ Point3D(-1,-1,-1));
dT->setAlignment(DRAWTEXT_ALIGN_RIGHT);
@@ -241,7 +238,8 @@ void BoundingBoxFilter::drawDimension(const BoundCube &bTotal, DrawStreamData *d
//Add the rectangle drawable
DrawRectPrism *dP = new DrawRectPrism;
dP->setAxisAligned(bTotal);
- dP->setColour(rLine,gLine,bLine,aLine);
+ dP->setColour(lineColour.r(),lineColour.g(),
+ lineColour.b(),lineColour.a());
dP->setLineWidth(lineWidth);
d->drawables.push_back(dP);
@@ -288,7 +286,8 @@ void BoundingBoxFilter::drawDimension(const BoundCube &bTotal, DrawStreamData *d
DrawVector *dV;
dV= new DrawVector;
- dV->setColour(rLine,gLine,bLine,aLine);
+ dV->setColour(lineColour.r(),lineColour.g(),
+ lineColour.b(),lineColour.a());
dV->wantsLight=true;
dV->setArrowSize(maxLen*ARROW_SCALE_FACTOR);
@@ -325,7 +324,8 @@ void BoundingBoxFilter::drawDimension(const BoundCube &bTotal, DrawStreamData *d
dT->setString(buffer);
dT->setSize(fontSize);
- dT->setColour(rLine,gLine,bLine,aLine);
+ dT->setColour(lineColour.r(),lineColour.g(),
+ lineColour.b(),lineColour.a());
dT->setOrigin(centrePt[ui]);
switch(ui)
{
@@ -488,7 +488,8 @@ unsigned int BoundingBoxFilter::refresh(const std::vector<const FilterStreamData
//Add the rectangle drawable
DrawRectPrism *dP = new DrawRectPrism;
dP->setAxisAligned(bTotal);
- dP->setColour(rLine,gLine,bLine,aLine);
+ dP->setColour(lineColour.r(),lineColour.g(),
+ lineColour.b(),lineColour.a());
dP->setLineWidth(lineWidth);
d->drawables.push_back(dP);
break;
@@ -540,11 +541,12 @@ void BoundingBoxFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Box display mode");
p.key=KEY_STYLE;
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Display mode"));
+ curGroup++;
if(boundStyle == BOUND_STYLE_TICKS)
{
- curGroup++;
//Properties are X Y and Z counts on ticks
stream_cast(tmpStr,fixedNumTicks);
@@ -612,14 +614,11 @@ void BoundingBoxFilter::getProperties(FilterPropGroup &propertyList) const
}
- //Box Line properties
- curGroup++;
//Colour
- genColString((unsigned char)(rLine*255.0),(unsigned char)(gLine*255.0),
- (unsigned char)(bLine*255),(unsigned char)(aLine*255),tmpStr);
+
p.name=TRANS("Box Colour");
- p.data= tmpStr;
+ p.data= lineColour.toColourRGBA().rgbString();
p.key=KEY_LINECOLOUR;
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Colour of the bounding box");
@@ -645,8 +644,8 @@ void BoundingBoxFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Relative size for text");
propertyList.addProperty(p,curGroup);
}
- propertyList.setGroupTitle(curGroup,TRANS("Appearance"));
}
+ propertyList.setGroupTitle(curGroup,TRANS("Appearance"));
}
bool BoundingBoxFilter::setProperty( unsigned int key,
@@ -658,18 +657,8 @@ bool BoundingBoxFilter::setProperty( unsigned int key,
{
case KEY_VISIBLE:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(isVisible,value,needUpdate))
return false;
-
- bool lastVal=isVisible;
- isVisible=(stripped == "1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=isVisible)
- needUpdate=true;
break;
}
case KEY_STYLE:
@@ -700,18 +689,8 @@ bool BoundingBoxFilter::setProperty( unsigned int key,
}
case KEY_FIXEDOUT:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(fixedNumTicks,value,needUpdate))
return false;
-
- bool lastVal=fixedNumTicks;
- fixedNumTicks=(stripped=="1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=fixedNumTicks)
- needUpdate=true;
break;
}
case KEY_COUNT_X:
@@ -733,18 +712,15 @@ bool BoundingBoxFilter::setProperty( unsigned int key,
}
case KEY_LINECOLOUR:
{
- unsigned char newR,newG,newB,newA;
+ ColourRGBA newLineColour;
+ if(!newLineColour.parse(value))
+ return false;
- parseColString(value,newR,newG,newB,newA);
- if(newB != bLine || newR != rLine ||
- newG !=gLine || newA != aLine)
+ if(lineColour.toColourRGBA() != newLineColour)
needUpdate=true;
+ lineColour=newLineColour.toRGBAf();
- rLine=newR/255.0;
- gLine=newG/255.0;
- bLine=newB/255.0;
- aLine=newA/255.0;
needUpdate=true;
break;
}
@@ -779,12 +755,8 @@ bool BoundingBoxFilter::setProperty( unsigned int key,
}
case KEY_FONTSIZE:
{
- unsigned int newCount;
- if(stream_cast(newCount,value))
+ if(!applyPropertyNow(fontSize,value,needUpdate))
return false;
-
- fontSize=newCount;
- needUpdate=true;
break;
}
default:
@@ -824,8 +796,8 @@ bool BoundingBoxFilter::writeState(std::ostream &f,unsigned int format, unsigned
<< tickSpacing[1] << "\" z=\""<< tickSpacing[2] <<"\"/>" << endl;
f << tabs(depth+1) << "<linewidth value=\"" << lineWidth << "\"/>"<<endl;
f << tabs(depth+1) << "<fontsize value=\"" << fontSize << "\"/>"<<endl;
- f << tabs(depth+1) << "<colour r=\"" << rLine<< "\" g=\"" << gLine << "\" b=\"" <<bLine
- << "\" a=\"" << aLine << "\"/>" <<endl;
+ f << tabs(depth+1) << "<colour r=\"" << lineColour.r()<< "\" g=\"" << lineColour.g() << "\" b=\"" <<lineColour.b()
+ << "\" a=\"" << lineColour.a() << "\"/>" <<endl;
f << tabs(depth) << "</" <<trueName()<< ">" << endl;
break;
}
@@ -862,11 +834,7 @@ bool BoundingBoxFilter::readState(xmlNodePtr &nodePtr, const std::string &stateF
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- isVisible=false;
- else if(tmpStr == "1")
- isVisible=true;
- else
+ if(!boolStrDec(tmpStr,isVisible))
return false;
xmlFree(xmlString);
@@ -899,11 +867,7 @@ bool BoundingBoxFilter::readState(xmlNodePtr &nodePtr, const std::string &stateF
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- fixedNumTicks=false;
- else if(tmpStr == "1")
- fixedNumTicks=true;
- else
+ if(!boolStrDec(tmpStr,fixedNumTicks))
return false;
xmlFree(xmlString);
@@ -1029,8 +993,10 @@ bool BoundingBoxFilter::readState(xmlNodePtr &nodePtr, const std::string &stateF
if(XMLHelpFwdToElem(nodePtr,"colour"))
return false;
- if(!parseXMLColour(nodePtr,rLine,gLine,bLine,aLine))
+ ColourRGBAf tmpCol;
+ if(!parseXMLColour(nodePtr,tmpCol))
return false;
+ lineColour=tmpCol;
//====
return true;
diff --git a/src/backend/filters/boundingBox.h b/src/backend/filters/boundingBox.h
index 3eece80..d70f13e 100644
--- a/src/backend/filters/boundingBox.h
+++ b/src/backend/filters/boundingBox.h
@@ -40,7 +40,7 @@ class BoundingBoxFilter : public Filter
unsigned int fontSize;
//!Line colour
- float rLine,gLine,bLine,aLine;
+ ColourRGBAf lineColour;
//!Line width
float lineWidth;
//!Use 3D text?
diff --git a/src/backend/filters/clusterAnalysis.cpp b/src/backend/filters/clusterAnalysis.cpp
index a33c6ef..476056c 100644
--- a/src/backend/filters/clusterAnalysis.cpp
+++ b/src/backend/filters/clusterAnalysis.cpp
@@ -24,9 +24,9 @@
#include <queue>
-#include <gsl/gsl_linalg.h>
#include "algorithms/K3DTree-mk2.h"
+#include "backend/plot.h"
enum
@@ -44,6 +44,7 @@ enum
KEY_WANT_LOGSIZEDIST,
KEY_WANT_COMPOSITIONDIST,
KEY_WANT_CLUSTERMORPHOLOGY,
+ KEY_WANT_CLUSTERID,
KEY_NORMALISE_COMPOSITION,
KEY_CROP_SIZE,
KEY_SIZE_COUNT_BULK,
@@ -57,7 +58,8 @@ enum
{
ABORT_ERR=1,
NOCORE_ERR,
- NOBULK_ERR
+ NOBULK_ERR,
+ CLUSTER_ERR_ENUM_END
};
enum
@@ -171,7 +173,7 @@ void makeCompositionTable(const IonStreamData *i ,const RangeFile *r,
// provide the transformation vectors, so singular values only provide
// scalar information separate from the original input basis. The first value
// does *not* correspond to the "x" direction of your input, for example.
-void computeSingularValues(float *data, size_t numRows, size_t numCols,
+/*void computeSingularValues(float *data, size_t numRows, size_t numCols,
vector<float> &resultValues, vector<Point3D> &resultVectors)
{
@@ -225,7 +227,7 @@ void computeSingularValues(float *data, size_t numRows, size_t numCols,
gsl_matrix_free(newSpace);
gsl_matrix_free(m);
}
-
+*/
void ClusterAnalysisFilter::checkIonEnabled(bool &core, bool &bulk) const
{
@@ -263,7 +265,7 @@ void ClusterAnalysisFilter::buildRangeEnabledMap(const RangeStreamData *r,
ClusterAnalysisFilter::ClusterAnalysisFilter() : algorithm(CLUSTER_LINK_ERODE),
enableCoreClassify(false), coreDist(0.0f), coreKNN(1), linkDist(0.5f),
enableBulkLink(false), bulkLink(1), enableErosion(false), dErosion(0.25),
- wantCropSize(false), nMin(0),nMax(std::numeric_limits<size_t>::max()),
+ wantClusterID(false), wantCropSize(false), nMin(0),nMax(std::numeric_limits<size_t>::max()),
wantClusterSizeDist(false),logClusterSize(false),
wantClusterComposition(true),normaliseComposition(true),
wantClusterMorphology(false), haveRangeParent(false)
@@ -301,6 +303,7 @@ Filter *ClusterAnalysisFilter::cloneUncached() const
p->wantClusterComposition=wantClusterComposition;
p->normaliseComposition = normaliseComposition;
+ p->wantClusterMorphology= wantClusterMorphology;
p->haveRangeParent=false; //lets assume not, and this will be reset at ::initFilter time
@@ -441,6 +444,9 @@ void ClusterAnalysisFilter::initFilter(const std::vector<const FilterStreamData
unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStreamData *> &dataIn,
std::vector<const FilterStreamData *> &getOut, ProgressData &progress, bool (*callback)(bool))
{
+ // - cluster ID alters the mass, so we can't use this analysis
+ // at the same time
+ ASSERT(!(wantClusterID && wantClusterComposition));
//By default, copy inputs to output, unless it is an ion or range stream type.
for(unsigned int ui=0;ui<dataIn.size();ui++)
{
@@ -566,7 +572,7 @@ unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStream
return 0;
//we can't have bulk, but no core...
- ASSERT(!(haveBulk && !haveCore));
+ASSERT(!(haveBulk && !haveCore));
//-------------
@@ -632,6 +638,7 @@ unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStream
}
}
+/*
if(wantClusterMorphology)
{
//Compute the singular values for each cluster
@@ -680,7 +687,7 @@ unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStream
p->parent=this;
p->plotMode=PLOT_MODE_1D;
- p->plotStyle=PLOT_TRACE_POINTS;
+ p->plotStyle=PLOT_LINE_POINTS;
p->dataLabel=TRANS("Morphology Plot");
p->xLabel=TRANS("\\lambda_1:\\lambda_2 ratio");
p->yLabel=TRANS("\\lambda_2:\\lambda_3 ratio");
@@ -770,7 +777,7 @@ unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStream
getOut.push_back(singularVectorDraw);
}
-
+*/
//Construct the output clustered data.
IonStreamData *i = new IonStreamData;
i->parent =this;
@@ -793,6 +800,26 @@ unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStream
totalSize+=clusteredCore[ui].size();
i->data.resize(totalSize);
+ if(wantClusterID)
+ {
+
+ #pragma omp parallel
+ {
+ #pragma omp for
+ for(size_t ui=0;ui<clusteredCore.size();ui++)
+ {
+ for(size_t uj=0;uj<clusteredCore[ui].size();uj++)
+ clusteredCore[ui][uj].setMassToCharge(ui);
+ }
+
+ #pragma omp for
+ for(size_t ui=0;ui<clusteredBulk.size();ui++)
+ {
+ for(size_t uj=0;uj<clusteredBulk[ui].size();uj++)
+ clusteredBulk[ui][uj].setMassToCharge(ui);
+ }
+ }
+ }
//copy across the core and bulk ions
//into the output
@@ -805,6 +832,7 @@ unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStream
copyPos++;
}
}
+
clusteredCore.clear();
for(size_t ui=0;ui<clusteredBulk.size();ui++)
@@ -823,19 +851,12 @@ unsigned int ClusterAnalysisFilter::refresh(const std::vector<const FilterStream
i->b=0.5f;
i->a=1.0f;
- //Save the ion stream data.
- if(cache)
- {
- i->cached=1;
- filterOutputs.push_back(i);
- cacheOK=true;
- }
- else
- i->cached=0;
+ cacheAsNeeded(i);
getOut.push_back(i);
+ //Run cluster composition if it is wanted.
if(wantClusterComposition)
{
ASSERT(r);
@@ -892,23 +913,28 @@ void ClusterAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
{
FilterProperty p;
size_t curGroup=0;
-
string tmpStr;
- vector<pair<unsigned int,string> > choices;
- tmpStr=TRANS("Core Link + Erode");
- choices.push_back(make_pair((unsigned int)CLUSTER_LINK_ERODE,tmpStr));
-
- tmpStr= choiceString(choices,algorithm);
- p.name=TRANS("Algorithm");
- p.data=tmpStr;
- choices.clear();
- p.type=PROPERTY_TYPE_CHOICE;
- p.helpText=TRANS("Cluster algorithm mode");
- p.key=KEY_CLUSTERANALYSIS_ALGORITHM;
- propertyList.addProperty(p,curGroup);
-
- curGroup++;
-
+
+ //Don't show options if there is only one algorithm
+ if(CLUSTER_ALGORITHM_ENUM_END > 1)
+ {
+ vector<pair<unsigned int,string> > choices;
+ tmpStr=TRANS("Core Link + Erode");
+ choices.push_back(make_pair((unsigned int)CLUSTER_LINK_ERODE,tmpStr));
+
+ tmpStr= choiceString(choices,algorithm);
+ p.name=TRANS("Algorithm");
+ p.data=tmpStr;
+ choices.clear();
+ p.type=PROPERTY_TYPE_CHOICE;
+ p.helpText=TRANS("Cluster algorithm mode");
+ p.key=KEY_CLUSTERANALYSIS_ALGORITHM;
+ propertyList.addProperty(p,curGroup);
+
+ propertyList.setGroupTitle(curGroup,TRANS("Algorithm"));
+ curGroup++;
+ }
+
if(algorithm == CLUSTER_LINK_ERODE)
{
@@ -1041,26 +1067,38 @@ void ClusterAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_WANT_CLUSTERMORPHOLOGY;
propertyList.addProperty(p,curGroup);
*/
- tmpStr=boolStrEnc(wantClusterComposition);
- p.name=TRANS("Chemistry Dist.");
+
+
+ tmpStr=boolStrEnc(wantClusterID);
+ p.name=TRANS("Cluster Id");
p.data=tmpStr;
p.type=PROPERTY_TYPE_BOOL;
- p.helpText=TRANS("Create a plot showing chemistry for each cluster size");
- p.key=KEY_WANT_COMPOSITIONDIST;
+ p.helpText=TRANS("Assign cluster output a unique per-cluster value (id).");
+ p.key=KEY_WANT_CLUSTERID;
propertyList.addProperty(p,curGroup);
-
- if(wantClusterComposition)
- {
- tmpStr=boolStrEnc(normaliseComposition);
- p.name=TRANS("Normalise");
+
+ if(!wantClusterID)
+ {
+ tmpStr=boolStrEnc(wantClusterComposition);
+ p.name=TRANS("Chemistry Dist.");
p.data=tmpStr;
p.type=PROPERTY_TYPE_BOOL;
- p.helpText=TRANS("Convert cluster counts to composition");
- p.key=KEY_NORMALISE_COMPOSITION;
+ p.helpText=TRANS("Create a plot showing chemistry for each cluster size");
+ p.key=KEY_WANT_COMPOSITIONDIST;
propertyList.addProperty(p,curGroup);
+
+ if(wantClusterComposition)
+ {
+ tmpStr=boolStrEnc(normaliseComposition);
+ p.name=TRANS("Normalise");
+ p.data=tmpStr;
+ p.type=PROPERTY_TYPE_BOOL;
+ p.helpText=TRANS("Convert cluster counts to composition");
+ p.key=KEY_NORMALISE_COMPOSITION;
+ propertyList.addProperty(p,curGroup);
+ }
}
-
propertyList.setGroupTitle(curGroup,TRANS("Postprocess"));
curGroup++;
@@ -1133,18 +1171,8 @@ bool ClusterAnalysisFilter::setProperty(unsigned int key,
}
case KEY_CORECLASSIFY_ENABLE:
{
- string stripped=stripWhite(value);
-
- bool newVal;
- if(!boolStrDec(stripped,newVal))
+ if(!applyPropertyNow(enableCoreClassify,value,needUpdate))
return false;
-
- if(newVal!=enableCoreClassify)
- {
- enableCoreClassify=newVal;
- clearCache();
- needUpdate=true;
- }
break;
}
case KEY_CORECLASSIFYDIST:
@@ -1194,18 +1222,8 @@ bool ClusterAnalysisFilter::setProperty(unsigned int key,
}
case KEY_BULKLINK_ENABLE:
{
- string stripped=stripWhite(value);
-
- bool newVal;
- if(!boolStrDec(stripped,newVal))
+ if(!applyPropertyNow(enableBulkLink,value,needUpdate))
return false;
-
- if(newVal!=enableBulkLink)
- {
- enableBulkLink=newVal;
- clearCache();
- needUpdate=true;
- }
break;
}
case KEY_BULKLINK:
@@ -1225,18 +1243,8 @@ bool ClusterAnalysisFilter::setProperty(unsigned int key,
}
case KEY_ERODE_ENABLE:
{
- string stripped=stripWhite(value);
-
- bool newVal;
- if(!boolStrDec(stripped,newVal))
+ if(!applyPropertyNow(enableErosion,value,needUpdate))
return false;
-
- if(newVal!=enableErosion)
- {
- enableErosion=newVal;
- clearCache();
- needUpdate=true;
- }
break;
}
case KEY_ERODEDIST:
@@ -1418,27 +1426,17 @@ bool ClusterAnalysisFilter::setProperty(unsigned int key,
needUpdate=true;
clearCache();
}
+
+ //composition analysis is mutually
+ // exclsive with ID
+ wantClusterID=false;
break;
}
case KEY_CROP_SIZE:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(wantCropSize,value,needUpdate))
return false;
-
- bool lastVal=wantCropSize;
- wantCropSize=(stripped == "1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=wantCropSize)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_CROP_NMIN:
@@ -1476,21 +1474,17 @@ bool ClusterAnalysisFilter::setProperty(unsigned int key,
}
case KEY_WANT_CLUSTERMORPHOLOGY:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(wantClusterMorphology,value,needUpdate))
+ return false;
+ break;
+ }
+ case KEY_WANT_CLUSTERID:
+ {
+ if(!applyPropertyNow(wantClusterID,value,needUpdate))
return false;
- bool lastVal=wantClusterMorphology;
- wantClusterMorphology=(stripped=="1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=wantClusterMorphology)
- {
- needUpdate=true;
- clearCache();
- }
+ //composition & id are mutually exclusive
+ wantClusterComposition=false;
break;
}
@@ -1575,17 +1569,18 @@ bool ClusterAnalysisFilter::writeState(std::ostream &f,unsigned int format,
f << tabs(depth+1) << "<derosion value=\""<<dErosion<< "\" enabled=\"" << boolStrEnc(enableErosion) << "\"/>" << endl;
//Cropping control
- f << tabs(depth+1) << "<wantcropsize value=\""<<wantCropSize<< "\"/>" << endl;
+ f << tabs(depth+1) << "<wantcropsize value=\""<<boolStrEnc(wantCropSize)<< "\"/>" << endl;
f << tabs(depth+1) << "<nmin value=\""<<nMin<< "\"/>" << endl;
f << tabs(depth+1) << "<nmax value=\""<<nMax<< "\"/>" << endl;
//Postprocessing
- f << tabs(depth+1) << "<wantclustersizedist value=\""<<wantClusterSizeDist<< "\" logarithmic=\"" <<
+ f << tabs(depth+1) << "<wantclustersizedist value=\""<<boolStrEnc(wantClusterSizeDist)<< "\" logarithmic=\"" <<
logClusterSize << "\"/>" << endl;
- f << tabs(depth+1) << "<wantclustercomposition value=\"" <<wantClusterComposition<< "\" normalise=\"" <<
+ f << tabs(depth+1) << "<wantclustercomposition value=\"" <<boolStrEnc(wantClusterComposition)<< "\" normalise=\"" <<
normaliseComposition<< "\"/>" << endl;
- f << tabs(depth+1) << "<wantclustermorphology value=\"" <<wantClusterMorphology << "\"/>" << endl;
+ f << tabs(depth+1) << "<wantclustermorphology value=\"" <<boolStrEnc(wantClusterMorphology) << "\"/>" << endl;
+ f << tabs(depth+1) << "<wantclusterid value=\"" <<boolStrEnc(wantClusterID)<< "\"/>" << endl;
f << tabs(depth+1) << "<enabledions>" << endl;
@@ -1721,6 +1716,17 @@ bool ClusterAnalysisFilter::readState(xmlNodePtr &nodePtr, const std::string &pa
nodePtr=tmpPtr;
if(!XMLGetNextElemAttrib(nodePtr,wantClusterMorphology,"wantclustermorphology","value"))
return false;
+
+ nodePtr=tmpPtr;
+ if(!XMLGetNextElemAttrib(nodePtr,wantClusterID,"wantclustermorphology","value"))
+ {
+ //COMPAT_BREAK: compat fix, 0.0.16.
+ wantClusterID=false;
+ }
+ else
+ {
+ wantClusterComposition=false;
+ }
//===
@@ -1797,17 +1803,15 @@ unsigned int ClusterAnalysisFilter::getRefreshUseMask() const
std::string ClusterAnalysisFilter::getErrString(unsigned int i) const
{
- switch(i)
- {
- case ABORT_ERR:
- return std::string(TRANS("Clustering aborted"));
- case NOCORE_ERR:
- return std::string(TRANS("No core ions for cluster"));
- case NOBULK_ERR:
- return std::string(TRANS("No bulk ions for cluster"));
- default:
- ASSERT(false);
- }
+ const char *errStrs[] = {"",
+ "Clustering aborted",
+ "No core ions for cluster",
+ "No bulk ions for cluster" };
+
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == CLUSTER_ERR_ENUM_END );
+ ASSERT(i < CLUSTER_ERR_ENUM_END);
+
+ return errStrs[i];
}
void ClusterAnalysisFilter::setPropFromBinding(const SelectionBinding &b)
@@ -2672,7 +2676,7 @@ PlotStreamData* ClusterAnalysisFilter::clusterSizeDistribution(const vector<vect
dist->dataLabel=SIZE_DIST_DATALABEL;
dist->logarithmic=logClusterSize;
- dist->plotStyle=PLOT_TRACE_STEM;
+ dist->plotStyle=PLOT_LINE_STEM;
dist->plotMode=PLOT_MODE_1D;
dist->xyData.resize(countMap.size());
std::copy(countMap.begin(),countMap.end(),dist->xyData.begin());
@@ -2879,7 +2883,7 @@ void ClusterAnalysisFilter::genCompositionVersusSize(const vector<vector<IonHit>
p->dataLabel=string(CHEM_DIST_DATALABEL) + string(":") + rng->getName(ui);
p->logarithmic=logClusterSize && !normaliseComposition;
- p->plotStyle=PLOT_TRACE_STEM;
+ p->plotStyle=PLOT_LINE_STEM;
p->xyData.resize(countMap.size());
@@ -2909,6 +2913,7 @@ void ClusterAnalysisFilter::genCompositionVersusSize(const vector<vector<IonHit>
}
+/*
void ClusterAnalysisFilter::getSingularValues(const vector<vector<IonHit> > &clusteredCore,
const vector<vector<IonHit> > &clusteredBulk, vector<vector<float> > &singularValues,
vector<std::pair<Point3D,vector<Point3D> > > &singularVectors) const
@@ -2988,8 +2993,8 @@ void ClusterAnalysisFilter::getSingularValues(const vector<vector<IonHit> > &clu
//Cmpute the DIMENSION-D singular value decomposition for
//this vector set
- computeSingularValues(data,numEntries,
- DIMENSION,curSingularVals,curSingularBases);
+// computeSingularValues(data,numEntries,
+// DIMENSION,curSingularVals,curSingularBases);
#pragma omp critical
{
@@ -3063,7 +3068,7 @@ void ClusterAnalysisFilter::getSingularValues(const vector<vector<IonHit> > &clu
if(data)
delete[] data;
}
-
+*/
#ifdef DEBUG
diff --git a/src/backend/filters/clusterAnalysis.h b/src/backend/filters/clusterAnalysis.h
index 7bc42bf..266bdff 100644
--- a/src/backend/filters/clusterAnalysis.h
+++ b/src/backend/filters/clusterAnalysis.h
@@ -50,6 +50,9 @@ class ClusterAnalysisFilter : public Filter
bool enableErosion;
//Erosion distance for bulk from nonclustered bulk
float dErosion;
+
+ //convert clusters mass to an ID #?
+ bool wantClusterID;
//---
//post processing options
diff --git a/src/backend/filters/compositionProfile.cpp b/src/backend/filters/compositionProfile.cpp
index 684331f..f0b7c75 100644
--- a/src/backend/filters/compositionProfile.cpp
+++ b/src/backend/filters/compositionProfile.cpp
@@ -35,7 +35,8 @@ enum
{
ERR_NUMBINS=1,
ERR_MEMALLOC,
- ERR_ABORT
+ ERR_ABORT,
+ ERR_COMP_ENUM_END
};
const char *PRIMITIVE_NAME[]={
@@ -50,7 +51,7 @@ const unsigned int MINEVENTS_DEFAULT =10;
CompositionProfileFilter::CompositionProfileFilter() : primitiveType(PRIMITIVE_CYLINDER),
showPrimitive(true), lockAxisMag(false),normalise(true), fixedBins(0),
- nBins(1000), binWidth(0.5f), minEvents(MINEVENTS_DEFAULT), r(0.0f),g(0.0f),b(1.0f),a(1.0f), plotStyle(0)
+ nBins(1000), binWidth(0.5f), minEvents(MINEVENTS_DEFAULT), rgba(0,0,1), plotStyle(0)
{
COMPILE_ASSERT(THREEDEP_ARRAYSIZE(PRIMITIVE_NAME) == PRIMITIVE_END);
@@ -78,7 +79,12 @@ void CompositionProfileFilter::binIon(unsigned int targetBin, const RangeStreamD
//that makes the target bin equate to the table size.
//disallow this.
if(targetBin < frequencyTable[0].size())
- frequencyTable[0][targetBin]++;
+ {
+ vector<size_t>::iterator it;
+ it=frequencyTable[0].begin()+targetBin;
+ #pragma omp critical
+ (*it)++;
+ }
return;
}
@@ -92,7 +98,10 @@ void CompositionProfileFilter::binIon(unsigned int targetBin, const RangeStreamD
unsigned int ionID=rng->rangeFile->getIonID(rangeID);
unsigned int pos;
pos = ionIDMapping.find(ionID)->second;
- frequencyTable[pos][targetBin]++;
+ vector<size_t>::iterator it;
+ it=frequencyTable[pos].begin()+targetBin;
+ #pragma omp critical
+ (*it)++;
}
}
@@ -112,13 +121,10 @@ Filter *CompositionProfileFilter::cloneUncached() const
p->normalise=normalise;
p->fixedBins=fixedBins;
p->lockAxisMag=lockAxisMag;
-
+
+ p->rgba=rgba;
p->binWidth=binWidth;
p->nBins = nBins;
- p->r=r;
- p->g=g;
- p->b=b;
- p->a=a;
p->plotStyle=plotStyle;
p->errMode=errMode;
//We are copying wether to cache or not,
@@ -406,12 +412,22 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
{
case STREAM_TYPE_IONS:
{
+ const IonStreamData *dIon = (const IonStreamData*)dataIn[ui];
+#ifdef _OPENMP
+ bool spin=false;
+#endif
//Process ion streams
- for(vector<IonHit>::const_iterator it=((const IonStreamData *)dataIn[ui])->data.begin();
- it!=((const IonStreamData *)dataIn[ui])->data.end(); ++it)
+
+ size_t nIons=dIon->data.size();
+ #pragma omp parallel for
+ for(size_t uj=0;uj<nIons;uj++)
{
+#ifdef _OPENMP
+ //if parallelised, abort computaiton
+ if(spin) continue;
+#endif
unsigned int targetBin;
- targetBin=dataMapping.mapIon1D(*it);
+ targetBin=dataMapping.mapIon1D(dIon->data[uj]);
//Keep ion if inside cylinder
if(targetBin!=(unsigned int)-1)
@@ -419,9 +435,13 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
//Push data into the correct bin.
// based upon eg ranging information and target 1D bin
binIon(targetBin,rngData,ionIDMapping,ionFrequencies,
- it->getMassToCharge());
+ dIon->data[uj].getMassToCharge());
}
+#ifdef _OPENMP
+ if(omp_get_thread_num() == 0)
+ {
+#endif
//update progress every CALLBACK ions
if(!curProg--)
{
@@ -429,9 +449,23 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
progress.filterProgress= (unsigned int)((float)(n)/((float)totalSize)*100.0f);
curProg=NUM_CALLBACK;
if(!(*callback)(false))
+ {
+ #ifdef _OPENMP
+ spin=true;
+ #else
return ERR_ABORT;
+ #endif
+ }
+ }
+#ifdef _OPENMP
}
+#endif
}
+
+#ifdef _OPENMP
+ if(spin)
+ return ERR_ABORT;
+#endif
break;
}
@@ -457,7 +491,6 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
normalisationFactor.resize(ionFrequencies[0].size());
normalisationCount.resize(ionFrequencies[0].size());
bool needNormalise=false;
- bool needNormaliseCount=false;
//Perform the appropriate normalisation
if(!rngData && normalise)
@@ -503,7 +536,6 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
// the loops' nesting is reversed as we need to sum over distinct plots
//Density profiles (non-ranged plots) have a fixed normalisation factor
needNormalise=true;
- needNormaliseCount = true; // we also need to have at least one count to normalise
for(unsigned int uj=0;uj<ionFrequencies[0].size(); uj++)
{
@@ -571,10 +603,10 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
//If it only has one component, then
//it's not really a composition profile is it?
plotData[ui]->dataLabel= TRANS("Freq. Profile");
- plotData[ui]->r = r;
- plotData[ui]->g = g;
- plotData[ui]->b = b;
- plotData[ui]->a = a;
+ plotData[ui]->r = rgba.r();
+ plotData[ui]->g = rgba.g();
+ plotData[ui]->b = rgba.b();
+ plotData[ui]->a = rgba.a();
}
plotData[ui]->xyData.reserve(ionFrequencies[ui].size());
@@ -585,6 +617,10 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
{
float xPos;
xPos = (((float)uj+0.5f)/(float)ionFrequencies[ui].size())*length;
+
+ if(ionFrequencies[ui][uj] < minEvents)
+ continue;
+
//Recompute normalisation value for this bin, if needed
if(needNormalise)
{
@@ -592,12 +628,9 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
//keep the data if we are not using minimum threshold for normalisation, or we met the
// threhsold
- if(!needNormaliseCount || normalisationCount[uj] > minEvents)
- {
- plotData[ui]->xyData.push_back(
- std::make_pair(xPos,
- normFactor*(float)ionFrequencies[ui][uj]));
- }
+ plotData[ui]->xyData.push_back(
+ std::make_pair(xPos,
+ normFactor*(float)ionFrequencies[ui][uj]));
}
else
{
@@ -608,13 +641,6 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
- if(cache)
- {
- plotData[ui]->cached=1;
- filterOutputs.push_back(plotData[ui]);
- }
- else
- plotData[ui]->cached=0;
plotData[ui]->plotStyle = plotStyle;
plotData[ui]->plotMode=PLOT_MODE_1D;
@@ -623,11 +649,14 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
// otherwise, trash the plot info
if(plotData[ui]->xyData.size())
{
- cacheOK=cache;
+ cacheAsNeeded(plotData[ui]);
getOut.push_back(plotData[ui]);
}
else
+ {
+ consoleOutput.push_back(TRANS("No data remained in profile - cannot display result"));
delete plotData[ui];
+ }
}
return 0;
@@ -635,16 +664,15 @@ unsigned int CompositionProfileFilter::refresh(const std::vector<const FilterStr
std::string CompositionProfileFilter::getErrString(unsigned int code) const
{
- switch(code)
- {
- case ERR_NUMBINS:
- return std::string(TRANS("Too many bins in comp. profile."));
- case ERR_MEMALLOC:
- return std::string(TRANS("Not enough memory for comp. profile."));
- case ERR_ABORT:
- return std::string(TRANS("Aborted composition prof."));
- }
- return std::string("BUG: (CompositionProfileFilter::getErrString) Shouldn't see this!");
+ const char *errCodes[] = { "",
+ "Too many bins in comp. profile.",
+ "Not enough memory for comp. profile.",
+ "Aborted composition prof." };
+
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errCodes) == ERR_COMP_ENUM_END);
+ ASSERT(code < ERR_COMP_ENUM_END);
+
+ return errCodes[code];
}
bool CompositionProfileFilter::setProperty( unsigned int key,
@@ -670,24 +698,8 @@ bool CompositionProfileFilter::setProperty( unsigned int key,
}
case COMPOSITION_KEY_FIXEDBINS:
{
- unsigned int valueInt;
- if(stream_cast(valueInt,value))
+ if(!applyPropertyNow(fixedBins,value,needUpdate))
return false;
-
- if(valueInt ==0 || valueInt == 1)
- {
- if(fixedBins!= (bool)valueInt)
- {
- needUpdate=true;
- fixedBins=valueInt;
- }
- else
- needUpdate=false;
- }
- else
- return false;
- clearCache();
- needUpdate=true;
break;
}
case COMPOSITION_KEY_NORMAL:
@@ -718,24 +730,10 @@ bool CompositionProfileFilter::setProperty( unsigned int key,
}
case COMPOSITION_KEY_MINEVENTS:
{
- unsigned int valueInt;
- if(stream_cast(valueInt,value))
+ if(!applyPropertyNow(minEvents,value,needUpdate))
return false;
-
- if(minEvents!= valueInt)
- {
- needUpdate=true;
- minEvents=valueInt;
- }
- else
- needUpdate=false;
-
- clearCache();
- needUpdate=true;
break;
}
-
-
case COMPOSITION_KEY_NUMBINS:
{
unsigned int newNumBins;
@@ -754,17 +752,8 @@ bool CompositionProfileFilter::setProperty( unsigned int key,
}
case COMPOSITION_KEY_ORIGIN:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(vectorParams[0],value,needUpdate))
return false;
-
- if(!(vectorParams[0] == newPt ))
- {
- vectorParams[0] = newPt;
- needUpdate=true;
- clearCache();
- }
-
return true;
}
case COMPOSITION_KEY_PRIMITIVETYPE:
@@ -854,67 +843,29 @@ bool CompositionProfileFilter::setProperty( unsigned int key,
}
case COMPOSITION_KEY_SHOWPRIMITIVE:
{
- unsigned int valueInt;
- if(stream_cast(valueInt,value))
+ if(!applyPropertyNow(showPrimitive,value,needUpdate))
return false;
-
- if(valueInt ==0 || valueInt == 1)
- {
- if(showPrimitive!= (bool)valueInt)
- {
- needUpdate=true;
- showPrimitive=valueInt;
- }
- else
- needUpdate=false;
- }
- else
- return false;
break;
}
-
case COMPOSITION_KEY_NORMALISE:
{
- unsigned int valueInt;
- if(stream_cast(valueInt,value))
- return false;
-
- if(!(valueInt ==0 || valueInt == 1))
+ if(!applyPropertyNow(normalise,value,needUpdate))
return false;
-
- if(normalise!= (bool)valueInt)
- {
- needUpdate=true;
- normalise=valueInt;
- }
- else
- needUpdate=false;
-
- clearCache();
- needUpdate=true;
break;
}
case COMPOSITION_KEY_LOCKAXISMAG:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(lockAxisMag,value,needUpdate))
return false;
-
- lockAxisMag=(stripped=="1");
-
- needUpdate=true;
-
break;
}
-
case COMPOSITION_KEY_PLOTTYPE:
{
unsigned int tmpPlotType;
tmpPlotType=plotID(value);
- if(tmpPlotType >= PLOT_TRACE_ENDOFENUM)
+ if(tmpPlotType >= PLOT_LINE_NONE)
return false;
plotStyle = tmpPlotType;
@@ -923,14 +874,11 @@ bool CompositionProfileFilter::setProperty( unsigned int key,
}
case COMPOSITION_KEY_COLOUR:
{
- unsigned char newR,newG,newB,newA;
- parseColString(value,newR,newG,newB,newA);
-
- r=((float)newR)/255.0f;
- g=((float)newG)/255.0f;
- b=((float)newB)/255.0f;
- a=1.0;
-
+ ColourRGBA tmpRgba;
+ if(!tmpRgba.parse(value))
+ return false;
+
+ rgba=tmpRgba.toRGBAf();
needUpdate=true;
break;
}
@@ -992,6 +940,7 @@ void CompositionProfileFilter::getProperties(FilterPropGroup &propertyList) cons
p.type=PROPERTY_TYPE_CHOICE;
p.helpText=TRANS("Basic shape to use for profile");
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Primitive"));
curGroup++;
}
@@ -1026,10 +975,7 @@ void CompositionProfileFilter::getProperties(FilterPropGroup &propertyList) cons
p.helpText=TRANS("Vector between ends of cylinder");
propertyList.addProperty(p,curGroup);
- if(lockAxisMag)
- str="1";
- else
- str="0";
+ str=boolStrEnc(lockAxisMag);
p.key=COMPOSITION_KEY_LOCKAXISMAG;
p.name=TRANS("Lock Axis Mag.");
p.data= str;
@@ -1119,6 +1065,7 @@ void CompositionProfileFilter::getProperties(FilterPropGroup &propertyList) cons
p.helpText=TRANS("Drop data that does not have this many events");
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Settings"));
@@ -1130,14 +1077,14 @@ void CompositionProfileFilter::getProperties(FilterPropGroup &propertyList) cons
vector<pair<unsigned int,string> > choices;
- tmpStr=plotString(PLOT_TRACE_LINES);
- choices.push_back(make_pair((unsigned int) PLOT_TRACE_LINES,tmpStr));
- tmpStr=plotString(PLOT_TRACE_BARS);
- choices.push_back(make_pair((unsigned int)PLOT_TRACE_BARS,tmpStr));
- tmpStr=plotString(PLOT_TRACE_STEPS);
- choices.push_back(make_pair((unsigned int)PLOT_TRACE_STEPS,tmpStr));
- tmpStr=plotString(PLOT_TRACE_STEM);
- choices.push_back(make_pair((unsigned int)PLOT_TRACE_STEM,tmpStr));
+ tmpStr=plotString(PLOT_LINE_LINES);
+ choices.push_back(make_pair((unsigned int) PLOT_LINE_LINES,tmpStr));
+ tmpStr=plotString(PLOT_LINE_BARS);
+ choices.push_back(make_pair((unsigned int)PLOT_LINE_BARS,tmpStr));
+ tmpStr=plotString(PLOT_LINE_STEPS);
+ choices.push_back(make_pair((unsigned int)PLOT_LINE_STEPS,tmpStr));
+ tmpStr=plotString(PLOT_LINE_STEM);
+ choices.push_back(make_pair((unsigned int)PLOT_LINE_STEM,tmpStr));
tmpStr= choiceString(choices,plotStyle);
p.name=TRANS("Plot Type");
@@ -1149,12 +1096,9 @@ void CompositionProfileFilter::getProperties(FilterPropGroup &propertyList) cons
//Convert the colour to a hex string
if(!haveRangeParent)
{
- string thisCol;
- genColString((unsigned char)(r*255.0),(unsigned char)(g*255.0),
- (unsigned char)(b*255.0),(unsigned char)(a*255.0),thisCol);
p.name=TRANS("Colour");
- p.data=thisCol;
+ p.data=rgba.toColourRGBA().rgbString();
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Colour of plot");
p.key=COMPOSITION_KEY_COLOUR;
@@ -1281,8 +1225,8 @@ bool CompositionProfileFilter::writeState(std::ostream &f,unsigned int format, u
f << tabs(depth+1) << "<fixedbins value=\"" << (int)fixedBins << "\"/>" << endl;
f << tabs(depth+1) << "<nbins value=\"" << nBins << "\"/>" << endl;
f << tabs(depth+1) << "<binwidth value=\"" << binWidth << "\"/>" << endl;
- f << tabs(depth+1) << "<colour r=\"" << r<< "\" g=\"" << g << "\" b=\"" <<b
- << "\" a=\"" << a << "\"/>" <<endl;
+ f << tabs(depth+1) << "<colour r=\"" << rgba.r() << "\" g=\"" << rgba.g() << "\" b=\"" << rgba.b()
+ << "\" a=\"" << rgba.a() << "\"/>" <<endl;
f << tabs(depth+1) << "<plottype value=\"" << plotStyle << "\"/>" << endl;
f << tabs(depth) << "</" << trueName() << ">" << endl;
@@ -1350,11 +1294,7 @@ bool CompositionProfileFilter::readState(xmlNodePtr &nodePtr, const std::string
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- showPrimitive=false;
- else if(tmpStr == "1")
- showPrimitive=true;
- else
+ if(!boolStrDec(tmpStr,showPrimitive))
return false;
xmlFree(xmlString);
@@ -1370,11 +1310,7 @@ bool CompositionProfileFilter::readState(xmlNodePtr &nodePtr, const std::string
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- lockAxisMag=false;
- else if(tmpStr == "1")
- lockAxisMag=true;
- else
+ if(!boolStrDec(tmpStr,lockAxisMag))
return false;
xmlFree(xmlString);
@@ -1485,11 +1421,8 @@ bool CompositionProfileFilter::readState(xmlNodePtr &nodePtr, const std::string
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- normalise=false;
- else if(tmpStr == "1")
- normalise=true;
- else
+
+ if(!boolStrDec(tmpStr,normalise))
return false;
xmlFree(xmlString);
@@ -1505,11 +1438,7 @@ bool CompositionProfileFilter::readState(xmlNodePtr &nodePtr, const std::string
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- fixedBins=false;
- else if(tmpStr == "1")
- fixedBins=true;
- else
+ if(!boolStrDec(tmpStr,fixedBins))
return false;
@@ -1553,7 +1482,7 @@ bool CompositionProfileFilter::readState(xmlNodePtr &nodePtr, const std::string
//====
if(XMLHelpFwdToElem(nodePtr,"colour"))
return false;
- if(!parseXMLColour(nodePtr,r,g,b,a))
+ if(!parseXMLColour(nodePtr,rgba))
return false;
//====
@@ -1571,7 +1500,7 @@ bool CompositionProfileFilter::readState(xmlNodePtr &nodePtr, const std::string
if(stream_cast(plotStyle,tmpStr))
return false;
- if(plotStyle >= PLOT_TRACE_ENDOFENUM)
+ if(plotStyle >= PLOT_LINE_NONE)
return false;
xmlFree(xmlString);
//====
@@ -1710,6 +1639,7 @@ bool testCompositionCylinder()
bool needUp; std::string s;
stream_cast(s,Point3D((startPt+endPt)*0.5f));
TEST(f->setProperty(COMPOSITION_KEY_ORIGIN,s,needUp),"set origin");
+ TEST(f->setProperty(COMPOSITION_KEY_MINEVENTS,"0",needUp),"set origin");
stream_cast(s,Point3D((endPt-startPt)*0.5f));
TEST(f->setProperty(COMPOSITION_KEY_NORMAL,s,needUp),"set direction");
diff --git a/src/backend/filters/compositionProfile.h b/src/backend/filters/compositionProfile.h
index 2799828..b4a677b 100644
--- a/src/backend/filters/compositionProfile.h
+++ b/src/backend/filters/compositionProfile.h
@@ -76,7 +76,7 @@ class CompositionProfileFilter : public Filter
//Plotting stuff
//--
//colour of plot
- float r,g,b,a;
+ ColourRGBAf rgba;
//Mode for plotting (eg lines, steps)
unsigned int plotStyle;
diff --git a/src/backend/filters/dataLoad.cpp b/src/backend/filters/dataLoad.cpp
index 5fc4809..b35a2df 100644
--- a/src/backend/filters/dataLoad.cpp
+++ b/src/backend/filters/dataLoad.cpp
@@ -68,7 +68,7 @@ const char *DEFAULT_LABEL="Mass-to-Charge (amu/e)";
// == Pos load filter ==
DataLoadFilter::DataLoadFilter() : fileType(FILEDATA_TYPE_POS), doSample(true), maxIons(MAX_IONS_LOAD_DEFAULT),
- r(1.0f),g(0.0f),b(0.0f),a(1.0f),ionSize(2.0f), numColumns(4), enabled(true),
+ rgbaf(1.0f,0.0f,0.0f,1.0f),ionSize(2.0f), numColumns(4), enabled(true),
volumeRestrict(false), monitorTimestamp(-1),monitorSize((size_t)-1),wantMonitor(false),
valueLabel(TRANS(DEFAULT_LABEL)), endianMode(0)
{
@@ -91,12 +91,8 @@ Filter *DataLoadFilter::cloneUncached() const
p->maxIons=maxIons;
p->ionSize=ionSize;
p->fileType=fileType;
- p->guessType=guessType;
//Colours
- p->r=r;
- p->g=g;
- p->b=b;
- p->a=a;
+ p->rgbaf=rgbaf;
//Bounding volume
p->bound.setBounds(bound);
p->volumeRestrict=volumeRestrict;
@@ -198,7 +194,7 @@ unsigned int DataLoadFilter::refresh(const std::vector<const FilterStreamData *>
//the same timestamp as on the file.
if(wantMonitor)
{
- if(!wxFile::Exists(wxStr(ionFilename)))
+ if(!wxFile::Exists((ionFilename)))
{
monitorTimestamp=-1;
monitorSize=-1;
@@ -214,7 +210,7 @@ unsigned int DataLoadFilter::refresh(const std::vector<const FilterStreamData *>
size_t fileSizeVal;
getFilesize(ionFilename.c_str(),fileSizeVal);
- if(wxFileModificationTime(wxStr(ionFilename)) ==monitorTimestamp
+ if(wxFileModificationTime((ionFilename)) ==monitorTimestamp
|| fileSizeVal!= monitorSize)
{
doUseCache=false;
@@ -235,9 +231,9 @@ unsigned int DataLoadFilter::refresh(const std::vector<const FilterStreamData *>
}
//If theres no file, then there is not a lot we can do..
- if(!wxFile::Exists(wxStr(ionFilename)))
+ if(!wxFile::Exists((ionFilename)))
{
- wxFileName f(wxStr(ionFilename));
+ wxFileName f((ionFilename));
errStr= stlStr(f.GetFullName()) + TRANS(" does not exist");
return ERR_FILE_OPEN;
@@ -245,7 +241,7 @@ unsigned int DataLoadFilter::refresh(const std::vector<const FilterStreamData *>
//If we have disable the filter, or we are are monitoring and
//there is no file
- if(!enabled ||(wantMonitor && !wxFile::Exists(wxStr(ionFilename))) )
+ if(!enabled ||(wantMonitor && !wxFile::Exists((ionFilename))) )
{
monitorTimestamp=-1;
monitorSize=-1;
@@ -257,7 +253,7 @@ unsigned int DataLoadFilter::refresh(const std::vector<const FilterStreamData *>
//Update the monitoring timestamp such that we know
//when the file was last loaded
- monitorTimestamp = wxFileModificationTime(wxStr(ionFilename));
+ monitorTimestamp = wxFileModificationTime((ionFilename));
size_t tmp;
if(getFilesize(ionFilename.c_str(),tmp))
monitorSize=tmp;
@@ -423,10 +419,10 @@ unsigned int DataLoadFilter::refresh(const std::vector<const FilterStreamData *>
ASSERT(false);
}
- ionData->r = r;
- ionData->g = g;
- ionData->b = b;
- ionData->a = a;
+ ionData->r = rgbaf.r();
+ ionData->g = rgbaf.g();
+ ionData->b = rgbaf.b();
+ ionData->a = rgbaf.a();
ionData->ionSize=ionSize;
ionData->valueType=valueLabel;
@@ -451,15 +447,7 @@ unsigned int DataLoadFilter::refresh(const std::vector<const FilterStreamData *>
"(magnitude too large). Consider rescaling data before loading"));
}
- if(cache)
- {
- ionData->cached=1;
- filterOutputs.push_back(ionData);
- cacheOK=true;
- }
- else
- ionData->cached=0;
-
+ cacheAsNeeded(ionData);
//Append the ion data
getOut.push_back(ionData);
@@ -476,11 +464,13 @@ void DataLoadFilter::getProperties(FilterPropGroup &propertyList) const
size_t curGroup=0;
- p.type=PROPERTY_TYPE_STRING;
+ p.type=PROPERTY_TYPE_FILE;
p.key=DATALOAD_KEY_FILE;
p.name=TRANS("File");
p.helpText=TRANS("File from which to load data");
p.data=ionFilename;
+ //Wx- acceptable string format
+ p.dataSecondary = TRANS("Readable files (*.xml, *.pos, *.txt,*.csv, *.ato)|*.xml;*.pos;*.txt;*.csv;*.ato|All Files|*") ;
propertyList.addProperty(p,curGroup);
@@ -497,6 +487,7 @@ void DataLoadFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("File"));
//---------
curGroup++;
@@ -603,7 +594,7 @@ void DataLoadFilter::getProperties(FilterPropGroup &propertyList) const
{
std::string tmpStr;
- //FIXME: ATO Files need an imeplmentation of sampling read
+ //FIXME: ATO Files need an implementation of sampling read
if(fileType!=FILEDATA_TYPE_ATO)
{
stream_cast(tmpStr,doSample);
@@ -633,18 +624,17 @@ void DataLoadFilter::getProperties(FilterPropGroup &propertyList) const
p.type=PROPERTY_TYPE_BOOL;
p.helpText=TRANS("Watch file timestamp to track changes to file contents from other programs");
propertyList.addProperty(p,curGroup);
- propertyList.setGroupTitle(curGroup,TRANS("Load params."));
+ }
+
+ propertyList.setGroupTitle(curGroup,TRANS("Load params."));
+ if(enabled)
+ {
curGroup++;
- string thisCol;
- //Convert the ion colour to a hex string
- genColString((unsigned char)(r*255),(unsigned char)(g*255),
- (unsigned char)(b*255),(unsigned char)(a*255),thisCol);
-
p.name=TRANS("Default colour ");
- p.data=thisCol;
+ p.data=rgbaf.toColourRGBA().rgbaString();
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Default colour for points, if not overridden by other filters");
p.key=DATALOAD_KEY_COLOUR;
@@ -656,6 +646,7 @@ void DataLoadFilter::getProperties(FilterPropGroup &propertyList) const
p.type=PROPERTY_TYPE_REAL;
p.helpText=TRANS("Default size for points, if not overridden by other filters");
p.key=DATALOAD_KEY_IONSIZE;
+
propertyList.addProperty(p,curGroup);
propertyList.setGroupTitle(curGroup,TRANS("Appearance"));
}
@@ -715,57 +706,21 @@ bool DataLoadFilter::setProperty( unsigned int key,
}
case DATALOAD_KEY_ENABLED:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(enabled,value,needUpdate))
return false;
-
- bool lastVal=enabled;
- enabled=(stripped == "1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=enabled)
- needUpdate=true;
-
- clearCache();
break;
}
case DATALOAD_KEY_MONITOR:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(wantMonitor,value,needUpdate))
return false;
-
- bool lastVal=wantMonitor;
- wantMonitor=(stripped=="1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=wantMonitor)
- needUpdate=true;
-
- clearCache();
break;
}
case DATALOAD_KEY_SAMPLE:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(doSample,value,needUpdate))
return false;
-
- bool lastVal=doSample;
- doSample=(stripped == "1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=doSample)
- needUpdate=true;
-
- clearCache();
break;
}
case DATALOAD_KEY_SIZE:
@@ -789,17 +744,12 @@ bool DataLoadFilter::setProperty( unsigned int key,
}
case DATALOAD_KEY_COLOUR:
{
- unsigned char newR,newG,newB,newA;
-
- parseColString(value,newR,newG,newB,newA);
+ ColourRGBA tmpRgba;
+ tmpRgba.parse(value);
- if(newB != b || newR != r ||
- newG !=g || newA != a)
+ if(tmpRgba != rgbaf.toColourRGBA())
{
- r=newR/255.0;
- g=newG/255.0;
- b=newB/255.0;
- a=newA/255.0;
+ rgbaf=tmpRgba.toRGBAf();
//Check the cache, updating it if needed
@@ -811,10 +761,10 @@ bool DataLoadFilter::setProperty( unsigned int key,
{
IonStreamData *i;
i=(IonStreamData *)filterOutputs[ui];
- i->r=r;
- i->g=g;
- i->b=b;
- i->a=a;
+ i->r=rgbaf.r();
+ i->g=rgbaf.g();
+ i->b=rgbaf.b();
+ i->a=rgbaf.a();
}
}
@@ -1145,7 +1095,7 @@ bool DataLoadFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFile
if(XMLHelpFwdToElem(nodePtr,"colour"))
return false;
- if(!parseXMLColour(nodePtr,r,g,b,a))
+ if(!parseXMLColour(nodePtr,rgbaf))
return false;
//====
@@ -1207,8 +1157,8 @@ bool DataLoadFilter::writeState(std::ostream &f,unsigned int format, unsigned in
f << tabs(depth+1) << "<dosample value=\"" << doSample << "\"/>" << endl;
f << tabs(depth+1) << "<maxions value=\"" << maxIons << "\"/>" << endl;
- f << tabs(depth+1) << "<colour r=\"" << r<< "\" g=\"" << g << "\" b=\"" <<b
- << "\" a=\"" << a << "\"/>" <<endl;
+ f << tabs(depth+1) << "<colour r=\"" << rgbaf.r() << "\" g=\"" << rgbaf.g()
+ << "\" b=\"" << rgbaf.b() << "\" a=\"" << rgbaf.a() << "\"/>" <<endl;
f << tabs(depth+1) << "<ionsize value=\"" << ionSize << "\"/>" << endl;
f << tabs(depth) << "</" << trueName() << ">" << endl;
break;
@@ -1257,7 +1207,7 @@ bool DataLoadFilter::monitorNeedsRefresh() const
{
//Check to see that the file exists, if
// not fall back to the cache.
- if(!wxFile::Exists(wxStr(ionFilename)))
+ if(!wxFile::Exists((ionFilename)))
return cacheOK;
@@ -1266,7 +1216,7 @@ bool DataLoadFilter::monitorNeedsRefresh() const
if(sizeVal != monitorSize)
return true;
- return( wxFileModificationTime(wxStr(ionFilename))
+ return( wxFileModificationTime((ionFilename))
!=monitorTimestamp);
diff --git a/src/backend/filters/dataLoad.h b/src/backend/filters/dataLoad.h
index 09499f9..cb28899 100644
--- a/src/backend/filters/dataLoad.h
+++ b/src/backend/filters/dataLoad.h
@@ -20,6 +20,7 @@
#include "../filter.h"
+#include "../../common/basics.h"
#include "../../common/translation.h"
enum
@@ -57,8 +58,6 @@ class DataLoadFilter:public Filter
//!Type of file to open
unsigned int fileType;
- //!Try our best to guess the file type?
- bool guessType;
//!Whether to randomly sample dataset during load or not
@@ -68,7 +67,7 @@ class DataLoadFilter:public Filter
size_t maxIons;
//!Default ion colour vars
- float r,g,b,a;
+ ColourRGBAf rgbaf;
//!Default ion size (view size)
float ionSize;
diff --git a/src/backend/filters/externalProgram.cpp b/src/backend/filters/externalProgram.cpp
index b82cc5b..fa621f2 100644
--- a/src/backend/filters/externalProgram.cpp
+++ b/src/backend/filters/externalProgram.cpp
@@ -21,6 +21,7 @@
#include "../../wx/wxcommon.h"
#include "backend/APT/APTFileIO.h"
+#include "backend/plot.h"
#include <wx/filename.h>
#include <wx/dir.h>
@@ -39,6 +40,7 @@ enum
READPOS_FAIL,
SUBSTITUTE_FAIL,
COMMAND_FAIL,
+ EXT_PROG_ERR_ENUM_END,
};
//=== External program filter ===
@@ -226,7 +228,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
string s;
wxString tempDir;
if(workingDir.size())
- tempDir=(wxStr(workingDir) +wxT("/inputData"));
+ tempDir=((workingDir) +wxT("/inputData"));
else
tempDir=(wxT("inputData"));
@@ -320,7 +322,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
if(workingDir.size())
{
//Set the working directory before launching
- if(!wxSetWorkingDirectory(wxStr(workingDir)))
+ if(!wxSetWorkingDirectory((workingDir)))
return SETWORKDIR_FAIL;
}
else
@@ -331,7 +333,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
bool result;
//Execute the program
- result=wxShell(wxStr(substitutedCommand));
+ result=wxShell((substitutedCommand));
if(cleanInput)
{
@@ -340,7 +342,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
for(unsigned int ui=0;ui<ionOutputNames.size();ui++)
{
//try to delete the file
- wxRemoveFile(wxStr(ionOutputNames[ui]));
+ wxRemoveFile((ionOutputNames[ui]));
//call the update to be nice
(*callback)(false);
@@ -348,7 +350,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
for(unsigned int ui=0;ui<plotOutputNames.size();ui++)
{
//try to delete the file
- wxRemoveFile(wxStr(plotOutputNames[ui]));
+ wxRemoveFile((plotOutputNames[ui]));
//call the update to be nice
(*callback)(false);
@@ -363,7 +365,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
wxDir *dir = new wxDir;
wxArrayString *a = new wxArrayString;
if(workingDir.size())
- dir->GetAllFiles(wxStr(workingDir),a,wxT("*.pos"),wxDIR_FILES);
+ dir->GetAllFiles((workingDir),a,wxT("*.pos"),wxDIR_FILES);
else
dir->GetAllFiles(wxGetCwd(),a,wxT("*.pos"),wxDIR_FILES);
@@ -418,7 +420,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
a->Clear();
if(workingDir.size())
- dir->GetAllFiles(wxStr(workingDir),a,wxT("*.xy"),wxDIR_FILES);
+ dir->GetAllFiles((workingDir),a,wxT("*.xy"),wxDIR_FILES);
else
dir->GetAllFiles(wxGetCwd(),a,wxT("*.xy"),wxDIR_FILES);
@@ -478,7 +480,7 @@ unsigned int ExternalProgramFilter::refresh(const std::vector<const FilterStream
d->a=1.0;
d->index=uj;
d->plotMode=PLOT_MODE_1D;
- d->plotStyle=PLOT_TRACE_LINES;
+ d->plotStyle=PLOT_LINE_LINES;
//set the title to the filename (trim the .xy extension
@@ -554,12 +556,9 @@ void ExternalProgramFilter::getProperties(FilterPropGroup &propertyList) const
p.key=EXTERNALPROGRAM_KEY_WORKDIR;
propertyList.addProperty(p,curGroup);
-
- if(cleanInput)
- tmpStr="1";
- else
- tmpStr="0";
-
+ propertyList.setGroupTitle(curGroup,TRANS("Command"));
+ curGroup++;
+ tmpStr=boolStrEnc(cleanInput);
p.name=TRANS("Cleanup input");
p.data=tmpStr;
p.type=PROPERTY_TYPE_BOOL;
@@ -567,11 +566,7 @@ void ExternalProgramFilter::getProperties(FilterPropGroup &propertyList) const
p.key=EXTERNALPROGRAM_KEY_CLEANUPINPUT;
propertyList.addProperty(p,curGroup);
- if(alwaysCache)
- tmpStr="1";
- else
- tmpStr="0";
-
+ tmpStr=boolStrEnc(alwaysCache);
p.name=TRANS("Cache");
p.data=tmpStr;
p.type=PROPERTY_TYPE_BOOL;
@@ -579,6 +574,7 @@ void ExternalProgramFilter::getProperties(FilterPropGroup &propertyList) const
p.key=EXTERNALPROGRAM_KEY_ALWAYSCACHE;
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Data"));
}
bool ExternalProgramFilter::setProperty( unsigned int key,
@@ -589,12 +585,8 @@ bool ExternalProgramFilter::setProperty( unsigned int key,
{
case EXTERNALPROGRAM_KEY_COMMAND:
{
- if(commandLine!=value)
- {
- commandLine=value;
- needUpdate=true;
- clearCache();
- }
+ if(!applyPropertyNow(commandLine,value,needUpdate))
+ return false;
break;
}
case EXTERNALPROGRAM_KEY_WORKDIR:
@@ -602,7 +594,7 @@ bool ExternalProgramFilter::setProperty( unsigned int key,
if(workingDir!=value)
{
//Check the directory exists
- if(!wxDirExists(wxStr(value)))
+ if(!wxDirExists((value)))
return false;
workingDir=value;
@@ -613,33 +605,14 @@ bool ExternalProgramFilter::setProperty( unsigned int key,
}
case EXTERNALPROGRAM_KEY_ALWAYSCACHE:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(alwaysCache,value,needUpdate))
return false;
-
- if(stripped=="1")
- alwaysCache=true;
- else
- {
- alwaysCache=false;
-
- //If we need to generate a cache, do so
- //otherwise, trash it
- clearCache();
- }
-
- needUpdate=true;
break;
}
case EXTERNALPROGRAM_KEY_CLEANUPINPUT:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(cleanInput,value,needUpdate))
return false;
- cleanInput=(stripped=="1");
- needUpdate=true;
break;
}
default:
@@ -653,33 +626,21 @@ bool ExternalProgramFilter::setProperty( unsigned int key,
std::string ExternalProgramFilter::getErrString(unsigned int code) const
{
-
- switch(code)
- {
- case COMMANDLINE_FAIL:
- return std::string(TRANS("Error processing command line"));
- case SETWORKDIR_FAIL:
- return std::string(TRANS("Unable to set working directory"));
- case WRITEPOS_FAIL:
- return std::string(TRANS("Error saving posfile result for external program"));
- case WRITEPLOT_FAIL:
- return std::string(TRANS("Error saving plot result for externalprogram"));
- case MAKEDIR_FAIL:
- return std::string(TRANS("Error creating temporary directory"));
- case PLOTCOLUMNS_FAIL:
- return std::string(TRANS("Detected unusable number of columns in plot"));
- case READPLOT_FAIL:
- return std::string(TRANS("Unable to parse plot result from external program"));
- case READPOS_FAIL:
- return std::string(TRANS("Unable to load ions from external program"));
- case SUBSTITUTE_FAIL:
- return std::string(TRANS("Unable to perform commandline substitution"));
- case COMMAND_FAIL:
- return std::string(TRANS("Error executing external program"));
- default:
- //Currently the only error is aborting
- return std::string("Bug: write me (externalProgramfilter).");
- }
+ const char *errStrs[] = { "",
+ "Error processing command line",
+ "Unable to set working directory",
+ "Error saving posfile result for external program",
+ "Error saving plot result for externalprogram",
+ "Error creating temporary directory",
+ "Detected unusable number of columns in plot",
+ "Unable to parse plot result from external program",
+ "Unable to load ions from external program",
+ "Unable to perform commandline substitution",
+ "Error executing external program" };
+
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == EXT_PROG_ERR_ENUM_END);
+ ASSERT(code < EXT_PROG_ERR_ENUM_END);
+ return errStrs[code];
}
void ExternalProgramFilter::setPropFromBinding(const SelectionBinding &b)
@@ -749,22 +710,14 @@ bool ExternalProgramFilter::readState(xmlNodePtr &nodePtr, const std::string &st
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"alwayscache","value"))
return false;
- if(tmpStr == "1")
- alwaysCache=true;
- else if(tmpStr== "0")
- alwaysCache=false;
- else
+ if(!boolStrDec(tmpStr,alwaysCache))
return false;
//check readable
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"cleaninput","value"))
return false;
- if(tmpStr == "1")
- cleanInput=true;
- else if(tmpStr== "0")
- cleanInput=false;
- else
+ if(!boolStrDec(tmpStr,cleanInput))
return false;
return true;
@@ -870,12 +823,18 @@ bool posTest()
#else
tmpDir=tmpDir + wxT("/3Depict/");
#endif
+ if(wxDirExists(tmpDir))
+ {
+ wxFileName dirFile(tmpDir);
+ dirFile.Rmdir( wxPATH_RMDIR_RECURSIVE);
+ }
+
+
wxMkdir(tmpDir);
tmpFilename=wxFileName::CreateTempFileName(tmpDir+ wxT("unittest-"));
- wxRemoveFile(tmpFilename);
tmpFilename+=wxT(".pos");
- s ="mv \%i " + stlStr(tmpFilename);
+ s ="mv -f \%i " + stlStr(tmpFilename);
ASSERT(tmpFilename.size());
@@ -943,13 +902,14 @@ bool ExternalProgramFilter::runUnitTests()
{
if(!echoTest())
return false;
-
+
+#ifndef __APPLE__
if(!posTest())
return false;
if(!substituteTest())
return false;
-
+#endif
return true;
}
diff --git a/src/backend/filters/filterCommon.cpp b/src/backend/filters/filterCommon.cpp
index 5b8afdf..4a754f7 100644
--- a/src/backend/filters/filterCommon.cpp
+++ b/src/backend/filters/filterCommon.cpp
@@ -19,7 +19,7 @@
#include "filterCommon.h"
#include "common/colourmap.h"
-
+#include "wx/wxcommon.h"
//TODO: Work out where the payoff for this is
@@ -111,9 +111,11 @@ bool readVectorsXML(xmlNodePtr nodePtr, std::vector<Point3D> &vectorParams)
return true;
}
-bool parseXMLColour(xmlNodePtr &nodePtr, float &r,float&g,float&b,float&a)
+bool parseXMLColour(xmlNodePtr &nodePtr, ColourRGBAf &rgba)
{
xmlChar *xmlString;
+
+ float r,g,b,a;
std::string tmpStr;
//--red--
xmlString=xmlGetProp(nodePtr,(const xmlChar *)"r");
@@ -185,6 +187,10 @@ bool parseXMLColour(xmlNodePtr &nodePtr, float &r,float&g,float&b,float&a)
//disallow negative or values gt 1.
if(a < 0.0f || a > 1.0f)
return false;
+ rgba.r(r);
+ rgba.g(g);
+ rgba.b(b);
+ rgba.a(a);
return true;
}
@@ -675,7 +681,7 @@ void freeConvexHull()
qhullInited=false;
}
-DrawColourBarOverlay *makeColourBar(float minV, float maxV,size_t nColours,size_t colourMap, bool reverseMap)
+DrawColourBarOverlay *makeColourBar(float minV, float maxV,size_t nColours,size_t colourMap, bool reverseMap, float alpha)
{
//Set up the colour bar. Place it in a draw stream type
DrawColourBarOverlay *dc = new DrawColourBarOverlay;
@@ -702,7 +708,39 @@ DrawColourBarOverlay *makeColourBar(float minV, float maxV,size_t nColours,size_
dc->setSize(0.08,0.6);
dc->setPosition(0.1,0.1);
dc->setMinMax(minV,maxV);
-
+ dc->setAlpha(alpha);
return dc;
}
+
+//creates a temporary filename for use
+std::string createTmpFilename(const char *dir,const char *extension)
+{
+ wxString tmpFilename,tmpDir;
+
+ if(!dir)
+ {
+ tmpDir=wxFileName::GetTempDir();
+
+
+ #if defined(__WIN32__) || defined(__WIN64__)
+ tmpDir=tmpDir + wxT("\\3Depict\\");
+
+ #else
+ tmpDir=tmpDir + wxT("/3Depict/");
+ #endif
+
+ }
+ else
+ tmpDir=dir;
+
+ if(!wxDirExists(tmpDir))
+ wxMkdir(tmpDir);
+ tmpFilename=wxFileName::CreateTempFileName(tmpDir+ wxT("unittest-"));
+ wxRemoveFile(tmpFilename);
+ if(extension)
+ tmpFilename+=wxT(".pos");
+
+ return stlStr(tmpFilename);
+}
+
diff --git a/src/backend/filters/filterCommon.h b/src/backend/filters/filterCommon.h
index eec1f41..5085124 100644
--- a/src/backend/filters/filterCommon.h
+++ b/src/backend/filters/filterCommon.h
@@ -22,6 +22,7 @@
#include "../filter.h"
#include "common/stringFuncs.h"
+#include "common/basics.h"
#include "common/xmlHelper.h"
#include "backend/APT/APTRanges.h"
@@ -105,8 +106,8 @@ bool readVectorsXML(xmlNodePtr nodePtr,
//Parse a "colour" node, extracting rgba data
-bool parseXMLColour(xmlNodePtr &nodePtr,
- float &r, float&g, float&b, float&a);
+bool parseXMLColour(xmlNodePtr &nodePtr, ColourRGBAf &rgbaf);
+
//Returns the ion stream's range ID from the rangefile, if and only if it every ion in input
// is ranged tht way. Otherwise returns -1.
@@ -130,6 +131,11 @@ unsigned int computeConvexHull(const std::vector<Point3D> &data,
//Release the memory held by qhull, and notify the computeConvexHull routines that this has been done
void freeConvexHull();
//Draw a colour bar
-DrawColourBarOverlay *makeColourBar(float minV, float maxV,size_t nColours,size_t colourMap, bool reverseMap=false) ;
+DrawColourBarOverlay *makeColourBar(float minV, float maxV,size_t nColours,size_t colourMap, bool reverseMap=false, float alpha=1.0f) ;
+
+
+//Create a temporary filename, optionally providing an extension to use/
+// - note that any subdirs will be automatically created if needed.
+std::string createTmpFilename(const char *dir=NULL,const char *extension=NULL);
#endif
diff --git a/src/backend/filters/ionClip.cpp b/src/backend/filters/ionClip.cpp
index 9e8ac91..6502ea9 100644
--- a/src/backend/filters/ionClip.cpp
+++ b/src/backend/filters/ionClip.cpp
@@ -29,6 +29,7 @@ enum
{
CALLBACK_FAIL=1,
BAD_ALLOC,
+ IONCLIP_ERR_ENUM_END
};
//!Possible primitive types for ion clipping
@@ -435,15 +436,7 @@ unsigned int IonClipFilter::refresh(const std::vector<const FilterStreamData *>
d->representationType=((IonStreamData *)dataIn[ui])->representationType;
//getOut is const, so shouldn't be modified
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
-
+ cacheAsNeeded(d);
getOut.push_back(d);
d=0;
@@ -581,10 +574,7 @@ void IonClipFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Positive vector for cylinder");
propertyList.addProperty(p,curGroup);
- if(lockAxisMag)
- tmpStr="1";
- else
- tmpStr="0";
+ tmpStr=boolStrEnc(lockAxisMag);
p.key=KEY_AXIS_LOCKMAG;
p.name=TRANS("Lock Axis Mag.");
p.data=tmpStr;
@@ -625,7 +615,8 @@ void IonClipFilter::getProperties(FilterPropGroup &propertyList) const
default:
ASSERT(false);
}
-
+
+ propertyList.setGroupTitle(curGroup,TRANS("Clipping"));
}
//!Set the properties for the nth filter. Returns true if prop set OK
@@ -737,50 +728,21 @@ bool IonClipFilter::setProperty(unsigned int key,
}
case KEY_ORIGIN:
{
- ASSERT(vectorParams.size() >= 1);
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(vectorParams[0],value,needUpdate))
return false;
-
- if(!(vectorParams[0] == newPt ))
- {
- vectorParams[0] = newPt;
- needUpdate=true;
- clearCache();
- }
-
- return true;
+ break;
}
case KEY_CORNER:
{
- ASSERT(vectorParams.size() >= 2);
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(vectorParams[1],value,needUpdate))
return false;
-
- if(!(vectorParams[1] == newPt ))
- {
- vectorParams[1] = newPt;
- needUpdate=true;
- clearCache();
- }
-
- return true;
+ break;
}
case KEY_RADIUS:
{
- ASSERT(scalarParams.size() >=1);
- float newRad;
- if(stream_cast(newRad,value))
+ if(!applyPropertyNow(scalarParams[0],value,needUpdate))
return false;
-
- if(scalarParams[0] != newRad )
- {
- scalarParams[0] = newRad;
- needUpdate=true;
- clearCache();
- }
- return true;
+ break;
}
case KEY_NORMAL:
{
@@ -808,58 +770,20 @@ bool IonClipFilter::setProperty(unsigned int key,
}
case KEY_PRIMITIVE_SHOW:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(showPrimitive,value,needUpdate))
return false;
-
- if(stripped=="1")
- showPrimitive=true;
- else
- showPrimitive=false;
-
- needUpdate=true;
-
break;
}
case KEY_PRIMITIVE_INVERTCLIP:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(invertedClip,value,needUpdate))
return false;
-
- bool lastVal=invertedClip;
- if(stripped=="1")
- invertedClip=true;
- else
- invertedClip=false;
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=invertedClip)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
-
case KEY_AXIS_LOCKMAG:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(lockAxisMag,value,needUpdate))
return false;
-
- if(stripped=="1")
- lockAxisMag=true;
- else
- lockAxisMag=false;
-
- needUpdate=true;
-
break;
}
default:
@@ -875,14 +799,13 @@ bool IonClipFilter::setProperty(unsigned int key,
//!Get the human readable error string associated with a particular error code during refresh(...)
std::string IonClipFilter::getErrString(unsigned int code) const
{
- switch(code)
- {
- case BAD_ALLOC:
- return std::string("Insufficient mem. for Ionclip");
- case CALLBACK_FAIL:
- return std::string("Ionclip Aborted");
- }
- ASSERT(false);
+ const char *errCode[] = { "",
+ "Insufficient mem. for Ionclip",
+ "Ionclip Aborted"
+ };
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errCode) == IONCLIP_ERR_ENUM_END);
+ ASSERT(code < IONCLIP_ERR_ENUM_END);
+ return errCode[code];
}
bool IonClipFilter::writeState(std::ostream &f,unsigned int format, unsigned int depth) const
@@ -942,11 +865,8 @@ bool IonClipFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFileD
//
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"invertedclip","value"))
return false;
- if(tmpStr == "0")
- invertedClip=false;
- else if(tmpStr == "1")
- invertedClip=true;
- else
+
+ if(!boolStrDec(tmpStr,invertedClip))
return false;
//====
@@ -954,11 +874,7 @@ bool IonClipFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFileD
//====
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"showprimitive","value"))
return false;
- if(tmpStr == "0")
- showPrimitive=false;
- else if(tmpStr == "1")
- showPrimitive=true;
- else
+ if(!boolStrDec(tmpStr,showPrimitive))
return false;
//====
@@ -966,11 +882,8 @@ bool IonClipFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFileD
//====
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"lockaxismag","value"))
return false;
- if(tmpStr == "0")
- lockAxisMag=false;
- else if(tmpStr == "1")
- lockAxisMag=true;
- else
+
+ if(!boolStrDec(tmpStr,lockAxisMag))
return false;
//====
diff --git a/src/backend/filters/ionColour.cpp b/src/backend/filters/ionColour.cpp
index 7bf43e0..cf2e05b 100644
--- a/src/backend/filters/ionColour.cpp
+++ b/src/backend/filters/ionColour.cpp
@@ -32,6 +32,7 @@ enum
KEY_IONCOLOURFILTER_NCOLOURS,
KEY_IONCOLOURFILTER_REVERSE,
KEY_IONCOLOURFILTER_SHOWBAR,
+ KEY_IONCOLOURFILTER_ALPHA,
};
enum
@@ -40,7 +41,7 @@ enum
};
IonColourFilter::IonColourFilter() : colourMap(0),reverseMap(false),
- nColours(MAX_NUM_COLOURS),showColourBar(true)
+ nColours(MAX_NUM_COLOURS),showColourBar(true), alpha(1.0f)
{
mapBounds[0] = 0.0f;
mapBounds[1] = 100.0f;
@@ -57,6 +58,7 @@ Filter *IonColourFilter::cloneUncached() const
p->mapBounds[0]=mapBounds[0];
p->mapBounds[1]=mapBounds[1];
p->nColours =nColours;
+ p->alpha = alpha;
p->showColourBar =showColourBar;
p->reverseMap=reverseMap;
@@ -88,10 +90,11 @@ unsigned int IonColourFilter::refresh(const std::vector<const FilterStreamData *
if(filterOutputs.size() && showColourBar)
{
+ //TODO: Can I remove this? Caching for drawables now should work, right?
DrawStreamData *d = new DrawStreamData;
d->parent=this;
d->drawables.push_back(makeColourBar(mapBounds[0],
- mapBounds[1],nColours,colourMap));
+ mapBounds[1],nColours,colourMap,alpha));
d->cached=0;
getOut.push_back(d);
}
@@ -191,7 +194,7 @@ unsigned int IonColourFilter::refresh(const std::vector<const FilterStreamData *
if(foundIons && showColourBar)
{
DrawStreamData *d = new DrawStreamData;
- d->drawables.push_back(makeColourBar(mapBounds[0],mapBounds[1],nColours,colourMap,reverseMap));
+ d->drawables.push_back(makeColourBar(mapBounds[0],mapBounds[1],nColours,colourMap,reverseMap,alpha));
d->parent=this;
d->cached=0;
getOut.push_back(d);
@@ -276,6 +279,12 @@ void IonColourFilter::getProperties(FilterPropGroup &propertyList) const
p.data=boolStrEnc(showColourBar);
p.type=PROPERTY_TYPE_BOOL;
propertyList.addProperty(p,curGroup);
+
+ p.name=TRANS("Opacity");
+ p.key=KEY_IONCOLOURFILTER_ALPHA;
+ stream_cast(p.data,alpha);
+ p.type=PROPERTY_TYPE_REAL;
+ propertyList.addProperty(p,curGroup);
stream_cast(tmpStr,nColours);
p.name=TRANS("Num Colours");
@@ -300,6 +309,7 @@ void IonColourFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_IONCOLOURFILTER_MAPEND;
p.type=PROPERTY_TYPE_REAL;
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Data"));
}
@@ -334,18 +344,8 @@ bool IonColourFilter::setProperty( unsigned int key,
}
case KEY_IONCOLOURFILTER_REVERSE:
{
- bool newVal;
- if(!boolStrDec(value,newVal))
+ if(!applyPropertyNow(reverseMap,value,needUpdate))
return false;
-
- //Only need update if changed
- if(newVal!=reverseMap)
- {
- clearCache();
- needUpdate=true;
- }
-
- reverseMap=newVal;
break;
}
case KEY_IONCOLOURFILTER_MAPSTART:
@@ -390,19 +390,16 @@ bool IonColourFilter::setProperty( unsigned int key,
}
case KEY_IONCOLOURFILTER_SHOWBAR:
{
- bool newVal;
- if(!boolStrDec(value,newVal))
+ if(!applyPropertyNow(showColourBar,value,needUpdate))
return false;
- //Only need update if changed
- if(newVal!=showColourBar)
- {
- needUpdate=true;
- clearCache();
- }
- showColourBar=newVal;
break;
}
-
+ case KEY_IONCOLOURFILTER_ALPHA:
+ {
+ if(!applyPropertyNow(alpha,value,needUpdate))
+ return false;
+ break;
+ }
default:
ASSERT(false);
}
@@ -434,7 +431,7 @@ bool IonColourFilter::writeState(std::ostream &f,unsigned int format, unsigned i
f << tabs(depth+1) << "<colourmap value=\"" << colourMap << "\"/>" << endl;
f << tabs(depth+1) << "<extrema min=\"" << mapBounds[0] << "\" max=\""
<< mapBounds[1] << "\"/>" << endl;
- f << tabs(depth+1) << "<ncolours value=\"" << nColours << "\"/>" << endl;
+ f << tabs(depth+1) << "<ncolours value=\"" << nColours << "\" opacity=\"" << alpha << "\"/>" << endl;
f << tabs(depth+1) << "<showcolourbar value=\"" << boolStrEnc(showColourBar)<< "\"/>" << endl;
f << tabs(depth+1) << "<reversemap value=\"" << boolStrEnc(reverseMap)<< "\"/>" << endl;
@@ -482,6 +479,16 @@ bool IonColourFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
if(colourMap>= NUM_COLOURMAPS)
return false;
xmlFree(xmlString);
+
+ if(XMLHelpGetProp(alpha, nodePtr,"opacity"))
+ {
+ alpha=1.0f;
+ }
+ else
+ {
+ //clamp alpha to [0,1]
+ alpha = std::max(0.0f,std::min(alpha,1.0f));
+ }
//====
//Retrieve Extrema
diff --git a/src/backend/filters/ionColour.h b/src/backend/filters/ionColour.h
index c57c979..8defcba 100644
--- a/src/backend/filters/ionColour.h
+++ b/src/backend/filters/ionColour.h
@@ -44,6 +44,8 @@ class IonColourFilter: public Filter
//!Should we display the colour bar?
bool showColourBar;
+ //Transparency value
+ float alpha;
public:
IonColourFilter();
//!Duplicate filter contents, excluding cache.
diff --git a/src/backend/filters/ionDownsample.cpp b/src/backend/filters/ionDownsample.cpp
index f9e7f65..6b0a174 100644
--- a/src/backend/filters/ionDownsample.cpp
+++ b/src/backend/filters/ionDownsample.cpp
@@ -28,6 +28,7 @@ enum
{
IONDOWNSAMPLE_ABORT_ERR=1,
IONDOWNSAMPLE_BAD_ALLOC,
+ IONDOWNSAMPLE_ERR_ENUM_END
};
@@ -268,15 +269,7 @@ unsigned int IonDownsampleFilter::refresh(const std::vector<const FilterStreamDa
d->valueType=((IonStreamData *)dataIn[ui])->valueType;
//getOut is const, so shouldn't be modified
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
-
+ cacheAsNeeded(d);
getOut.push_back(d);
break;
@@ -414,15 +407,7 @@ unsigned int IonDownsampleFilter::refresh(const std::vector<const FilterStreamDa
//getOut is const, so shouldn't be modified
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
-
+ cacheAsNeeded(d);
getOut.push_back(d);
}
@@ -475,7 +460,7 @@ void IonDownsampleFilter::getProperties(FilterPropGroup &propertyList) const
}
- propertyList.setGroupTitle(curGroup,TRANS("Sampling rates"));
+ propertyList.setGroupTitle(curGroup,TRANS("Mode"));
curGroup++;
if(rsdIncoming && perSpecies)
{
@@ -485,6 +470,7 @@ void IonDownsampleFilter::getProperties(FilterPropGroup &propertyList) const
else
typeVal=PROPERTY_TYPE_REAL;
+ bool haveProp=false;
//create a single line for each
for(unsigned int ui=0; ui<rsdIncoming->enabledIons.size(); ui++)
{
@@ -501,8 +487,12 @@ void IonDownsampleFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Sampling value for species");
p.key=KEY_IONDOWNSAMPLE_DYNAMIC+ui;
propertyList.addProperty(p,curGroup);
+
+ haveProp=true;
}
}
+ if(haveProp)
+ propertyList.setGroupTitle(curGroup,TRANS("Sampling rates"));
}
else
{
@@ -526,6 +516,7 @@ void IonDownsampleFilter::getProperties(FilterPropGroup &propertyList) const
}
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Sampling rates"));
}
}
@@ -537,21 +528,8 @@ bool IonDownsampleFilter::setProperty( unsigned int key,
{
case KEY_IONDOWNSAMPLE_FIXEDOUT:
{
- string stripped=stripWhite(value);
-
- bool lastVal=fixedNumOut;
-
- if(!boolStrDec(stripped,fixedNumOut))
+ if(!applyPropertyNow(fixedNumOut,value,needUpdate))
return false;
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=fixedNumOut)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_IONDOWNSAMPLE_FRACTION:
@@ -578,38 +556,14 @@ bool IonDownsampleFilter::setProperty( unsigned int key,
}
case KEY_IONDOWNSAMPLE_COUNT:
{
- size_t count;
-
- if(stream_cast(count,value))
+ if(!applyPropertyNow(maxAfterFilter,value,needUpdate))
return false;
-
- maxAfterFilter=count;
- //In the case of fixed number output,
- //our cache is invalidated
- if(fixedNumOut)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_IONDOWNSAMPLE_PERSPECIES:
{
- string stripped=stripWhite(value);
-
- bool lastVal=perSpecies;
- if(!boolStrDec(stripped,perSpecies))
+ if(!applyPropertyNow(perSpecies,value,needUpdate))
return false;
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=perSpecies)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
default:
@@ -663,15 +617,13 @@ bool IonDownsampleFilter::setProperty( unsigned int key,
std::string IonDownsampleFilter::getErrString(unsigned int code) const
{
- switch(code)
- {
- case IONDOWNSAMPLE_ABORT_ERR:
- return std::string(TRANS("Downsample Aborted"));
- case IONDOWNSAMPLE_BAD_ALLOC:
- return std::string(TRANS("Insuffient memory for downsample"));
- }
-
- return std::string("BUG! Should not see this (IonDownsample)");
+ const char *errStrs[] = { "",
+ "Downsample Aborted",
+ "Insuffient memory for downsample",
+ };
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == IONDOWNSAMPLE_ERR_ENUM_END);
+ ASSERT(code < IONDOWNSAMPLE_ERR_ENUM_END);
+ return errStrs[code];
}
void IonDownsampleFilter::setPropFromBinding(const SelectionBinding &b)
diff --git a/src/backend/filters/ionInfo.cpp b/src/backend/filters/ionInfo.cpp
index 5b9984b..d640d9c 100644
--- a/src/backend/filters/ionInfo.cpp
+++ b/src/backend/filters/ionInfo.cpp
@@ -33,9 +33,9 @@ const char *volumeModeString[] = {
enum
{
- ERR_NO_MEM,
- ERR_USER_ABORT,
- ERR_BAD_QHULL
+ ERR_USER_ABORT=1,
+ ERR_BAD_QHULL,
+ IONINFO_ERR_ENUM_END
};
@@ -418,6 +418,7 @@ void IonInfoFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.addProperty(p,curGroup);
}
+ propertyList.setGroupTitle(curGroup,TRANS("Ion data"));
curGroup++;
stream_cast(str,wantVolume);
@@ -453,55 +454,31 @@ void IonInfoFilter::getProperties(FilterPropGroup &propertyList) const
}
}
+ propertyList.setGroupTitle(curGroup,TRANS("Volume data"));
}
bool IonInfoFilter::setProperty( unsigned int key,
const std::string &value, bool &needUpdate)
{
- string stripped=stripWhite(value);
switch(key)
{
case IONINFO_KEY_TOTALS:
{
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(wantIonCounts,value,needUpdate))
return false;
-
- bool newVal;
- newVal= (value == "1");
-
- if(newVal == wantIonCounts)
- return false;
- wantIonCounts=newVal;
- needUpdate=true;
break;
}
case IONINFO_KEY_NORMALISE:
{
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(wantNormalise,value,needUpdate))
return false;
-
- bool newVal;
- newVal= (value == "1");
-
- if(newVal == wantNormalise)
- return false;
- wantNormalise=newVal;
- needUpdate=true;
break;
}
case IONINFO_KEY_VOLUME:
{
- if(!(stripped == "1"|| stripped == "0"))
- return false;
-
- bool newVal;
- newVal= (value == "1");
-
- if(newVal == wantVolume)
+ if(!applyPropertyNow(wantVolume,value,needUpdate))
return false;
- wantVolume=newVal;
- needUpdate=true;
break;
}
case IONINFO_KEY_VOLUME_ALGORITHM:
@@ -533,16 +510,15 @@ bool IonInfoFilter::setProperty( unsigned int key,
std::string IonInfoFilter::getErrString(unsigned int code) const
{
- switch(code)
- {
- case ERR_NO_MEM:
- return string(TRANS("Insufficient memory for operation"));
- case ERR_USER_ABORT:
- return string(TRANS("Aborted"));
- case ERR_BAD_QHULL:
- return string(TRANS("Bug? Problem with qhull library, cannot run convex hull."));
- }
- ASSERT(false);
+ const char *errStrs[] = { "",
+ "Aborted",
+ "Bug? Problem with qhull library, cannot run convex hull.",
+ };
+
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == IONINFO_ERR_ENUM_END);
+ ASSERT(code < IONINFO_ERR_ENUM_END);
+
+ return errStrs[code];
}
void IonInfoFilter::setPropFromBinding(const SelectionBinding &b)
@@ -664,22 +640,14 @@ bool IonInfoFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFileD
//--
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"wantioncounts","value"))
return false;
- if(tmpStr == "1")
- wantIonCounts=true;
- else if(tmpStr == "0")
- wantIonCounts=false;
- else
+ if(!boolStrDec(tmpStr,wantIonCounts))
return false;
//--=
//--
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"wantnormalise","value"))
return false;
- if(tmpStr == "1")
- wantNormalise=true;
- else if(tmpStr == "0")
- wantNormalise=false;
- else
+ if(!boolStrDec(tmpStr,wantNormalise))
return false;
//--=
@@ -687,11 +655,7 @@ bool IonInfoFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFileD
//--
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"wantvolume","value"))
return false;
- if(tmpStr == "1")
- wantVolume=true;
- else if(tmpStr == "0")
- wantVolume=false;
- else
+ if(!boolStrDec(tmpStr,wantVolume))
return false;
//--=
diff --git a/src/backend/filters/rangeFile.cpp b/src/backend/filters/rangeFile.cpp
index 1bada94..667d917 100644
--- a/src/backend/filters/rangeFile.cpp
+++ b/src/backend/filters/rangeFile.cpp
@@ -30,13 +30,15 @@ const unsigned int NUM_ROWS_RANGE=4;
enum
{
RANGEFILE_ABORT_FAIL=1,
- RANGEFILE_BAD_ALLOC
+ RANGEFILE_BAD_ALLOC,
+ RANGEFILE_ERR_ENUM_END
};
//== Range File Filter ==
RangeFileFilter::RangeFileFilter()
{
dropUnranged=true;
+ showLegend=false;
assumedFileFormat=RANGE_FORMAT_ORNL;
}
@@ -467,26 +469,42 @@ unsigned int RangeFileFilter::refresh(const std::vector<const FilterStreamData *
//======================================
//Having ranged all streams, merge them back into one ranged stream.
- if(cache)
- {
- for(unsigned int ui=0;ui<d.size(); ui++)
- {
- d[ui]->cached=1; //IMPORTANT: ->cached must be set PRIOR to push back
- filterOutputs.push_back(d[ui]);
- }
- }
- else
- {
- for(unsigned int ui=0;ui<d.size(); ui++)
- d[ui]->cached=0; //IMPORTANT: ->cached must be set PRIOR to push back
- cacheOK=false;
- }
+ for(unsigned int ui=0;ui<d.size(); ui++)
+ cacheAsNeeded(d[ui]);
for(unsigned int ui=0;ui<d.size(); ui++)
getOut.push_back(d[ui]);
}
+ if(haveEnabled && showLegend)
+ {
+ //Create a legend bar, which shows the ions that are present
+ DrawStreamData *dS = new DrawStreamData;
+
+ dS->parent=this;
+
+ DrawPointLegendOverlay *dl=new DrawPointLegendOverlay;
+ dl->setPosition(0.1,0.1);
+
+ for(unsigned int ui=0;ui<enabledIons.size();ui++)
+ {
+ if(!enabledIons[ui])
+ continue;
+
+ RGBf curRGBf;
+ curRGBf =rng.getColour(ui);
+ dl->addItem(rng.getName(ui),
+ curRGBf.red, curRGBf.green,curRGBf.blue);
+ }
+
+ dS->drawables.push_back(dl);
+ cacheAsNeeded(dS);
+
+ getOut.push_back(dS);
+ }
+
+
//Put out rangeData
RangeStreamData *rngData=new RangeStreamData;
rngData->parent=this;
@@ -497,12 +515,8 @@ unsigned int RangeFileFilter::refresh(const std::vector<const FilterStreamData *
rngData->enabledIons.resize(enabledIons.size());
std::copy(enabledIons.begin(),enabledIons.end(),rngData->enabledIons.begin());
-
- rngData->cached=cache;
-
- if(cache)
- filterOutputs.push_back(rngData);
+ cacheAsNeeded(rngData);
getOut.push_back(rngData);
cacheOK=cache;
@@ -515,15 +529,9 @@ bool RangeFileFilter::updateRng()
return false;
unsigned int nRng = rng.getNumRanges();
- enabledRanges.resize(nRng);
+ enabledRanges.resize(nRng,(char)1);
unsigned int nIon = rng.getNumIons();
- enabledIons.resize(nIon);
- //Turn all ranges to "on"
- for(unsigned int ui=0;ui<enabledRanges.size(); ui++)
- enabledRanges[ui]=(char)1;
- //Turn all ions to "on"
- for(unsigned int ui=0;ui<enabledIons.size(); ui++)
- enabledIons[ui]=(char)1;
+ enabledIons.resize(nIon,(char)1);
return true;
}
@@ -533,15 +541,9 @@ void RangeFileFilter::setRangeData(const RangeFile &rngNew)
rng=rngNew;
unsigned int nRng = rng.getNumRanges();
- enabledRanges.resize(nRng);
+ enabledRanges.resize(nRng,1);
unsigned int nIon = rng.getNumIons();
- enabledIons.resize(nIon);
- //Turn all ranges to "on"
- for(unsigned int ui=0;ui<enabledRanges.size(); ui++)
- enabledRanges[ui]=(char)1;
- //Turn all ions to "on"
- for(unsigned int ui=0;ui<enabledIons.size(); ui++)
- enabledIons[ui]=(char)1;
+ enabledIons.resize(nIon,1);
clearCache();
}
@@ -565,19 +567,18 @@ void RangeFileFilter::getProperties(FilterPropGroup &p) const
size_t curGroup=0;
prop.name=TRANS("File");
- prop.type=PROPERTY_TYPE_STRING;
+ //Wx- acceptable string format
+ prop.type=PROPERTY_TYPE_FILE;
prop.helpText=TRANS("File to use for range data");
prop.key=RANGE_KEY_RANGE_FILENAME;
prop.data=rngName;
+ prop.dataSecondary=TRANS(RANGEFILE_WX_CONSTANT);
+
p.addProperty(prop,curGroup);
std::string tmpStr;
- if(dropUnranged)
- tmpStr="1";
- else
- tmpStr="0";
-
+ tmpStr=boolStrEnc(dropUnranged);
prop.name=TRANS("Drop unranged");
prop.type=PROPERTY_TYPE_BOOL;
prop.helpText=TRANS("Remove unranged points when generating output");
@@ -585,8 +586,20 @@ void RangeFileFilter::getProperties(FilterPropGroup &p) const
prop.data=tmpStr;
p.addProperty(prop,curGroup);
+ p.setGroupTitle(curGroup,TRANS("File"));
curGroup++;
+
+
+ prop.name = TRANS("Legend");
+ prop.type = PROPERTY_TYPE_BOOL;
+ prop.helpText = TRANS("Display colour legend for enabled ions");
+ prop.key= RANGE_KEY_ENABLE_LEGEND;
+ prop.data=boolStrEnc(showLegend);
+ p.addProperty(prop,curGroup);
+ p.setGroupTitle(curGroup,TRANS("View"));
+ curGroup++;
+
//---
//Option to disable/enable all ions
if(rng.getNumIons())
@@ -624,11 +637,8 @@ void RangeFileFilter::getProperties(FilterPropGroup &p) const
p.addProperty(prop,curGroup);
- string str;
- if(enabledIons[ui])
- str="1";
- else
- str="0";
+ string str;
+ str=boolStrEnc(enabledIons[ui]);
prop.name=TRANS("Active Ion ") + suffix;
prop.type=PROPERTY_TYPE_BOOL;
@@ -638,16 +648,13 @@ void RangeFileFilter::getProperties(FilterPropGroup &p) const
p.addProperty(prop,curGroup);
- RGBf col;
- string thisCol;
-
+ ColourRGBAf col;
//Convert the ion colour to a hex string
col=rng.getColour(ui);
- genColString((unsigned char)(col.red*255),(unsigned char)(col.green*255),
- (unsigned char)(col.blue*255),255,thisCol);
-
+
prop.name=TRANS("Colour ") + suffix;
- prop.data=thisCol;
+ prop.data=col.toColourRGBA().rgbaString();
+
prop.type=PROPERTY_TYPE_COLOUR;
prop.helpText=TRANS("Colour used to represent ion");
prop.key=NUM_ROWS_ION*ui+3+RANGE_KEY_ENABLE_ALL_IONS;
@@ -655,12 +662,11 @@ void RangeFileFilter::getProperties(FilterPropGroup &p) const
p.addProperty(prop,curGroup);
}
+ p.setGroupTitle(curGroup,TRANS("Ions"));
+ curGroup++;
}
//----
-
- curGroup++;
-
//----
if(rng.getNumRanges())
{
@@ -686,11 +692,8 @@ void RangeFileFilter::getProperties(FilterPropGroup &p) const
std::string suffix;
stream_cast(suffix,ui);
- string str;
- if(enabledRanges[ui])
- str="1";
- else
- str="0";
+ string str;
+ str=boolStrEnc(enabledRanges[ui]);
prop.name=TRANS("Active Rng ")+suffix;
prop.data=str;
@@ -773,37 +776,21 @@ bool RangeFileFilter::setProperty(unsigned int key,
}
case RANGE_KEY_DROP_UNRANGED: //Enable/disable unranged dropping
{
- unsigned int valueInt;
- if(stream_cast(valueInt,value))
+ if(!applyPropertyNow(dropUnranged,value,needUpdate))
+ return false;
+ break;
+ }
+ case RANGE_KEY_ENABLE_LEGEND:
+ {
+ if(!applyPropertyNow(showLegend,value,needUpdate))
return false;
-
- if(valueInt ==0 || valueInt == 1)
- {
- if(dropUnranged!= (bool)valueInt)
- {
- needUpdate=true;
- dropUnranged=valueInt;
- }
- else
- needUpdate=false;
- }
- else
- return false;
-
- if(needUpdate)
- clearCache();
-
break;
}
case RANGE_KEY_ENABLE_ALL_RANGES:
{
bool allEnable;
- if(value == "1")
- allEnable=true;
- else if ( value == "0")
- allEnable=false;
- else
+ if(!boolStrDec(value,allEnable))
return false;
//set them to the opposite of whatever we have now
@@ -826,11 +813,7 @@ bool RangeFileFilter::setProperty(unsigned int key,
{
bool allEnable;
- if(value == "1")
- allEnable=true;
- else if ( value == "0")
- allEnable=false;
- else
+ if(!boolStrDec(value,allEnable))
return false;
//set them to the opposite of whatever we have now
@@ -902,15 +885,9 @@ bool RangeFileFilter::setProperty(unsigned int key,
}
case 2: //Colour of the ion
{
- unsigned char r,g,b,a;
- parseColString(value,r,g,b,a);
-
- RGBf newCol;
- newCol.red=(float)r/255.0f;
- newCol.green=(float)g/255.0f;
- newCol.blue=(float)b/255.0f;
-
- rng.setColour(ionID,newCol);
+ ColourRGBA rgba;
+ rgba.parse(value);
+ rng.setColour(ionID,rgba.toRGBAf().toRGBf());
needUpdate=true;
break;
}
@@ -1023,15 +1000,15 @@ bool RangeFileFilter::setProperty(unsigned int key,
std::string RangeFileFilter::getErrString(unsigned int code) const
{
- switch(code)
- {
- case RANGEFILE_ABORT_FAIL:
- return std::string(TRANS("Ranging aborted by user"));
- case RANGEFILE_BAD_ALLOC:
- return std::string(TRANS("Insufficient memory for range"));
- }
+ const char *errStrs[] ={ "",
+ "Ranging aborted by user",
+ "Insufficient memory for range",
+ };
+
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == RANGEFILE_ERR_ENUM_END);
+ ASSERT(code < RANGEFILE_ERR_ENUM_END);
- return std::string("BUG(range file filter): Shouldn't see this!");
+ return errStrs[code];
}
void RangeFileFilter::setPropFromBinding(const SelectionBinding &b)
@@ -1057,18 +1034,17 @@ bool RangeFileFilter::writeState(std::ostream &f,unsigned int format, unsigned i
f << tabs(depth+1) << "<userstring value=\""<< escapeXML(userString) << "\"/>" << endl;
f << tabs(depth+1) << "<file name=\""<< escapeXML(convertFileStringToCanonical(rngName)) << "\"/>" << endl;
+ f << tabs(depth+1) << "<legend enabled=\""<< boolStrEnc(showLegend) << "\"/>" << endl;
f << tabs(depth+1) << "<dropunranged value=\""<<(int)dropUnranged<< "\"/>" << endl;
f << tabs(depth+1) << "<enabledions>"<< endl;
for(unsigned int ui=0;ui<enabledIons.size();ui++)
{
- RGBf col;
- string colourString;
+ ColourRGBAf col;
col = rng.getColour(ui);
- genColString((unsigned char)(col.red*255),(unsigned char)(col.green*255),
- (unsigned char)(col.blue*255),255,colourString);
+
f<< tabs(depth+2) << "<ion id=\"" << ui << "\" enabled=\""
- << (int)enabledIons[ui] << "\" colour=\"" << colourString << "\"/>" << endl;
+ << (int)enabledIons[ui] << "\" colour=\"" << col.toColourRGBA().rgbString()<< "\"/>" << endl;
}
f << tabs(depth+1) << "</enabledions>"<< endl;
@@ -1118,7 +1094,7 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
rngName=(char *)xmlString;
xmlFree(xmlString);
- //Override the string, as needed
+ //Override the string to strip leading ./ notation, as needed
if( (stateFileDir.size()) &&
(rngName.size() > 2 && rngName.substr(0,2) == "./") )
{
@@ -1132,18 +1108,28 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
return false;
//==
-
+
+
+ //TODO: Deprecate me. Did not exist prior to 0.0.17/
+ // internal 3e88134daeea
+ xmlNodePtr tmpNode=nodePtr;
+ if(!XMLHelpFwdToElem(tmpNode,"legend"))
+ {
+ if(XMLHelpGetProp(showLegend,tmpNode,"enabled"))
+ {
+ return false;
+ }
+ }
+ else
+ showLegend=false;
+
std::string tmpStr;
- //Retrieve user string
+ //Retrieve range status
//==
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"dropunranged","value"))
return false;
-
- if(tmpStr=="1")
- dropUnranged=true;
- else if(tmpStr=="0")
- dropUnranged=false;
- else
+
+ if(!boolStrDec(tmpStr,dropUnranged))
return false;
//==
@@ -1153,7 +1139,7 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
//===
if(XMLHelpFwdToElem(nodePtr,"enabledions"))
return false;
- xmlNodePtr tmpNode=nodePtr;
+ tmpNode=nodePtr;
nodePtr=nodePtr->xmlChildrenNode;
@@ -1161,7 +1147,7 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
bool enabled;
//By default, turn ions off, but use state file to turn them on
map<unsigned int ,char> tmpEnabledIons;
- map<unsigned int, RGBf> tmpCol;
+ map<unsigned int ,RGBf> tmpCol;
while(!XMLHelpFwdToElem(nodePtr,"ion"))
{
//Get ID value
@@ -1183,13 +1169,8 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- enabled=false;
- else if(tmpStr == "1")
- enabled=true;
- else
+ if(!boolStrDec(tmpStr,enabled))
return false;
-
tmpEnabledIons[ionID]=enabled;
xmlFree(xmlString);
@@ -1201,15 +1182,11 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
tmpStr=(char *)xmlString;
- unsigned char r,g,b,a;
- if(!parseColString(tmpStr,r,g,b,a))
+ ColourRGBA rgbaTmp;
+ if(!rgbaTmp.parse(tmpStr))
return false;
- RGBf col;
- col.red=(float)r/255.0f;
- col.green=(float)g/255.0f;
- col.blue=(float)b/255.0f;
- tmpCol[ionID]=col;
+ tmpCol[ionID]=rgbaTmp.toRGBAf().toRGBf();
xmlFree(xmlString);
}
@@ -1250,11 +1227,7 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "0")
- enabled=false;
- else if(tmpStr == "1")
- enabled=true;
- else
+ if(!boolStrDec(tmpStr,enabled))
return false;
xmlFree(xmlString);
@@ -1271,7 +1244,11 @@ bool RangeFileFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFil
if(tmpEnabledIons.size() == rng.getNumIons())
{
for(size_t ui=0;ui<tmpEnabledIons.size(); ui++)
+ {
enabledIons[ui] = tmpEnabledIons[ui];
+ rng.setColour(ui,tmpCol[ui]);
+
+ }
for(size_t ui=0;ui<tmpEnabledRanges.size(); ui++)
enabledRanges[ui] = tmpEnabledRanges[ui];
@@ -1291,7 +1268,10 @@ unsigned int RangeFileFilter::getRefreshBlockMask() const
unsigned int RangeFileFilter::getRefreshEmitMask() const
{
- return STREAM_TYPE_RANGE | STREAM_TYPE_IONS ;
+ unsigned int retmask= STREAM_TYPE_RANGE | STREAM_TYPE_IONS;
+ if(showLegend)
+ retmask |= STREAM_TYPE_DRAW;
+ return retmask;
}
unsigned int RangeFileFilter::getRefreshUseMask() const
diff --git a/src/backend/filters/rangeFile.h b/src/backend/filters/rangeFile.h
index 57e6d51..f8190d9 100644
--- a/src/backend/filters/rangeFile.h
+++ b/src/backend/filters/rangeFile.h
@@ -26,6 +26,7 @@ enum
RANGE_KEY_RANGE_ACTIVE=1,
RANGE_KEY_DROP_UNRANGED,
RANGE_KEY_RANGE_FILENAME,
+ RANGE_KEY_ENABLE_LEGEND,
RANGE_KEY_ENABLE_ALL_IONS, //Limited to ~100K ions
RANGE_KEY_ENABLE_ALL_RANGES=100000,
};
@@ -51,6 +52,9 @@ class RangeFileFilter : public Filter
//!range file object
RangeFile rng;
+ //Show a legend of enabled ions
+ bool showLegend;
+
public:
//!Set the format to assume when loading file
diff --git a/src/backend/filters/spatialAnalysis.cpp b/src/backend/filters/spatialAnalysis.cpp
index dc98e01..b0fdb44 100644
--- a/src/backend/filters/spatialAnalysis.cpp
+++ b/src/backend/filters/spatialAnalysis.cpp
@@ -23,7 +23,9 @@
#include "geometryHelpers.h"
#include "filterCommon.h"
#include "algorithms/binomial.h"
-
+#include "algorithms/K3DTree-mk2.h"
+#include "backend/plot.h"
+#include "../APT/APTFileIO.h"
enum
{
@@ -31,6 +33,7 @@ enum
KEY_ALGORITHM,
KEY_DISTMAX,
KEY_NNMAX,
+ KEY_NNMAX_NORMALISE,
KEY_NUMBINS,
KEY_REMOVAL,
KEY_REDUCTIONDIST,
@@ -49,6 +52,10 @@ enum
KEY_SHOW_BINOM_3D_GRID,
KEY_BINOMIAL_MAX_ASPECT,
KEY_BINOMIAL_EXTRUDE_DIR,
+ KEY_REPLACE_FILE,
+ KEY_REPLACE_TOLERANCE,
+ KEY_REPLACE_ALGORITHM,
+ KEY_REPLACE_VALUE,
};
enum {
@@ -57,6 +64,7 @@ enum {
ALGORITHM_RDF, //Radial Distribution Function
ALGORITHM_AXIAL_DF, //Axial Distribution Function (aka atomvicinity, sdm, 1D rdf)
ALGORITHM_BINOMIAL, //Binomial block method for statistical randomness testing
+ ALGORITHM_REPLACE, //Remove, set or modify points using an external file
ALGORITHM_ENUM_END,
};
@@ -66,14 +74,23 @@ enum{
STOP_MODE_ENUM_END
};
+enum
+{
+ REPLACE_MODE_SUBTRACT,
+ REPLACE_MODE_INTERSECT,
+ REPLACE_MODE_UNION,
+ REPLACE_MODE_ENUM_END
+};
+
//!Error codes
enum
{
- ABORT_ERR=1,
+ ERR_ABORT_FAIL=1,
ERR_BINOMIAL_NO_MEM,
ERR_BINOMIAL_NO_RANGE,
ERR_BINOMIAL_BIN_FAIL,
INSUFFICIENT_SIZE_ERR,
+ ERR_FILE_READ_FAIL,
SPAT_ERR_END_OF_ENUM,
};
// == NN analysis filter ==
@@ -85,7 +102,8 @@ const char *SPATIAL_ALGORITHMS[] = {
NTRANS("Density Filtering"),
NTRANS("Radial Distribution"),
NTRANS("Axial Distribution"),
- NTRANS("Binomial Distribution")
+ NTRANS("Binomial Distribution"),
+ NTRANS("Point Em/Replacement")
};
const char *STOP_MODES[] = {
@@ -93,12 +111,20 @@ const char *STOP_MODES[] = {
NTRANS("Radius")
};
+//User viisble names for the replace sub-algorithms
+const char *REPLACE_ALGORITHMS[] = { "Subtract",
+ "Intersect",
+ "Union",
+ };
+
+
//Switch to determine if algorithms need range propagation or not
const bool WANT_RANGE_PROPAGATION[] = { false,
true,
false,
false,
- false
+ false,
+ true,
};
@@ -118,6 +144,9 @@ SpatialAnalysisFilter::SpatialAnalysisFilter()
COMPILE_ASSERT(THREEDEP_ARRAYSIZE(STOP_MODES) == STOP_MODE_ENUM_END);
COMPILE_ASSERT(THREEDEP_ARRAYSIZE(SPATIAL_ALGORITHMS) == ALGORITHM_ENUM_END);
COMPILE_ASSERT(THREEDEP_ARRAYSIZE(WANT_RANGE_PROPAGATION) == ALGORITHM_ENUM_END);
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(REPLACE_ALGORITHMS) == REPLACE_MODE_ENUM_END);
+
+
algorithm=ALGORITHM_DENSITY;
nnMax=1;
distMax=1;
@@ -126,13 +155,13 @@ SpatialAnalysisFilter::SpatialAnalysisFilter()
haveRangeParent=false;
//Default colour is red
- r=a=1.0f;
- g=b=0.0f;
+ rgba=ColourRGBAf(1.0f,0,0);
//RDF params
numBins=100;
excludeSurface=false;
-
+ reductionDistance=distMax;
+ normaliseNNHist=true;
//Density filtering params
densityCutoff=1.0f;
keepDensityUpper=true;
@@ -148,7 +177,10 @@ SpatialAnalysisFilter::SpatialAnalysisFilter()
showGridOverlay=true;
//--
- reductionDistance=distMax;
+ //replace tolerance
+ replaceTolerance=sqrt(std::numeric_limits<float>::epsilon());
+ replaceMode=REPLACE_MODE_SUBTRACT;
+ replaceMass=true;
cacheOK=false;
cache=true; //By default, we should cache, but decision is made higher up
@@ -159,10 +191,7 @@ Filter *SpatialAnalysisFilter::cloneUncached() const
{
SpatialAnalysisFilter *p=new SpatialAnalysisFilter;
- p->r=r;
- p->g=g;
- p->b=b;
- p->a=a;
+ p->rgba=rgba;
p->algorithm=algorithm;
p->stopMode=stopMode;
@@ -185,6 +214,11 @@ Filter *SpatialAnalysisFilter::cloneUncached() const
p->showTheoreticFrequencies=showTheoreticFrequencies;
p->showGridOverlay=showGridOverlay;
+ p->replaceFile=replaceFile;
+ p->replaceMode=replaceMode;
+ p->replaceTolerance=replaceTolerance;
+ p->replaceMass=replaceMass;
+
//We are copying whether to cache or not,
//not the cache itself
p->cache=cache;
@@ -280,7 +314,7 @@ unsigned int SpatialAnalysisFilter::refresh(const std::vector<const FilterStream
if(cacheOK)
{
size_t mask=STREAM_TYPE_IONS;
- if(WANT_RANGE_PROPAGATION[algorithm])
+ if(!WANT_RANGE_PROPAGATION[algorithm])
mask|=STREAM_TYPE_RANGE;
//Propagate input streams as desired
@@ -348,6 +382,10 @@ unsigned int SpatialAnalysisFilter::refresh(const std::vector<const FilterStream
dataIn,getOut,rngF);
break;
}
+ case ALGORITHM_REPLACE:
+ result=algorithmReplace(progress,callback,totalDataSize,
+ dataIn,getOut);
+ break;
default:
ASSERT(false);
}
@@ -355,6 +393,136 @@ unsigned int SpatialAnalysisFilter::refresh(const std::vector<const FilterStream
return result;
}
+size_t SpatialAnalysisFilter::algorithmReplace(ProgressData &progress, bool (*callback)(bool), size_t totalDataSize,
+ const vector<const FilterStreamData *> &dataIn,
+ vector<const FilterStreamData * > &getOut)
+{
+ //Merge the ions form the incoming streams
+ vector<IonHit> inIons;
+ Filter::collateIons(dataIn,inIons,progress,callback,totalDataSize);
+
+ vector<IonHit> fileIons;
+ const unsigned int loadPositions[] = {
+ 0,1,2,3};
+ unsigned int errCode=GenericLoadFloatFile(4,4,loadPositions,
+ fileIons,replaceFile.c_str(),progress.filterProgress,callback);
+
+ if(errCode)
+ return ERR_FILE_READ_FAIL;
+
+
+ K3DTreeMk2 tree;
+ tree.setProgressPointer(&progress.filterProgress);
+ tree.setCallback(callback);
+ tree.resetPts(fileIons,false);
+ tree.build();
+ BoundCube b;
+ tree.getBoundCube(b);
+
+ //map the offset of the nearest to
+ //the tree ID
+ vector<size_t > nearestVec;
+ nearestVec.resize(inIons.size());
+
+ //TODO: pair vector might be faster
+ // as we can use it in sequence, and can use openmp
+ map<size_t,size_t> matchedMap;
+
+ #pragma omp parallel
+ {
+ //Find the nearest point for all points in the dataset
+
+ #pragma omp for
+ for(size_t ui=0;ui<inIons.size();ui++)
+ {
+ nearestVec[ui]=tree.findNearestUntagged(inIons[ui].getPos(),b,false);
+ }
+
+ //Filter this to only points that had an NN within range
+ for(size_t ui=0;ui<inIons.size();ui++)
+ {
+ if(nearestVec[ui]!=(size_t)-1 && inIons[ui].getPos().sqrDist(*tree.getPt(nearestVec[ui])) <=replaceTolerance)
+ {
+ #pragma omp critical
+ matchedMap[ui]=nearestVec[ui];
+ }
+ }
+ }
+
+ nearestVec.clear();
+
+ if(matchedMap.empty())
+ return 1;
+
+ vector<IonHit> outIons;
+ switch(replaceMode)
+ {
+ case REPLACE_MODE_SUBTRACT:
+ {
+ //In subtraction mode, we should have
+ // at least this many ions
+ if(inIons.size() > matchedMap.size())
+ outIons.reserve(inIons.size()-matchedMap.size());
+
+ //
+ #pragma omp parallel for
+ for(unsigned int ui=0;ui<inIons.size();ui++)
+ {
+ map<size_t,size_t>::iterator it;
+ it=matchedMap.find(ui);
+ if(it != matchedMap.end())
+ continue;
+
+ #pragma omp critical
+ outIons.push_back(inIons[ui]);
+ }
+ break;
+ }
+ case REPLACE_MODE_INTERSECT:
+ {
+ outIons.reserve(matchedMap.size());
+
+ if(replaceMass)
+ {
+ for(map<size_t,size_t>::const_iterator it=matchedMap.begin();it!=matchedMap.end();++it)
+ {
+ outIons.push_back(fileIons[it->second]);
+ }
+ }
+ else
+ {
+ for(map<size_t,size_t>::const_iterator it=matchedMap.begin();it!=matchedMap.end();++it)
+ {
+ outIons.push_back(inIons[it->first]);
+ }
+ }
+ break;
+ }
+ case REPLACE_MODE_UNION:
+ {
+ ASSERT(false);
+ break;
+ }
+ default:
+ ASSERT(false);
+ }
+
+ //Only output ions if any were found
+ if(outIons.size())
+ {
+ IonStreamData *outData = new IonStreamData(this);
+
+ outData->g = outData->b = outData->r = 0.5;
+ outData->data.swap(outIons);
+ cacheAsNeeded(outData);
+
+
+ getOut.push_back(outData);
+ }
+
+ return 0;
+}
+
void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
{
FilterProperty p;
@@ -378,6 +546,7 @@ void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.addProperty(p,curGroup);
choices.clear();
+ propertyList.setGroupTitle(curGroup,TRANS("Algorithm"));
curGroup++;
//Get the options for the current algorithm
@@ -410,6 +579,16 @@ void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
p.type=PROPERTY_TYPE_INTEGER;
p.helpText=TRANS("Maximum number of neighbours to examine");
p.key=KEY_NNMAX;
+ if(algorithm == ALGORITHM_RDF)
+ {
+ propertyList.addProperty(p,curGroup);
+
+ p.name=TRANS("Normalise bins");
+ p.data=boolStrEnc(normaliseNNHist);
+ p.type=PROPERTY_TYPE_BOOL;
+ p.helpText=TRANS("Normalise counts by binwidth. Needed when comparing NN histograms against one another");
+ p.key=KEY_NNMAX_NORMALISE;
+ }
}
else
{
@@ -460,16 +639,14 @@ void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
string thisCol;
//Convert the ion colour to a hex string
- genColString((unsigned char)(r*255),(unsigned char)(g*255),
- (unsigned char)(b*255),(unsigned char)(a*255),thisCol);
-
p.name=TRANS("Plot colour ");
- p.data=thisCol;
+ p.data=rgba.toColourRGBA().rgbaString();
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Colour of output plot");
p.key=KEY_COLOUR;
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Alg. Params."));
if(haveRangeParent)
{
ASSERT(ionSourceEnabled.size() == ionNames.size());
@@ -506,6 +683,8 @@ void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_ENABLE_SOURCE*1000+ui;
propertyList.addProperty(p,curGroup);
}
+
+ propertyList.setGroupTitle(curGroup,TRANS("Source Ion"));
curGroup++;
@@ -535,10 +714,10 @@ void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_ENABLE_TARGET*1000+ui;
propertyList.addProperty(p,curGroup);
}
+ propertyList.setGroupTitle(curGroup,TRANS("Target Ion"));
}
- propertyList.setGroupTitle(curGroup,TRANS("Alg. Params."));
break;
}
case ALGORITHM_DENSITY_FILTER:
@@ -579,13 +758,9 @@ void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_NUMBINS;
propertyList.addProperty(p,curGroup);
- string thisCol;
- //Convert the ion colour to a hex string
- genColString((unsigned char)(r*255),(unsigned char)(g*255),
- (unsigned char)(b*255),(unsigned char)(a*255),thisCol);
-
+
p.name=TRANS("Plot colour ");
- p.data=thisCol;
+ p.data=rgba.toColourRGBA().rgbString();
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Colour of output plot");
p.key=KEY_COLOUR;
@@ -700,6 +875,54 @@ void SpatialAnalysisFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.setGroupTitle(curGroup,TRANS("View Options"));
break;
}
+ case ALGORITHM_REPLACE:
+ {
+ tmpStr = replaceFile;
+ p.name=TRANS("Data File");
+ p.data=tmpStr;
+ p.dataSecondary="Pos File (*.pos)|*.pos|All Files|*";
+ p.type=PROPERTY_TYPE_FILE;
+ p.helpText=TRANS("Pos file of points to subtract/replace/etc");
+ p.key=KEY_REPLACE_FILE;
+ propertyList.addProperty(p,curGroup);
+
+ stream_cast(tmpStr,replaceTolerance);
+ p.name=TRANS("Match Tol.");
+ p.data=tmpStr;
+ p.type=PROPERTY_TYPE_REAL;
+ p.helpText=TRANS("Tolerance to allow for matching");
+ p.key=KEY_REPLACE_TOLERANCE;
+ propertyList.addProperty(p,curGroup);
+
+
+ vector<pair<unsigned int,string> > choices;
+
+ for(unsigned int ui=0;ui<REPLACE_MODE_ENUM_END;ui++)
+ {
+ tmpStr=TRANS(REPLACE_ALGORITHMS[ui]);
+ choices.push_back(make_pair(ui,tmpStr));
+ }
+
+ p.name=TRANS("Mode");
+ p.data= choiceString(choices,replaceMode);
+ p.type=PROPERTY_TYPE_CHOICE;
+ p.helpText=TRANS("Replacment condition");
+ p.key=KEY_REPLACE_ALGORITHM;
+ propertyList.addProperty(p,curGroup);
+
+ if(replaceMode != REPLACE_MODE_SUBTRACT)
+ {
+ p.name=TRANS("Replace value");
+ p.data=boolStrEnc(replaceMass);
+ p.type=PROPERTY_TYPE_BOOL;
+ p.helpText=TRANS("Use value data from file when replacing ions");
+ p.key=KEY_REPLACE_VALUE;
+ propertyList.addProperty(p,curGroup);
+ }
+
+ propertyList.setGroupTitle(curGroup,TRANS("Replacement"));
+ break;
+ }
default:
ASSERT(false);
}
@@ -803,6 +1026,12 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
break;
}
+ case KEY_NNMAX_NORMALISE:
+ {
+ if(!applyPropertyNow(normaliseNNHist,value,needUpdate))
+ return false;
+ break;
+ }
case KEY_NUMBINS:
{
unsigned int ltmp;
@@ -835,37 +1064,21 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
}
case KEY_REMOVAL:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(excludeSurface,value,needUpdate))
return false;
-
- bool lastVal=excludeSurface;
- excludeSurface=(stripped=="1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=excludeSurface)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_COLOUR:
{
- unsigned char newR,newG,newB,newA;
+ ColourRGBA tmpRgba;
- parseColString(value,newR,newG,newB,newA);
+ if(!tmpRgba.parse(value))
+ return false;
- if(newB != b || newR != r ||
- newG !=g || newA != a)
+
+ if(rgba.toColourRGBA() != tmpRgba)
{
- r=newR/255.0;
- g=newG/255.0;
- b=newB/255.0;
- a=newA/255.0;
+ rgba=tmpRgba.toRGBAf();
if(cacheOK)
{
@@ -876,9 +1089,9 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
PlotStreamData *p;
p =(PlotStreamData*)filterOutputs[ui];
- p->r=r;
- p->g=g;
- p->b=b;
+ p->r=rgba.r();
+ p->g=rgba.g();
+ p->b=rgba.b();
}
}
@@ -957,22 +1170,8 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
}
case KEY_RETAIN_UPPER:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(keepDensityUpper,value,needUpdate))
return false;
-
- bool lastVal=keepDensityUpper;
- keepDensityUpper=(stripped=="1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=keepDensityUpper)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_RADIUS:
@@ -1011,17 +1210,8 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
}
case KEY_ORIGIN:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(vectorParams[0],value,needUpdate))
return false;
-
- if(!(vectorParams[0] == newPt ))
- {
- vectorParams[0] = newPt;
- needUpdate=true;
- clearCache();
- }
-
return true;
}
case KEY_NUMIONS:
@@ -1041,59 +1231,20 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
}
case KEY_SHOW_BINOM_FREQ:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(showBinomialFrequencies,value,needUpdate))
return false;
-
- bool lastVal=showBinomialFrequencies;
- showBinomialFrequencies=(stripped=="1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=showBinomialFrequencies)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_SHOW_BINOM_NORM_FREQ:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(showNormalisedBinomialFrequencies,value,needUpdate))
return false;
-
- bool lastVal=showNormalisedBinomialFrequencies;
- showNormalisedBinomialFrequencies=(stripped=="1");
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=showNormalisedBinomialFrequencies)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_SHOW_BINOM_THEOR_FREQ:
{
- bool lastVal=showTheoreticFrequencies;
-
- if(!boolStrDec(value,showTheoreticFrequencies))
+ if(!applyPropertyNow(showTheoreticFrequencies,value,needUpdate))
return false;
-
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=showTheoreticFrequencies)
- {
- needUpdate=true;
- clearCache();
- }
-
break;
}
case KEY_BINOMIAL_MAX_ASPECT:
@@ -1131,20 +1282,52 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
}
case KEY_SHOW_BINOM_3D_GRID:
{
- bool lastVal=showGridOverlay;
- if(!boolStrDec(value,showGridOverlay))
+ if(!applyPropertyNow(showGridOverlay,value,needUpdate))
return false;
- //if the result is different, the
- //cache should be invalidated
- if(lastVal!=showGridOverlay)
+ break;
+ }
+ case KEY_REPLACE_FILE:
+ {
+ if(!applyPropertyNow(replaceFile,value,needUpdate))
+ return false;
+ break;
+ }
+ case KEY_REPLACE_TOLERANCE:
+ {
+ if(!applyPropertyNow(replaceTolerance,value,needUpdate))
+ return false;
+ break;
+ }
+ case KEY_REPLACE_ALGORITHM:
+ {
+ size_t newVal=REPLACE_MODE_ENUM_END;
+ for(size_t ui=0;ui<REPLACE_MODE_ENUM_END; ui++)
+ {
+ if( value == TRANS(REPLACE_ALGORITHMS[ui]))
+ {
+ newVal=ui;
+ break;
+ }
+ }
+ if(newVal==REPLACE_MODE_ENUM_END)
+ return false;
+
+ if(replaceMode != newVal)
{
needUpdate=true;
clearCache();
+ replaceMode=newVal;
}
-
break;
}
+ case KEY_REPLACE_VALUE:
+ {
+ if(!applyPropertyNow(replaceMass,value,needUpdate))
+ return false;
+ break;
+
+ }
default:
{
ASSERT(haveRangeParent);
@@ -1218,33 +1401,26 @@ bool SpatialAnalysisFilter::setProperty( unsigned int key,
std::string SpatialAnalysisFilter::getErrString(unsigned int code) const
{
- //Currently the only error is aborting
-
-
- switch(code)
- {
- case ABORT_ERR:
- return std::string(TRANS("Spatial analysis aborted by user"));
- case INSUFFICIENT_SIZE_ERR:
- return std::string(TRANS("Insufficient data to complete analysis."));
- case ERR_BINOMIAL_BIN_FAIL:
- return std::string(TRANS("Insufficient bins in histogram for analysis."));
- case ERR_BINOMIAL_NO_MEM:
- return std::string(TRANS("Insufficient memory for binomial. Reduce input size?"));
- case ERR_BINOMIAL_NO_RANGE:
- return std::string(TRANS("Binomial requires a parent range file"));
- default:
- ASSERT(false);
-
- }
+ const char *errStrings[] = {"",
+ "Spatial analysis aborted by user",
+ "Insufficient memory to complete analysis",
+ "Insufficient bins in histogram for analysis",
+ "Insufficient memory for binomial. Reduce input size?",
+ "Binomial requires a parent range file",
+ "File read failed",
+ };
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrings) == SPAT_ERR_END_OF_ENUM);
+
+
+ ASSERT(code < SPAT_ERR_END_OF_ENUM);
- return std::string("Bug! (Spatial analysis filter) Shouldn't see this");
+ return std::string(errStrings[code]);
}
void SpatialAnalysisFilter::setUserString(const std::string &str)
{
//Which algorithms have plot outputs?
- const bool ALGORITHM_HAS_PLOTS[] = { false,false,true,true,true};
+ const bool ALGORITHM_HAS_PLOTS[] = { false,false,true,true,true,false};
COMPILE_ASSERT(THREEDEP_ARRAYSIZE(ALGORITHM_HAS_PLOTS) == ALGORITHM_ENUM_END);
@@ -1299,14 +1475,19 @@ bool SpatialAnalysisFilter::writeState(std::ostream &f,unsigned int format, unsi
f << tabs(depth+1) << "<algorithm value=\""<<algorithm<< "\"/>" << endl;
f << tabs(depth+1) << "<stopmode value=\""<<stopMode<< "\"/>" << endl;
f << tabs(depth+1) << "<nnmax value=\""<<nnMax<< "\"/>" << endl;
+ f << tabs(depth+1) << "<normalisennhist value=\""<<boolStrEnc(normaliseNNHist)<< "\"/>" << endl;
f << tabs(depth+1) << "<distmax value=\""<<distMax<< "\"/>" << endl;
f << tabs(depth+1) << "<numbins value=\""<<numBins<< "\"/>" << endl;
f << tabs(depth+1) << "<excludesurface value=\""<<excludeSurface<< "\"/>" << endl;
f << tabs(depth+1) << "<reductiondistance value=\""<<reductionDistance<< "\"/>" << endl;
- f << tabs(depth+1) << "<colour r=\"" << r<< "\" g=\"" << g << "\" b=\"" <<b
- << "\" a=\"" << a << "\"/>" <<endl;
+ f << tabs(depth+1) << "<colour r=\"" << rgba.r() << "\" g=\"" << rgba.g() << "\" b=\"" <<rgba.b()
+ << "\" a=\"" << rgba.a() << "\"/>" <<endl;
+
f << tabs(depth+1) << "<densitycutoff value=\""<<densityCutoff<< "\"/>" << endl;
f << tabs(depth+1) << "<keepdensityupper value=\""<<(int)keepDensityUpper<< "\"/>" << endl;
+
+ f << tabs(depth+1) << "<replace file=\""<<replaceFile << "\" mode=\"" << replaceMode
+ << "\" tolerance=\"" << replaceTolerance << "\" replacemass=\"" << boolStrEnc(replaceMass) << "\" />" << endl;
//-- Binomial paramters ---
@@ -1322,11 +1503,11 @@ bool SpatialAnalysisFilter::writeState(std::ostream &f,unsigned int format, unsi
//--------------------------
- writeVectorsXML(f,"vectorparams",vectorParams,depth);
- writeScalarsXML(f,"scalarparams",scalarParams,depth);
+ writeVectorsXML(f,"vectorparams",vectorParams,depth+1);
+ writeScalarsXML(f,"scalarparams",scalarParams,depth+1);
- writeIonsEnabledXML(f,"source",ionSourceEnabled,ionNames,depth);
- writeIonsEnabledXML(f,"target",ionTargetEnabled,ionNames,depth);
+ writeIonsEnabledXML(f,"source",ionSourceEnabled,ionNames,depth+1);
+ writeIonsEnabledXML(f,"target",ionTargetEnabled,ionNames,depth+1);
f << tabs(depth) << "</" << trueName() << ">" << endl;
break;
@@ -1380,6 +1561,17 @@ bool SpatialAnalysisFilter::readState(xmlNodePtr &nodePtr, const std::string &st
return false;
//===
+ //Retrieve histogram normalisation
+ //TODO: COMPAT : did not exist prior to 0.0.17
+ // internal 5033191f0c61
+ //======
+ xmlNodePtr tmpNode = nodePtr;
+ if(!XMLGetNextElemAttrib(tmpNode,nnMax,"normalisennhist","value"))
+ {
+ normaliseNNHist=false;
+ }
+ //===
+
//Retrieve distMax val
//======
if(!XMLGetNextElemAttrib(nodePtr,distMax,"distmax","value"))
@@ -1418,8 +1610,10 @@ bool SpatialAnalysisFilter::readState(xmlNodePtr &nodePtr, const std::string &st
//====
if(XMLHelpFwdToElem(nodePtr,"colour"))
return false;
- if(!parseXMLColour(nodePtr,r,g,b,a))
+ ColourRGBAf tmpRgbaf;
+ if(!parseXMLColour(nodePtr,tmpRgbaf))
return false;
+ rgba=tmpRgbaf;
//====
@@ -1436,9 +1630,29 @@ bool SpatialAnalysisFilter::readState(xmlNodePtr &nodePtr, const std::string &st
return false;
+ //FIXME:COMPAT_BREAK : 3Depict <= internal fb7d66397b7b does not contain
+ tmpNode=nodePtr;
+ if(!XMLHelpFwdToElem(nodePtr,"replace"))
+ {
+ if(XMLHelpGetProp(replaceFile,nodePtr,"file"))
+ return false;
+
+ if(XMLHelpGetProp(replaceMode,nodePtr,"mode"))
+ return false;
+
+ if(replaceMode>REPLACE_MODE_ENUM_END)
+ return false;
+
+ if(XMLHelpGetProp(replaceTolerance,nodePtr,"tolerance"))
+ return false;
+ if(replaceTolerance < 0)
+ return false;
+ }
+ else
+ nodePtr=tmpNode;
+
//FIXME:COMPAT_BREAK : 3Depict <= 1796:5639f6d50732 does not contain
// this section
- xmlNodePtr tmpNode;
tmpNode=nodePtr;
if(!XMLHelpFwdToElem(nodePtr,"binomial"))
@@ -1650,7 +1864,7 @@ size_t SpatialAnalysisFilter::buildSplitPoints(const vector<const FilterStreamDa
{
if(extendPointVector(pSource,d->data,callback,
progress.filterProgress,curPos[0]))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
curPos[0]+=d->data.size();
}
@@ -1659,7 +1873,7 @@ size_t SpatialAnalysisFilter::buildSplitPoints(const vector<const FilterStreamDa
{
if(extendPointVector(pTarget,d->data,callback,
progress.filterProgress,curPos[1]))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
curPos[1]+=d->data.size();
}
@@ -1721,7 +1935,7 @@ size_t buildMonolithicPoints(const vector<const FilterStreamData *> &dataIn,
progress.filterProgress=0;
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
for(unsigned int ui=0;ui<dataIn.size() ;ui++)
{
@@ -1735,7 +1949,7 @@ size_t buildMonolithicPoints(const vector<const FilterStreamData *> &dataIn,
if(extendPointVector(p,d->data,
callback,progress.filterProgress,
dataSize))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
dataSize+=d->data.size();
}
@@ -1762,7 +1976,7 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
progress.maxStep=3;
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
K3DTree kdTree;
kdTree.setCallbackMethod(callback);
@@ -1793,6 +2007,8 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
//Build the tree using the target ions
//(its roughly nlogn timing, but worst case n^2)
kdTree.buildByRef(pts[1]);
+ if(!(*callback)(true))
+ return ERR_ABORT_FAIL;
pts[1].clear();
//Remove surface points from sources if desired
@@ -1803,7 +2019,7 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
progress.stepName=TRANS("Surface");
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
//Take the input points, then use them
@@ -1818,12 +2034,12 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
else
{
ASSERT(false);
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
}
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
pts[0].clear();
//Forget the original points, and use the new ones
@@ -1846,6 +2062,8 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
//Build the tree (its roughly nlogn timing, but worst case n^2)
kdTree.buildByRef(p);
+ if(!(*callback)(true))
+ return ERR_ABORT_FAIL;
//Remove surface points if desired
if(excludeSurface)
@@ -1855,7 +2073,7 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
progress.stepName=TRANS("Surface");
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
//Take the input points, then use them
@@ -1870,11 +2088,11 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
if(errCode ==1)
return INSUFFICIENT_SIZE_ERR;
else if(errCode ==2)
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
else
{
ASSERT(false);
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
}
@@ -1884,7 +2102,7 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
p.swap(returnPoints);
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
@@ -1933,12 +2151,37 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
case RDF_ABORT_FAIL:
{
delete[] binWidth;
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
default:
ASSERT(false);
}
+
+ vector<vector<float> > histogramFloat;
+ histogramFloat.resize(nnMax);
+ //Normalise the NN histograms to a per bin width as required
+ if(normaliseNNHist)
+ {
+ for(unsigned int ui=0;ui<nnMax; ui++)
+ {
+ histogramFloat[ui].resize(numBins);
+ for(unsigned int uj=0;uj<numBins;uj++)
+ histogramFloat[ui][uj] = (float)histogram[ui][uj]/binWidth[ui] ;
+ }
+
+ }
+ else
+ {
+ for(unsigned int ui=0;ui<nnMax;ui++)
+ {
+ histogramFloat[ui].resize(numBins);
+ for(unsigned int uj=0;uj<numBins;uj++)
+ histogramFloat[ui][uj] = (float)histogram[ui][uj];
+ }
+ }
+ histogram.clear();
+
//Alright then, we have the histogram in x-{y1,y2,y3...y_n} form
//lets make some plots shall we?
PlotStreamData *plotData[nnMax];
@@ -1950,36 +2193,30 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
plotData[ui]->parent=this;
plotData[ui]->plotMode=PLOT_MODE_1D;
plotData[ui]->xLabel=TRANS("Radial Distance");
- plotData[ui]->yLabel=TRANS("Count");
+ if(normaliseNNHist)
+ plotData[ui]->yLabel=TRANS("Count/Distance");
+ else
+ plotData[ui]->yLabel=TRANS("Count");
std::string tmpStr;
stream_cast(tmpStr,ui+1);
plotData[ui]->dataLabel=getUserString() + string(" ") +tmpStr + TRANS("NN Freq.");
//Red plot.
- plotData[ui]->r=r;
- plotData[ui]->g=g;
- plotData[ui]->b=b;
+ plotData[ui]->r=rgba.r();
+ plotData[ui]->g=rgba.g();
+ plotData[ui]->b=rgba.b();
plotData[ui]->xyData.resize(numBins);
for(unsigned int uj=0;uj<numBins;uj++)
{
float dist;
- ASSERT(ui < histogram.size() && uj<histogram[ui].size());
+ ASSERT(ui < histogramFloat.size() && uj<histogramFloat[ui].size());
dist = (float)uj*binWidth[ui];
plotData[ui]->xyData[uj] = std::make_pair(dist,
- histogram[ui][uj]);
+ histogramFloat[ui][uj]);
}
- if(cache)
- {
- plotData[ui]->cached=1;
- filterOutputs.push_back(plotData[ui]);
- cacheOK=true;
- }
- else
- {
- plotData[ui]->cached=0;
- }
+ cacheAsNeeded(plotData[ui]);
getOut.push_back(plotData[ui]);
}
@@ -2002,7 +2239,7 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
warnBiasCount,&(progress.filterProgress),callback);
if(errcode)
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
if(warnBiasCount)
{
@@ -2022,9 +2259,9 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
plotData->yLabel=TRANS("Count");
plotData->dataLabel=getUserString() + TRANS(" RDF");
- plotData->r=r;
- plotData->g=g;
- plotData->b=b;
+ plotData->r=rgba.r();
+ plotData->g=rgba.g();
+ plotData->b=rgba.b();
plotData->xyData.resize(numBins);
for(unsigned int uj=0;uj<numBins;uj++)
@@ -2036,15 +2273,8 @@ size_t SpatialAnalysisFilter::algorithmRDF(ProgressData &progress, bool (*callba
}
delete[] histogram;
-
- if(cache)
- {
- plotData->cached=1;
- filterOutputs.push_back(plotData);
- cacheOK=true;
- }
- else
- plotData->cached=0;
+
+ cacheAsNeeded(plotData);
getOut.push_back(plotData);
@@ -2090,7 +2320,7 @@ size_t SpatialAnalysisFilter::algorithmDensity(ProgressData &progress,
progress.stepName=TRANS("Build");
progress.filterProgress=0;
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
BoundCube treeDomain;
treeDomain.setBounds(p);
@@ -2101,13 +2331,13 @@ size_t SpatialAnalysisFilter::algorithmDensity(ProgressData &progress,
kdTree.setProgressPointer(&(progress.filterProgress));
kdTree.buildByRef(p);
- p.clear(); //We don't need pts any more, as tree *is* a copy.
//Update progress & User interface by calling callback
- if(!(*callback)(false))
- return ABORT_ERR;
+ if(!(*callback)(true))
+ return ERR_ABORT_FAIL;
+ p.clear(); //We don't need pts any more, as tree *is* a copy.
//Its algorithm time!
//----
@@ -2117,7 +2347,7 @@ size_t SpatialAnalysisFilter::algorithmDensity(ProgressData &progress,
progress.stepName=TRANS("Analyse");
progress.filterProgress=0;
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
//List of points for which there was a failure
//first entry is the point Id, second is the
@@ -2190,7 +2420,7 @@ size_t SpatialAnalysisFilter::algorithmDensity(ProgressData &progress,
if(spin)
{
delete newD;
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
@@ -2247,7 +2477,7 @@ size_t SpatialAnalysisFilter::algorithmDensity(ProgressData &progress,
spin=true;
#else
delete newD;
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
#endif
}
}
@@ -2271,7 +2501,7 @@ size_t SpatialAnalysisFilter::algorithmDensity(ProgressData &progress,
if(spin)
{
delete newD;
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
#endif
}
@@ -2312,15 +2542,8 @@ size_t SpatialAnalysisFilter::algorithmDensity(ProgressData &progress,
newD->representationType=d->representationType;
newD->valueType=TRANS("Number Density (\\#/Vol^3)");
- //Cache result as needed
- if(cache)
- {
- newD->cached=1;
- filterOutputs.push_back(newD);
- cacheOK=true;
- }
- else
- newD->cached=0;
+ //Cache result as neede
+ cacheAsNeeded(newD);
getOut.push_back(newD);
}
else
@@ -2388,7 +2611,7 @@ size_t SpatialAnalysisFilter::algorithmDensityFilter(ProgressData &progress,
progress.stepName=TRANS("Build");
progress.filterProgress=0;
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
BoundCube treeDomain;
treeDomain.setBounds(p);
@@ -2402,8 +2625,8 @@ size_t SpatialAnalysisFilter::algorithmDensityFilter(ProgressData &progress,
//Update progress & User interface by calling callback
- if(!(*callback)(false))
- return ABORT_ERR;
+ if(!(*callback)(true))
+ return ERR_ABORT_FAIL;
p.clear(); //We don't need pts any more, as tree *is* a copy.
@@ -2415,7 +2638,7 @@ size_t SpatialAnalysisFilter::algorithmDensityFilter(ProgressData &progress,
progress.stepName=TRANS("Analyse");
progress.filterProgress=0;
if(!(*callback)(true))
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
//List of points for which there was a failure
//first entry is the point Id, second is the
@@ -2494,7 +2717,7 @@ size_t SpatialAnalysisFilter::algorithmDensityFilter(ProgressData &progress,
if(spin)
{
delete newD;
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
@@ -2551,7 +2774,7 @@ size_t SpatialAnalysisFilter::algorithmDensityFilter(ProgressData &progress,
spin=true;
#else
delete newD;
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
#endif
}
}
@@ -2579,7 +2802,7 @@ size_t SpatialAnalysisFilter::algorithmDensityFilter(ProgressData &progress,
if(spin)
{
delete newD;
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
#endif
}
@@ -2621,14 +2844,7 @@ size_t SpatialAnalysisFilter::algorithmDensityFilter(ProgressData &progress,
newD->valueType=TRANS("Number Density (\\#/Vol^3)");
//Cache result as needed
- if(cache)
- {
- newD->cached=1;
- filterOutputs.push_back(newD);
- cacheOK=true;
- }
- else
- newD->cached=0;
+ cacheAsNeeded(newD);
getOut.push_back(newD);
}
else
@@ -2798,7 +3014,7 @@ size_t SpatialAnalysisFilter::algorithmAxialDf(ProgressData &progress,
}
if(wantAbort)
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
//Now, the ions outside the targeting volume may be reduced
vector<IonHit> ionsOutside;
@@ -2862,10 +3078,10 @@ size_t SpatialAnalysisFilter::algorithmAxialDf(ProgressData &progress,
case ERR_CROP_INSUFFICIENT_MEM:
return INSUFFICIENT_SIZE_ERR;
case ERR_CROP_CALLBACK_FAIL:
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
default:
ASSERT(false);
- return ABORT_ERR;
+ return ERR_ABORT_FAIL;
}
tmp.swap(ionsOutside);
@@ -2932,6 +3148,8 @@ size_t SpatialAnalysisFilter::algorithmAxialDf(ProgressData &progress,
tree.setProgressPointer(&progress.filterProgress);
tree.setCallbackMethod(callback);
tree.buildByRef(dest);
+ if(!(*callback)(true))
+ return ERR_ABORT_FAIL;
progress.step=4;
progress.stepName=TRANS("Compute");
@@ -2955,19 +3173,6 @@ size_t SpatialAnalysisFilter::algorithmAxialDf(ProgressData &progress,
errCode=generate1DAxialNNHist(src,tree,axisNormal, histogram,
binWidth,nnMax,numBins,&progress.filterProgress,callback);
- //Remap the underlying function code ot that for this function
- switch(errCode)
- {
- case 0:
- histOK=true;
- break;
- case RDF_ERR_INSUFFICIENT_INPUT_POINTS:
- consoleOutput.push_back(TRANS("Insufficient points to complete analysis"));
- errCode=0;
- break;
- default:
- ASSERT(false);
- }
break;
}
case STOP_MODE_RADIUS:
@@ -2978,12 +3183,29 @@ size_t SpatialAnalysisFilter::algorithmAxialDf(ProgressData &progress,
errCode=generate1DAxialDistHist(src,tree,axisNormal, histogram,
distMax,numBins,&progress.filterProgress,callback);
- histOK = (errCode !=0);
+ histOK = (errCode ==0);
break;
}
default:
ASSERT(false);
}
+
+ //Remap the underlying function code to that for this function
+ switch(errCode)
+ {
+ case 0:
+ histOK=true;
+ break;
+ case RDF_ERR_INSUFFICIENT_INPUT_POINTS:
+ consoleOutput.push_back(TRANS("Insufficient points to complete analysis"));
+ errCode=0;
+ break;
+ case RDF_ABORT_FAIL:
+ errCode=ERR_ABORT_FAIL;
+ break;
+ default:
+ ASSERT(false);
+ }
if(errCode)
{
@@ -3002,9 +3224,9 @@ size_t SpatialAnalysisFilter::algorithmAxialDf(ProgressData &progress,
plotData->yLabel=TRANS("Count");
plotData->dataLabel=getUserString() + TRANS(" 1D Dist. Func.");
- plotData->r=r;
- plotData->g=g;
- plotData->b=b;
+ plotData->r=rgba.r();
+ plotData->g=rgba.g();
+ plotData->b=rgba.b();
plotData->xyData.resize(numBins);
for(unsigned int uj=0;uj<numBins;uj++)
@@ -3025,14 +3247,7 @@ size_t SpatialAnalysisFilter::algorithmAxialDf(ProgressData &progress,
histogram[uj]);
}
- if(cache)
- {
- plotData->cached=1;
- filterOutputs.push_back(plotData);
- cacheOK=true;
- }
- else
- plotData->cached=0;
+ cacheAsNeeded(plotData);
getOut.push_back(plotData);
}
@@ -3213,7 +3428,7 @@ size_t SpatialAnalysisFilter::algorithmBinomial(ProgressData &progress,
plt->index=ui;
plt->parent=this;
plt->plotMode=PLOT_MODE_1D;
- plt->plotStyle=PLOT_TRACE_STEM;
+ plt->plotStyle=PLOT_LINE_STEM;
plt->xLabel=TRANS("Block size");
if(showNormalisedBinomialFrequencies)
plt->yLabel=TRANS("Rel. Frequency");
@@ -3254,17 +3469,7 @@ size_t SpatialAnalysisFilter::algorithmBinomial(ProgressData &progress,
}
}
- if(cache)
- {
- plt->cached=1;
- filterOutputs.push_back(plt);
- cacheOK=true;
- }
- else
- {
- plt->cached=0;
- }
-
+ cacheAsNeeded(plt);
getOut.push_back(plt);
}
@@ -3282,7 +3487,7 @@ size_t SpatialAnalysisFilter::algorithmBinomial(ProgressData &progress,
plt->index=ui + binHist.mapIonFrequencies.size();
plt->parent=this;
plt->plotMode=PLOT_MODE_1D;
- plt->plotStyle=PLOT_TRACE_STEM;
+ plt->plotStyle=PLOT_LINE_STEM;
plt->xLabel=TRANS("Block size");
if(showNormalisedBinomialFrequencies)
plt->yLabel=TRANS("Rel. Frequency");
@@ -3323,16 +3528,7 @@ size_t SpatialAnalysisFilter::algorithmBinomial(ProgressData &progress,
}
}
- if(cache)
- {
- plt->cached=1;
- filterOutputs.push_back(plt);
- cacheOK=true;
- }
- else
- {
- plt->cached=0;
- }
+ cacheAsNeeded(plt);
getOut.push_back(plt);
@@ -3347,6 +3543,7 @@ bool densityPairTest();
bool nnHistogramTest();
bool rdfPlotTest();
bool axialDistTest();
+bool replaceTest();
bool SpatialAnalysisFilter::runUnitTests()
{
@@ -3361,7 +3558,8 @@ bool SpatialAnalysisFilter::runUnitTests()
if(!axialDistTest())
return false;
-
+ if(!replaceTest())
+ return false;
return true;
}
@@ -3627,5 +3825,66 @@ bool axialDistTest()
return true;
}
+bool replaceTest()
+{
+ std::string ionFile=createTmpFilename(NULL,".pos");
+
+ vector<IonHit> ions;
+ const unsigned int NIONS=10;
+ for(unsigned int ui=0;ui<NIONS;ui++)
+ ions.push_back(IonHit(Point3D(ui,ui,ui),1));
+
+ IonHit::makePos(ions,ionFile.c_str());
+
+ for(unsigned int ui=0;ui<NIONS;ui++)
+ ions[ui].setMassToCharge(2);
+
+ IonStreamData *d = new IonStreamData;
+ d->data.swap(ions);
+
+ //Create a spatial analysis filter
+ SpatialAnalysisFilter *f=new SpatialAnalysisFilter;
+ f->setCaching(false);
+
+ //Set it to do a union calculation
+ bool needUp;
+ string s;
+ s=TRANS(SPATIAL_ALGORITHMS[ALGORITHM_REPLACE]);
+ TEST(f->setProperty(KEY_ALGORITHM,s,needUp),"Set prop");
+ TEST(f->setProperty(KEY_REPLACE_FILE,ionFile,needUp),"Set prop");
+ s=TRANS(REPLACE_ALGORITHMS[REPLACE_MODE_INTERSECT]);
+ TEST(f->setProperty(KEY_REPLACE_ALGORITHM,s,needUp),"Set prop");
+
+ s="1";
+ TEST(f->setProperty(KEY_REPLACE_VALUE,s,needUp),"Set prop");
+
+
+ //Do the refresh
+ ProgressData p;
+ vector<const FilterStreamData*> streamIn,streamOut;
+ streamIn.push_back(d);
+ TEST(!f->refresh(streamIn,streamOut,p,dummyCallback),"refresh OK");
+ delete f;
+ delete d;
+ streamIn.clear();
+
+ TEST(streamOut.size() == 1,"stream count");
+ TEST(streamOut[0]->getStreamType() == STREAM_TYPE_IONS,"stream type");
+ TEST(streamOut[0]->getNumBasicObjects() == NIONS,"Number objects");
+
+ //we should have taken the mass-to-charge from the file
+ const IonStreamData *outIons = (const IonStreamData*)streamOut[0];
+ for(unsigned int ui=0;ui<NIONS; ui++)
+ {
+ ASSERT(outIons->data[ui].getMassToCharge() == 1);
+ }
+
+ wxRemoveFile(ionFile);
+
+ delete streamOut[0];
+
+ return true;
+}
+
#endif
diff --git a/src/backend/filters/spatialAnalysis.h b/src/backend/filters/spatialAnalysis.h
index 2a5260d..42422fc 100644
--- a/src/backend/filters/spatialAnalysis.h
+++ b/src/backend/filters/spatialAnalysis.h
@@ -25,7 +25,7 @@ class SpatialAnalysisFilter : public Filter
{
private:
//!Colour to use for output plots
- float r,g,b,a;
+ ColourRGBAf rgba;
//!Which algorithm to use
unsigned int algorithm;
@@ -56,6 +56,10 @@ class SpatialAnalysisFilter : public Filter
//!Surface reduction distance (convex hull)
float reductionDistance;
+
+ //!Change the NN histograms from counts to counts/nm
+ // - this allows comparing different binwidth histograms
+ bool normaliseNNHist;
//--------
//Density filtering specific params
@@ -105,7 +109,20 @@ class SpatialAnalysisFilter : public Filter
//--------
+ //Replace specific code
+ //---------
+ //file to use as other data source
+ string replaceFile;
+
+ //replacement operator mode
+ unsigned int replaceMode;
+ //distance up to which to allow replacement
+ float replaceTolerance;
+
+ //should we replace the current mass by the other file's ?
+ bool replaceMass;
+ //---------
//Radial distribution function - creates a 1D histogram of spherical atom counts, centered around each atom
size_t algorithmRDF(ProgressData &progress, bool (*callback)(bool), size_t totalDataSize,
@@ -132,6 +149,10 @@ class SpatialAnalysisFilter : public Filter
const vector<const FilterStreamData *> &dataIn,
vector<const FilterStreamData * > &getOut,const RangeFile *rngF);
+ size_t algorithmReplace(ProgressData &progress, bool (*callback)(bool), size_t totalDataSize,
+ const vector<const FilterStreamData *> &dataIn,
+ vector<const FilterStreamData * > &getOut);
+
//Create a 3D manipulable cylinder as an output drawable
// using the parameters stored inside the vector/scalar params
// both parameters are outputs from this function
diff --git a/src/backend/filters/spectrumPlot.cpp b/src/backend/filters/spectrumPlot.cpp
index 39e6250..90f320a 100644
--- a/src/backend/filters/spectrumPlot.cpp
+++ b/src/backend/filters/spectrumPlot.cpp
@@ -27,6 +27,7 @@ enum
SPECTRUM_BAD_ALLOC=1,
SPECTRUM_BAD_BINCOUNT,
SPECTRUM_ABORT_FAIL,
+ SPECTRUM_ERR_ENUM_END,
};
enum
@@ -55,8 +56,7 @@ SpectrumPlotFilter::SpectrumPlotFilter()
logarithmic=1;
//Default to blue plot
- r=g=0;
- b=a=1;
+ rgba = ColourRGBAf(0,0,1.0f,1.0f);
}
Filter *SpectrumPlotFilter::cloneUncached() const
@@ -67,10 +67,7 @@ Filter *SpectrumPlotFilter::cloneUncached() const
p->maxPlot=maxPlot;
p->binWidth=binWidth;
p->autoExtrema=autoExtrema;
- p->r=r;
- p->g=g;
- p->b=b;
- p->a=a;
+ p->rgba=rgba;
p->plotStyle=plotStyle;
p->logarithmic = logarithmic;
@@ -185,7 +182,7 @@ unsigned int SpectrumPlotFilter::refresh(const std::vector<const FilterStreamDat
fabs(delta) > std::numeric_limits<float>::max() || // Check for out-of-range
binWidth < sqrt(std::numeric_limits<float>::epsilon()) )
{
- //If not, then simply set it to "1".
+ //If not, then simply set it to some defaults.
minPlot=0; maxPlot=1.0; binWidth=0.1;
}
@@ -225,10 +222,10 @@ unsigned int SpectrumPlotFilter::refresh(const std::vector<const FilterStreamDat
}
- d->r = r;
- d->g = g;
- d->b = b;
- d->a = a;
+ d->r =rgba.r();
+ d->g = rgba.g();
+ d->b = rgba.b();
+ d->a = rgba.a();
d->logarithmic=logarithmic;
d->plotStyle = plotStyle;
@@ -371,15 +368,8 @@ unsigned int SpectrumPlotFilter::refresh(const std::vector<const FilterStreamDat
}
- if(cache)
- {
- d->cached=1; //IMPORTANT: cached must be set PRIOR to push back
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
-
+ cacheAsNeeded(d);
+
getOut.push_back(d);
return 0;
@@ -400,11 +390,7 @@ void SpectrumPlotFilter::getProperties(FilterPropGroup &propertyList) const
p.helpText=TRANS("Step size for spectrum");
propertyList.addProperty(p,curGroup);
- if(autoExtrema)
- str = "1";
- else
- str = "0";
-
+ str=boolStrEnc(autoExtrema);
p.name=TRANS("Auto Min/max");
p.data=str;
@@ -428,11 +414,11 @@ void SpectrumPlotFilter::getProperties(FilterPropGroup &propertyList) const
p.type=PROPERTY_TYPE_REAL;
p.helpText=TRANS("Ending position for spectrum");
propertyList.addProperty(p,curGroup);
-
- if(logarithmic)
- str = "1";
- else
- str = "0";
+
+ propertyList.setGroupTitle(curGroup,TRANS("Data"));
+ curGroup++;
+
+ str=boolStrEnc(logarithmic);
p.key=KEY_SPECTRUM_LOGARITHMIC;
p.name=TRANS("Logarithmic");
p.data=str;
@@ -445,14 +431,14 @@ void SpectrumPlotFilter::getProperties(FilterPropGroup &propertyList) const
string tmpStr;
- tmpStr=plotString(PLOT_TRACE_LINES);
- choices.push_back(make_pair((unsigned int) PLOT_TRACE_LINES,tmpStr));
- tmpStr=plotString(PLOT_TRACE_BARS);
- choices.push_back(make_pair((unsigned int)PLOT_TRACE_BARS,tmpStr));
- tmpStr=plotString(PLOT_TRACE_STEPS);
- choices.push_back(make_pair((unsigned int)PLOT_TRACE_STEPS,tmpStr));
- tmpStr=plotString(PLOT_TRACE_STEM);
- choices.push_back(make_pair((unsigned int)PLOT_TRACE_STEM,tmpStr));
+ tmpStr=plotString(PLOT_LINE_LINES);
+ choices.push_back(make_pair((unsigned int) PLOT_LINE_LINES,tmpStr));
+ tmpStr=plotString(PLOT_LINE_BARS);
+ choices.push_back(make_pair((unsigned int)PLOT_LINE_BARS,tmpStr));
+ tmpStr=plotString(PLOT_LINE_STEPS);
+ choices.push_back(make_pair((unsigned int)PLOT_LINE_STEPS,tmpStr));
+ tmpStr=plotString(PLOT_LINE_STEM);
+ choices.push_back(make_pair((unsigned int)PLOT_LINE_STEM,tmpStr));
tmpStr= choiceString(choices,plotStyle);
@@ -463,18 +449,14 @@ void SpectrumPlotFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_SPECTRUM_PLOTTYPE;
propertyList.addProperty(p,curGroup);
- string thisCol;
-
- //Convert the colour to a hex string
- genColString((unsigned char)(r*255.0),(unsigned char)(g*255.0),
- (unsigned char)(b*255.0),(unsigned char)(a*255.0),thisCol);
-
p.name=TRANS("Colour");
- p.data=thisCol;
+ p.data=rgba.toColourRGBA().rgbaString();
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Colour of plotted spectrum");
p.key=KEY_SPECTRUM_COLOUR;
propertyList.addProperty(p,curGroup);
+
+ propertyList.setGroupTitle(curGroup,TRANS("Appearance"));
}
bool SpectrumPlotFilter::setProperty( unsigned int key,
@@ -512,28 +494,8 @@ bool SpectrumPlotFilter::setProperty( unsigned int key,
//Auto min/max
case KEY_SPECTRUM_AUTOEXTREMA:
{
- //Only allow valid values
- unsigned int valueInt;
- if(stream_cast(valueInt,value))
+ if(!applyPropertyNow(autoExtrema,value,needUpdate))
return false;
-
- //Only update as needed
- if(valueInt ==0 || valueInt == 1)
- {
- if(autoExtrema != (bool)valueInt)
- {
- needUpdate=true;
- autoExtrema=valueInt;
- }
- else
- needUpdate=false;
-
- }
- else
- return false;
-
- clearCache();
-
break;
}
@@ -623,7 +585,7 @@ bool SpectrumPlotFilter::setProperty( unsigned int key,
tmpPlotType=plotID(value);
- if(tmpPlotType >= PLOT_TRACE_ENDOFENUM)
+ if(tmpPlotType >= PLOT_LINE_NONE)
return false;
plotStyle = tmpPlotType;
@@ -651,17 +613,15 @@ bool SpectrumPlotFilter::setProperty( unsigned int key,
}
case KEY_SPECTRUM_COLOUR:
{
- unsigned char newR,newG,newB,newA;
+ ColourRGBA tmpRgb;
+ tmpRgb.parse(value);
- parseColString(value,newR,newG,newB,newA);
-
- if(newB != b || newR != r ||
- newG !=g || newA != a)
+ if(tmpRgb.toRGBAf() != rgba)
+ {
+ rgba=tmpRgb.toRGBAf();
needUpdate=true;
- r=newR/255.0;
- g=newG/255.0;
- b=newB/255.0;
- a=newA/255.0;
+ }
+
if(cacheOK)
{
for(size_t ui=0;ui<filterOutputs.size();ui++)
@@ -671,9 +631,9 @@ bool SpectrumPlotFilter::setProperty( unsigned int key,
PlotStreamData *p;
p =(PlotStreamData*)filterOutputs[ui];
- p->r=r;
- p->g=g;
- p->b=b;
+ p->r=rgba.r();
+ p->g=rgba.g();
+ p->b=rgba.b();
}
}
@@ -703,14 +663,15 @@ void SpectrumPlotFilter::setUserString(const std::string &s)
std::string SpectrumPlotFilter::getErrString(unsigned int code) const
{
- switch(code)
- {
- case SPECTRUM_BAD_ALLOC:
- return string(TRANS("Insufficient memory for spectrum filter."));
- case SPECTRUM_BAD_BINCOUNT:
- return string(TRANS("Bad bincount value in spectrum filter."));
- }
- return std::string("BUG: (SpectrumPlotFilter::getErrString) Shouldn't see this!");
+ const char *errStrs[] = {
+ "",
+ "Insufficient memory for spectrum filter.",
+ "Bad bincount value in spectrum filter.",
+ "Aborted."
+ };
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == SPECTRUM_ERR_ENUM_END);
+ ASSERT(code < SPECTRUM_ERR_ENUM_END);
+ return errStrs[code];
}
void SpectrumPlotFilter::setPropFromBinding(const SelectionBinding &b)
@@ -732,8 +693,8 @@ bool SpectrumPlotFilter::writeState(std::ostream &f,unsigned int format, unsigne
maxPlot << "\" auto=\"" << autoExtrema << "\"/>" << endl;
f << tabs(depth+1) << "<binwidth value=\"" << binWidth<< "\"/>" << endl;
- f << tabs(depth+1) << "<colour r=\"" << r<< "\" g=\"" << g << "\" b=\"" <<b
- << "\" a=\"" << a << "\"/>" <<endl;
+ f << tabs(depth+1) << "<colour r=\"" << rgba.r() << "\" g=\"" << rgba.g() << "\" b=\"" << rgba.b()
+ << "\" a=\"" << rgba.a() << "\"/>" <<endl;
f << tabs(depth+1) << "<logarithmic value=\"" << logarithmic<< "\"/>" << endl;
@@ -805,11 +766,7 @@ bool SpectrumPlotFilter::readState(xmlNodePtr &nodePtr, const std::string &state
return false;
tmpStr=(char *)xmlString;
- if(tmpStr == "1")
- autoExtrema=true;
- else if(tmpStr== "0")
- autoExtrema=false;
- else
+ if(!boolStrDec(tmpStr,autoExtrema))
{
xmlFree(xmlString);
return false;
@@ -833,19 +790,17 @@ bool SpectrumPlotFilter::readState(xmlNodePtr &nodePtr, const std::string &state
//====
if(XMLHelpFwdToElem(nodePtr,"colour"))
return false;
- if(!parseXMLColour(nodePtr,r,g,b,a))
+ ColourRGBAf tmpRgba;
+ if(!parseXMLColour(nodePtr,tmpRgba))
return false;
+ rgba=tmpRgba;
//====
//Retrieve logarithmic mode
//====
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"logarithmic","value"))
return false;
- if(tmpStr == "0")
- logarithmic=false;
- else if(tmpStr == "1")
- logarithmic=true;
- else
+ if(!boolStrDec(tmpStr,logarithmic))
return false;
//====
@@ -853,7 +808,7 @@ bool SpectrumPlotFilter::readState(xmlNodePtr &nodePtr, const std::string &state
//====
if(!XMLGetNextElemAttrib(nodePtr,plotStyle,"plottype","value"))
return false;
- if(plotStyle >= PLOT_TRACE_ENDOFENUM)
+ if(plotStyle >= PLOT_LINE_NONE)
return false;
//====
@@ -909,11 +864,10 @@ bool countTest()
bool needUp;
- std::string s;
TEST(f->setProperty(KEY_SPECTRUM_LOGARITHMIC,"0",needUp),"Set prop");
- genColString(255,0,0,s);
- TEST(f->setProperty(KEY_SPECTRUM_COLOUR,s,needUp),"Set prop");
+ ColourRGBA tmpRGBA(255,0,0);
+ TEST(f->setProperty(KEY_SPECTRUM_COLOUR,tmpRGBA.rgbString(),needUp),"Set prop");
vector<const FilterStreamData*> streamIn,streamOut;
diff --git a/src/backend/filters/spectrumPlot.h b/src/backend/filters/spectrumPlot.h
index 09c25b1..a4c207d 100644
--- a/src/backend/filters/spectrumPlot.h
+++ b/src/backend/filters/spectrumPlot.h
@@ -33,7 +33,7 @@ class SpectrumPlotFilter : public Filter
//Vector of spectra. Each spectra is comprised of a sorted Y data
std::vector< std::vector<float > > spectraCache;
- float r,g,b,a;
+ ColourRGBAf rgba;
unsigned int plotStyle;
public:
SpectrumPlotFilter();
diff --git a/src/backend/filters/transform.cpp b/src/backend/filters/transform.cpp
index 6b04ed6..3da7e09 100644
--- a/src/backend/filters/transform.cpp
+++ b/src/backend/filters/transform.cpp
@@ -71,7 +71,8 @@ enum
enum
{
ERR_CALLBACK_FAIL=1,
- ERR_NOMEM
+ ERR_NOMEM,
+ TRANSFORM_ERR_ENUM_END
};
const char *TRANSFORM_MODE_STRING[] = { NTRANS("Translate"),
@@ -273,13 +274,8 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
DrawStreamData *d=makeMarkerSphere(s);
if(s)
devices.push_back(s);
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- }
- else
- d->cached=0;
+
+ cacheAsNeeded(d);
getOut.push_back(d);
}
@@ -417,14 +413,7 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
#endif
ASSERT(d->data.size() == src->data.size());
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
+ cacheAsNeeded(d);
getOut.push_back(d);
break;
@@ -538,14 +527,7 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
#endif
ASSERT(d->data.size() == src->data.size());
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
+ cacheAsNeeded(d);
getOut.push_back(d);
break;
@@ -659,14 +641,8 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
ASSERT(pos == d->data.size());
#endif
ASSERT(d->data.size() == src->data.size());
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
+
+ cacheAsNeeded(d);
getOut.push_back(d);
break;
@@ -776,14 +752,8 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
ASSERT(pos == d->data.size());
#endif
ASSERT(d->data.size() == src->data.size());
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
+
+ cacheAsNeeded(d);
getOut.push_back(d);
break;
@@ -876,14 +846,8 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
}
ASSERT(d->data.size() == src->data.size());
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
+
+ cacheAsNeeded(d);
getOut.push_back(d);
break;
@@ -1005,14 +969,8 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
}
ASSERT(d->data.size() == src->data.size());
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
+
+ cacheAsNeeded(d);
getOut.push_back(d);
break;
@@ -1150,15 +1108,8 @@ unsigned int TransformFilter::refresh(const std::vector<const FilterStreamData *
massData.clear();
- if(cache)
- {
- d->cached=1;
- filterOutputs.push_back(d);
- cacheOK=true;
- }
- else
- d->cached=0;
-
+ cacheAsNeeded(d);
+
getOut.push_back(d);
}
@@ -1186,6 +1137,7 @@ void TransformFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_MODE;
propertyList.addProperty(p,curGroup);
+ propertyList.setGroupTitle(curGroup,TRANS("Algorithm"));
curGroup++;
//non-translation transforms require a user to select an origin
@@ -1451,48 +1403,20 @@ bool TransformFilter::setProperty( unsigned int key,
case KEY_NOISELEVEL:
case KEY_ORIGIN_VALUE:
{
- ASSERT(scalarParams.size());
-
- float newScale;
- if(stream_cast(newScale,value))
+ if(!applyPropertyNow(scalarParams[0],value,needUpdate))
return false;
-
- if(scalarParams[0] != newScale )
- {
- scalarParams[0] = newScale;
- needUpdate=true;
- clearCache();
- }
return true;
}
case KEY_SCALEFACTOR_ANISOTROPIC:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(vectorParams[1],value,needUpdate))
return false;
-
- if(!(vectorParams[1] == newPt ))
- {
- vectorParams[1] = newPt;
- needUpdate=true;
- clearCache();
- }
-
return true;
}
case KEY_ORIGIN:
{
- Point3D newPt;
- if(!newPt.parse(value))
+ if(!applyPropertyNow(vectorParams[0],value,needUpdate))
return false;
-
- if(!(vectorParams[0] == newPt ))
- {
- vectorParams[0] = newPt;
- needUpdate=true;
- clearCache();
- }
-
return true;
}
case KEY_ROTATE_AXIS:
@@ -1534,15 +1458,8 @@ bool TransformFilter::setProperty( unsigned int key,
}
case KEY_TRANSFORM_SHOWORIGIN:
{
- string stripped=stripWhite(value);
-
- if(!(stripped == "1"|| stripped == "0"))
+ if(!applyPropertyNow(showOrigin,value,needUpdate))
return false;
-
- showOrigin=(stripped=="1");
-
- needUpdate=true;
-
break;
}
case KEY_NOISETYPE:
@@ -1571,17 +1488,14 @@ bool TransformFilter::setProperty( unsigned int key,
std::string TransformFilter::getErrString(unsigned int code) const
{
-
- switch(code)
- {
- //User aborted in a callback
- case ERR_CALLBACK_FAIL:
- return std::string(TRANS("Aborted"));
- //Caught a memory issue
- case ERR_NOMEM:
- return std::string(TRANS("Unable to allocate memory"));
- }
- ASSERT(false);
+ const char *errStrs[] = { "",
+ "Aborted",//User aborted in a callback
+ "Unable to allocate memory"//Caught a memory issue,
+ };
+
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == TRANSFORM_ERR_ENUM_END);
+ ASSERT(code < TRANSFORM_ERR_ENUM_END);
+ return errStrs[code];
}
bool TransformFilter::writeState(std::ostream &f,unsigned int format, unsigned int depth) const
diff --git a/src/backend/filters/voxelise.cpp b/src/backend/filters/voxelise.cpp
index 3001475..aaf7e55 100644
--- a/src/backend/filters/voxelise.cpp
+++ b/src/backend/filters/voxelise.cpp
@@ -88,10 +88,11 @@ enum
//--
enum
{
- VOXELISE_ABORT_ERR,
+ VOXELISE_ABORT_ERR=1,
VOXELISE_MEMORY_ERR,
VOXELISE_CONVOLVE_ERR,
- VOXELISE_BOUNDS_INVALID_ERR
+ VOXELISE_BOUNDS_INVALID_ERR,
+ VOXELISE_ERR_ENUM_END
};
//--
@@ -184,8 +185,7 @@ VoxeliseFilter::VoxeliseFilter()
COMPILE_ASSERT(THREEDEP_ARRAYSIZE(VOXEL_REPRESENT_KEEPCACHE) == VOXEL_REPRESENT_END);
splatSize=1.0f;
- a=0.9f;
- r=g=b=0.5;
+ rgba=ColourRGBAf(0.5,0.5,0.5,0.9f);
isoLevel=0.5;
filterBins=3;
@@ -231,10 +231,7 @@ Filter *VoxeliseFilter::cloneUncached() const
{
VoxeliseFilter *p=new VoxeliseFilter();
p->splatSize=splatSize;
- p->a=a;
- p->r=r;
- p->g=g;
- p->b=b;
+ p->rgba=rgba;
p->isoLevel=isoLevel;
@@ -624,10 +621,10 @@ unsigned int VoxeliseFilter::refresh(const std::vector<const FilterStreamData *>
vs->representationType= representation;
vs->splatSize = splatSize;
vs->isoLevel=isoLevel;
- vs->r=r;
- vs->g=g;
- vs->b=b;
- vs->a=a;
+ vs->r=rgba.r();
+ vs->g=rgba.g();
+ vs->b=rgba.b();
+ vs->a=rgba.a();
if(cache)
{
@@ -672,7 +669,7 @@ unsigned int VoxeliseFilter::refresh(const std::vector<const FilterStreamData *>
if(showColourBar)
- d->drawables.push_back(makeColourBar(minV,maxV,255,colourMap));
+ d->drawables.push_back(makeColourBar(minV,maxV,255,colourMap,1.0f));
d->cached=0;
d->parent=this;
@@ -814,6 +811,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
//Let the user know what the valid values for voxel value types are
vector<pair<unsigned int,string> > choices;
+ unsigned int defaultChoice=normaliseType;
tmpStr=getNormaliseTypeString(VOXELISE_NORMALISETYPE_NONE);
choices.push_back(make_pair((unsigned int)VOXELISE_NORMALISETYPE_NONE,tmpStr));
tmpStr=getNormaliseTypeString(VOXELISE_NORMALISETYPE_VOLUME);
@@ -827,8 +825,16 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
tmpStr=getNormaliseTypeString(VOXELISE_NORMALISETYPE_COUNT2INVOXEL);
choices.push_back(make_pair((unsigned int)VOXELISE_NORMALISETYPE_COUNT2INVOXEL,tmpStr));
}
+ else
+ {
+ //prevent the case where we usd to have an incoing range stream, but now we dont.
+ // selected item within choice string must still be valid
+ if(normaliseType > VOXELISE_NORMALISETYPE_VOLUME)
+ defaultChoice= VOXELISE_NORMALISETYPE_NONE;
+
+ }
- tmpStr= choiceString(choices,normaliseType);
+ tmpStr= choiceString(choices,defaultChoice);
p.name=TRANS("Normalise by");
p.data=tmpStr;
p.type=PROPERTY_TYPE_CHOICE;
@@ -843,7 +849,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
if (rsdIncoming)
{
p.name=TRANS("Numerator");
- p.data=numeratorAll ? "1" : "0";
+ p.data=boolStrEnc(numeratorAll);
p.type=PROPERTY_TYPE_BOOL;
p.helpText=TRANS("Parmeter \"a\" used in fraction (a/b) to get voxel value");
p.key=KEY_ENABLE_NUMERATOR;
@@ -856,10 +862,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
for(unsigned int ui=0; ui<rsdIncoming->enabledIons.size(); ui++)
{
string str;
- if(enabledIons[0][ui])
- str="1";
- else
- str="0";
+ str=boolStrEnc(enabledIons[0][ui]);
//Append the ion name with a checkbox
p.name=rsdIncoming->rangeFile->getName(ui);
@@ -870,6 +873,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.addProperty(p,curGroup);
}
+ propertyList.setGroupTitle(curGroup,TRANS("Ranges"));
curGroup++;
}
@@ -877,7 +881,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
if (normaliseType == VOXELISE_NORMALISETYPE_COUNT2INVOXEL && rsdIncoming)
{
p.name=TRANS("Denominator");
- p.data=denominatorAll ? "1" : "0";
+ p.data=boolStrEnc(denominatorAll );
p.type=PROPERTY_TYPE_BOOL;
p.helpText=TRANS("Parameter \"b\" used in fraction (a/b) to get voxel value");
p.key=KEY_ENABLE_DENOMINATOR;
@@ -885,10 +889,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
for(unsigned int ui=0; ui<rsdIncoming->enabledIons.size(); ui++)
{
string str;
- if(enabledIons[1][ui])
- str="1";
- else
- str="0";
+ str=boolStrEnc(enabledIons[1][ui]);
//Append the ion name with a checkbox
p.key=KEY_ENABLE_DENOMINATOR*1000 + ui;
@@ -899,14 +900,15 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.addProperty(p,curGroup);
}
+ propertyList.setGroupTitle(curGroup,TRANS("Mode"));
curGroup++;
}
+/*
//Start a new set for filtering
//----
//TODO: Other filtering? threshold/median? laplacian? etc
-/*
choices.clear();
//Post-filtering method
for(unsigned int ui=0;ui<VOXELISE_FILTERTYPE_MAX; ui++)
@@ -988,7 +990,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_SPOTSIZE;
propertyList.addProperty(p,curGroup);
- stream_cast(tmpStr,1.0-a);
+ stream_cast(tmpStr,1.0-rgba.a());
p.name=TRANS("Transparency");
p.data=tmpStr;
p.type=PROPERTY_TYPE_REAL;
@@ -1012,21 +1014,18 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.addProperty(p,curGroup);
//--
-
+ propertyList.setGroupTitle(curGroup,TRANS("Surface"));
curGroup++;
//-- Isosurface appearance --
- //Convert the ion colour to a hex string
- genColString((unsigned char)(r*255),(unsigned char)(g*255),
- (unsigned char)(b*255),(unsigned char)(a*255),tmpStr);
p.name=TRANS("Colour");
- p.data=tmpStr;
+ p.data=rgba.toColourRGBA().rgbString();
p.type=PROPERTY_TYPE_COLOUR;
p.helpText=TRANS("Colour of isosurface");
p.key=KEY_COLOUR;
propertyList.addProperty(p,curGroup);
- stream_cast(tmpStr,1.0-a);
+ stream_cast(tmpStr,1.0-rgba.a());
p.name=TRANS("Transparency");
p.data=tmpStr;
p.type=PROPERTY_TYPE_REAL;
@@ -1034,7 +1033,6 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_TRANSPARENCY;
propertyList.addProperty(p,curGroup);
- propertyList.setGroupTitle(curGroup,TRANS("Appearance"));
//----
break;
@@ -1081,6 +1079,7 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
propertyList.addProperty(p,curGroup);
choices.clear();
// ---
+ propertyList.setGroupTitle(curGroup,TRANS("Surface"));
curGroup++;
@@ -1098,21 +1097,14 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
p.key=KEY_VOXEL_COLOURMODE;
propertyList.addProperty(p,curGroup);
- if(showColourBar)
- tmpStr="1";
- else
- tmpStr="0";
-
+ tmpStr=boolStrEnc(showColourBar);
p.name=TRANS("Show Bar");
p.key=KEY_SHOW_COLOURBAR;
p.data=tmpStr;
p.type=PROPERTY_TYPE_BOOL;
propertyList.addProperty(p,curGroup);
- if(autoColourMap)
- tmpStr="1";
- else
- tmpStr="0";
+ tmpStr=boolStrEnc(autoColourMap);
p.name=TRANS("Auto Bounds");
p.helpText=TRANS("Auto-compute min/max values in map");
p.data= tmpStr;
@@ -1147,6 +1139,8 @@ void VoxeliseFilter::getProperties(FilterPropGroup &propertyList) const
ASSERT(false);
;
}
+
+ propertyList.setGroupTitle(curGroup,TRANS("Appearance"));
curGroup++;
//----------------------------
@@ -1161,125 +1155,26 @@ bool VoxeliseFilter::setProperty(unsigned int key,
{
case KEY_FIXEDWIDTH:
{
- bool b;
- if(stream_cast(b,value))
+ if(!applyPropertyNow(fixedWidth,value,needUpdate))
return false;
-
- //if the result is different, the
- //cache should be invalidated
- if(b!=fixedWidth)
- {
- needUpdate=true;
- fixedWidth=b;
- clearCache();
- }
break;
}
case KEY_NBINSX:
- {
- unsigned int i;
- if(stream_cast(i,value))
- return false;
- if(!i)
- return false;
-
- //if the result is different, the
- //cache should be invalidated
- if(i!=nBins[0])
- {
- needUpdate=true;
- nBins[0]=i;
- calculateWidthsFromNumBins(binWidth, nBins);
- clearCache();
- }
- break;
- }
case KEY_NBINSY:
- {
- unsigned int i;
- if(stream_cast(i,value))
- return false;
- if(!i)
- return false;
- needUpdate=true;
- //if the result is different, the
- //cache should be invalidated
- if(i!=nBins[1])
- {
- needUpdate=true;
- nBins[1]=i;
- calculateWidthsFromNumBins(binWidth, nBins);
- clearCache();
- }
- break;
- }
case KEY_NBINSZ:
{
- unsigned int i;
- if(stream_cast(i,value))
- return false;
- if(!i)
+ if(!applyPropertyNow(nBins[key-KEY_NBINSX],value,needUpdate))
return false;
-
- //if the result is different, the
- //cache should be invalidated
- if(i!=nBins[2])
- {
- needUpdate=true;
- nBins[2]=i;
- calculateWidthsFromNumBins(binWidth, nBins);
- clearCache();
- }
+ calculateWidthsFromNumBins(binWidth, nBins);
break;
}
case KEY_WIDTHBINSX:
- {
- float f;
- if(stream_cast(f,value))
- return false;
- if(f <= 0.0f)
- return false;
-
- if(f!=binWidth[0])
- {
- needUpdate=true;
- binWidth[0]=f;
- calculateNumBinsFromWidths(binWidth, nBins);
- clearCache();
- }
- break;
- }
case KEY_WIDTHBINSY:
- {
- float f;
- if(stream_cast(f,value))
- return false;
- if(f <= 0.0f)
- return false;
-
- if(f!=binWidth[1])
- {
- needUpdate=true;
- binWidth[1]=f;
- calculateNumBinsFromWidths(binWidth, nBins);
- clearCache();
- }
- break;
- }
case KEY_WIDTHBINSZ:
{
- float f;
- if(stream_cast(f,value))
+ if(!applyPropertyNow(binWidth[key-KEY_WIDTHBINSX],value,needUpdate))
return false;
- if(f <= 0.0f)
- return false;
- if(f!=binWidth[2])
- {
- needUpdate=true;
- binWidth[2]=f;
- calculateNumBinsFromWidths(binWidth, nBins);
- clearCache();
- }
+ calculateNumBinsFromWidths(binWidth, nBins);
break;
}
case KEY_NORMALISE_TYPE:
@@ -1334,7 +1229,7 @@ bool VoxeliseFilter::setProperty(unsigned int key,
return false;
needUpdate=true;
//Alpha is opacity, which is 1-transparancy
- a=1.0f-f;
+ rgba.a(1.0f-f);
//Go in and manually adjust the cached
//entries to have the new value, rather
//than doing a full recomputation
@@ -1344,7 +1239,7 @@ bool VoxeliseFilter::setProperty(unsigned int key,
{
VoxelStreamData *d;
d=(VoxelStreamData*)filterOutputs[ui];
- d->a=a;
+ d->a=rgba.a();
}
}
break;
@@ -1374,16 +1269,17 @@ bool VoxeliseFilter::setProperty(unsigned int key,
}
case KEY_COLOUR:
{
- unsigned char newR,newG,newB,newA;
+ ColourRGBA tmpRGBA;
- parseColString(value,newR,newG,newB,newA);
+ if(!tmpRGBA.parse(value))
+ return false;
- if(newB != b || newR != r ||
- newG !=g || newA != a)
+ if(tmpRGBA.toRGBAf() != rgba)
+ {
+ rgba=tmpRGBA.toRGBAf();
needUpdate=true;
- r=newR/255.0;
- g=newG/255.0;
- b=newB/255.0;
+ }
+
//Go in and manually adjust the cached
//entries to have the new value, rather
//than doing a full recomputation
@@ -1393,9 +1289,9 @@ bool VoxeliseFilter::setProperty(unsigned int key,
{
VoxelStreamData *d;
d=(VoxelStreamData*)filterOutputs[ui];
- d->r=r;
- d->g=g;
- d->b=b;
+ d->r=rgba.r();
+ d->g=rgba.g();
+ d->b=rgba.b();
}
}
break;
@@ -1513,7 +1409,7 @@ bool VoxeliseFilter::setProperty(unsigned int key,
case KEY_VOXEL_SLICE_COLOURAUTO:
{
bool b;
- if(stream_cast(b,value))
+ if(!boolStrDec(value,b))
return false;
//if the result is different, the
@@ -1615,7 +1511,7 @@ bool VoxeliseFilter::setProperty(unsigned int key,
case KEY_SHOW_COLOURBAR:
{
bool b;
- if(stream_cast(b,value))
+ if(!boolStrDec(value,b))
return false;
//if the result is different, the
@@ -1672,7 +1568,7 @@ bool VoxeliseFilter::setProperty(unsigned int key,
// TODO: This is a bit of a hack.
if (key >= KEY_ENABLE_DENOMINATOR*1000) {
bool b;
- if(stream_cast(b,value))
+ if(!boolStrDec(value,b))
return false;
enabledIons[1][key - KEY_ENABLE_DENOMINATOR*1000]=b;
@@ -1683,7 +1579,7 @@ bool VoxeliseFilter::setProperty(unsigned int key,
clearCache();
} else if (key >= KEY_ENABLE_NUMERATOR*1000) {
bool b;
- if(stream_cast(b,value))
+ if(!boolStrDec(value,b))
return false;
enabledIons[0][key - KEY_ENABLE_NUMERATOR*1000]=b;
@@ -1705,19 +1601,17 @@ bool VoxeliseFilter::setProperty(unsigned int key,
std::string VoxeliseFilter::getErrString(unsigned int code) const
{
- switch(code)
- {
- case VOXELISE_ABORT_ERR:
- return std::string(TRANS("Voxelisation aborted"));
- case VOXELISE_MEMORY_ERR:
- return std::string(TRANS("Out of memory"));
- case VOXELISE_CONVOLVE_ERR:
- return std::string(TRANS("Unable to perform filter convolution"));
- case VOXELISE_BOUNDS_INVALID_ERR:
- return std::string(TRANS("Voxelisation bounds are invalid"));
- }
+ const char *errStrs[]={
+ "",
+ "Voxelisation aborted",
+ "Out of memory",
+ "Unable to perform filter convolution",
+ "Voxelisation bounds are invalid",
+ };
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(errStrs) == VOXELISE_ERR_ENUM_END);
- return std::string("BUG! Should not see this (VoxeliseFilter)");
+ ASSERT(code < VOXELISE_ERR_ENUM_END);
+ return errStrs[code];
}
bool VoxeliseFilter::writeState(std::ostream &f,unsigned int format, unsigned int depth) const
@@ -1737,29 +1631,28 @@ bool VoxeliseFilter::writeState(std::ostream &f,unsigned int format, unsigned in
f << tabs(depth+2) << "<numerator>" << endl;
for(unsigned int ui=0;ui<enabledIons[0].size(); ui++)
- f << tabs(depth+3) << "<enabled value=\"" << (enabledIons[0][ui]?1:0) << "\"/>" << endl;
+ f << tabs(depth+3) << "<enabled value=\"" << boolStrEnc(enabledIons[0][ui]) << "\"/>" << endl;
f << tabs(depth+2) << "</numerator>" << endl;
f << tabs(depth+2) << "<denominator>" << endl;
for(unsigned int ui=0;ui<enabledIons[1].size(); ui++)
- f << tabs(depth+3) << "<enabled value=\"" << (enabledIons[1][ui]?1:0) << "\"/>" << endl;
+ f << tabs(depth+3) << "<enabled value=\"" << boolStrEnc(enabledIons[1][ui]) << "\"/>" << endl;
f << tabs(depth+2) << "</denominator>" << endl;
f << tabs(depth+1) << "</enabledions>" << endl;
f << tabs(depth+1) << "<representation value=\""<<representation << "\"/>" << endl;
f << tabs(depth+1) << "<isovalue value=\""<<isoLevel << "\"/>" << endl;
- f << tabs(depth+1) << "<colour r=\"" << r<< "\" g=\"" << g << "\" b=\"" <<b
- << "\" a=\"" << a << "\"/>" <<endl;
+ f << tabs(depth+1) << "<colour r=\"" << rgba.r()<< "\" g=\"" << rgba.g() << "\" b=\"" <<rgba.b()
+ << "\" a=\"" << rgba.a() << "\"/>" <<endl;
f << tabs(depth+1) << "<axialslice>" << endl;
f << tabs(depth+2) << "<offset value=\""<<sliceOffset<< "\"/>" << endl;
f << tabs(depth+2) << "<interpolate value=\""<<sliceInterpolate<< "\"/>" << endl;
f << tabs(depth+2) << "<axis value=\""<<sliceAxis<< "\"/>" << endl;
- f << tabs(depth+2) << "<colourbar show=\""<<(showColourBar?1:0)<<
- "\" auto=\"" << (autoColourMap?1:0)<< "\" min=\"" <<
- colourMapBounds[0] << "\" max=\"" <<
- colourMapBounds[1] << "\"/>" << endl;
+ f << tabs(depth+2) << "<colourbar show=\""<<boolStrEnc(showColourBar)<<
+ "\" auto=\"" << boolStrEnc(autoColourMap)<< "\" min=\"" <<
+ colourMapBounds[0] << "\" max=\"" << colourMapBounds[1] << "\"/>" << endl;
f << tabs(depth+1) << "</axialslice>" << endl;
@@ -1797,11 +1690,7 @@ bool VoxeliseFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFile
//Retrieve fixedWidth mode
if(!XMLGetNextElemAttrib(nodePtr,tmpStr,"fixedwidth","value"))
return false;
- if(tmpStr == "1")
- fixedWidth=true;
- else if(tmpStr== "0")
- fixedWidth=false;
- else
+ if(!boolStrDec(tmpStr,fixedWidth))
return false;
//Retrieve nBins
@@ -1942,8 +1831,10 @@ bool VoxeliseFilter::readState(xmlNodePtr &nodePtr, const std::string &stateFile
//====
if(XMLHelpFwdToElem(nodePtr,"colour"))
return false;
- if(!parseXMLColour(nodePtr,r,g,b,a))
+ ColourRGBAf tmpRgba;
+ if(!parseXMLColour(nodePtr,tmpRgba))
return false;
+ rgba=tmpRgba;
//====
diff --git a/src/backend/filters/voxelise.h b/src/backend/filters/voxelise.h
index 3ceb373..25b6f24 100644
--- a/src/backend/filters/voxelise.h
+++ b/src/backend/filters/voxelise.h
@@ -48,7 +48,7 @@ private:
//This is filter's enabled ranges
RangeStreamData *rsdIncoming;
- float r,g,b,a;
+ ColourRGBAf rgba;
//!Filter mode to apply to data before output
unsigned int filterMode;
diff --git a/src/backend/filtertree.cpp b/src/backend/filtertree.cpp
index d9ad635..34a3e8e 100644
--- a/src/backend/filtertree.cpp
+++ b/src/backend/filtertree.cpp
@@ -43,6 +43,9 @@ class FilterRefreshCollector
//Pile of lists of pointers that we are tracking
vector<list<const FilterStreamData *> > nodes;
+ //List of pointers we should *not* erase
+ set<const FilterStreamData *> forgottenNodes;
+
//Find out if a filter tracks itself or not
static bool tracksSelf(const FilterStreamData *p) { return p->cached;}
@@ -78,22 +81,16 @@ void FilterRefreshCollector::checkSanity()
for(list<const FilterStreamData *>::iterator it=nodes[ui].begin();
it!=nodes[ui].end(); ++it)
{
- //Check that we hve not already inserted this
+ //Should never have something that tracks itself
+ ASSERT(!tracksSelf(*it) )
+ //Check that we have not already inserted this
ASSERT(s.find(*it) == s.end())
s.insert(*it);
- }
- }
- s.clear();
- //Should never have something that tracks itself
- for(size_t ui=0;ui<nodes.size();ui++)
- {
- for(list<const FilterStreamData *>::iterator it=nodes[ui].begin();
- it!=nodes[ui].end(); ++it)
- {
- ASSERT(!tracksSelf(*it) )
+ ASSERT(forgottenNodes.find(*it) == forgottenNodes.end());
}
}
+ s.clear();
}
#endif
@@ -126,6 +123,8 @@ void FilterRefreshCollector::trackPointers(const vector<const FilterStreamData *
}
+ found|=(forgottenNodes.find(v[ui]) != forgottenNodes.end());
+
if(!found)
lKeep.push_back(v[ui]);
}
@@ -150,9 +149,10 @@ void FilterRefreshCollector::forgetPointers(const vector<const FilterStreamData
it=std::find(nodes[ui].begin(),nodes[ui].end(),v[uj]) ;
if(it != nodes[ui].end())
{
- nodes[ui].erase(it);
+ forgottenNodes.insert(*it);
//We deleted the source of this, no need to continue
// checking for this particular pointer.
+ nodes[ui].erase(it);
break;
}
}
@@ -652,37 +652,39 @@ unsigned int FilterTree::refreshFilterTree(list<FILTER_OUTPUT_DATA > &outData,
//Step 2: Check if we should cache this filter or not.
//Get the number of bytes that the filter expects to use
//---
- unsigned long long cacheBytes;
- if(inDataStack.empty())
- cacheBytes=currentFilter->numBytesForCache(0);
- else
- cacheBytes=currentFilter->numBytesForCache(numElements(inDataStack.top()));
-
- if(cacheBytes != (unsigned long long)(-1))
+ if(!currentFilter->haveCache())
{
- //As long as we have caching enabled, let us cache according to the
- //selected strategy
- switch(cacheStrategy)
+ unsigned long long cacheBytes;
+ if(inDataStack.empty())
+ cacheBytes=currentFilter->numBytesForCache(0);
+ else
+ cacheBytes=currentFilter->numBytesForCache(numElements(inDataStack.top()));
+
+ if(cacheBytes != (unsigned long long)(-1))
{
- case CACHE_NEVER:
- currentFilter->setCaching(false);
- break;
- case CACHE_DEPTH_FIRST:
+ //As long as we have caching enabled, let us cache according to the
+ //selected strategy
+ switch(cacheStrategy)
{
- float ramFreeForUse;
- ramFreeForUse= maxCachePercent/(float)100.0f*getAvailRAM();
-
- bool cache;
- cache=(cacheBytes/(1024*1024) ) < ramFreeForUse;
-
- currentFilter->setCaching( cache);
- break;
+ case CACHE_NEVER:
+ currentFilter->setCaching(false);
+ break;
+ case CACHE_DEPTH_FIRST:
+ {
+ float ramFreeForUse;
+ ramFreeForUse= maxCachePercent/(float)100.0f*getAvailRAM();
+
+ bool cache;
+ cache=(cacheBytes/(1024*1024) ) < ramFreeForUse;
+
+ currentFilter->setCaching( cache);
+ break;
+ }
}
}
+ else
+ currentFilter->setCaching(false);
}
- else
- currentFilter->setCaching(false);
-
//---
//Step 3: Take the stack top, and turn it into "curdata" and refresh using the filter.
@@ -779,7 +781,7 @@ unsigned int FilterTree::refreshFilterTree(list<FILTER_OUTPUT_DATA > &outData,
refreshCollector.trackPointers(curData);
//Put this in the intermediary stack,
- //so it is available for any other children at this leve.
+ //so it is available for any other children at this level.
inDataStack.push(curData);
}
else if(curData.size())
@@ -788,7 +790,7 @@ unsigned int FilterTree::refreshFilterTree(list<FILTER_OUTPUT_DATA > &outData,
outData.push_back(make_pair(currentFilter,curData));
refreshCollector.forgetPointers(curData);
}
- //Cur data is recorded either in outDta or on the data stack
+ //Cur data is recorded either in outData or on the data stack
curData.clear();
//---
@@ -1224,7 +1226,7 @@ void FilterTree::stripHazardousContents()
bool FilterTree::isChild(const tree<Filter *> &treeInst,
const tree<Filter *>::iterator &testParent,
- tree<Filter *>::iterator testChild) const
+ tree<Filter *>::iterator testChild)
{
// NOTE: A comparison against tree root (treeInst.begin())is INVALID
// for trees that have multiple base nodes.
@@ -1320,7 +1322,6 @@ void FilterTree::checkRefreshValidity(const vector< const FilterStreamData *> &c
//Filter outputs should
// - Always have isCached set to 0 or 1.
// - Filter should report that it has a cache, if it is emitting cached objects
- // - If caching is disabled, filter should not be caching objects
bool hasSomeCached=false;
for(size_t ui=0; ui<curData.size(); ui++)
{
@@ -1328,13 +1329,7 @@ void FilterTree::checkRefreshValidity(const vector< const FilterStreamData *> &c
curData[ui]->cached == 0);
if(curData[ui]->parent == refreshFilter)
- {
- if(!(refreshFilter->cacheEnabled()) )
- {
- ASSERT(curData[ui]->cached==0);
- }
hasSomeCached|=curData[ui]->cached;
- }
}
ASSERT(!(hasSomeCached == false && refreshFilter->haveCache()));
@@ -1420,7 +1415,7 @@ void FilterTree::checkRefreshValidity(const vector< const FilterStreamData *> &c
#endif
void FilterTree::safeDeleteFilterList( std::list<FILTER_OUTPUT_DATA> &outData,
- size_t typeMask, bool maskPrevents) const
+ size_t typeMask, bool maskPrevents)
{
//Loop through the list of vectors of filterstreamdata, then drop any elements that are deleted
for(list<FILTER_OUTPUT_DATA> ::iterator it=outData.begin();
diff --git a/src/backend/filtertree.h b/src/backend/filtertree.h
index 2baaa29..ca57afd 100644
--- a/src/backend/filtertree.h
+++ b/src/backend/filtertree.h
@@ -73,9 +73,9 @@ class FilterTree
//!Returns true if the testChild is a child of testParent.
// returns false if testchild == testParent, or if the testParent
// is not a parent of testChild.
- bool isChild(const tree<Filter *> &treeInst,
+ static bool isChild(const tree<Filter *> &treeInst,
const tree<Filter *>::iterator &testParent,
- tree<Filter *>::iterator testChild) const;
+ tree<Filter *>::iterator testChild);
static size_t countChildFilters(const tree<Filter *> &treeInst,
@@ -130,8 +130,8 @@ class FilterTree
//!Safely delete data generated by refreshFilterTree(...).
//a mask can be used to *prevent* STREAM_TYPE_blah from being deleted. Deleted items are removed from the list.
- void safeDeleteFilterList(std::list<FILTER_OUTPUT_DATA> &outData,
- size_t typeMask=STREAMTYPE_MASK_ALL, bool maskPrevents=false) const;
+ static void safeDeleteFilterList(std::list<FILTER_OUTPUT_DATA> &outData,
+ size_t typeMask=STREAMTYPE_MASK_ALL, bool maskPrevents=false);
//!compute the integrated (accumulated) propagation maps for emission and blocking.
// For emission this value gives the possible types that
diff --git a/src/backend/filtertreeAnalyse.cpp b/src/backend/filtertreeAnalyse.cpp
index e346c5e..7500c2b 100644
--- a/src/backend/filtertreeAnalyse.cpp
+++ b/src/backend/filtertreeAnalyse.cpp
@@ -401,13 +401,14 @@ bool filterAltersComposition(const Filter *f)
p=props.getPropValue(KEY_IONDOWNSAMPLE_PERSPECIES);
+ const int GROUP_SAMPLING=1;
- if(p.data== "1")
+ if(p.data== "1" && props.hasGroup(GROUP_SAMPLING))
{
vector<FilterProperty> propVec;
- const int GROUP_SAMPLING=1;
props.getGroup(GROUP_SAMPLING,propVec);
+
//If using per-species mode, then
// we may affect the output ion composition
// if we have differing values
diff --git a/src/backend/plot.cpp b/src/backend/plot.cpp
index ea958a0..a6c5e99 100644
--- a/src/backend/plot.cpp
+++ b/src/backend/plot.cpp
@@ -21,9 +21,7 @@
#include "common/translation.h"
-#ifdef USE_MGL2
- #include <mgl2/canvas_wnd.h>
-#endif
+#include <mgl2/canvas_wnd.h>
//!Plot error bar estimation strings
const char *errModeStrings[] = {
@@ -31,12 +29,15 @@ const char *errModeStrings[] = {
NTRANS("Moving avg.")
};
-const char *plotModeStrings[]= {
+const char *plotTypeStrings[]= {
NTRANS("Lines"),
NTRANS("Bars"),
NTRANS("Steps"),
NTRANS("Stem"),
- NTRANS("Points")
+ NTRANS("Points"),
+ (""),
+ NTRANS("Density"),
+ NTRANS("Scatter"),
};
using std::string;
@@ -47,118 +48,6 @@ using std::vector;
// perform a little "push off" by this fudge factor
const float AXIS_MIN_TOLERANCE=10*sqrtf(std::numeric_limits<float>::epsilon());
-int MGLColourFixer::maxCols=-1;
-
-void MGLColourFixer::reset()
-{
- rs.clear();
- gs.clear();
- bs.clear();
-}
-
-char MGLColourFixer::haveExactColour(float r, float g, float b) const
-{
- ASSERT(rs.size() == gs.size())
- ASSERT(gs.size() == bs.size())
-
- ASSERT(rs.size() <=getMaxColours());
-
- for(unsigned int ui=0; ui<rs.size(); ui++)
- {
- if( fabs(r-rs[ui]) <std::numeric_limits<float>::epsilon()
- && fabs(g-gs[ui]) <std::numeric_limits<float>::epsilon()
- && fabs(b-bs[ui]) <std::numeric_limits<float>::epsilon())
- return mglColorIds[ui+1].id; //Add one to offset to avoid the reserved "k"
- }
-
- return 0;
-}
-
-unsigned int MGLColourFixer::getMaxColours()
-{
- //Used cached value if available
- if(maxCols!=-1)
- return maxCols;
-
- //The array is statically defined in
- //mgl/mgl_main.cpp, and must end with an id of zero.
- //
- //this is not documented at all.
- maxCols=0;
- while(mglColorIds[maxCols].id)
- maxCols++;
-
- return maxCols;
-}
-
-char MGLColourFixer::getNextBestColour(float r, float g, float b)
-{
- ASSERT(rs.size() == gs.size());
- ASSERT(gs.size() == bs.size());
-
-
- //As a special case, mgl has its own black
- if(r == 0.0f && g == 0.0f && b == 0.0f)
- return mglColorIds[0].id;
-
-
- unsigned int best=0;
- if(rs.size() == getMaxColours())
- {
- ASSERT(getMaxColours());
- //Looks like we ran out of palette colours.
- //lets just give up and try to match this against our existing colours
-
- //TODO: let this modify the existing palette
- // to find a better match.
- float distanceSqr=std::numeric_limits<float>::max();
- for(unsigned int ui=0; ui<rs.size(); ui++)
- {
- float distanceTmp;
- if(r <= 0.5)
- {
- //3,4,2 weighted euclidean distance. Weights allow for closer human perception
- distanceTmp= 3.0*(rs[ui] - r )*(rs[ui] - r ) +4.0*(gs[ui] - g )*(gs[ui] - g )
- + 2.0*(bs[ui] - b )*(bs[ui] - b );
- }
- else
- {
- //use alternate weighting for closer colour perception in "non-red" half of colour cube
- distanceTmp= 2.0*(rs[ui] - r )*(rs[ui] - r ) +4.0*(gs[ui] - g )*(gs[ui] - g )
- + 3.0*(bs[ui] - b )*(bs[ui] - b );
- }
-
- if(distanceTmp < distanceSqr)
- {
- distanceSqr = (distanceTmp);
- best=ui+1; //offset by 1 because mathgl colour 0 is special
- }
-
- }
- }
- else
- {
- char exactMatch;
- //Check to see if we don't already have this
- // no use wasting palette positions on existing
- // colours
- exactMatch=haveExactColour(r,g,b);
-
- if(exactMatch)
- return exactMatch;
-
- //Offset zero is special, for black things, like axes
- best=rs.size()+1;
- mglColorIds[best].col = mglColor(r,g,b);
-
- rs.push_back(r);
- gs.push_back(g);
- bs.push_back(b);
- }
-
- ASSERT(mglColorIds[best].id != 'k');
- return mglColorIds[best].id;
-}
//Mathgl uses some internal for(float=...) constructions,
// which are just generally a bad idea, as they often won't terminate
@@ -209,19 +98,35 @@ std::string wstrToStr(const std::wstring& s)
}
+std::string mglColourCode(float r, float g, float b)
+{
+ ASSERT(r >=0.0f && g >=0.0f && b >=0.0f)
+ ASSERT(r <=255.0f && g <=255.0f && b <=255.0f)
+
+ ColourRGBA rgba(r*255.0,g*255.0,b*255.0);
+
+ std::string s;
+ //Make a #rrggbb hex string
+ s=rgba.rgbString();
+ s=s.substr(1);
+
+ return string("{x") + uppercase(s) + string("}");
+}
+
//TODO: Refactor these functions to use a common string map
//-----------
-string plotString(unsigned int traceType)
+string plotString(unsigned int plotMode)
{
- ASSERT(traceType< PLOT_TRACE_ENDOFENUM);
- return TRANS(plotModeStrings[traceType]);
+ ASSERT(plotMode< PLOT_TYPE_ENUM_END);
+ return TRANS(plotTypeStrings[plotMode]);
}
unsigned int plotID(const std::string &plotString)
{
- for(unsigned int ui=0;ui<PLOT_TRACE_ENDOFENUM; ui++)
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(plotTypeStrings) == PLOT_TYPE_ENUM_END);
+ for(unsigned int ui=0;ui<PLOT_TYPE_ENUM_END; ui++)
{
- if(plotString==TRANS(plotModeStrings[ui]))
+ if(plotString==TRANS(plotTypeStrings[ui]))
return ui;
}
@@ -441,7 +346,7 @@ std::string PlotRegion::getName() const
PlotWrapper::PlotWrapper()
{
- COMPILE_ASSERT(THREEDEP_ARRAYSIZE(plotModeStrings) == PLOT_TRACE_ENDOFENUM);
+ //COMPILE_ASSERT(THREEDEP_ARRAYSIZE(plotTypeStrings) == PLOT_TYPE_ENUM_END);
applyUserBounds=false;
plotChanged=true;
@@ -489,12 +394,13 @@ const PlotWrapper &PlotWrapper::operator=(const PlotWrapper &p)
return *this;
}
-std::wstring PlotWrapper::getTitle(size_t plotId) const
+std::string PlotWrapper::getTitle(size_t plotId) const
{
unsigned int plotPos=plotIDHandler.getPos(plotId);
- return plottingData[plotPos]->title;
+ return plottingData[plotPos]->getTitle();
}
+
void PlotWrapper::getPlotIDs(vector<unsigned int> &ids) const
{
plotIDHandler.getIds(ids);
@@ -511,6 +417,10 @@ size_t PlotWrapper::getParentType(size_t plotId) const
unsigned int PlotWrapper::addPlot(PlotBase *p)
{
+#ifdef DEBUG
+ p->checkConsistent();
+#endif
+
plottingData.push_back(p);
//assign a unique identifier to this plot, by which it can be referenced
@@ -554,36 +464,23 @@ void PlotWrapper::setStrings(unsigned int plotID, const std::string &x,
const std::string &y, const std::string &t)
{
unsigned int plotPos=plotIDHandler.getPos(plotID);
- plottingData[plotPos]->xLabel = strToWStr(x);
- plottingData[plotPos]->yLabel = strToWStr(y);
-
- plottingData[plotPos]->title = strToWStr(t);
- plotChanged=true;
-}
-void PlotWrapper::setParentData(unsigned int plotID, const void *parentObj, unsigned int idx)
-{
- unsigned int plotPos=plotIDHandler.getPos(plotID);
- plottingData[plotPos]->parentObject= parentObj;
- plottingData[plotPos]->parentPlotIndex=idx;
-
+ plottingData[plotPos]->setStrings(x,y,t);
plotChanged=true;
}
void PlotWrapper::setTraceStyle(unsigned int plotUniqueID,unsigned int mode)
{
- ASSERT(mode<PLOT_TRACE_ENDOFENUM);
- plottingData[plotIDHandler.getPos(plotUniqueID)]->traceType=mode;
+ ASSERT(mode<PLOT_TYPE_ENUM_END);
+ plottingData[plotIDHandler.getPos(plotUniqueID)]->setPlotMode(mode);
plotChanged=true;
}
-void PlotWrapper::setColours(unsigned int plotUniqueID, float rN,float gN,float bN)
+void PlotWrapper::setColours(unsigned int plotUniqueID, float r,float g,float b)
{
unsigned int plotPos=plotIDHandler.getPos(plotUniqueID);
- plottingData[plotPos]->r=rN;
- plottingData[plotPos]->g=gN;
- plottingData[plotPos]->b=bN;
+ plottingData[plotPos]->setColour(r,g,b);
plotChanged=true;
}
@@ -703,8 +600,70 @@ void PlotWrapper::bestEffortRestoreVisibility()
plotChanged=true;
}
+
+void PlotWrapper::getAppliedBounds(mglPoint &min, mglPoint &max) const
+{
+
+ if(applyUserBounds)
+ {
+ ASSERT(yUserMax >=yUserMin);
+ ASSERT(xUserMax >=xUserMin);
+
+ max.x =xUserMax;
+ max.y=yUserMax;
+
+ min.x =xUserMin;
+ min.y =yUserMin;
+
+ }
+ else
+ {
+ //Retrieve the bounds of the data that is in the plot
+ float minX,maxX,minY,maxY;
+ minX=std::numeric_limits<float>::max();
+ maxX=-std::numeric_limits<float>::max();
+ minY=std::numeric_limits<float>::max();
+ maxY=-std::numeric_limits<float>::max();
+
+ for(unsigned int ui=0;ui<plottingData.size(); ui++)
+ {
+ if(plottingData[ui]->visible)
+ {
+ float tmpMinX,tmpMinY,tmpMaxX,tmpMaxY;
+ plottingData[ui]->getBounds(
+ tmpMinX,tmpMaxX,tmpMinY,tmpMaxY);
+
+ minX=std::min(minX,tmpMinX);
+ maxX=std::max(maxX,tmpMaxX);
+ minY=std::min(minY,tmpMinY);
+ maxY=std::max(maxY,tmpMaxY);
+ }
+ }
+
+ min.x=minX;
+ min.y=minY;
+ max.x=maxX;
+ max.y=maxY;
+
+ }
+
+
+ //"Push" bounds around to prevent min == max
+ // This is a hack to prevent mathgl from inf. looping
+ //---
+ if(mglFloatTooClose(min.x , max.x))
+ {
+ min.x-=0.05;
+ max.x+=0.05;
+ }
+
+ if(mglFloatTooClose(min.y , max.y))
+ max.y+=0.01;
+ //------
+}
+
void PlotWrapper::getRawData(vector<vector<vector<float> > > &data,
- std::vector<std::vector<std::wstring> > &labels) const
+ std::vector<std::vector<std::string> > &labels) const
{
if(plottingData.empty())
return;
@@ -712,9 +671,10 @@ void PlotWrapper::getRawData(vector<vector<vector<float> > > &data,
//Determine if we have multiple types of plot.
//if so, we cannot really return the raw data for this
//in a meaningful fashion
- switch(getVisibleType())
+ switch(getVisibleMode())
{
- case PLOT_TYPE_ONED:
+ case PLOT_MODE_1D:
+ case PLOT_MODE_2D:
{
//Try to retrieve the raw data from the visible plots
for(unsigned int ui=0;ui<plottingData.size();ui++)
@@ -722,7 +682,7 @@ void PlotWrapper::getRawData(vector<vector<vector<float> > > &data,
if(plottingData[ui]->visible)
{
vector<vector<float> > thisDat,dummy;
- vector<std::wstring> thisLabel;
+ vector<std::string> thisLabel;
plottingData[ui]->getRawData(thisDat,thisLabel);
//Data title size should hopefully be the same
@@ -740,35 +700,36 @@ void PlotWrapper::getRawData(vector<vector<vector<float> > > &data,
}
break;
}
- case PLOT_TYPE_ENUM_END:
+ case PLOT_MODE_ENUM_END:
+ case PLOT_MODE_MIXED:
return;
default:
ASSERT(false);
}
}
-unsigned int PlotWrapper::getVisibleType() const
+unsigned int PlotWrapper::getVisibleMode() const
{
- unsigned int visibleType=PLOT_TYPE_ENUM_END;
+ unsigned int visibleMode=PLOT_MODE_ENUM_END;
for(unsigned int ui=0;ui<plottingData.size() ; ui++)
{
if(plottingData[ui]->visible &&
- plottingData[ui]->plotType!= visibleType)
+ plottingData[ui]->getPlotMode()!= visibleMode)
{
- if(visibleType == PLOT_TYPE_ENUM_END)
+ if(visibleMode == PLOT_MODE_ENUM_END)
{
- visibleType=plottingData[ui]->plotType;
+ visibleMode=plottingData[ui]->getMode();
continue;
}
else
{
- visibleType=PLOT_TYPE_MIXED;
+ visibleMode=PLOT_MODE_MIXED;
break;
}
}
}
- return visibleType;
+ return visibleMode;
}
void PlotWrapper::getVisibleIDs(vector<unsigned int> &visiblePlotIDs ) const
@@ -794,68 +755,53 @@ void PlotWrapper::findRegionLimit(unsigned int plotId, unsigned int regionId,
void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
{
- unsigned int visType = getVisibleType();
- if(visType == PLOT_TYPE_ENUM_END ||
- visType == PLOT_TYPE_MIXED)
+ unsigned int visMode = getVisibleMode();
+ if(visMode == PLOT_MODE_ENUM_END ||
+ visMode == PLOT_MODE_MIXED)
{
//We don't handle the drawing case well here, so assert this.
// calling code should check this case and ensure that it draws something
// meaningful
- ASSERT(false);
+ WARN(false,"Mixed calling code");
return;
}
//Un-fudger for mathgl plots
- MGLColourFixer colourFixer;
bool haveMultiTitles=false;
- float minX,maxX,minY,maxY;
- minX=std::numeric_limits<float>::max();
- maxX=-std::numeric_limits<float>::max();
- minY=std::numeric_limits<float>::max();
- maxY=-std::numeric_limits<float>::max();
//Compute the bounding box in data coordinates
- std::wstring xLabel,yLabel,plotTitle;
+ std::string xLabel,yLabel,plotTitle;
for(unsigned int ui=0;ui<plottingData.size(); ui++)
{
if(plottingData[ui]->visible)
{
- float tmpMinX,tmpMinY,tmpMaxX,tmpMaxY;
- plottingData[ui]->getBounds(
- tmpMinX,tmpMaxX,tmpMinY,tmpMaxY);
-
- minX=std::min(minX,tmpMinX);
- maxX=std::max(maxX,tmpMaxX);
- minY=std::min(minY,tmpMinY);
- maxY=std::max(maxY,tmpMaxY);
-
if(!xLabel.size())
- xLabel=plottingData[ui]->xLabel;
+ xLabel=plottingData[ui]->getXLabel();
else
{
- if(xLabel!=plottingData[ui]->xLabel)
- xLabel=stlStrToStlWStr(TRANS("Multiple data types"));
+ if(xLabel!=plottingData[ui]->getXLabel())
+ xLabel=string(TRANS("Multiple data types"));
}
if(!yLabel.size())
- yLabel=plottingData[ui]->yLabel;
+ yLabel=plottingData[ui]->getYLabel();
else
{
- if(yLabel!=plottingData[ui]->yLabel)
- yLabel=stlStrToStlWStr(TRANS("Multiple data types"));
+ if(yLabel!=plottingData[ui]->getYLabel())
+ yLabel=string(TRANS("Multiple data types"));
}
if(!haveMultiTitles && !plotTitle.size())
- plotTitle=plottingData[ui]->title;
+ plotTitle=plottingData[ui]->getTitle();
else
{
- if(plotTitle!=plottingData[ui]->title)
+ if(plotTitle!=plottingData[ui]->getTitle())
{
- plotTitle=L"";//L prefix means wide char
+ plotTitle="";
haveMultiTitles=true;
}
}
@@ -864,8 +810,6 @@ void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
}
}
-
-
string sX,sY;
sX.assign(xLabel.begin(),xLabel.end()); //unicode conversion
sY.assign(yLabel.begin(),yLabel.end()); //unicode conversion
@@ -877,87 +821,46 @@ void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
haveUsedLog=false;
mglPoint min,max;
- switch(visType)
+ //work out the bounding box for the plot,
+ //and where the axis should cross
+ getAppliedBounds(min,max);
+
+ //set up the graph axes as needed
+ switch(visMode)
{
- case PLOT_TYPE_ONED:
+ case PLOT_MODE_1D:
{
//OneD connected value line plot f(x)
bool useLogPlot=false;
- bool notLog=false;
for(unsigned int ui=0;ui<plottingData.size(); ui++)
{
- if(plottingData[ui]->visible)
- {
- if(((Plot1D*)plottingData[ui])->wantLogPlot())
- useLogPlot=true;
- else
- notLog=true;
- }
+ if(!plottingData[ui]->visible)
+ continue;
+
+ if(plottingData[ui]->getType()!= PLOT_MODE_1D)
+ continue;
+
+ if(((Plot1D*)plottingData[ui])->wantLogPlot())
+ useLogPlot=true;
}
haveUsedLog|=useLogPlot;
- //work out the bounding box for the plot,
- //and where the axis should cross
- mglPoint axisCross;
- if(applyUserBounds)
- {
- ASSERT(yUserMax >=yUserMin);
- ASSERT(xUserMax >=xUserMin);
-
- max.x =xUserMax;
- max.y=yUserMax;
-
- min.x =xUserMin;
- min.y =yUserMin;
- axisCross.x=min.x;
- axisCross.y=min.y;
-
- }
- else
- {
- //Retrieve the bounds of the data that is in the plot
-
- min.x=minX;
- min.y=minY;
- max.x=maxX;
- max.y=maxY;
-
- axisCross.x = minX;
- axisCross.y=min.y;
- }
- //Allow logarithmic mode, as needed.
+ //Allow for logarithmic mode, as needed.
// mathgl does not like a zero coordinate for plotting
if(min.y == 0 && useLogPlot)
{
min.y=0.1;
- if(axisCross.y < min.y)
- axisCross.y=min.y;
- }
- //"Push" bounds around to prevent min == max
- // This is a hack to prevent mathgl from inf. looping
- //---
- if(mglFloatTooClose(min.x , max.x))
- {
- min.x-=5;
- max.x+=5;
}
-
- if(mglFloatTooClose(min.y , max.y))
- max.y+=1;
- //------
//tell mathgl about the bounding box
-#ifdef USE_MGL2
gr->SetRanges(min,max);
-
- gr->SetOrigin(axisCross);
-#endif
+ gr->SetOrigin(min);
WARN((fabs(min.x-max.x) > sqrt(std::numeric_limits<float>::epsilon())),
"WARNING: Mgl limits (X) too Close! Due to limitiations in MGL, This may inf. loop!");
@@ -968,24 +871,19 @@ void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
gr->SetFunc("","lg(y)");
else
gr->SetFunc("","");
-#ifdef USE_MGL2
- gr->Axis();
mglCanvas *canvas = dynamic_cast<mglCanvas *>(gr->Self());
canvas->AdjustTicks("x");
canvas->SetTickTempl('x',"%g"); //Set the tick type
canvas->Axis("xy"); //Build an X-Y crossing axis
-#else
- gr->Axis(min,max,axisCross);
- gr->AdjustTicks("x");
- gr->SetXTT("%g"); //Set the tick type
- gr->Axis("xy"); //Build an X-Y crossing axis
-#endif
//---
//Loop through the plots, drawing them as needed
for(unsigned int ui=0;ui<plottingData.size();ui++)
{
+ if(plottingData[ui]->getPlotMode() != PLOT_MODE_1D)
+ continue;
+
Plot1D *curPlot;
curPlot=(Plot1D*)plottingData[ui];
@@ -994,17 +892,15 @@ void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
if(!curPlot->visible)
continue;
- curPlot->drawRegions(gr,colourFixer,min,max);
- curPlot->drawPlot(gr,colourFixer);
+ curPlot->drawRegions(gr,min,max);
+ curPlot->drawPlot(gr);
if(drawLegend)
{
- //Fake an mgl colour code
- char colourCode[2];
- colourCode[0]=colourFixer.getNextBestColour(
- curPlot->r,curPlot->g,curPlot->b);
- colourCode[1]='\0';
- gr->AddLegend(curPlot->title.c_str(),colourCode);
+ float r,g,b;
+ curPlot->getColour(r,g,b);
+ std::string mglColStr= mglColourCode(r,g,b);
+ gr->AddLegend(curPlot->getTitle().c_str(),mglColStr.c_str());
}
}
@@ -1017,7 +913,7 @@ void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
vector<pair<size_t,size_t> > overlapId;
vector<pair<float,float> > overlapXCoords;
- char colourCode=colourFixer.getNextBestColour(1.0f,0.0f,0.0f);
+ string colourCode=mglColourCode(1.0f,0.0f,0.0f);
getRegionOverlaps(overlapId,overlapXCoords);
float rMinY,rMaxY;
@@ -1043,19 +939,47 @@ void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
continue;
-#ifdef USE_MGL2
gr->FaceZ(mglPoint(rMinX,rMinY,-1),rMaxX-rMinX,rMaxY-rMinY,
- &colourCode);
-#else
- gr->FaceZ(rMinX,rMinY,-1,rMaxX-rMinX,rMaxY-rMinY,
- &colourCode);
-#endif
+ colourCode.c_str());
}
}
break;
}
+ case PLOT_MODE_2D:
+ {
+
+ gr->SetFunc("","");
+ gr->SetRanges(min,max);
+ gr->SetOrigin(min);
+
+ gr->Axis();
+ bool wantColourbar=false;
+ for(unsigned int ui=0;ui<plottingData.size();ui++)
+ {
+ if(!plottingData[ui]->visible)
+ continue;
+ Plot2DFunc *curPlot;
+ curPlot=(Plot2DFunc*)plottingData[ui];
+
+ if(curPlot->getType() == PLOT_2D_DENS)
+ {
+ wantColourbar=true;
+ }
+
+ //If a plot is not visible, it cannot own a region
+ //nor have a legend in this run.
+ if(!curPlot->visible)
+ continue;
+
+ curPlot->drawPlot(gr);
+
+ }
+ if(wantColourbar)
+ gr->Colorbar();
+ break;
+ }
default:
ASSERT(false);
}
@@ -1064,25 +988,10 @@ void PlotWrapper::drawPlot(mglGraph *gr, bool &haveUsedLog) const
gr->Label('x',sX.c_str());
gr->Label('y',sY.c_str(),0);
- if(haveMultiTitles)
- {
-#ifdef USE_MGL2
- if(drawLegend)
- gr->Legend();
-#else
- gr->SetLegendBox(false);
- //I have NO idea what this size value is about,
- //I just kept changing the number until it looked nice.
- //the library default is -0.85 (why negative??)
- const float LEGEND_SIZE=-1.1f;
-
- //Legend at top right (0x3), in default font "rL" at specified size
- if(drawLegend)
- gr->Legend(0x3,"rL",LEGEND_SIZE);
-#endif
- }
+ if(haveMultiTitles && drawLegend)
+ gr->Legend();
- overlays.draw(gr,colourFixer,min,max,haveUsedLog);
+ overlays.draw(gr,min,max,haveUsedLog);
}
void PlotWrapper::hideAll()
@@ -1174,7 +1083,7 @@ void PlotWrapper::getRegion(unsigned int plotId, unsigned int regionId, PlotRegi
unsigned int PlotWrapper::plotType(unsigned int plotId) const
{
- return plottingData[plotIDHandler.getPos(plotId)]->plotType;
+ return plottingData[plotIDHandler.getPos(plotId)]->getPlotMode();
}
@@ -1224,16 +1133,93 @@ void PlotWrapper::overrideLastVisible(vector< pair<const void *,unsigned int> >
//-----------
+PlotBase::PlotBase()
+{
+ parentObject=0;
+ parentPlotIndex=(unsigned int)-1;
+ visible=true;
+}
+
+
+void PlotBase::getColour(float &rN, float &gN, float &bN) const
+{
+ rN=r;
+ gN=g;
+ bN=b;
+}
+
+void PlotBase::getBounds(float &xMin,float &xMax,float &yMin,float &yMax) const
+{
+ xMin=minX;
+ xMax=maxX;
+ yMin=minY;
+ yMax=maxY;
+
+ ASSERT(yMin <=yMax);
+}
+
+void PlotBase::setStrings(const std::string &x, const std::string &y, const std::string &t)
+{
+
+ xLabel = x;
+ yLabel = y;
+ title = t;
+
+}
+
+void PlotBase::copyBase(PlotBase *target) const
+{
+ target->plotType=plotType;
+ target->minX=minX;
+ target->maxX=maxX;
+ target->minY=minY;
+ target->maxY=maxY;
+ target->r=r;
+ target->g=g;
+ target->b=b;
+ target->visible=visible;
+ target->plotMode=plotMode;
+ target->xLabel=xLabel;
+ target->yLabel=yLabel;
+ target->title=title;
+ target->titleAsRawDataLabel=titleAsRawDataLabel;
+ target->parentObject=parentObject;
+ target->regionGroup=regionGroup;
+ target->parentPlotIndex=parentPlotIndex;
+
+}
+
+unsigned int PlotBase::getType() const
+{
+ return plotType;
+}
+
+unsigned int PlotBase::getMode() const
+{
+ switch(plotType)
+ {
+ case PLOT_LINE_LINES:
+ case PLOT_LINE_BARS:
+ case PLOT_LINE_STEPS:
+ case PLOT_LINE_STEM:
+ case PLOT_LINE_POINTS:
+ return PLOT_MODE_1D;
+
+ case PLOT_2D_DENS:
+ case PLOT_2D_SCATTER:
+ return PLOT_MODE_2D;
+ }
+ ASSERT(false);
+}
Plot1D::Plot1D()
{
//Set the default plot properties
- visible=(true);
- traceType=PLOT_TRACE_LINES;
- plotType=PLOT_TYPE_ONED;
- xLabel=(strToWStr(""));
- yLabel=(strToWStr(""));
- title=(strToWStr(""));
+ plotType=PLOT_LINE_LINES;
+ plotMode=PLOT_MODE_1D;
+ xLabel="";
+ yLabel="";
+ title="";
r=(0);g=(0);b=(1);
}
@@ -1247,28 +1233,12 @@ PlotBase *Plot1D::clone() const
p->yValues=yValues;
p->errBars=errBars;
- //TODO Move to base
- p->plotType=plotType;
- p->minX=minX;
- p->maxX=maxX;
- p->minY=minY;
- p->maxY=maxY;
- p->r=r;
- p->g=g;
- p->b=b;
- p->visible=visible;
- p->traceType=traceType;
- p->xLabel=xLabel;
- p->yLabel=yLabel;
- p->title=title;
- p->titleAsRawDataLabel=titleAsRawDataLabel;
- p->parentObject=parentObject;
- p->regionGroup=regionGroup;
- p->parentPlotIndex=parentPlotIndex;
+ copyBase(p);
return p;
}
+
void Plot1D::setData(const vector<float> &vX, const vector<float> &vY,
const vector<float> &vErr)
{
@@ -1342,71 +1312,109 @@ void Plot1D::setData(const vector<std::pair<float,float> > &v,const vector<float
yValues[ui]=v[ui].second;
}
- errBars.resize(vErr.size());
- std::copy(vErr.begin(),vErr.end(),errBars.begin());
+ computeDataBounds(xValues,minX,maxX);
+ if(vErr.empty())
+ {
+ computeDataBounds(yValues,minY,maxY);
+ }
+ else
+ {
+ errBars.resize(vErr.size());
+ std::copy(vErr.begin(),vErr.end(),errBars.begin());
+ computeDataBounds(yValues,vErr,minX,maxX);
+ }
+}
+void PlotBase::computeDataBounds(const vector<float> &d, const vector<float> &vErr,
+ float &minV,float &maxV)
+{
+ //Compute minima and maxima of plot data, and keep a copy of it
+ float maxThis=-std::numeric_limits<float>::max();
+ float minThis=std::numeric_limits<float>::max();
+ for(unsigned int ui=0;ui<d.size();ui++)
+ {
+ minThis=std::min(minThis,d[ui]-vErr[ui]);
+ maxThis=std::max(maxThis,d[ui]+vErr[ui]);
+ }
+ minV=minThis;
+ maxV=maxThis;
+}
+
+void PlotBase::computeDataBounds(const vector<float> &d, float &minV,float &maxV)
+{
//Compute minima and maxima of plot data, and keep a copy of it
float maxThis=-std::numeric_limits<float>::max();
float minThis=std::numeric_limits<float>::max();
- // --------- X Values ---
- for(unsigned int ui=0;ui<v.size();ui++)
+ // --------- Values ---
+ for(unsigned int ui=0;ui<d.size();ui++)
{
- minThis=std::min(minThis,v[ui].first);
- maxThis=std::max(maxThis,v[ui].first);
+ minThis=std::min(minThis,d[ui]);
+ maxThis=std::max(maxThis,d[ui]);
}
- minX=minThis;
- maxX=maxThis;
+ minV=minThis;
+ maxV=maxThis;
//------------
+}
- // Y values, taking into account any error bars
- //------------------
- minThis=std::numeric_limits<float>::max();
- maxThis=-std::numeric_limits<float>::max();
- if(vErr.size())
+void PlotBase::computeDataBounds(const vector<pair<float,float> > &d,
+ float &minX,float &maxX, float &minY, float &maxY)
+{
+ //Compute minima and maxima of plot data, and keep a copy of it
+ float maxThisX=-std::numeric_limits<float>::max();
+ float minThisX=std::numeric_limits<float>::max();
+
+ // --------- Values ---
+ for(unsigned int ui=0;ui<d.size();ui++)
{
- ASSERT(vErr.size() == v.size());
- for(unsigned int ui=0;ui<v.size();ui++)
- {
- minThis=std::min(minThis,v[ui].second-vErr[ui]);
- maxThis=std::max(maxThis,v[ui].second+vErr[ui]);
- }
+ minThisX=std::min(minThisX,d[ui].first);
+ maxThisX=std::max(maxThisX,d[ui].first);
}
- else
- {
- for(unsigned int ui=0;ui<v.size();ui++)
- {
- minThis=std::min(minThis,v[ui].second);
- maxThis=std::max(maxThis,v[ui].second);
- }
+ minX=minThisX;
+ maxX=maxThisX;
+ //------------
+
+ //Compute minima and maxima of plot data, and keep a copy of it
+ float maxThisY=-std::numeric_limits<float>::max();
+ float minThisY=std::numeric_limits<float>::max();
+ // --------- Values ---
+ for(unsigned int ui=0;ui<d.size();ui++)
+ {
+ minThisY=std::min(minThisY,d[ui].second);
+ maxThisY=std::max(maxThisY,d[ui].second);
}
- minY=minThis;
- maxY=maxThis;
- //------------------
+ minY=minThisY;
+ maxY=maxThisY;
+ //------------
+
}
-void Plot1D::getBounds(float &xMin,float &xMax,float &yMin,float &yMax) const
+void PlotBase::setColour(float rN, float gN, float bN)
{
- xMin=minX;
- xMax=maxX;
- yMin=minY;
- yMax=maxY;
-
- ASSERT(yMin <=yMax);
+ ASSERT( rN <=1.0f&& rN >=0.0f);
+ ASSERT( gN <=1.0f&& gN >=0.0f);
+ ASSERT( bN <=1.0f&& bN >=0.0f);
+
+ r=rN;
+ g=gN;
+ b=bN;
}
-bool Plot1D::empty() const
+bool Plot1D::isEmpty() const
{
ASSERT(xValues.size() == yValues.size());
return xValues.empty();
}
-void Plot1D::drawPlot(mglGraph *gr,MGLColourFixer &fixer) const
+void Plot1D::drawPlot(mglGraph *gr) const
{
+#ifdef DEBUG
+ checkConsistent();
+#endif
bool showErrs;
mglData xDat,yDat,eDat;
@@ -1453,40 +1461,41 @@ void Plot1D::drawPlot(mglGraph *gr,MGLColourFixer &fixer) const
//Obtain a colour code to use for the plot, based upon
// the actual colour we wish to use
- char colourCode[2];
- colourCode[0]=fixer.getNextBestColour(r,g,b);
- colourCode[1]='\0';
+ string colourCode;
+ colourCode=mglColourCode(r,g,b);
//---
//Plot the appropriate form
- switch(traceType)
+ switch(plotMode)
{
- case PLOT_TRACE_LINES:
+ case PLOT_LINE_LINES:
//Unfortunately, when using line plots, mathgl moves the data points to the plot boundary,
//rather than linear interpolating them back along their paths. I have emailed the author.
//for now, we shall have to put up with missing lines :( Absolute worst case, I may have to draw them myself.
gr->SetCut(true);
-
- gr->Plot(xDat,yDat,colourCode);
+
+ gr->Plot(xDat,yDat,colourCode.c_str());
if(showErrs)
- gr->Error(xDat,yDat,eDat,colourCode);
+ gr->Error(xDat,yDat,eDat,colourCode.c_str());
gr->SetCut(false);
break;
- case PLOT_TRACE_BARS:
- gr->Bars(xDat,yDat,colourCode);
+ case PLOT_LINE_BARS:
+ gr->Bars(xDat,yDat,colourCode.c_str());
break;
- case PLOT_TRACE_STEPS:
+ case PLOT_LINE_STEPS:
//Same problem as for line plot.
gr->SetCut(true);
- gr->Step(xDat,yDat,colourCode);
+ gr->Step(xDat,yDat,colourCode.c_str());
gr->SetCut(false);
break;
- case PLOT_TRACE_STEM:
- gr->Stem(xDat,yDat,colourCode);
+ case PLOT_LINE_STEM:
+ gr->SetCut(true);
+ gr->Stem(xDat,yDat,colourCode.c_str());
+ gr->SetCut(false);
break;
- case PLOT_TRACE_POINTS:
+ case PLOT_LINE_POINTS:
{
std::string s;
s = colourCode;
@@ -1518,7 +1527,7 @@ void Plot1D::drawPlot(mglGraph *gr,MGLColourFixer &fixer) const
}
void Plot1D::getRawData(std::vector<std::vector< float> > &rawData,
- std::vector<std::wstring> &labels) const
+ std::vector<std::string> &labels) const
{
vector<float> tmp,dummy;
@@ -1547,23 +1556,16 @@ void Plot1D::getRawData(std::vector<std::vector< float> > &rawData,
rawData.push_back(dummy);
rawData.back().swap(tmp);
- labels.push_back(stlStrToStlWStr(TRANS("error")));
+ labels.push_back(string(TRANS("error")));
}
}
-void Plot1D::clear( bool preserveVisiblity)
-{
- regionGroup.clear();
-}
-
-void Plot1D::drawRegions(mglGraph *gr,MGLColourFixer &fixer,
+void Plot1D::drawRegions(mglGraph *gr,
const mglPoint &min,const mglPoint &max) const
{
//Mathgl palette colour name
- char colourCode[2];
- colourCode[1]='\0';
-
+ string colourCode;
for(unsigned int uj=0;uj<regionGroup.regions.size();uj++)
{
@@ -1577,17 +1579,11 @@ void Plot1D::drawRegions(mglGraph *gr,MGLColourFixer &fixer,
//Prevent drawing inverted regionGroup.regions
if(rMaxX > rMinX && rMaxY > rMinY)
{
- colourCode[0] = fixer.getNextBestColour(regionGroup.regions[uj].r,
+ colourCode = mglColourCode(regionGroup.regions[uj].r,
regionGroup.regions[uj].g,
regionGroup.regions[uj].b);
- colourCode[1] = '\0';
-#ifdef USE_MGL2
gr->FaceZ(mglPoint(rMinX,rMinY,-1),rMaxX-rMinX,rMaxY-rMinY,
- colourCode);
-#else
- gr->FaceZ(rMinX,rMinY,-1,rMaxX-rMinX,rMaxY-rMinY,
- colourCode);
-#endif
+ colourCode.c_str());
}
}
@@ -1595,6 +1591,206 @@ void Plot1D::drawRegions(mglGraph *gr,MGLColourFixer &fixer,
//--
+//2D plotting code
+Plot2DFunc::Plot2DFunc()
+{
+ plotMode = PLOT_MODE_2D;
+ plotType=PLOT_2D_DENS;
+}
+
+void Plot2DFunc::setData(const Array2D<float> &a,
+ float xLow,float xHigh, float yLow, float yHigh)
+{
+ xyValues=a;
+ minX=xLow;
+ maxX=xHigh;
+ minY=yLow;
+ maxY=yHigh;
+}
+
+
+bool Plot2DFunc::isEmpty() const
+{
+ return xyValues.empty();
+}
+
+PlotBase * Plot2DFunc::clone() const
+{
+ Plot2DFunc *pb = new Plot2DFunc;
+
+ pb->xyValues=xyValues;
+
+ copyBase(pb);
+
+ return pb;
+}
+
+void Plot2DFunc::drawPlot(mglGraph *graph) const
+{
+#ifdef DEBUG
+ checkConsistent();
+#endif
+ size_t w,h;
+ w=xyValues.width();
+ h=xyValues.height();
+
+ mglData xyData(w,h);
+
+ #pragma omp parallel for
+ for(size_t ui=0;ui<w;ui++)
+ {
+ for(size_t uj=0;uj<h;uj++)
+ {
+ xyData[uj*w+ui]=xyValues[ui][uj];
+ }
+ }
+
+ mglData xAxis(w),yAxis(h);
+ xAxis.Fill(minX,maxX);
+ yAxis.Fill(minY,maxY);
+
+ graph->Axis("xy");
+ graph->SetCut(false);
+ graph->Dens(xAxis,yAxis,xyData);
+ graph->SetCut(true);
+}
+
+void Plot2DFunc::getRawData(std::vector<std::vector<float> > &rawData,
+ std::vector<std::string> &labels) const
+{
+
+ xyValues.unpack(rawData);
+ labels.resize(rawData.size(),title);
+
+}
+
+//--
+
+Plot2DScatter::Plot2DScatter()
+{
+ plotType=PLOT_2D_SCATTER;
+}
+
+void Plot2DScatter::setData(const vector<pair<float,float> > &f)
+{
+ points =f;
+ computeDataBounds(f,minX,maxX,minY,maxY);
+}
+
+void Plot2DScatter::setData(const vector<pair<float,float> > &f, const vector<float> &inten)
+{
+ points =f;
+ intensity=inten;
+ computeDataBounds(f,minX,maxX,minY,maxY);
+}
+
+bool Plot2DScatter::isEmpty() const
+{
+ return points.empty();
+}
+
+PlotBase *Plot2DScatter::clone() const
+{
+ Plot2DScatter *pb = new Plot2DScatter;
+
+ pb->points=points;
+
+ copyBase(pb);
+
+ return pb;
+}
+
+void Plot2DScatter::drawPlot(mglGraph *graph) const
+{
+
+ mglData xDat, yDat,sizeDat;
+
+ float *bufX,*bufY;
+ bufX = new float[points.size()];
+ if(!bufX)
+ return;
+ bufY = new float[points.size()];
+ if(!bufY)
+ {
+ delete[] bufX;
+ return;
+ }
+
+ for(unsigned int ui=0;ui<points.size();ui++)
+ {
+ bufX[ui]=points[ui].first;
+ bufY[ui] = points[ui].second;
+ }
+
+ //TODO: Implement scatter intesity
+ xDat.Set(bufX,points.size());
+ yDat.Set(bufY,points.size());
+
+ delete[] bufX;
+ delete[] bufY;
+
+ if(intensity.empty())
+ {
+ float *bufSize = new float[points.size()];
+ for(unsigned int ui=0;ui<points.size();ui++)
+ bufSize[ui]=1;
+ sizeDat.Set(bufSize,points.size());
+ delete[] bufSize;
+ }
+ else
+ {
+ sizeDat.Set(intensity);
+ }
+
+ string colourCode;
+ colourCode=mglColourCode(r,g,b);
+
+ graph->SetCut(false);
+ graph->Mark(xDat,yDat,sizeDat,"+",colourCode.c_str());
+ graph->SetCut(true);
+
+
+}
+void Plot2DScatter::getRawData(std::vector<std::vector<float> > &rawData,
+ std::vector<std::string> &labels) const
+{
+
+ if(intensity.size())
+ {
+ rawData.resize(3);
+ for(unsigned int ui=0;ui<3;ui++)
+ rawData[ui].resize(points.size());
+
+ for(unsigned int ui=0;ui<points.size();ui++)
+ {
+ rawData[0][ui] = points[ui].first;
+ rawData[1][ui] = points[ui].second;
+ rawData[2][ui] = intensity[ui];
+ }
+
+ labels.resize(3);
+ labels[2]=TRANS("Amplitude");
+ }
+ else
+ {
+ rawData.resize(2);
+ for(unsigned int ui=0;ui<2;ui++)
+ rawData[ui].resize(points.size());
+
+ for(unsigned int ui=0;ui<points.size();ui++)
+ {
+ rawData[0][ui] = points[ui].first;
+ rawData[1][ui] = points[ui].second;
+ }
+
+ labels.resize(2);
+ }
+
+ labels[0] = xLabel;
+ labels[1] = yLabel;
+}
+
+//--
bool RegionGroup::getRegionIdAtPosition(float x, float y, unsigned int &id) const
{
for(unsigned int ui=0;ui<regions.size();ui++)
@@ -1791,18 +1987,17 @@ void PlotWrapper::setRegionGroup(size_t plotId,RegionGroup &r)
}
-void PlotOverlays::draw(mglGraph *gr,MGLColourFixer &fixer,
+void PlotOverlays::draw(mglGraph *gr,
const mglPoint &boundMin, const mglPoint &boundMax,bool logMode ) const
{
if(!isEnabled)
return;
- char colourCode[2];
+ string colourCode;
//Draw the overlays in black
- colourCode[0] = fixer.getNextBestColour(0.0,0.0,0.0);
- colourCode[1]='\0';
+ colourCode = mglColourCode(0.0,0.0,0.0);
for(size_t ui=0;ui<overlayData.size();ui++)
{
@@ -1826,21 +2021,14 @@ void PlotOverlays::draw(mglGraph *gr,MGLColourFixer &fixer,
//Rescale to plot size
for(size_t uj=0;uj<overlayData[ui].coordData.size();uj++)
{
- if(logMode)
- {
- //Compute log10(probability*maximum) =
- // log10(probability) + log10(maximum)
- // maximum = 10^boundMax.y
-
- bufY[uj]=log10(bufY[uj]) +boundMax.y*0.95;
- bufY[uj]=std::max(bufY[uj],0.0f);
- }
- else
- {
- bufY[uj]*=boundMax.y/maxV*0.95;
- }
+ bufY[uj]*=boundMax.y/maxV*0.95;
}
+ mglData xDat,yDat;
+ xDat.Set(bufX);
+ yDat.Set(bufY);
+
+ //TODO: Deprecate me. Upstream now allows single stems
//Draw stems. can't use stem plot due to mathgl bug whereby single stems
// will not be drawn
for(size_t uj=0;uj<overlayData[ui].coordData.size();uj++)
@@ -1848,22 +2036,22 @@ void PlotOverlays::draw(mglGraph *gr,MGLColourFixer &fixer,
if(bufX[uj]> boundMin.x && bufX[uj]< boundMax.x &&
boundMin.y < bufY[uj])
{
- gr->Line (mglPoint(bufX[uj],std::max(0.0f,(float)boundMin.y)),
- mglPoint(bufX[uj],bufY[uj]),colourCode,100);
-
//Print labels near to the text
const float STANDOFF_FACTOR=1.05;
-#ifdef USE_MGL2
gr->Puts(mglPoint(bufX[uj],bufY[uj]*STANDOFF_FACTOR),
overlayData[ui].title.c_str());
-#else
- //Font size in mathgl uses negative values to set a relative font size
- gr->Text(mglPoint(bufX[uj],bufY[uj]*STANDOFF_FACTOR),
- overlayData[ui].title.c_str(),"",-0.6);
-
-#endif
}
}
+
+ //Draw stems.
+ gr->Stem(xDat,yDat,"k");
}
}
+#ifdef DEBUG
+void PlotBase::checkConsistent() const
+{
+ ASSERT(parentObject);
+ ASSERT(parentPlotIndex != (unsigned int)-1);
+}
+#endif
diff --git a/src/backend/plot.h b/src/backend/plot.h
index 6270ee8..d31fd2b 100644
--- a/src/backend/plot.h
+++ b/src/backend/plot.h
@@ -21,7 +21,7 @@
#include "backend/filter.h"
-
+#include "common/array2D.h"
#include <map>
@@ -32,28 +32,39 @@
//Use config header to determine if we need to enable mgl2 support
#include "../config.h"
-#ifdef USE_MGL2
#include <mgl2/mgl.h>
-#else
-#include <mgl/mgl.h>
-#endif
//mathgl shadows std::isnan
#undef isnan
-enum
+//Plot style/mode enum
+enum
{
- PLOT_TYPE_ONED,
- PLOT_TYPE_MIXED,
- PLOT_TYPE_ENUM_END //not a plot, just end of enum
+ PLOT_LINE_LINES=0,
+ PLOT_LINE_BARS,
+ PLOT_LINE_STEPS,
+ PLOT_LINE_STEM,
+ PLOT_LINE_POINTS,
+ PLOT_LINE_NONE, // not a plot, just marker for enum break
+ PLOT_2D_DENS,
+ PLOT_2D_SCATTER,
+ PLOT_TYPE_ENUM_END
};
-
-
+//This is the plot mode,
+// it can be determined as a function of the
+// plot-style/mode enum
+enum
+{
+ PLOT_MODE_1D,
+ PLOT_MODE_2D,
+ PLOT_MODE_MIXED, //special marker - different types of plots, when looking at multiple plots
+ PLOT_MODE_ENUM_END //not a plot, just end of enum
+};
//!Return a human readable string for a given plot type
-std::string plotString(unsigned int traceType);
+std::string plotString(unsigned int plotMode);
//!Return a human readable string for the plot error mode
std::string plotErrmodeString(unsigned int errMode);
@@ -64,26 +75,6 @@ unsigned int plotID(const std::string &plotString);
//!Return the error mode type, given the human readable string
unsigned int plotErrmodeID(const std::string &s);
-//!Nasty hack class to change mathgl API from named char palette to rgb specification
-class MGLColourFixer
-{
- private:
- vector<float> rs,gs,bs;
- static int maxCols;
- public:
- //Restore the MGL colour strings
- void reset();
- //Return the exact colour, if there is one
- char haveExactColour(float r, float g, float b) const;
- //Get the best colour that is available
- // returns the char to give to mathgl; may be exact,
- // maybe nearest match, depending upon number of colours used
- // and mgl palette size
- char getNextBestColour(float r, float g, float b);
-
- static unsigned int getMaxColours();
-};
-
//!Data class for holding info about non-overlapping
// interactive rectilinear "zones" overlaid on plots
@@ -137,7 +128,6 @@ class PlotRegion
};
//Handles an array of regions, for drawing and editing of the array
-
class RegionGroup
{
private:
@@ -188,6 +178,8 @@ struct OVERLAY_DATA
bool enabled;
};
+//!Thse are 1D-stem style overlays that can be used
+// to draw onto the plot
class PlotOverlays
{
private:
@@ -199,7 +191,7 @@ class PlotOverlays
//Add a new overlay to the plot
void add(const OVERLAY_DATA &overlay) {overlayData.push_back(overlay);}
//Draw the overlay on the current plot
- void draw(mglGraph *g,MGLColourFixer &fixer,
+ void draw(mglGraph *g,
const mglPoint &boundMin, const mglPoint &boundMax,bool logMode) const;
//Enable the specified overlay
void setEnabled(size_t offset,bool isEnabled)
@@ -218,31 +210,53 @@ class PlotOverlays
//!Base class for data plotting
class PlotBase
{
+ protected:
+ //!Sub type of plot (eg lines, bars for 1D)
+ unsigned int plotMode;
+ //!xaxis label
+ std::string xLabel;
+ //!y axis label
+ std::string yLabel;
+ //!Plot title
+ std::string title;
+
+ //plot colour (for single coloured plots)
+ float r,g,b;
+
+ //The type of plot (ie what class is it?)
+ unsigned int plotType;
+
+ void copyBase(PlotBase *target) const;
+
+ //Find the upper and lower limit of a given dataset
+ static void computeDataBounds(const vector<float> &d, float &minV,float &maxV) ;
+
+ //Find the upper and lower limit of a given dataset
+ static void computeDataBounds(const vector<float> &d, const vector<float> &errorBar,
+ float &minV,float &maxV);
+
+ //Find the upper and lower limit of a given dataset
+ static void computeDataBounds(const vector<pair<float,float> > &d,
+ float &minVx,float &maxVx,float &minVy, float &maxVy);
public:
- PlotBase(){};
+ PlotBase();
virtual ~PlotBase(){};
virtual PlotBase *clone() const = 0;
- //The type of plot (ie what class is it?)
- unsigned int plotType;
-
- //!Bounding box for plot - may exceed plot data area
+
+ //return the plot type
+ unsigned int getType() const;
+
+ //return the plot mode, which is derived
+ // uniquely from the plot type
+ unsigned int getMode() const;
+
+ //!Bounding box for plot
float minX,maxX,minY,maxY;
- //!Colour of trace
- float r,g,b;
//!Is trace visible?
bool visible;
- //!Type of plot (lines, bars, sticks, etc)
- unsigned int traceType;
- //!xaxis label
- std::wstring xLabel;
- //!y axis label
- std::wstring yLabel;
- //!Plot title
- std::wstring title;
-
//!Use the plot title for Y data label when exporting raw data
// (true), or use the yLabel
bool titleAsRawDataLabel;
@@ -258,25 +272,45 @@ class PlotBase
RegionGroup regionGroup;
- //True if the plot has data
- virtual bool empty() const=0;
+ //True if the plot has no data
+ virtual bool isEmpty() const=0;
//Draw the plot onto a given MGL graph
- virtual void drawPlot(mglGraph *graph, MGLColourFixer &fixer) const=0;
+ virtual void drawPlot(mglGraph *graph) const=0;
- //!Scan for the data bounds.
+ //!Return the true data bounds for this plot
virtual void getBounds(float &xMin,float &xMax,
- float &yMin,float &yMax) const = 0;
+ float &yMin,float &yMax) const;
+
//Retrieve the raw data associated with this plot.
virtual void getRawData(vector<vector<float> > &f,
- std::vector<std::wstring> &labels) const=0;
+ std::vector<std::string> &labels) const=0;
+
+ //set the plot axis strings (x,y and title)
+ void setStrings(const std::string &x,
+ const std::string &y,const std::string &t);
+
+ void setColour(float rNew, float gNew, float bNew);
+
+ std::string getXLabel() const { return xLabel;}
+ std::string getTitle() const { return title;}
+ std::string getYLabel() const { return yLabel;}
+
+ //Plot mode is, eg 2D or 1D plot
+ unsigned int getPlotMode() const { return plotMode;}
+ //FIXME: Deprecate me. Plot mode should be intrinsic
+ void setPlotMode(unsigned int newMode) { plotMode= newMode;}
+ void getColour(float &r, float &g, float &b) const ;
+
+#ifdef DEBUG
+ void checkConsistent() const;
+#endif
};
-//!1D Function f(x) Plot with ranges
-// data must be a pure Function.
+//!1D Function f(x)
class Plot1D : public PlotBase
{
private:
@@ -288,11 +322,9 @@ class Plot1D : public PlotBase
public:
Plot1D();
- virtual bool empty() const;
+ virtual bool isEmpty() const;
virtual PlotBase *clone() const;
- void getBounds(float &xMin,float &xMax,float &yMin,float &yMax) const;
-
//!Set the plot data from a pair and symmetric Y error
void setData(const vector<std::pair<float,float> > &v);
void setData(const vector<std::pair<float,float> > &v,const vector<float> &symYErr);
@@ -305,21 +337,19 @@ class Plot1D : public PlotBase
//!Move a region to a new location.
void moveRegion(unsigned int region, unsigned int method, float newPos);
- void clear(bool preserveVisibility);
-
//Draw the plot onto a given MGL graph
- virtual void drawPlot(mglGraph *graph,MGLColourFixer &fixer) const;
+ virtual void drawPlot(mglGraph *graph) const;
//Draw the associated regions
- void drawRegions(mglGraph *graph, MGLColourFixer &fixer,
- const mglPoint &min, const mglPoint &max) const;
+ void drawRegions(mglGraph *graph,
+ const mglPoint &min, const mglPoint &max) const;
//!Retrieve the raw data associated with the currently visible plots.
//note that this is the FULL data not the zoomed data for the current user bounds
void getRawData(std::vector<std::vector<float> > &rawData,
- std::vector<std::wstring> &labels) const;
+ std::vector<std::string> &labels) const;
//!Retrieve the ID of the non-overlapping region in X-Y space
bool getRegionIdAtPosition(float x, float y, unsigned int &id) const;
@@ -339,6 +369,54 @@ class Plot1D : public PlotBase
bool wantLogPlot() const { return logarithmic;};
void setLogarithmic(bool p){logarithmic=p;};
+
+};
+
+//!2D function, f(x,y).
+class Plot2DFunc : public PlotBase
+{
+ private:
+ //2D array, for f(x,y) plots
+ Array2D<float> xyValues;
+ public:
+ Plot2DFunc();
+ virtual bool isEmpty() const;
+ virtual PlotBase *clone() const;
+
+ //Draw the plot onto a given MGL graph
+ virtual void drawPlot(mglGraph *graph) const;
+
+ //!Retrieve the raw data associated with the currently visible plots.
+ //note that this is the FULL data not the zoomed data for the current user bounds
+ void getRawData(std::vector<std::vector<float> > &rawData,
+ std::vector<std::string> &labels) const;
+
+ void setData(const Array2D<float> &a, float xLow, float xHigh, float yLow, float yHigh) ;
+
+};
+
+//!2D scatter plot, {x,y}_i
+class Plot2DScatter : public PlotBase
+{
+ private:
+ vector<pair<float,float> > points;
+ vector<float > intensity;
+ public:
+ Plot2DScatter();
+ virtual bool isEmpty() const;
+ virtual PlotBase *clone() const;
+
+ //Draw the plot onto a given MGL graph
+ virtual void drawPlot(mglGraph *graph) const;
+
+ //!Retrieve the raw data associated with the currently visible plots.
+ //note that this is the FULL data not the zoomed data for the current user bounds
+ void getRawData(std::vector<std::vector<float> > &rawData,
+ std::vector<std::string> &labels) const;
+
+ //reset the data stored in the plot
+ void setData(const vector<pair<float,float> > &pts);
+ void setData(const vector<pair<float,float> > &pts ,const vector<float> &intens);
};
//Wrapper class for containing multiple plots
@@ -378,6 +456,8 @@ class PlotWrapper
//!Do we want to highlight positions where regions overlap?
bool highlightRegionOverlaps;
+
+ void getAppliedBounds(mglPoint &min,mglPoint &max) const;
public:
//"stick" type overlays for marking amplitudes on top of the plot
PlotOverlays overlays;
@@ -397,7 +477,7 @@ class PlotWrapper
void getPlotIDs(vector<unsigned int> &ids) const ;
//Retrieve the title of the plot
- std::wstring getTitle(size_t plotId) const;
+ std::string getTitle(size_t plotId) const;
void setEnableHighlightOverlap(bool enable=true) { highlightRegionOverlaps=enable;}
@@ -435,9 +515,6 @@ class PlotWrapper
const char *x, const char *y, const char *t);
void setStrings(unsigned int plotID,const std::string &x,
const std::string &y,const std::string &t);
- //!Set the parent information for a given plot
- void setParentData(unsigned int plotID,
- const void *parentObj, unsigned int plotIndex);
//TODO: Type hack - should return const Filter *
//!Get the parent object fo rthis plot
@@ -511,14 +588,14 @@ class PlotWrapper
std::vector< pair<float,float> > &coords) const;
//!Retrieve the raw data associated with the selected plots.
- void getRawData(vector<vector<vector<float> > > &data, std::vector<std::vector<std::wstring> > &labels) const;
+ void getRawData(vector<vector<vector<float> > > &data, std::vector<std::vector<std::string> > &labels) const;
//!obtain the type of a plot, given the plot's uniqueID
unsigned int plotType(unsigned int plotId) const;
//Retrieve the types of visible plots
- unsigned int getVisibleType() const;
+ unsigned int getVisibleMode() const;
//!Obtain limit of motion for a given region movement type
void findRegionLimit(unsigned int plotId, unsigned int regionId,
diff --git a/src/backend/state.cpp b/src/backend/state.cpp
index 8c3ab8f..be6f70a 100644
--- a/src/backend/state.cpp
+++ b/src/backend/state.cpp
@@ -270,7 +270,7 @@ bool AnalysisState::save(const char *cpFilename, std::map<string,string> &fileMa
return true;
}
-bool AnalysisState::load(const char *cpFilename, std::ostream &errStream, bool merge)
+bool AnalysisState::load(const char *cpFilename, std::ostream &errStream )
{
clear();
@@ -302,8 +302,7 @@ bool AnalysisState::load(const char *cpFilename, std::ostream &errStream, bool m
//By default, lets not use relative paths
- if(!merge)
- useRelativePathsForSave=false;
+ useRelativePathsForSave=false;
//Lets do some parsing goodness
//ahh parsing - verbose and boring
@@ -770,89 +769,38 @@ bool AnalysisState::load(const char *cpFilename, std::ostream &errStream, bool m
}
}
- if(!merge)
- {
- //Now replace it with the new data
- activeTree.swap(newFilterTree);
- std::swap(stashedTrees,newStashes);
- }
- else
- {
- //If we are merging, then there is a chance
- //of a name-clash. We avoid this by trying to append -merge continuously
- for(unsigned int ui=0;ui<newStashes.size();ui++)
- {
- //protect against overload (very unlikely)
- unsigned int maxCount;
- maxCount=100;
- while(hasFirstInPairVec(stashedTrees,newStashes[ui]) && --maxCount)
- newStashes[ui].first+=TRANS("-merge");
-
- if(maxCount)
- stashedTrees.push_back(newStashes[ui]);
- else
- errStream << TRANS(" Unable to merge stashes correctly. This is improbable, so please report this.") << endl;
- }
-
- activeTree.addFilterTree(newFilterTree,0);
- undoTrees.clear();
- redoTrees.clear();
- }
+ //Now replace it with the new data
+ activeTree.swap(newFilterTree);
+ std::swap(stashedTrees,newStashes);
activeTree.initFilterTree();
//Wipe the existing cameras, and then put the new cameras in place
- if(!merge)
- savedCameras.clear();
+ savedCameras.clear();
//Set a default camera as needed. We don't need to track its unique ID, as this is
//"invisible" to the UI
- if(!savedCameras.size())
- {
- Camera *c=new CameraLookAt();
- savedCameras.push_back(c);
- activeCamera=0;
- }
+ Camera *c=new CameraLookAt();
+ savedCameras.push_back(c);
+ activeCamera=0;
//spin through
for(unsigned int ui=0;ui<newCameraVec.size();ui++)
{
- if(merge)
+ //If there is no userstring, then its a "default"
+ // camera (one that does not show up to the users,
+ // and cannot be erased from the scene)
+ // set it directly. Otherwise, its a user camera.
+ if(newCameraVec[ui]->getUserString().size())
{
- //Don't merge the default camera (which has no name)
- if(newCameraVec[ui]->getUserString().empty())
- continue;
-
- //Keep trying new names appending "-merge" each time to obtain a new, and hopefully unique name
- // Abort after many times
- unsigned int maxCount;
- maxCount=100;
- while(camNameExists(newCameraVec[ui]->getUserString()) && --maxCount)
- {
- newCameraVec[ui]->setUserString(newCameraVec[ui]->getUserString()+"-merge");
- }
-
- //If we have any attempts left, then it worked
- if(maxCount)
- savedCameras.push_back(newCameraVec[ui]);
+ savedCameras.push_back(newCameraVec[ui]);
+ activeCamera=ui;
}
else
{
- //If there is no userstring, then its a "default"
- // camera (one that does not show up to the users,
- // and cannot be erased from the scene)
- // set it directly. Otherwise, its a user camera.
- if(newCameraVec[ui]->getUserString().size())
- {
- savedCameras.push_back(newCameraVec[ui]);
- activeCamera=ui;
- }
- else
- {
- ASSERT(savedCameras.size());
- delete savedCameras[0];
- savedCameras[0]=newCameraVec[ui];
- }
+ ASSERT(savedCameras.size());
+ delete savedCameras[0];
+ savedCameras[0]=newCameraVec[ui];
}
}
@@ -889,15 +837,69 @@ bool AnalysisState::load(const char *cpFilename, std::ostream &errStream, bool m
//If we are merging then the default state has been altered
// if we are not merging, then it is overwritten
- if(merge)
- setModifyLevel(STATE_MODIFIED_DATA);
- else
- setModifyLevel(STATE_MODIFIED_NONE);
+ setModifyLevel(STATE_MODIFIED_NONE);
//Perform sanitisation on results
return true;
}
+bool AnalysisState::merge(const AnalysisState &otherState)
+{
+
+ setModifyLevel(STATE_MODIFIED_DATA);
+
+ //If we are merging, then there is a chance
+ //of a name-clash. We avoid this by trying to append -merge continuously
+ vector<std::pair<string,FilterTree> > newStashes;
+ newStashes.resize(otherState.stashedTrees.size());
+ for(size_t ui=0;ui<otherState.stashedTrees.size();ui++)
+ newStashes[ui]=otherState.stashedTrees[ui];
+ for(unsigned int ui=0;ui<newStashes.size();ui++)
+ {
+ //protect against overload (very unlikely)
+ unsigned int maxCount;
+ maxCount=100;
+ while(hasFirstInPairVec(stashedTrees,newStashes[ui]) && --maxCount)
+ newStashes[ui].first+=TRANS("-merge");
+
+ if(maxCount)
+ stashedTrees.push_back(newStashes[ui]);
+ else
+ {
+ WARN(false," Unable to merge stashes correctly. This is improbable, so please report this.");
+ }
+ }
+
+ FilterTree f = otherState.activeTree;
+ activeTree.addFilterTree(f,0);
+
+ //wipe our undo/redo trees, as we can no longer rely on them
+ undoTrees.clear();
+ redoTrees.clear();
+
+ const vector<Camera *> &newCameraVec = otherState.savedCameras;
+ for(unsigned int ui=0;ui<newCameraVec.size();ui++)
+ {
+ //Don't merge the default camera (which has no name)
+ if(newCameraVec[ui]->getUserString().empty())
+ continue;
+
+ //Keep trying new names appending "-merge" each time to obtain a new, and hopefully unique name
+ // Abort after many times
+ unsigned int maxCount;
+ maxCount=100;
+ while(camNameExists(newCameraVec[ui]->getUserString()) && --maxCount)
+ {
+ newCameraVec[ui]->setUserString(newCameraVec[ui]->getUserString()+"-merge");
+ }
+
+ //If we have any attempts left, then it worked
+ if(maxCount)
+ savedCameras.push_back(newCameraVec[ui]->clone());
+ }
+}
+
+
bool AnalysisState::camNameExists(const std::string &s) const
{
for(size_t ui=0; ui<savedCameras.size(); ui++)
@@ -1173,7 +1175,7 @@ bool testStateReload()
someState.clear();
std::ofstream strm;
- TEST(someState.load(saveString.c_str(),strm,false),"State load");
+ TEST(someState.load(saveString.c_str(),strm),"State load");
TEST(someState.getStashCount() == 1,"Stash save+load");
std::pair<string,FilterTree> stashOut;
diff --git a/src/backend/state.h b/src/backend/state.h
index 3ea33e1..3ebcb9e 100644
--- a/src/backend/state.h
+++ b/src/backend/state.h
@@ -143,11 +143,8 @@ class AnalysisState
// - returns true on success, false on fail
// - errStream will have human readable messages in
// the case that there is a failure
- // - set merge to true, if should attempt to merge
- // the two states together
bool load(const char *cpFilename,
- std::ostream &errStream,
- bool merge) ;
+ std::ostream &errStream);
//save an XML-ised representation of the analysis sate
// - mapping provides the on-disk to local name mapping to use when saving
@@ -156,6 +153,8 @@ class AnalysisState
bool save(const char *cpFilename, std::map<string,string> &fileMapping,
bool writePackage) const ;
+ //Combine a separate state file into this one, avoiding clashes
+ bool merge(const AnalysisState &srcState);
//Return the current state's filename
string getFilename() const { return fileName; }
diff --git a/src/backend/tree.hh b/src/backend/tree.hh
old mode 100755
new mode 100644
diff --git a/src/backend/viscontrol.cpp b/src/backend/viscontrol.cpp
index 1f00d31..fbd804f 100644
--- a/src/backend/viscontrol.cpp
+++ b/src/backend/viscontrol.cpp
@@ -20,6 +20,7 @@
#include "wx/wxcommon.h"
#include "wx/wxcomponents.h"
+#include "wx/propertyGridUpdater.h"
#include "gl/scene.h"
@@ -196,6 +197,13 @@ const Filter* VisController::getFilterById(size_t filterId) const
return filterMap.at(filterId);
}
+size_t VisController::getPlotID(size_t position) const
+{
+ ASSERT(plotMap.size());
+ ASSERT(plotMap.find(position)!=plotMap.end());
+ return plotMap.find(position)->second;
+}
+
size_t VisController::getIdByFilter(const Filter *f) const
{
for(map<size_t,Filter *>::const_iterator it=filterMap.begin();it!=filterMap.end();++it)
@@ -292,10 +300,10 @@ unsigned int VisController::refreshFilterTree(bool doUpdateScene)
textConsole->AppendText(wxT("============\n\n\n"));
lastFilt=consoleMessages[ui].first;
- textConsole->AppendText(wxStr(lastFilt->getUserString()));
+ textConsole->AppendText((lastFilt->getUserString()));
textConsole->AppendText(wxT("\n============\n"));
}
- textConsole->AppendText(wxStr(consoleMessages[ui].second));
+ textConsole->AppendText((consoleMessages[ui].second));
textConsole->AppendText(wxT("\n"));
}
@@ -371,8 +379,9 @@ void VisController::updateWxTreeCtrl(wxTreeCtrl *t, const Filter *visibleFilt)
upWxTreeCtrl(filterTree,t,filterMap,persistentFilters,visibleFilt);
}
-void VisController::updateFilterPropGrid(wxCustomPropGrid *g,size_t filterId) const
+void VisController::updateFilterPropGrid(wxPropertyGrid *g,size_t filterId, const std::string &stateStr) const
{
+
//The filterID can never be set to zero,
//except for the root item, as set by
//upWxTreeCtrl
@@ -384,9 +393,18 @@ void VisController::updateFilterPropGrid(wxCustomPropGrid *g,size_t filterId) co
ASSERT(targetFilter);
- updateFilterPropertyGrid(g,targetFilter);
+ updateFilterPropertyGrid(g,targetFilter,stateStr);
}
+void VisController::updateCameraPropGrid(wxPropertyGrid *g, size_t camId) const
+{
+ ASSERT(g);
+
+ const Camera *c;
+ c= currentState.getCam(camId);
+
+ updateCameraPropertyGrid(g,c);
+}
bool VisController::setCamProperties(size_t camID,unsigned int key, const std::string &value)
{
@@ -559,7 +577,6 @@ unsigned int VisController::updateScene(list<vector<const FilterStreamData *> >
//rate-limit the number of drawables to show in the scene
throttleSceneInput(sceneData);
-
//-- Build buffer of new objects to send to scene
for(list<vector<const FilterStreamData *> > ::iterator it=sceneData.begin();
it!=sceneData.end(); ++it)
@@ -622,74 +639,112 @@ unsigned int VisController::updateScene(list<vector<const FilterStreamData *> >
//The plot should have some data in it.
ASSERT(plotData->getNumBasicObjects());
- //The plot should have a parent filter
- ASSERT(plotData->parent);
//The plot should have an index, so we can keep
//filter choices between refreshes (where possible)
ASSERT(plotData->index !=(unsigned int)-1);
//Construct a new plot
unsigned int plotID;
- switch(plotData->plotMode)
+
+ //No other plot mode is currently implemented.
+ ASSERT(plotData->plotMode == PLOT_MODE_1D);
+
+ //Create a 1D plot
+ Plot1D *plotNew= new Plot1D;
+
+ plotNew->setData(plotData->xyData);
+ plotNew->setLogarithmic(plotData->logarithmic);
+ plotNew->titleAsRawDataLabel=plotData->useDataLabelAsYDescriptor;
+
+ //Construct any regions that the plot may have
+ for(unsigned int ui=0;ui<plotData->regions.size();ui++)
+ {
+ //add a region to the plot,
+ //using the region data stored
+ //in the plot stream
+ plotNew->regionGroup.addRegion(plotData->regionID[ui],
+ plotData->regionTitle[ui],
+ plotData->regions[ui].first,
+ plotData->regions[ui].second,
+ plotData->regionR[ui],
+ plotData->regionG[ui],
+ plotData->regionB[ui],plotData->regionParent);
+ }
+
+ //transfer the axis labels
+ plotNew->setStrings(plotData->xLabel,
+ plotData->yLabel,plotData->dataLabel);
+
+ //set the appearance of the plot
+ //plotNew->setTraceStyle(plotStyle);
+ plotNew->setColour(plotData->r,plotData->g,plotData->b);
+
+
+ plotNew->parentObject=plotData->parent;
+ plotNew->parentPlotIndex=plotData->index;
+
+ plotID=targetPlots->addPlot(plotNew);
+
+ plotLabels.push_back(make_pair(plotID,plotData->dataLabel));
+
+ break;
+ }
+ //TODO: Merge back into STREAM_TYPE_PLOT
+ case STREAM_TYPE_PLOT2D:
+ {
+ const Plot2DStreamData *plotData;
+ plotData=((Plot2DStreamData *)((*it)[ui]));
+ //The plot should have some data in it.
+ ASSERT(plotData->getNumBasicObjects());
+ //The plot should have an index, so we can keep
+ //filter choices between refreshes (where possible)
+ ASSERT(plotData->index !=(unsigned int)-1);
+ unsigned int plotID;
+
+ PlotBase *plotNew;
+ switch(plotData->plotType)
{
- case PLOT_MODE_1D:
+ case PLOT_2D_DENS:
+ {
+ //Create a 2D plot
+ plotNew= new Plot2DFunc;
+
+ //set the plot info
+ ((Plot2DFunc*)plotNew)->setData(plotData->xyData,
+ plotData->xMin, plotData->xMax,
+ plotData->yMin,plotData->yMax);
+
+ break;
+ }
+ case PLOT_2D_SCATTER:
{
- //Create a 1D plot
- Plot1D *plotNew= new Plot1D;
-
- plotNew->setData(plotData->xyData);
- plotNew->setLogarithmic(plotData->logarithmic);
- plotNew->titleAsRawDataLabel=plotData->useDataLabelAsYDescriptor;
-
- //Construct any regions that the plot may have
- for(unsigned int ui=0;ui<plotData->regions.size();ui++)
- {
- //add a region to the plot,
- //using the region data stored
- //in the plot stream
- plotNew->regionGroup.addRegion(plotData->regionID[ui],
- plotData->regionTitle[ui],
- plotData->regions[ui].first,
- plotData->regions[ui].second,
- plotData->regionR[ui],
- plotData->regionG[ui],
- plotData->regionB[ui],plotData->regionParent);
- }
-
- plotID=targetPlots->addPlot(plotNew);
+ //Create a 2D plot
+ plotNew= new Plot2DScatter;
+
+ //set the plot info
+ if(plotData->scatterIntensity.size())
+ ((Plot2DScatter*)plotNew)->setData(plotData->scatterData,plotData->scatterIntensity);
+ else
+ ((Plot2DScatter*)plotNew)->setData(plotData->scatterData);
+ //FIXME: scatter intesity data??
break;
}
default:
ASSERT(false);
}
-
-
- //set the appearance of the plot
- // -----
- targetPlots->setTraceStyle(plotID,plotData->plotStyle);
- targetPlots->setColours(plotID,plotData->r,
- plotData->g,plotData->b);
-
- std::wstring xL,yL,titleW;
- std::string x,y,t;
-
- xL=stlStrToStlWStr(plotData->xLabel);
- yL=stlStrToStlWStr(plotData->yLabel);
- titleW=stlStrToStlWStr(plotData->dataLabel);
-
- x=stlWStrToStlStr(xL);
- y=stlWStrToStlStr(yL);
- t=stlWStrToStlStr(titleW);
-
- targetPlots->setStrings(plotID,x,y,t);
+ //transfer the axis labels
+ plotNew->setStrings(plotData->xLabel,
+ plotData->yLabel,plotData->dataLabel);
+
+ //transfer the parent info
+ plotNew->parentObject=plotData->parent;
+ plotNew->parentPlotIndex=plotData->index;
+
+ plotID=targetPlots->addPlot(plotNew);
+
// -----
-
- //set the data origin
- targetPlots->setParentData(plotID,plotData->parent,
- plotData->index);
plotLabels.push_back(make_pair(plotID,plotData->dataLabel));
-
break;
}
case STREAM_TYPE_DRAW:
@@ -813,14 +868,13 @@ unsigned int VisController::updateScene(list<vector<const FilterStreamData *> >
//Update the plotting UI contols
//-----------
plotSelList->Clear(); // erase wx list
-
+ plotMap.clear();
for(size_t ui=0;ui<plotLabels.size();ui++)
{
//Append the plot to the list in the user interface
- wxListUint *l = new wxListUint(plotLabels[ui].first);
- plotSelList->Append(wxStr(plotLabels[ui].second),l);
+ plotSelList->Append((plotLabels[ui].second));
+ plotMap[ui] = plotLabels[ui].first;
}
- plotLabels.clear();
//If there is only one spectrum, select it
if(plotSelList->GetCount() == 1 )
@@ -831,6 +885,10 @@ unsigned int VisController::updateScene(list<vector<const FilterStreamData *> >
//to set the selection
targetPlots->bestEffortRestoreVisibility();
+ }
+
+ for(unsigned int ui=0; ui<plotSelList->GetCount();ui++)
+ {
#if defined(__WIN32__) || defined(__WIN64__)
//Bug under windows. SetSelection(wxNOT_FOUND) does not work for multi-selection list boxes
plotSelList->SetSelection(-1, false);
@@ -839,12 +897,9 @@ unsigned int VisController::updateScene(list<vector<const FilterStreamData *> >
#endif
for(unsigned int ui=0; ui<plotSelList->GetCount();ui++)
{
- wxListUint *l;
- unsigned int plotID;
-
//Retrieve the uniqueID
- l=(wxListUint*)plotSelList->GetClientObject(ui);
- plotID = l->value;
+ unsigned int plotID;
+ plotID=plotMap[ui];
if(targetPlots->isPlotVisible(plotID))
plotSelList->SetSelection(ui);
}
@@ -908,18 +963,19 @@ unsigned int VisController::updateScene(list<vector<const FilterStreamData *> >
displayList->endList();
targetScene->addDrawable(displayList);
}
-
- delete displayList;
+ else
+ delete displayList;
}
else
{
for(unsigned int ui=0;ui<drawIons.size(); ui++)
targetScene->addDrawable(drawIons[ui]);
}
-
+
+ //add all drawable objects (not ions)
for(size_t ui=0;ui<sceneDrawables.size();ui++)
targetScene->addDrawable(sceneDrawables[ui]);
-
+
sceneDrawables.clear();
targetScene->computeSceneLimits();
targetScene->addSelectionDevices(devices);
@@ -979,37 +1035,6 @@ bool VisController::setCam(unsigned int offset)
return true;
}
-void VisController::updateCamPropertyGrid(wxCustomPropGrid *g,unsigned int offset) const
-{
-
- //Erase the grid
- g->clearKeys();
-
- //Abort if there are no cameras
- if(!currentState.getNumCams())
- return;
-
- //Obtain the properties of the currently active camera
- CameraProperties p;
- currentState.getCam(offset)->getProperties(p);
-
- //Set the property grid
- g->setNumGroups(p.data.size());
- //Create the keys for the property grid to do its thing
- for(unsigned int ui=0;ui<p.data.size();ui++)
- {
- for(unsigned int uj=0;uj<p.data[ui].size();uj++)
- {
- //TODO: ADD TOOLTIP
- g->addKey(p.data[ui][uj].first, ui,p.keys[ui][uj],
- p.types[ui][uj],p.data[ui][uj].second,string(""));
- }
- }
-
- //Let the property grid layout what it needs to
- g->propertyLayout();
-}
-
bool VisController::reparentFilter(size_t filter, size_t newParent)
{
//Save current filter state to undo stack
@@ -1138,14 +1163,20 @@ bool VisController::loadState(const char *cpFilename, std::ostream &errStream, b
//Load into a temporary state
// and if successful, transfer to full state
- AnalysisState state;
- bool result=state.load(cpFilename,errStream,merge);
+ AnalysisState tmpState;
+ bool result=tmpState.load(cpFilename,errStream);
if(!result)
return false;
-
- currentState=state;
-
+
+ if(merge)
+ {
+ currentState.merge(tmpState);
+ }
+ else
+ {
+ currentState=tmpState;
+ }
//Synchronise scene and viscontrol components to
// current state
@@ -1217,8 +1248,8 @@ bool VisController::loadState(const char *cpFilename, std::ostream &errStream, b
//Try to restore the working directory as needed
std::string wd;
wd=currentState.getWorkingDir();
- if(wd.size() && wxDirExists(wxStr(wd)))
- wxSetWorkingDirectory(wxStr(currentState.getWorkingDir()));
+ if(wd.size() && wxDirExists((wd)))
+ wxSetWorkingDirectory((currentState.getWorkingDir()));
currentState.setStateModified(false);
return true;
@@ -1349,7 +1380,7 @@ void VisController::getStashes(std::vector<std::pair<std::string,unsigned int >
void VisController::updateRawGrid() const
{
vector<vector<vector<float> > > plotData;
- vector<std::vector<std::wstring> > labels;
+ vector<std::vector<std::string> > labels;
//grab the data for the currently visible plots
targetPlots->getRawData(plotData,labels);
@@ -1373,8 +1404,8 @@ void VisController::updateRawGrid() const
for(unsigned int uj=0;uj<labels[ui].size();uj++)
{
std::string s;
- s=stlWStrToStlStr(labels[ui][uj]);
- targetRawGrid->SetColLabelValue(curCol,wxStr(s));
+ s=(labels[ui][uj]);
+ targetRawGrid->SetColLabelValue(curCol,(s));
curCol++;
}
@@ -1389,7 +1420,7 @@ void VisController::updateRawGrid() const
{
std::string tmpStr;
stream_cast(tmpStr,plotData[ui][uj][uk]);
- targetRawGrid->SetCellValue(uk,startCol,wxStr(tmpStr));
+ targetRawGrid->SetCellValue(uk,startCol,(tmpStr));
}
startCol++;
}
@@ -1433,7 +1464,7 @@ void VisController::updateConsole(const std::vector<std::string> &v, const Filte
{
std::string s;
s = f->getUserString() + string(" : ") + v[ui];
- textConsole->AppendText(wxStr(s));
+ textConsole->AppendText((s));
textConsole->AppendText(wxT("\n"));
}
diff --git a/src/backend/viscontrol.h b/src/backend/viscontrol.h
index 6b348e0..107770a 100644
--- a/src/backend/viscontrol.h
+++ b/src/backend/viscontrol.h
@@ -24,7 +24,6 @@
class VisController;
class wxGrid;
-class wxCustomPropGrid;
class wxTreeCtrl;
class Scene;
@@ -33,6 +32,7 @@ class Scene;
#include "backend/plot.h"
#include "backend/animator.h"
#include "state.h"
+#include "filter.h"
#include "backend/APT/APTFileIO.h"
@@ -99,7 +99,6 @@ class VisController
// this is used when loading a state file to prevent from bringing older selection state into current plots
bool deferClearPlotVisibility;
- void clear();
//!Retreive the updates to the filter tree from the scene
@@ -135,6 +134,9 @@ class VisController
// the wxTree control
std::vector<const Filter *> persistentFilters;
+ //Map plot position to ID
+ std::map<size_t, size_t> plotMap;
+
public:
VisController();
@@ -228,7 +230,7 @@ class VisController
//Move a filter from one part of the tree to another
bool reparentFilter(size_t filterID, size_t newParentID);
- //!Set the properties using a key-value result (as obtained from updatewxCustomPropGrid)
+ //!Set the properties using a key-value result
/*
* The return code tells whether to reject or accept the change.
* need update tells us if the change to the filter resulted in a change to the scene
@@ -264,7 +266,7 @@ class VisController
void setScene(Scene *theScene);
//!Set the backend plot
void setPlotWrapper(PlotWrapper *thePlots){targetPlots=thePlots;};
-
+
PlotWrapper *getPlotWrapper(){return targetPlots;};
//!Set the listbox for plot selection
void setPlotList(wxListBox *box){plotSelList=box;};
@@ -272,17 +274,18 @@ class VisController
//!Set the backend grid control for raw data
void setRawGrid(wxGrid *theRawGrid){targetRawGrid=theRawGrid;};
-
+
+ //Get a plot ID from the listbox position
+ size_t getPlotID(size_t position) const ;
//!Write out the filters into a wxtreecontrol.
// optional argument is the fitler to keep visible in the control
void updateWxTreeCtrl(wxTreeCtrl *t,const Filter *f=0);
- //!Update a wxCustomPropGrid with the properties for a given filter
- void updateFilterPropGrid(wxCustomPropGrid *g,size_t filterId) const;
-
-
-
-
+ //!Update a wxPropertyGrid with the properties for a given filter
+ void updateFilterPropGrid(wxPropertyGrid *g,size_t filterId, const std::string &stateString="") const;
+ //!Update a wxPropertyGrid with the properties for a given filter
+ void updateCameraPropGrid(wxPropertyGrid *g,size_t cameraId) const;
+
//!Set the camera to use in the scene
bool setCam(unsigned int uniqueID) ;
@@ -292,13 +295,10 @@ class VisController
//!Add a new camera to the scene
unsigned int addCam(const std::string &camName);
- //!Update a wxtGrid with the properties for a given filter
- void updateCamPropertyGrid(wxCustomPropGrid *g,unsigned int camId) const;
-
//!Return the number of cameras
unsigned int numCams() const ;
- //!Set the properties using a key-value result (as obtaed from updatewxCustomPropGrid)
+ //!Set the properties using a key-value result
/*! The return code tells whether to reject or accept the change.
*/
bool setCamProperties(size_t camId,
@@ -456,6 +456,11 @@ class VisController
void getAnimationState(PropertyAnimator &pA,
std::vector<pair<string,size_t> > &pathMapping) const;
+ //wipe the state. Does not perform a refresh need to do this manually
+ void clear();
+
+ //Return the number of filters that are currently in the state
+ size_t getNumFilters() const { return filterTree.size();}
#ifdef DEBUG
//Check that the tree conrol is synced up to the filter map correctly
void checkTree(wxTreeCtrl *t);
diff --git a/src/common/array2D.h b/src/common/array2D.h
new file mode 100644
index 0000000..65f0660
--- /dev/null
+++ b/src/common/array2D.h
@@ -0,0 +1,223 @@
+/*
+ * Array2D.h: This file was part of RawTherapee, but is
+ * used as a general-purpose array module.
+ *
+ * Copyright (c) 2011 Jan Rinze Peterzon (janrinze at gmail.com)
+ *
+ * this program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Declaration of flexible 2D arrays
+ *
+ * Usage:
+ *
+ * Array2D<type> name (X-size,Y-size);
+ * Array2D<type> name (X-size,Y-size type ** data);
+ *
+ * creates an array which is valid within the normal C/C++ scope "{ ... }"
+ *
+ * access to elements is a simple as:
+ *
+ * Array2D<float> my_array (10,10); // creates 10x10 array of floats
+ * value = my_array[3][5];
+ * my_array[4][6]=value;
+ *
+ * or copy an existing 2D array
+ *
+ * float ** mydata;
+ * Array2D<float> my_array (10,10,mydata);
+ *
+ *
+ * Useful extra pointers
+ *
+ * <type> ** my_array gives access to the pointer for access with [][]
+ * <type> * my_array gives access to the flat stored data.
+ *
+ * Advanced usage:
+ * Array2D<float> my_array ; // empty container.
+ * my_array(10,10) ; // resize to 10x10 array
+ * my_array(10,10,ARRAY2D_CLEAR_DATA) ; // resize to 10x10 and clear data
+ *
+ */
+#ifndef ARRAY2D_H_
+#define ARRAY2D_H_
+
+#include <cstring>
+#include <cstdio>
+
+template<typename T>
+class Array2D {
+
+private:
+ unsigned int x, y;
+ T ** ptr;
+ T * data;
+ void ar_realloc(unsigned int w, unsigned int h) {
+ if ((ptr) && ((h > y) || (4 * h < y))) {
+ delete[] ptr;
+ ptr = NULL;
+ }
+ if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) {
+ delete[] data;
+ data = NULL;
+ }
+ if (ptr == NULL)
+ ptr = new T*[h];
+ if (data == NULL)
+ data = new T[h * w];
+
+ x = w;
+ y = h;
+ #pragma omp parallel for
+ for (unsigned int i = 0; i < h; i++)
+ ptr[i] = data + w * i;
+ }
+public:
+
+ // use as empty declaration, resize before use!
+ // very useful as a member object
+ Array2D() :
+ x(0), y(0), ptr(NULL), data(NULL) {
+ }
+
+ // creator type1
+ Array2D(unsigned int w, unsigned int h) {
+ data = new T[h * w];
+ x = w;
+ y = h;
+ ptr = new T*[h];
+ #pragma omp parallel for
+ for (unsigned int i = 0; i < h; i++)
+ ptr[i] = data + i * w;
+ }
+
+ // creator type 2
+ Array2D(unsigned int w, unsigned int h, T ** source ) {
+ // when by reference
+ // TODO: improve this code with ar_realloc()
+ data = new T[h * w];
+ x = w;
+ y = h;
+ ptr = new T*[h];
+ #pragma omp parallel for
+ for (unsigned int i = 0; i < h; i++) {
+ ptr[i] = data + i * w;
+ for (unsigned int j = 0; j < w; j++)
+ ptr[i][j] = source[i][j];
+ }
+ }
+
+ // destructor
+ ~Array2D() {
+
+ if (data)
+ delete[] data;
+ if (ptr)
+ delete[] ptr;
+ }
+
+ Array2D(const Array2D &other)
+ {
+ *this=other;
+ }
+
+ // use with indices
+ T * operator[](unsigned int index) const {
+ ASSERT((index>=0) && (index < y));
+ return ptr[index];
+ }
+
+ // use as pointer to T**
+ operator T**() const {
+ return ptr;
+ }
+
+ // use as pointer to data
+ operator T*() const {
+ return data;
+ }
+
+
+ // useful within init of parent object
+ // or use as resize of 2D array
+ void operator()(unsigned int w, unsigned int h ) {
+ ar_realloc(w,h);
+ }
+
+ // import from flat data
+ void operator()(unsigned int w, unsigned int h, T* copy) {
+ ar_realloc(w,h);
+ memcpy(data, copy, w * h * sizeof(T));
+ }
+ unsigned int width() const {
+ return x;
+ }
+ unsigned int height() const {
+ return y;
+ }
+
+ bool empty() const
+ {
+ return data == NULL;
+ }
+
+ operator bool() const {
+ return (x > 0 && y > 0);
+ }
+
+
+ void resize(unsigned int newX, unsigned int newY)
+ {
+ ar_realloc(newX,newY);
+ }
+
+ unsigned int size() const
+ {
+ return x*y;
+ }
+ void clear()
+ {
+ delete data;
+ data=NULL;
+ }
+
+ void unpack(std::vector<std::vector<T> > &data) const
+ {
+ data.resize(y);
+#pragma omp parallel for
+ for(unsigned int ui=0;ui<y; ui++)
+ {
+ data[ui].resize(x);
+ for(unsigned int uj=0;uj<x;uj++)
+ data[ui][uj]=ptr[ui][uj];
+ }
+ }
+
+ Array2D<T> & operator=( const Array2D<T> & rhs) {
+ if (this != &rhs)
+
+ {
+ ar_realloc(rhs.x, rhs.y);
+ // we could have been created from a different
+ // array format where each row is created by 'new'
+ #pragma omp parallel for
+ for (unsigned int i=0;i<y;i++)
+ memcpy(ptr[i],rhs.ptr[i],x*sizeof(T));
+ }
+ return *this;
+ }
+
+};
+#endif /* Array2D_H_ */
diff --git a/src/common/basics.cpp b/src/common/basics.cpp
index 061d074..85062fb 100644
--- a/src/common/basics.cpp
+++ b/src/common/basics.cpp
@@ -49,21 +49,7 @@ using std::vector;
using std::list;
-//Name of the DTD file for state loading
-const char *DTD_NAME="threeDepict-state.dtd";
-//Program name
-const char *PROGRAM_NAME = "3Depict";
-//Program version
-const char *PROGRAM_VERSION = "0.0.16";
-//Path to font for Default FTGL font
-const char *FONT_FILE= "FreeSans.ttf";
-
-const char *TEXT_LOAD_ERR_STRINGS[] = { "",
- NTRANS("Error opening file"),
- NTRANS("Error whilst reading file contents"),
- NTRANS("Error interpreting field in file"),
- NTRANS("Inconsistent number of columns found")
- };
+
//default font to use.
std::string defaultFontFile;
@@ -310,7 +296,334 @@ string veryFuzzyTimeSince( time_t origTime, time_t nowTime)
return TRANS("moments ago");
}
+ColourRGBA::ColourRGBA()
+{
+}
+
+ColourRGBA::ColourRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+{
+ data[0]=r;
+ data[1]=g;
+ data[2]=b;
+ data[3]=a;
+}
+
+
+ColourRGBA::ColourRGBA(unsigned char r, unsigned char g, unsigned char b)
+{
+ data[0]=r;
+ data[1]=g;
+ data[2]=b;
+}
+
+unsigned char ColourRGBA::at(unsigned int idx) const
+{
+ ASSERT(idx< 4);
+ return data[idx];
+}
+
+unsigned char ColourRGBA::r() const
+{
+ return data[0];
+}
+
+unsigned char ColourRGBA::g() const
+{
+ return data[1];
+}
+
+unsigned char ColourRGBA::b() const
+{
+ return data[2];
+}
+
+unsigned char ColourRGBA::a() const
+{
+ return data[3];
+}
+
+bool ColourRGBA::parse(const std::string &str)
+{
+ //Input string is in 2 char hex form, 3 or 4 colour, with # leading. RGB order
+ //lowercase string.
+ if(str.size() != 9 && str.size() != 7)
+ return false;
+
+ if(str[0] != '#')
+ return false;
+
+ string rS,gS,bS,aS;
+ rS=str.substr(1,2);
+ gS=str.substr(3,2);
+ bS=str.substr(5,2);
+
+ if(!isxdigit(rS[0]) || !isxdigit(rS[1]))
+ return false;
+ if(!isxdigit(gS[0]) || !isxdigit(gS[1]))
+ return false;
+ if(!isxdigit(bS[0]) || !isxdigit(bS[1]))
+ return false;
+
+ unsigned char r,g,b,a;
+ hexStrToUChar(str.substr(1,2),r);
+ hexStrToUChar(str.substr(3,2),g);
+ hexStrToUChar(str.substr(5,2),b);
+ //3 colour must have a=255.
+ if(str.size() == 7)
+ a = 255;
+ else
+ {
+ aS=str.substr(7,2);
+ if(!isxdigit(aS[0]) || !isxdigit(aS[1]))
+ return false;
+ hexStrToUChar(str.substr(7,2),a);
+ }
+
+ data[0]=r;
+ data[1]=g;
+ data[2]=b;
+ data[3]=a;
+ return true;
+}
+
+std::string ColourRGBA::rgbaString() const
+{
+ std::string s="#", tmp;
+ ucharToHexStr(data[0],tmp);
+ s+=tmp;
+ ucharToHexStr(data[1],tmp);
+ s+=tmp;
+ ucharToHexStr(data[2],tmp);
+ s+=tmp;
+ ucharToHexStr(data[3],tmp);
+ s+=tmp;
+
+ return s;
+}
+
+std::string ColourRGBA::rgbString() const
+{
+ string tmp,s;
+ s="#";
+ ucharToHexStr(data[0],tmp);
+ s+=tmp;
+ ucharToHexStr(data[1],tmp);
+ s+=tmp;
+ ucharToHexStr(data[2],tmp);
+ s+=tmp;
+
+ return s;
+}
+
+RGBf ColourRGBA::toFloat() const
+{
+ RGBf ret;
+ ret.red=(float)data[0]/255.0f;
+ ret.green=(float)data[1]/255.0f;
+ ret.blue=(float)data[2]/255.0f;
+
+ return ret;
+}
+
+ColourRGBAf ColourRGBA::toRGBAf() const
+{
+ ColourRGBAf tmp;
+
+ for(unsigned int ui=0;ui<4;ui++)
+ {
+ tmp[ui] = (float)data[ui]/255.0f;
+ }
+
+ return tmp;
+}
+
+void ColourRGBA::fromRGBf(const RGBf &oth)
+{
+ data[0]=oth.red*255.0f;
+ data[1]=oth.green*255.0f;
+ data[2]=oth.blue*255.0f;
+ data[3]=255.0f;
+}
+
+bool ColourRGBA::operator==(const ColourRGBA &oth) const
+{
+ for(unsigned int ui=0;ui<4;ui++)
+ {
+ if(data[ui] != oth.data[ui])
+ return false;
+ }
+ return true;
+}
+
+bool ColourRGBA::operator==(const ColourRGBAf &oth) const
+{
+ for(unsigned int ui=0;ui<4;ui++)
+ {
+ if(data[ui] != oth.at(ui))
+ return false;
+ }
+ return true;
+}
+
+bool ColourRGBA::operator==(const RGBf &oth) const
+{
+ return (data[0]/255.0f == oth.red && data[1]/255.0f == oth.green && data[2]/255.0f == oth.blue);
+
+}
+
+bool ColourRGBA::operator!=(const ColourRGBA &oth) const
+{
+ return !(*this == oth);
+}
+
+bool ColourRGBA::operator!=(const ColourRGBAf &oth) const
+{
+ return !(*this == oth);
+}
+
+
+ColourRGBAf::ColourRGBAf()
+{
+}
+
+ColourRGBAf::ColourRGBAf(float r, float g, float b, float a)
+{
+ ASSERT(r >=0 && r <=1.0f);
+ ASSERT(g >=0 && g <=1.0f);
+ ASSERT(b >=0 && b <=1.0f);
+ ASSERT(a >=0 && a <=1.0f);
+ data[0]=r;
+ data[1]=g;
+ data[2]=b;
+ data[3]=a;
+}
+
+
+ColourRGBAf::ColourRGBAf(float r, float g, float b)
+{
+ ASSERT(r >=0 && r <=1.0f);
+ ASSERT(g >=0 && g <=1.0f);
+ ASSERT(b >=0 && b <=1.0f);
+ data[0]=r;
+ data[1]=g;
+ data[2]=b;
+ data[3]=1.0f;
+}
+float ColourRGBAf::r() const
+{
+ return data[0];
+}
+
+float ColourRGBAf::g() const
+{
+ return data[1];
+}
+
+float ColourRGBAf::b() const
+{
+ return data[2];
+}
+
+float ColourRGBAf::a() const
+{
+ return data[3];
+}
+
+void ColourRGBAf::r(float v)
+{
+ ASSERT(v >=0.0f && v <=1.0f);
+ data[0]=v;
+}
+
+void ColourRGBAf::g(float v)
+{
+ ASSERT(v >=0.0f && v <=1.0f);
+ data[1]=v;
+}
+
+void ColourRGBAf::b(float v)
+{
+ ASSERT(v >=0.0f && v <=1.0f);
+ data[2]=v;
+}
+
+void ColourRGBAf::a(float v)
+{
+ ASSERT(v >=0.0f && v <=1.0f);
+ data[3]=v;
+}
+float &ColourRGBAf::operator[](unsigned int idx)
+{
+ ASSERT(idx < 4);
+ return data[idx];
+}
+
+float ColourRGBAf::at(unsigned int idx) const
+{
+ return data[idx];
+}
+
+
+ColourRGBAf ColourRGBAf::interpolate(float delta, const ColourRGBAf &other)
+{
+ ColourRGBAf result;
+
+ for(unsigned int ui=0;ui<3;ui++)
+ result[ui] = data[ui] + (other.data[ui] - data[ui])*delta;
+ return result;
+}
+
+ColourRGBA ColourRGBAf::toColourRGBA() const
+{
+ ColourRGBA tmp(data[0]*255.0f,data[1]*255.0f,
+ data[2]*255.0f,data[3]*255.0f);
+ return tmp;
+}
+
+RGBf ColourRGBAf::toRGBf() const
+{
+ RGBf tmp;
+ tmp.red=data[0];
+ tmp.green=data[1];
+ tmp.blue=data[2];
+ return tmp;
+}
+
+
+void ColourRGBAf::operator=(const RGBf &oth)
+{
+ data[0]= oth.red;
+ data[1]= oth.green;
+ data[2]= oth.blue;
+ data[3]= 1.0f;
+}
+
+
+bool ColourRGBAf::operator==(const ColourRGBA &oth) const
+{
+ for(unsigned int ui=0;ui<3;ui++)
+ {
+ if(data[ui] != (float)oth.at(ui)/255.0f)
+ return false;
+ }
+
+ return true;
+}
+
+bool ColourRGBAf::operator==(const ColourRGBAf &oth) const
+{
+ for(unsigned int ui=0;ui<3;ui++)
+ {
+ if(data[ui] != (float)oth.data[ui])
+ return false;
+ }
+ return true;
+}
+bool ColourRGBAf::operator!=(const ColourRGBAf &oth) const
+{
+ return !(*this == oth);
+}
void BoundCube::getBound(Point3D &retBound, unsigned int minMax) const
{
retBound=Point3D(bounds[0][minMax],
@@ -367,6 +680,17 @@ void BoundCube::setBounds(const std::vector<Point3D> &points)
#endif
}
+void BoundCube::setBounds(const Point3D &p, float r)
+{
+ for(unsigned int dim=0;dim<3;dim++)
+ {
+ bounds[dim][0] = p[dim] - r;
+ bounds[dim][1] = p[dim] + r;
+ valid[dim][0]=true;
+ valid[dim][1]=true;
+ }
+}
+
void BoundCube::getVertices(std::vector<Point3D> &points, bool centre) const
{
points.resize(8);
@@ -610,6 +934,38 @@ bool BoundCube::intersects(const Point3D &pt, float sqrRad)
return (nearPt.sqrDist(pt) <=sqrRad);
}
+BoundCube BoundCube::makeUnion(const BoundCube &bC) const
+{
+ BoundCube res;
+ for(unsigned int dim=0;dim<3;dim++)
+ {
+ float a,b;
+ a=bounds[dim][0]; b=bC.bounds[dim][0];
+ res.setBound(dim,0,std::max(a,b));
+ a=bounds[dim][1]; b=bC.bounds[dim][1];
+ res.setBound(dim,1,std::min(a,b));
+ }
+
+ return res;
+}
+
+unsigned int BoundCube::segmentTriple(unsigned int dim, float slice) const
+{
+ ASSERT(dim < 3);
+
+ //check lower
+ if( slice < bounds[dim][0])
+ return 0;
+
+ //check upper
+ if( slice >=bounds[dim][1])
+ return 2;
+
+ return 1;
+
+}
+
+
Point3D BoundCube::getCentroid() const
{
#ifdef DEBUG
@@ -1147,36 +1503,27 @@ bool isValidXML(const char *filename)
return true;
}
+#if !defined(__WIN32__) && !defined(__WIN64)
-//FIXME: Why negative?
bool isNotDirectory(const char *filename)
{
-#if !defined(__WIN32__) && !defined(__WIN64__)
struct stat statbuf;
if(stat(filename,&statbuf) == -1)
return false;
return (statbuf.st_mode !=S_IFDIR);
-#else
-
- WARN(false, "Untested function. calling win api");
- DWORD fileAttribs;
- fileAttribs=GetFileAttributes((LPCWSTR)filename);
- if(fileAttribs == INVALID_FILE_ATTRIBUTES)
- return false;
-
- return !(fileAttribs & FILE_ATTRIBUTE_DIRECTORY);
-#endif
}
bool rmFile(const std::string &filename)
{
-#if !defined(__WIN32__) && !defined(__WIN64__)
return remove(filename.c_str()) == 0;
-#else
- WARN(false, "Untested function. calling win api");
- return DeleteFile((LPCWSTR)filename.c_str());
-#endif
}
+#elif defined(__WIN32) || defined(__WIN64)
+bool rmFile(const std::string &filename)
+{
+ return DeleteFile((const wchar_t*)filename.c_str()) == 0;
+}
+#endif
+
#endif
diff --git a/src/common/basics.h b/src/common/basics.h
index d0f5d5f..5067d40 100644
--- a/src/common/basics.h
+++ b/src/common/basics.h
@@ -36,10 +36,6 @@ class K3DTree;
bool dummyCallback(bool);
-extern const char *DTD_NAME;
-extern const char *PROGRAM_NAME;
-extern const char *PROGRAM_VERSION;
-extern const char *FONT_FILE;
//Set new locale code. Must be followed by a popLocale call before completion
@@ -95,7 +91,6 @@ enum
ERR_FILE_ENUM_END // not an error, just end of enum
};
-extern const char *TEXT_LOAD_ERR_STRINGS[];
//Perform a a<-b<-c<-a rotation of data
template<class T>
@@ -359,8 +354,16 @@ public:
void setBounds( const Point3D &p, const Point3D &q);
//!Obtain bounds from an array of Point3Ds
void setBounds(const std::vector<Point3D> &ptArray);
+
+ //!Set bounds via cube that contains given sphere
+ void setBounds(const Point3D &p, float radius);
+
+ //Set & set-like operations
//!Checks if a point intersects a sphere of centre Pt, radius^2 sqrRad
bool intersects(const Point3D &pt, float sqrRad);
+
+ //Create a union of two bounding cubes, which is itself a cube
+ BoundCube makeUnion(const BoundCube &b) const;
//Check to see if the point is contained in, or part of the walls
//of the cube
bool containsPt(const Point3D &pt) const;
@@ -370,6 +373,8 @@ public:
//!Is this bounding cube completely contained within a sphere centred on pt of sqr size sqrRad?
bool containedInSphere(const Point3D &pt, float sqrRad) const;
+
+ unsigned int segmentTriple(unsigned int dim, float slice) const;
//!Returns maximum distnace to box corners (which is an upper bound on max box distance).
//Bounding box must be valid.
float getMaxDistanceToBox(const Point3D &pt) const;
@@ -397,72 +402,97 @@ public:
friend class K3DTreeMk2;
};
+//!Data holder for colour as float
+typedef struct RGBf
+{
+ float red;
+ float green;
+ float blue;
+} RGBf;
+class ColourRGBAf;
-
-//OK, this is a bit tricky. We override the operators to call
-//a callback, so the UI updates keep happening, even inside the STL function
-//----
-template<class T>
-class GreaterWithCallback
+//Colour storage class. Uses uchar internally
+class ColourRGBA
{
- private:
- bool (*callback)(bool);
- //!Reduction frequency (use callback every k its)
- unsigned int redMax;
- //!Current reduction counter
- unsigned int reduction;
- //!pointer to progress value
- unsigned int *prgPtr;
public:
- //!Second argument is a "reduction" value to set the number of calls
- //to the random functor before initiating a callback
- GreaterWithCallback( bool (*ptr)(bool),unsigned int red) : callback(ptr), redMax(red), reduction(red)
- {};
+ unsigned char data[4];
+ public:
+ ColourRGBA();
+ ColourRGBA(unsigned char , unsigned char, unsigned char);
+ ColourRGBA(unsigned char , unsigned char, unsigned char, unsigned char);
+ unsigned char r() const;
+ unsigned char g() const;
+ unsigned char b() const;
+ unsigned char a() const;
+
+ //Parse a colour string, such as #aabbccdd into its RGBA 8-bit components. alpha value (last) can be omitted. Will assume 255.
+ bool parse(const std::string &);
+
+ //Convert an RGB its
+ // hexadecimal colour string
+ // format is "#rrggbb" such as "#11ee00"
+ std::string rgbString() const;
+ //Convert RGB to hex colour string, with alpha channel
+ std::string rgbaString() const;
+
+ //convert data from RGB/[0->255] integers to [0->1] float.
+ // alpha channel is not used
+ RGBf toFloat() const;
+
+ void fromRGBAf(const ColourRGBAf &);
+ ColourRGBAf toRGBAf() const;
+
+ void fromRGBf(const RGBf &);
- bool operator()(const T &a, const T &b)
- {
- if(!reduction--)
- {
- reduction=redMax;
- //Execute callback
- (*callback)(false);
- }
+ bool operator==(const ColourRGBA &oth) const;
+ bool operator==(const ColourRGBAf &oth) const;
+ bool operator==(const RGBf &oth) const;
+
+ bool operator!=(const ColourRGBA &oth) const;
+ bool operator!=(const ColourRGBAf &oth) const;
+
+ unsigned char at(unsigned int idx) const;
- return a < b;
- }
};
-
-template<class T>
-class EqualWithCallback
+//Colour storage class. Uses float internally
+class ColourRGBAf
{
private:
- bool (*callback)(bool);
- //!Reduction frequency (use callback every k its)
- unsigned int redMax;
- //!Current reduction counter
- unsigned int reduction;
+ float data[4];
public:
- //!Second argument is a "reduction" value to set the number of calls
- //to the random functor before initiating a callback
- EqualWithCallback( bool (*ptr)(bool),unsigned int red) : callback(ptr), redMax(red), reduction(red)
- { };
-
- bool operator()(const T &a, const T &b)
- {
- if(!reduction--)
- {
- reduction=redMax;
- //Execute callback
- (*callback)(false);
- }
-
- return a ==b;
- }
+ ColourRGBAf();
+ ColourRGBAf(float, float, float);
+ ColourRGBAf(float, float, float,float);
+ float r() const;
+ float g() const;
+ float b() const;
+ float a() const;
+
+ void r(float);
+ void g(float);
+ void b(float);
+ void a(float);
+
+
+ ColourRGBAf interpolate(float delta, const ColourRGBAf &other);
+ //convert to a ColourRGBA (uchar representation)
+ //TODO : Rename me!
+ ColourRGBA toColourRGBA() const;
+ RGBf toRGBf() const;
+ bool operator==(const ColourRGBA &oth) const;
+ bool operator!=(const ColourRGBA &oth) const;
+ bool operator==(const ColourRGBAf &oth) const;
+ bool operator!=(const ColourRGBAf &oth) const;
+
+ //TODO: Deprecate me!
+ bool operator==(const RGBf &oth) const;
+
+ void operator=(const RGBf &oth);
+ float &operator[](unsigned int idx) ;
+ float at(unsigned int idx) const;
};
-//----
-
//Randomly select subset. Subset will be (somewhat) sorted on output
template<class T> size_t randomSelect(std::vector<T> &result, const std::vector<T> &source,
@@ -503,10 +533,7 @@ template<class T> size_t randomSelect(std::vector<T> &result, const std::vector<
ticks[ui]=(size_t)(rng.genUniformDev()*(source.size()-1));
//Remove duplicates. Intersperse some callbacks to be nice
- GreaterWithCallback<size_t> gFunctor(callback,50000);
- std::sort(ticks.begin(),ticks.end(),gFunctor);
- EqualWithCallback<size_t> eqFunctor(callback,50000);
-
+ std::sort(ticks.begin(),ticks.end());
std::vector<size_t>::iterator newLast;
newLast=std::unique(ticks.begin(),ticks.end());
ticks.erase(newLast,ticks.end());
@@ -526,8 +553,8 @@ template<class T> size_t randomSelect(std::vector<T> &result, const std::vector<
}
- std::sort(ticks.begin(),ticks.end(),gFunctor);
- newLast=std::unique(ticks.begin(),ticks.end(),eqFunctor);
+ std::sort(ticks.begin(),ticks.end());
+ newLast=std::unique(ticks.begin(),ticks.end());
ticks.erase(newLast,ticks.end());
}
@@ -556,7 +583,7 @@ template<class T> size_t randomSelect(std::vector<T> &result, const std::vector<
else
{
//Sort the ticks properly (mostly sorted anyway..)
- std::sort(ticks.begin(),ticks.end(),gFunctor);
+ std::sort(ticks.begin(),ticks.end());
unsigned int curTick=0;
for(size_t ui=0;ui<source.size(); ui++)
@@ -677,13 +704,12 @@ template<class T> size_t randomDigitSelection(std::vector<T> &result, const size
ticks[ui]=(size_t)(rng.genUniformDev()*(max-1));
//Remove duplicates. Intersperse some callbacks to be nice
- GreaterWithCallback<size_t> gFunctor(callback,50000);
- std::sort(ticks.begin(),ticks.end(),gFunctor);
- EqualWithCallback<size_t> eqFunctor(callback,50000);
-
+ std::sort(ticks.begin(),ticks.end());
+ (*callback)(false);
std::vector<size_t>::iterator itLast;
- itLast=std::unique(ticks.begin(),ticks.end(),eqFunctor);
+ itLast=std::unique(ticks.begin(),ticks.end());
ticks.erase(itLast,ticks.end());
+ (*callback)(false);
//Top up with unique entries
while(ticks.size() < numTicksNeeded)
@@ -698,9 +724,11 @@ template<class T> size_t randomDigitSelection(std::vector<T> &result, const size
}
- std::sort(ticks.begin(),ticks.end(),gFunctor);
- itLast=std::unique(ticks.begin(),ticks.end(),eqFunctor);
+ std::sort(ticks.begin(),ticks.end());
+ (*callback)(false);
+ itLast=std::unique(ticks.begin(),ticks.end());
ticks.erase(itLast,ticks.end());
+ (*callback)(false);
}
@@ -730,7 +758,7 @@ template<class T> size_t randomDigitSelection(std::vector<T> &result, const size
else
{
//Sort the ticks properly (mostly sorted anyway..)
- std::sort(ticks.begin(),ticks.end(),gFunctor);
+ std::sort(ticks.begin(),ticks.end());
unsigned int curTick=0;
for(size_t ui=0;ui<numTicksNeeded; ui++)
diff --git a/src/common/translation.h b/src/common/constants.cpp
similarity index 50%
copy from src/common/translation.h
copy to src/common/constants.cpp
index 1a7eea7..61d3da9 100644
--- a/src/common/translation.h
+++ b/src/common/constants.cpp
@@ -1,5 +1,5 @@
/*
- * common/translation.h - Program gettext translation macros
+ * common/constants.cpp - Common constants used across program
* Copyright (C) 2013 D Haley
*
* This program is free software: you can redistribute it and/or modify
@@ -15,26 +15,17 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-#ifndef TRANSLATION_H
-#define TRANSLATION_H
-
-#include <locale>
-
-
-#if defined(__APPLE__) || defined(__WIN32__) || defined(__WIN64__)
-#include <libintl.h>
-#endif
-
-//!Gettext translation macro
-#define TRANS(x) (gettext(x))
-
-//!Gettext null-translation macro (mark for translation, but do nothing)
-#define NTRANS(x) (x)
-
-//!Wx friendly gettext translation macro
-#define wxTRANS(x) (wxString(gettext(x),*wxConvCurrent))
-
-#define wxNTRANS(x) wxT(x)
-
-#endif
+#include "constants.h"
+#include "translation.h"
+
+//pattern to use when looking for rangefiles
+const char *RANGEFILE_WX_CONSTANT= NTRANS("Range Files (*.rng; *.env; *.rrng)|*.rng;*.env;*.rrng;*.RRNG;*.RNG;*.ENV|RNG File (*.rng)|*.rng;*.RNG|Environment File (*.env)|*.env;*.ENV|RRNG Files (*.rrng)|*.rrng;*.RRNG|All Files (*)|*");
+
+//Name of the DTD file for state loading
+const char *DTD_NAME="threeDepict-state.dtd";
+//Program name
+const char *PROGRAM_NAME = "3Depict";
+//Program version
+const char *PROGRAM_VERSION = "0.0.17";
+//Path to font for Default FTGL font
+const char *FONT_FILE= "FreeSans.ttf";
diff --git a/src/common/constants.h b/src/common/constants.h
index ed33513..56208fe 100644
--- a/src/common/constants.h
+++ b/src/common/constants.h
@@ -18,6 +18,8 @@
#ifndef COMMONCONSTANTS_H
#define COMMONCONSTANTS_H
+#include "translation.h"
+
//C-style Array size macro
#define THREEDEP_ARRAYSIZE(f) (sizeof (f) / sizeof(*f))
//C++1x availabilty (as far as we are concerned)
@@ -30,25 +32,6 @@
const unsigned int OPENMP_MIN_DATASIZE=1000;
-enum
-{
- PLOT_TRACE_LINES=0,
- PLOT_TRACE_BARS,
- PLOT_TRACE_STEPS,
- PLOT_TRACE_STEM,
- PLOT_TRACE_POINTS,
- PLOT_TRACE_ENDOFENUM
-};
-
-//Plot types
-enum
-{
- PLOT_MODE_1D,
- PLOT_MODE_2D,
- PLOT_MODE_ENUM_END
-};
-
-
//Plot error types
enum
{
@@ -73,6 +56,7 @@ enum
PROPERTY_TYPE_STRING,
PROPERTY_TYPE_POINT3D,
PROPERTY_TYPE_CHOICE,
+ PROPERTY_TYPE_FILE,
PROPERTY_TYPE_ENUM_END //Not a prop, just end of enum
};
@@ -97,4 +81,11 @@ struct PLOT_ERROR
unsigned int edgeMode;
};
+extern const char *RANGEFILE_WX_CONSTANT;
+
+extern const char *DTD_NAME;
+extern const char *PROGRAM_NAME;
+extern const char *PROGRAM_VERSION;
+extern const char *FONT_FILE;
+
#endif
diff --git a/src/common/stringFuncs.cpp b/src/common/stringFuncs.cpp
index b109b06..cd0ffdc 100644
--- a/src/common/stringFuncs.cpp
+++ b/src/common/stringFuncs.cpp
@@ -334,73 +334,6 @@ std::string choiceString(std::vector<std::pair<unsigned int, std::string> > comb
return s;
}
-bool parseColString(const std::string &str,
- unsigned char &r, unsigned char &g, unsigned char &b, unsigned char &a)
-{
- //Input string is in 2 char hex form, 3 or 4 colour, with # leading. RGB order
- //lowercase string.
- if(str.size() != 9 && str.size() != 7)
- return false;
-
- if(str[0] != '#')
- return false;
-
- string rS,gS,bS,aS;
- rS=str.substr(1,2);
- gS=str.substr(3,2);
- bS=str.substr(5,2);
-
- if(!isxdigit(rS[0]) || !isxdigit(rS[1]))
- return false;
- if(!isxdigit(gS[0]) || !isxdigit(gS[1]))
- return false;
- if(!isxdigit(bS[0]) || !isxdigit(bS[1]))
- return false;
-
- hexStrToUChar(str.substr(1,2),r);
- hexStrToUChar(str.substr(3,2),g);
- hexStrToUChar(str.substr(5,2),b);
- //3 colour must have a=255.
- if(str.size() == 7)
- a = 255;
- else
- {
- aS=str.substr(7,2);
- if(!isxdigit(aS[0]) || !isxdigit(aS[1]))
- return false;
- hexStrToUChar(str.substr(7,2),a);
- }
- return true;
-}
-
-void genColString(unsigned char r, unsigned char g,
- unsigned char b, unsigned char a, std::string &s)
-{
- s="#";
- string tmp;
- ucharToHexStr(r,tmp);
- s+=tmp;
- ucharToHexStr(g,tmp);
- s+=tmp;
- ucharToHexStr(b,tmp);
- s+=tmp;
- ucharToHexStr(a,tmp);
- s+=tmp;
-
-}
-
-void genColString(unsigned char r, unsigned char g,
- unsigned char b, std::string &s)
-{
- string tmp;
- s="#";
- ucharToHexStr(r,tmp);
- s+=tmp;
- ucharToHexStr(g,tmp);
- s+=tmp;
- ucharToHexStr(b,tmp);
- s+=tmp;
-}
//Strip "whitespace"
std::string stripWhite(const std::string &str)
@@ -457,6 +390,16 @@ std::string lowercase(std::string s)
return s;
}
+std::string uppercase(std::string s)
+{
+ for(unsigned int ui=0;ui<s.size();ui++)
+ {
+ if(isascii(s[ui]) && islower(s[ui]))
+ s[ui] = toupper(s[ui]);
+ }
+ return s;
+}
+
//Split strings around a delimiter
void splitStrsRef(const char *cpStr, const char delim,std::vector<string> &v )
{
diff --git a/src/common/stringFuncs.h b/src/common/stringFuncs.h
index 9d48c35..878a5df 100644
--- a/src/common/stringFuncs.h
+++ b/src/common/stringFuncs.h
@@ -34,6 +34,10 @@ std::string boolStrEnc(bool b);
// Whitespace is stripped from either end. If string cannot be understood, returns false
bool boolStrDec(const std::string &s,bool &result);
+void ucharToHexStr(unsigned char c, std::string &s);
+
+void hexStrToUChar(const std::string &s, unsigned char &c);
+//TODO : Eliminate this function.
//!Generate string that can be parsed by wxPropertyGrid for combo control
//String format is CHOICEID:id1|string 1,id2|string 2,id3|string 3,.....,idN|string_N
// where id1->idN are integers
@@ -61,22 +65,12 @@ std::string stripWhite(const std::string &str);
std::string stripChars(const std::string &Str, const char *chars);
//!Return a lowercase version for a given string
std::string lowercase(std::string s);
+//!Return a uppercase version for a given string
+std::string uppercase(std::string s);
//Drop empty entries from a string of vector
void stripZeroEntries(std::vector<std::string> &s);
-
-//Parse a colour string, such as #aabbccdd into its RGBA 8-bit components
-bool parseColString(const std::string &str,
- unsigned char &r, unsigned char &g, unsigned char &b, unsigned char &a);
-
-//Convert an RGBA 8-bit/channel quadruplet into its hexadecimal colour string
-void genColString(unsigned char r, unsigned char g,
- unsigned char b, unsigned char a, std::string &s);
-//Convert an RGB 8-bit/channel quadruplet into its hexadecimal colour string
-void genColString(unsigned char r, unsigned char g,
- unsigned char b, std::string &s);
-
//Check to see if a given string is a valid version number string,
// consisting of decmials and ints (eg 0.1.2.3.4)
bool isVersionNumberString(const std::string &s);
diff --git a/src/common/translation.h b/src/common/translation.h
index 1a7eea7..8593603 100644
--- a/src/common/translation.h
+++ b/src/common/translation.h
@@ -32,9 +32,4 @@
//!Gettext null-translation macro (mark for translation, but do nothing)
#define NTRANS(x) (x)
-//!Wx friendly gettext translation macro
-#define wxTRANS(x) (wxString(gettext(x),*wxConvCurrent))
-
-#define wxNTRANS(x) wxT(x)
-
#endif
diff --git a/src/gl/cameras.cpp b/src/gl/cameras.cpp
index aac6789..7d368d7 100644
--- a/src/gl/cameras.cpp
+++ b/src/gl/cameras.cpp
@@ -587,71 +587,70 @@ void CameraLookAt::move(float moveLRAngle, float moveUDAngle)
void CameraLookAt::getProperties(CameraProperties &p) const
{
- p.data.clear();
- p.types.clear();
- p.keys.clear();
-
- std::vector<std::pair<string,string> > s;
- std::vector<unsigned int> type,keys;
-
- if(lock)
- s.push_back(std::make_pair(TRANS("Lock"),"1"));
- else
- s.push_back(std::make_pair(TRANS("Lock"),"0"));
-
- type.push_back(PROPERTY_TYPE_BOOL);
- keys.push_back(CAMERA_KEY_LOOKAT_LOCK);
-
- string ptStr;
- stream_cast(ptStr,origin);
- s.push_back(std::make_pair(TRANS("Origin"), ptStr));
- type.push_back(PROPERTY_TYPE_POINT3D);
- keys.push_back(CAMERA_KEY_LOOKAT_ORIGIN);
-
- stream_cast(ptStr,target);
- s.push_back(std::make_pair(TRANS("Target"), ptStr));
- type.push_back(PROPERTY_TYPE_POINT3D);
- keys.push_back(CAMERA_KEY_LOOKAT_TARGET);
-
- stream_cast(ptStr,upDirection);
- s.push_back(std::make_pair(TRANS("Up Dir."), ptStr));
- type.push_back(PROPERTY_TYPE_POINT3D);
- keys.push_back(CAMERA_KEY_LOOKAT_UPDIRECTION);
-
+ p.clear();
+
+ CameraProperty cp;
+
+ p.addGroup();
+
+ cp.name=TRANS("Lock");
+ cp.data=boolStrEnc(lock);
+ cp.type=PROPERTY_TYPE_BOOL;
+ cp.key=CAMERA_KEY_LOOKAT_LOCK;
+ p.addEntry(cp);
+
+ //Add origin
+ cp.name=TRANS("Origin");
+ stream_cast(cp.data,origin);
+ cp.type=PROPERTY_TYPE_POINT3D;
+ cp.key=CAMERA_KEY_LOOKAT_ORIGIN;
+ p.addEntry(cp);
+
+ //Add camea target pt
+ stream_cast(cp.data,target);
+ cp.name=TRANS("Target");
+ cp.type=PROPERTY_TYPE_POINT3D;
+ cp.key=CAMERA_KEY_LOOKAT_TARGET;
+ p.addEntry(cp);
+
+ stream_cast(cp.data,upDirection);
+ cp.name=TRANS("Up Dir.");
+ cp.type=PROPERTY_TYPE_POINT3D;
+ cp.key=CAMERA_KEY_LOOKAT_UPDIRECTION;
+ p.addEntry(cp);
+
+ //add camera projection options
std::vector<std::pair<unsigned int,string> > choices;
string tmp;
-
-
tmp=TRANS("Perspective");
choices.push_back(make_pair((unsigned int)PROJECTION_MODE_PERSPECTIVE,tmp));
tmp=TRANS("Orthogonal");
choices.push_back(make_pair((unsigned int)PROJECTION_MODE_ORTHOGONAL,tmp));
- tmp= choiceString(choices,projectionMode);
- s.push_back(std::make_pair(TRANS("Projection"), tmp));
- type.push_back(PROPERTY_TYPE_CHOICE);
- keys.push_back(CAMERA_KEY_LOOKAT_PROJECTIONMODE);
+ cp.data=choiceString(choices,projectionMode);
+ cp.name=TRANS("Projection");
+ cp.type=PROPERTY_TYPE_CHOICE;
+ cp.key=CAMERA_KEY_LOOKAT_PROJECTIONMODE;
+ p.addEntry(cp);
switch(projectionMode)
{
case PROJECTION_MODE_PERSPECTIVE:
- stream_cast(tmp,fovAngle);
- s.push_back(std::make_pair(TRANS("Field of View (deg)"), tmp));
- type.push_back(PROPERTY_TYPE_REAL);
- keys.push_back(CAMERA_KEY_LOOKAT_FOV);
+ stream_cast(cp.data,fovAngle);
+ cp.name=TRANS("Field of View (deg)");
+ cp.type=PROPERTY_TYPE_REAL;
+ cp.key=CAMERA_KEY_LOOKAT_FOV;
break;
case PROJECTION_MODE_ORTHOGONAL:
- stream_cast(tmp,orthoScale);
- s.push_back(std::make_pair(TRANS("View size"), tmp));
- type.push_back(PROPERTY_TYPE_REAL);
- keys.push_back(CAMERA_KEY_LOOKAT_ORTHOSCALE);
+ stream_cast(cp.data,orthoScale);
+ cp.name=TRANS("View size");
+ cp.type=PROPERTY_TYPE_REAL;
+ cp.key=CAMERA_KEY_LOOKAT_ORTHOSCALE;
break;
-
+ default:
+ ASSERT(false);
}
-
- p.data.push_back(s);
- p.keys.push_back(keys);
- p.types.push_back(type);
+ p.addEntry(cp);
}
bool CameraLookAt::setProperty(unsigned int key, const string &value)
diff --git a/src/gl/cameras.h b/src/gl/cameras.h
index 1158fce..6dd25c8 100644
--- a/src/gl/cameras.h
+++ b/src/gl/cameras.h
@@ -56,19 +56,27 @@ enum
CAMERA_KEY_LOOKAT_ORTHOSCALE
};
+class CameraProperty
+{
+ public:
+ unsigned int type;
+ unsigned int key;
+ std::string data;
+ std::string name;
+};
+
class CameraProperties
{
public:
- //Filter property data, one per output, each is value then name
- std::vector<std::vector<std::pair< std::string, std::string > > > data;
- //Data types for each single element
- std::vector<std::vector<unsigned int> > types;
-
- //!Key numbers for filter. Must be unique per set
- std::vector<std::vector<unsigned int> > keys;
-
+ std::vector<std::vector<CameraProperty> > props;
+ void clear() { props.clear();};
+ void addGroup() {props.resize(props.size()+1);}
+ void addEntry(CameraProperty &p) { ASSERT(props.size()); props.back().push_back(p);}
};
+
+
+
//!An abstract base class for a camera
class Camera
{
diff --git a/src/gl/drawables.cpp b/src/gl/drawables.cpp
index b5bc147..543c98f 100644
--- a/src/gl/drawables.cpp
+++ b/src/gl/drawables.cpp
@@ -38,11 +38,13 @@ float DrawableObj::backgroundG;
float DrawableObj::backgroundB;
bool DrawableObj::useAlphaBlend;
-TexturePool *DrawableObj::texPool;
+TexturePool *DrawableObj::texPool=0;
unsigned int DrawableObj::winX;
unsigned int DrawableObj::winY;
+DrawTexturedQuad DrawPointLegendOverlay::dQuad;
+bool DrawPointLegendOverlay::quadSet=false;
//==
@@ -229,6 +231,36 @@ DrawableObj::DrawableObj() : active(true), haveChanged(true), canSelect(false),
DrawableObj::~DrawableObj()
{
}
+
+
+float DrawableObj::getHighContrastValue() const
+{
+ //Perform luminence check on background to try to create most appropriate
+ // colour
+ //-------
+ // TODO: I have this in a few places now, need to refactor into a single colour class
+
+ //weights
+ const float CHANNEL_LUM_WEIGHTS[3] = { 0.299f,0.587f,0.114f};
+ float totalBright=backgroundR*CHANNEL_LUM_WEIGHTS[0] +
+ backgroundG*CHANNEL_LUM_WEIGHTS[1] +
+ backgroundB*CHANNEL_LUM_WEIGHTS[2];
+
+ float contrastCol;
+ if(totalBright > 0.5f)
+ {
+ //"bright" scene, use black text
+ contrastCol=0.0f;
+ }
+ else
+ {
+ //"Dark" background, use white text
+ contrastCol=1.0f;
+ }
+
+ return contrastCol;
+
+}
void DrawableObj::explode(std::vector<DrawableObj *> &simpleObjects)
{
@@ -248,7 +280,7 @@ void DrawableObj::clearTexPool()
{
ASSERT(texPool);
delete texPool;
-
+ texPool=0;
}
Point3D DrawableObj::getCentroid() const
@@ -508,6 +540,12 @@ void DrawQuad::setVertices(const Point3D *v)
vertices[ui]=v[ui];
}
+void DrawQuad::setVertex(unsigned int v, const Point3D &p)
+{
+ ASSERT(v <4);
+ vertices[v] = p;
+}
+
Point3D DrawQuad::getOrigin() const
{
return Point3D::centroid(vertices,4);
@@ -537,16 +575,24 @@ void DrawQuad::recomputeParams(const vector<Point3D> &vecs,
}
}
-DrawTexturedQuad::DrawTexturedQuad() :textureData(0), textureId((unsigned int)-1)
+DrawTexturedQuad::DrawTexturedQuad() :textureData(0), textureId((unsigned int)-1), noColour(false)
{
}
-DrawTexturedQuad::~DrawTexturedQuad()
+DrawTexturedQuad::DrawTexturedQuad(const DrawTexturedQuad &oth)
{
- if(textureData)
- delete[] textureData;
+ ASSERT(false);
+}
- texPool->closeTexture(textureId);
+DrawTexturedQuad::~DrawTexturedQuad()
+{
+ //hack to work around static construct/destruct.
+ // normally we use the texture pool do to everything
+ if(texPool && textureId != -1)
+ {
+ texPool->closeTexture(textureId);
+ textureId=-1;
+ }
}
void DrawTexturedQuad::draw() const
@@ -554,14 +600,15 @@ void DrawTexturedQuad::draw() const
ASSERT(glIsTexture(textureId));
glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D,textureId);
glPushAttrib(GL_CULL_FACE);
glDisable(GL_CULL_FACE);
glBindTexture(GL_TEXTURE_2D,textureId);
- glColor4f(1.0f,1.0f,1.0f,1.0f);
+ if(!noColour)
+ glColor4f(1.0f,1.0f,1.0f,1.0f);
+
const float COORD_SEQ_X[]={ 0,0,1,1};
const float COORD_SEQ_Y[]={ 0,1,1,0};
glBegin(GL_QUADS);
@@ -601,23 +648,25 @@ void DrawTexturedQuad::resize(size_t numX, size_t numY,
}
-void DrawTexturedQuad::rebindTexture()
+void DrawTexturedQuad::rebindTexture(unsigned int mode)
{
ASSERT(texPool);
ASSERT(textureData);
if(textureId == (unsigned int)-1)
texPool->genTexID(textureId);
-
- //Construc the texture
+
+ ASSERT(!(mode == GL_RGB && channels !=3 ));
+ ASSERT(!(mode == GL_RGBA && channels !=4 ));
+
+ //Construct the texture
glBindTexture(GL_TEXTURE_2D,textureId);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
- ASSERT(channels == 3);
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,nX,nY,
- 0,GL_RGB,GL_UNSIGNED_BYTE,textureData);
+ glTexImage2D(GL_TEXTURE_2D,0,mode,nX,nY,
+ 0,mode,GL_UNSIGNED_BYTE,textureData);
@@ -626,7 +675,7 @@ void DrawTexturedQuad::rebindTexture()
void DrawTexturedQuad::setData(size_t x, size_t y, unsigned char *entry)
{
ASSERT(textureData);
- ASSERT(channels == 3);
+ ASSERT(x < nX && y < nY);
for(size_t ui=0;ui<channels;ui++)
textureData[(y*nX + x)*channels + ui] = entry[ui];
@@ -1232,7 +1281,6 @@ void DrawGLText::draw() const
axis.fz=rotateAxis[2];
-// cerr << "Gl rotate (1):" << rotateAxis << " , " << angle << endl;
glRotatef(angle*180.0f/M_PI,rotateAxis[0],rotateAxis[1],rotateAxis[2]);
quat_rot(&tmp,&axis,angle); //angle is in radiians
@@ -1250,7 +1298,6 @@ void DrawGLText::draw() const
rotateAxis = newUp.crossProd(Point3D(0,-1,0));
rotateAxis.normalise();
glRotatef(angle*180.0f/M_PI,rotateAxis[0],rotateAxis[1],rotateAxis[2]);
- //cerr << "Gl rotate (2):" << rotateAxis << " , " << angle << endl;
}
//Ensure that the text is not back-culled (i.e. if the
@@ -1640,28 +1687,31 @@ void DrawRectPrism::recomputeParams(const vector<Point3D> &vecs,
}
}
-DrawTexturedQuadOverlay::DrawTexturedQuadOverlay()
+DrawableOverlay::~DrawableOverlay()
{
}
-DrawTexturedQuadOverlay::~DrawTexturedQuadOverlay()
+DrawTexturedQuadOverlay::DrawTexturedQuadOverlay()
+: textureId(-1),textureOK(false)
{
- texPool->closeTexture(textureId);
}
-void DrawTexturedQuadOverlay::setSize(float s)
+DrawTexturedQuadOverlay::~DrawTexturedQuadOverlay()
{
- length=s;
+ texPool->closeTexture(textureId);
}
-
void DrawTexturedQuadOverlay::draw() const
{
if(!textureOK)
return;
+ ASSERT(height == width);
+
ASSERT(glIsTexture(textureId));
+ //TODO: Is this redundant? might be already handled
+ // by scene?
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -1679,13 +1729,13 @@ void DrawTexturedQuadOverlay::draw() const
glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);
- glVertex3f(position[0]-length/2.0,position[1]-length/2.0,0.0);
+ glVertex3f(position[0]-height/2.0,position[1]-height/2.0,0.0);
glTexCoord2f(0.0f,1.0f);
- glVertex3f(position[0]-length/2.0,position[1]+length/2.0,0.0);
+ glVertex3f(position[0]-height/2.0,position[1]+height/2.0,0.0);
glTexCoord2f(1.0f,1.0f);
- glVertex3f(position[0]+length/2.0,position[1]+length/2.0,0.0);
+ glVertex3f(position[0]+height/2.0,position[1]+height/2.0,0.0);
glTexCoord2f(1.0f,0.0f);
- glVertex3f(position[0]+length/2.0,position[1]-length/2.0,0.0);
+ glVertex3f(position[0]+height/2.0,position[1]-height/2.0,0.0);
glEnd();
glDisable(GL_TEXTURE_2D);
@@ -1707,11 +1757,6 @@ bool DrawTexturedQuadOverlay::setTexture(const char *textureFile)
return textureOK;
}
-void DrawTexturedQuadOverlay::getBoundingBox(BoundCube &b) const
-{
- b.setInvalid();
-}
-
DrawAnimatedOverlay::DrawAnimatedOverlay()
{
fadeIn=0.0f;
@@ -1738,12 +1783,6 @@ bool DrawAnimatedOverlay::setTexture(const vector<string> &texFiles,
return textureOK;
}
-void DrawAnimatedOverlay::setSize(float newLen)
-{
- length=newLen;
-}
-
-
void DrawAnimatedOverlay::draw() const
{
if(!textureOK)
@@ -1784,16 +1823,18 @@ void DrawAnimatedOverlay::draw() const
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MULT);
// Draw overlay quad
+ ASSERT(width == height); // width/height should be the same
glColor4f(1.0f,1.0f,1.0f,alphaVal);
+
glBegin(GL_QUADS);
glTexCoord3f(0.0f,0.0f,texCoordZ);
- glVertex3f(position[0]-length/2.0,position[1]-length/2.0,0.0);
+ glVertex3f(position[0]-width/2.0,position[1]-width/2.0,0.0);
glTexCoord3f(0.0f,1.0f,texCoordZ);
- glVertex3f(position[0]-length/2.0,position[1]+length/2.0,0.0);
+ glVertex3f(position[0]-width/2.0,position[1]+width/2.0,0.0);
glTexCoord3f(1.0f,1.0f,texCoordZ);
- glVertex3f(position[0]+length/2.0,position[1]+length/2.0,0.0);
+ glVertex3f(position[0]+width/2.0,position[1]+width/2.0,0.0);
glTexCoord3f(1.0f,0.0f,texCoordZ);
- glVertex3f(position[0]+length/2.0,position[1]-length/2.0,0.0);
+ glVertex3f(position[0]+width/2.0,position[1]-width/2.0,0.0);
glEnd();
glDisable(GL_TEXTURE_3D);
@@ -1806,10 +1847,7 @@ void DrawAnimatedOverlay::draw() const
glMatrixMode(GL_MODELVIEW);
}
-void DrawAnimatedOverlay::getBoundingBox(BoundCube &b) const
-{
- b.setInvalid();
-}
+
DrawColourBarOverlay::DrawColourBarOverlay()
{
@@ -1834,8 +1872,8 @@ DrawColourBarOverlay::DrawColourBarOverlay(const DrawColourBarOverlay &oth)
height=oth.height;
width=oth.width;
- tlX=oth.tlX;
- tlY=oth.tlY;
+ position[0]=oth.position[0];
+ position[1]=oth.position[1];
};
void DrawColourBarOverlay::draw() const
@@ -1851,52 +1889,30 @@ void DrawColourBarOverlay::draw() const
//Set the quad colour for bar element
glColor4f(rgb[rgb.size()-(ui+1)].v[0],
rgb[rgb.size()-(ui+1)].v[1],
- rgb[rgb.size()-(ui+1)].v[2],1.0);
+ rgb[rgb.size()-(ui+1)].v[2],a);
//draw this quad (bar element)
- glVertex3f(tlX,tlY+(float)ui*elemHeight,0);
- glVertex3f(tlX,tlY+(float)(ui+1)*elemHeight,0);
- glVertex3f(tlX+barWidth,tlY+(float)(ui+1)*elemHeight,0);
- glVertex3f(tlX+barWidth,tlY+(float)(ui)*elemHeight,0);
+ glVertex2f(position[0],position[1]+(float)ui*elemHeight);
+ glVertex2f(position[0],position[1]+(float)(ui+1)*elemHeight);
+ glVertex2f(position[0]+barWidth,position[1]+(float)(ui+1)*elemHeight);
+ glVertex2f(position[0]+barWidth,position[1]+(float)(ui)*elemHeight);
}
glEnd();
- //Perform luminence check on background to try to create most appropriate
- // colour
- //-------
- // TODO: I have this in a few places now, need to refactor into a single colour class
-
- //weights
- const float CHANNEL_LUM_WEIGHTS[3] = { 0.299f,0.587f,0.114f};
- float totalBright=backgroundR*CHANNEL_LUM_WEIGHTS[0] +
- backgroundG*CHANNEL_LUM_WEIGHTS[1] +
- backgroundB*CHANNEL_LUM_WEIGHTS[2];
-
- float textGrey;
- if(totalBright > 0.5f)
- {
- //"bright" scene, use black text
- textGrey=0.0f;
- }
- else
- {
- //"Dark" background, use white text
- textGrey=1.0f;
- }
-
//-------
+ float textGrey=getHighContrastValue();
//Draw ticks on colour bar
glBegin(GL_LINES);
- glColor4f(textGrey,textGrey,textGrey,1.0f);
+ glColor4f(textGrey,textGrey,textGrey,a);
//Top tick
- glVertex3f(tlX,tlY,0);
- glVertex3f(tlX+width,tlY,0);
+ glVertex2f(position[0],position[1]);
+ glVertex2f(position[0]+width,position[1]);
//Bottom tick
- glVertex3f(tlX,tlY+height,0);
- glVertex3f(tlX+width,tlY+height,0);
+ glVertex2f(position[0],position[1]+height);
+ glVertex2f(position[0]+width,position[1]+height);
glEnd();
@@ -1922,7 +1938,7 @@ void DrawColourBarOverlay::draw() const
font->FaceSize(3);
glDisable(GL_CULL_FACE);
glPushMatrix();
- glTranslatef(tlX+width,tlY,0);
+ glTranslatef(position[0]+width,position[1],0);
string s;
stream_cast(s,max);
//Note negative sign to flip from y-down screen (opengl) to text dir
@@ -1933,7 +1949,7 @@ void DrawColourBarOverlay::draw() const
glPopMatrix();
glPushMatrix();
- glTranslatef(tlX+width,tlY+height,0);
+ glTranslatef(position[0]+width,position[1]+height,0);
stream_cast(s,min);
//Note negative sign to flip from y-down screen (opengl) to text dir
//(y up)
@@ -1962,9 +1978,154 @@ void DrawColourBarOverlay::setColourVec(const vector<float> &r,
}
-void DrawColourBarOverlay::getBoundingBox(BoundCube &b) const
+DrawPointLegendOverlay::DrawPointLegendOverlay() : enabled(true)
{
- b.setInvalid();
+ a=1.0f;
+
+ std::string tmpStr =getDefaultFontFile();
+ font = new FTGLPolygonFont(tmpStr.c_str());
+
+ //check to see if we need to init the texture quad
+ if(!quadSet && texPool)
+ {
+
+ dQuad.setUseColouring(false);
+
+ //Create a ciruclar texture
+ const unsigned int N_CHANNELS=4;
+ unsigned int LEG_TEX_SIZE = 256;
+ unsigned char colourWhite[N_CHANNELS]= { 255,255,255,255 };
+ unsigned char colourBlack[N_CHANNELS]= { 0,0,0,0 };
+
+ //TODO: Convert to single channel texture, to save space?
+ // DrawQuad does not support single channel at this time
+ dQuad.resize(LEG_TEX_SIZE,LEG_TEX_SIZE,N_CHANNELS);
+ const float HALF_CIRCLE_R2 = 0.25;
+ #pragma omp parallel for
+ for(unsigned int nX=0;nX<LEG_TEX_SIZE;nX++)
+ {
+ float fx;
+ fx= (float) nX/(float)LEG_TEX_SIZE - 0.5;
+ for(unsigned int nY=0;nY<LEG_TEX_SIZE;nY++)
+ {
+ float fy;
+ fy = (float) nY/(float)LEG_TEX_SIZE -0.5;
+ if( fx*fx + fy*fy < HALF_CIRCLE_R2)
+ dQuad.setData(nX,nY,colourWhite);
+ else
+ dQuad.setData(nX,nY,colourBlack);
+ }
+
+ }
+
+ dQuad.rebindTexture(GL_RGBA);
+
+ quadSet=true;
+
+ }
+}
+
+DrawPointLegendOverlay::~DrawPointLegendOverlay()
+{
+}
+
+DrawableObj *DrawPointLegendOverlay::clone() const
+{
+ DrawPointLegendOverlay *dp = new DrawPointLegendOverlay(*this);
+
+ return dp;
+}
+
+DrawPointLegendOverlay::DrawPointLegendOverlay(const DrawPointLegendOverlay &oth)
+{
+ string f;
+ f=getDefaultFontFile();
+
+ font = new FTGLPolygonFont(f.c_str());
+ a=oth.a;
+ legendItems = oth.legendItems;
+ enabled = oth.enabled;
+
+ height=oth.height;
+ width=oth.width;
+
+ position[0]=oth.position[0];
+ position[1]=oth.position[1];
+ quadSet=oth.quadSet;
+}
+
+void DrawPointLegendOverlay::draw() const
+{
+
+ if(!enabled || legendItems.empty())
+ return;
+
+ ASSERT(winX >0 && winY > 0);
+ float curX = position[0];
+ float curY = position[1];
+
+ float delta = std::max(std::min(1.0f/legendItems.size(),0.02f),0.05f);
+ float size = delta*0.9f;
+ glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ float maxTextWidth=0;
+
+
+ font->FaceSize(1);
+ for(unsigned int ui=0; ui<legendItems.size();ui++)
+ {
+ for(;ui<legendItems.size();ui++)
+ {
+
+ //Draw textured quad (circle)
+ //--
+ dQuad.setVertex(0,Point3D(curX,curY,0));
+ dQuad.setVertex(1,Point3D(curX+size,curY,0));
+ dQuad.setVertex(2,Point3D(curX+size,curY+size,0));
+ dQuad.setVertex(3,Point3D(curX,curY+size,0));
+
+ const RGBFloat *f;
+ f = &legendItems[ui].second;
+ glColor3f(f->v[0],f->v[1],f->v[2]);
+ dQuad.draw();
+
+
+ //--
+
+ //Draw text, if possible
+ if( font && !font->Error())
+ {
+ float textGrey=getHighContrastValue();
+ glColor3f(textGrey,textGrey,textGrey);
+ float fminX,fminY,fminZ;
+ float fmaxX,fmaxY,fmaxZ;
+ font->BBox(legendItems[ui].first.c_str(),fminX,
+ fminY,fminZ,fmaxX,fmaxY,fmaxZ);
+ glPushMatrix();
+ glTranslatef(curX+1.5*size,curY+0.85*size,0.0f);
+ glScalef(size,-size,0);
+ font->Render(legendItems[ui].first.c_str());
+ glPopMatrix();
+ maxTextWidth=std::max(fmaxX-fminX,maxTextWidth);
+ }
+
+
+ curY+=delta;
+ }
+
+ curX+=maxTextWidth + size;
+ curY=position[1] + 0.5*delta;
+ }
+ glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+void DrawPointLegendOverlay::addItem(const std::string &s, float r, float g, float b)
+{
+ RGBFloat rgb;
+ rgb.v[0]=r;
+ rgb.v[1]= g;
+ rgb.v[2]= b;
+ legendItems.push_back(make_pair(s,rgb));
}
@@ -2132,7 +2293,6 @@ void DrawField3D::draw() const
drawBox(field->getMinBounds(),field->getMaxBounds(),
boxColourR, boxColourG,boxColourB,alphaUse);
}
- //Draw the projections
}
void DrawField3D::setAlpha(float newAlpha)
diff --git a/src/gl/drawables.h b/src/gl/drawables.h
index aad4671..9d0e1de 100644
--- a/src/gl/drawables.h
+++ b/src/gl/drawables.h
@@ -19,9 +19,6 @@
#ifndef DRAWABLES_H
#define DRAWABLES_H
-#include "textures.h"
-#include "cameras.h"
-#include "isoSurface.h"
//STL includes
@@ -37,6 +34,10 @@
#include <sys/time.h>
+#include "textures.h"
+#include "cameras.h"
+#include "isoSurface.h"
+
//TODO: Work out if there is any way of obtaining the maximum
//number of items that can be drawn in an opengl context
//For now Max it out at 10 million (~120MB of vertex data)
@@ -102,6 +103,7 @@ enum
DRAW_TYPE_FIELD3D,
DRAW_TYPE_ISOSURFACE,
DRAW_TYPE_AXIS,
+ DRAW_TYPE_LEGENDOVERLAY,
};
//TODO: It seems unnecessary to have multiple types for the bind
@@ -151,7 +153,10 @@ class DrawableObj
static bool useAlphaBlend;
+ //Size of the opengl window
static unsigned int winX,winY;
+
+ float getHighContrastValue() const;
public:
//!Can be selected from openGL viewport interactively?
bool canSelect;
@@ -462,6 +467,7 @@ class DrawQuad : public DrawableObj
class DrawTexturedQuad : public DrawQuad
{
+ private:
//TODO: Move this back
// into the texture pool
unsigned char *textureData;
@@ -473,9 +479,16 @@ class DrawTexturedQuad : public DrawQuad
// to opengl
unsigned int textureId;
+ //!FTGL font instance
+ FTFont *font;
+
+ //disallow resetting base colour to white
+ bool noColour;
+
public:
DrawTexturedQuad();
~DrawTexturedQuad();
+ DrawTexturedQuad(const DrawTexturedQuad &d);
//Resize the texture contents, destroying any existing contents
void resize(size_t nx, size_t nY, unsigned int nChannels);
@@ -484,81 +497,12 @@ class DrawTexturedQuad : public DrawQuad
//Set the specified pixel in the texture to this value
void setData(size_t x, size_t y, unsigned char *entry);
//Send the texture to the video card.
- void rebindTexture();
-};
-
-
-class DrawAnimatedOverlay : public DrawQuad
-{
- private:
- size_t nX,nY,nZ;
-
- //ID of the texture to use when drawing, -1 if not bound
- // to opengl
- unsigned int textureId;
-
- float position[2];
-
- timeval animStartTime;
-
- bool textureOK;
-
- //Time delta before repeating animation
- float repeatInterval;
+ void rebindTexture(unsigned int mode=GL_RGB);
- //Length to use for the quad to represent icon
- float length;
-
- //Time before showing the image
- float delayBeforeShow;
-
- //Time for fadein after show
- float fadeIn;
-
- public:
- DrawAnimatedOverlay();
- ~DrawAnimatedOverlay();
-
- virtual unsigned int getType() const {return DRAW_TYPE_ANIMATEDOVERLAY;}
-
- //!This is an overlay
- bool isOverlay() const {return true;};
-
-
- //!Set the texture position in XY (z is ignored)
- void setPos(float xp,float yp)
- {
- position[0]=xp;
- position[1]=yp;
- };
-
- void setSize(float size);
-
- //Set the time between repeats for the animation
- void setRepeatTime(float timeV) { repeatInterval=timeV;}
-
- //Set the time before the texture appears
- void setShowDelayTime(float showDelayTime)
- { ASSERT(showDelayTime >=0.0f); delayBeforeShow = showDelayTime;}
-
- //Set the time during which the alpha value will be ramped up.
- // activated after the delay time (ie time before 100% visible is fadeInTime +
- // delayTime.
- void setFadeInTime(float fadeInTime)
- { ASSERT(fadeInTime >=0.0f); fadeIn=fadeInTime;}
-
- //!Set the texture by name
- bool setTexture(const vector<string> &textureFiles, float timeRepeat=1.0f);
-
- void resetTime() ;
-
- //!Draw object
- void draw() const;
+ void setUseColouring(bool useColouring) {noColour= !useColouring;};
+};
- void getBoundingBox(BoundCube &b) const ;
- bool isOK() const { return textureOK; }
-};
//!A sphere drawing
class DrawSphere : public DrawableObj
@@ -909,21 +853,39 @@ struct RGBFloat
float v[3];
};
-class DrawColourBarOverlay : public DrawableObj
+//Abstract class as base for overlays
+class DrawableOverlay : public DrawableObj
+{
+ protected:
+ //alpha (transparancy) value
+ float a;
+ //!Height and width of overlay (total)
+ float height,width;
+ //Fractional coordinates for the top left of the overlay
+ float position[2];
+ public:
+ DrawableOverlay() {} ;
+ //Declared as pure virtual to force ABC
+ virtual ~DrawableOverlay() =0;
+ void setAlpha(float alpha) { a=alpha;};
+ void setSize(float widthN, float heightN) {height=heightN, width=widthN;}
+ void setSize(float size) {width=height=size;};
+ void setPosition(float newTLX,float newTLY) { position[0]=newTLX; position[1]=newTLY;}
+
+ void getBoundingBox(BoundCube &b) const {b.setInvalid();};
+ //!This is an overlay
+ bool isOverlay() const {return true;};
+};
+
+class DrawColourBarOverlay : public DrawableOverlay
{
private:
FTFont *font;
//!Colours for each element
vector<RGBFloat> rgb;
- //alpha (transparancy) value
- float a;
//!Minimum and maximum values for the colour bar (for ticks)
float min,max;
- //!Height and width of bar (total)
- float height,width;
- //!top left of bar
- float tlX,tlY;
public:
@@ -933,63 +895,114 @@ class DrawColourBarOverlay : public DrawableObj
virtual unsigned int getType() const {return DRAW_TYPE_COLOURBAR;}
-
-
- void getBoundingBox(BoundCube &b) const ;
- //!This is an overlay
- bool isOverlay() const {return true;};
void setColourVec(const vector<float> &r,
const vector<float> &g,
const vector<float> &b);
//!Draw object
void draw() const;
- void setAlpha(float alpha) { a=alpha;};
- void setSize(float widthN, float heightN) {height=heightN, width=widthN;}
- void setPosition(float newTLX,float newTLY) { tlX=newTLX; tlY=newTLY;}
void setMinMax(float minNew,float maxNew) { min=minNew;max=maxNew;};
};
//!A class to hande textures to draw
-class DrawTexturedQuadOverlay : public DrawableObj
+class DrawTexturedQuadOverlay : public DrawableOverlay
{
private:
unsigned int textureId;
- //Fractional coordinates for the
- float position[2];
- //Length of the rectangle to use for the icon
- float length;
-
bool textureOK;
+
public:
DrawTexturedQuadOverlay();
~DrawTexturedQuadOverlay();
-
- virtual unsigned int getType() const {return DRAW_TYPE_TEXTUREDOVERLAY;}
- //!This is an overlay
- bool isOverlay() const {return true;};
+ virtual unsigned int getType() const {return DRAW_TYPE_TEXTUREDOVERLAY;}
static void setWindowSize(unsigned int x, unsigned int y){winX=x;winY=y;};
+ //!Set the texture by name
+ bool setTexture(const char *textureFile);
+ //!Draw object
+ void draw() const;
+};
+
+
+//!Multi-frame texture - Animated overlay
+class DrawAnimatedOverlay : public DrawableOverlay
+{
+ private:
+ //ID of the texture to use when drawing, -1 if not bound
+ // to opengl
+ unsigned int textureId;
+
+ timeval animStartTime;
+
+ bool textureOK;
- //!Set the texture position in XY (z is ignored)
- void setPos(float xp,float yp){position[0]=xp; position[1]=yp;};
+ //Time delta before repeating animation
+ float repeatInterval;
+
+ //Time before showing the image
+ float delayBeforeShow;
- void setSize(float size);
+ //Time for fadein after show
+ float fadeIn;
+
+ public:
+ DrawAnimatedOverlay();
+ ~DrawAnimatedOverlay();
+
+ virtual unsigned int getType() const {return DRAW_TYPE_ANIMATEDOVERLAY;}
+
+ //Set the time between repeats for the animation
+ void setRepeatTime(float timeV) { repeatInterval=timeV;}
+
+ //Set the time before the texture appears
+ void setShowDelayTime(float showDelayTime)
+ { ASSERT(showDelayTime >=0.0f); delayBeforeShow = showDelayTime;}
+
+ //Set the time during which the alpha value will be ramped up.
+ // activated after the delay time (ie time before 100% visible is fadeInTime +
+ // delayTime.
+ void setFadeInTime(float fadeInTime)
+ { ASSERT(fadeInTime >=0.0f); fadeIn=fadeInTime;}
//!Set the texture by name
- bool setTexture(const char *textureFile);
+ bool setTexture(const vector<string> &textureFiles, float timeRepeat=1.0f);
+ void resetTime() ;
//!Draw object
void draw() const;
- void getBoundingBox(BoundCube &b) const ;
+ bool isOK() const { return textureOK; }
};
+class DrawPointLegendOverlay : public DrawableOverlay
+{
+ private:
+ static DrawTexturedQuad dQuad;
+ static bool quadSet;
+
+ FTFont *font;
+ //Items to draw n overlay, and colour to use to draw
+ vector<pair<string,RGBFloat> > legendItems;
+ bool enabled;
+ public:
+ DrawPointLegendOverlay();
+ ~DrawPointLegendOverlay();
+
+ DrawPointLegendOverlay(const DrawPointLegendOverlay &);
+
+ DrawableObj *clone() const;
+ virtual unsigned int getType() const {return DRAW_TYPE_LEGENDOVERLAY;}
+ void draw() const;
+
+ void clear();
+ void addItem(const string &s, float r, float g, float b);
+
+};
struct RGBThis
{
diff --git a/src/gl/glDebug.h b/src/gl/glDebug.h
index 5e464c6..e975a62 100644
--- a/src/gl/glDebug.h
+++ b/src/gl/glDebug.h
@@ -1,3 +1,21 @@
+/*
+ * glDebug.h - opengl debugging routines
+ * Copyright (C) 2014, D Haley
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#ifndef GLDEBUG_H
#define GLDEBUG_H
@@ -19,14 +37,23 @@
} \
std::cerr << "glErr Clean " << __FILE__ << ":" << __LINE__ << std::endl; \
}
+
+inline int glCurStackDepth(int stackDepthSelector)
+{
+ ASSERT(stackDepthSelector == GL_MODELVIEW_STACK_DEPTH ||
+ stackDepthSelector == GL_PROJECTION_STACK_DEPTH ||
+ stackDepthSelector == GL_TEXTURE_STACK_DEPTH );
+ int gldepthdebug;
+ glGetIntegerv (stackDepthSelector,&gldepthdebug);
+ return gldepthdebug;
+}
#define glStackDepths() { \
- int gldepthdebug[3];glGetIntegerv (GL_MODELVIEW_STACK_DEPTH, gldepthdebug);\
- glGetIntegerv (GL_PROJECTION_STACK_DEPTH, gldepthdebug+1);\
- glGetIntegerv (GL_TEXTURE_STACK_DEPTH, gldepthdebug+2);\
- std::cerr << "OpenGL Stack Depths: ModelV:" << gldepthdebug[0] << " Pr: "\
- << gldepthdebug[1] << " Tex:" << gldepthdebug[2] << std::endl;}
+ std::cerr << "OpenGL Stack Depths: ModelV:" \
+ << glCurStackDepth(GL_MODELVIEW_STACK_DEPTH) << " Pr: "\
+ << glCurStackDepth(GL_PROJECTION_STACK_DEPTH) << " Tex:" \
+ << glCurStackDepth(GL_TEXTURE_STACK_DEPTH) << std::endl;}
inline void glPrintMatrix(int matrixMode )
diff --git a/src/gl/scene.cpp b/src/gl/scene.cpp
index 361394e..e240e7e 100644
--- a/src/gl/scene.cpp
+++ b/src/gl/scene.cpp
@@ -177,6 +177,23 @@ unsigned int Scene::initDraw()
return passes;
}
+bool Scene::hasOverlays() const
+{
+ for(unsigned int ui=0;ui<objects.size();ui++)
+ {
+ if(objects[ui]->isOverlay())
+ return true;
+ }
+
+ for(unsigned int ui=0;ui<refObjects.size();ui++)
+ {
+ if(refObjects[ui]->isOverlay())
+ return true;
+ }
+
+ return false;
+}
+
void Scene::updateCam(const Camera *camToUse, bool useIdent=true) const
{
Point3D lightNormal;
@@ -189,7 +206,7 @@ void Scene::updateCam(const Camera *camToUse, bool useIdent=true) const
void Scene::updateProgressOverlay()
{
- progressAnimTex.setPos(0.9*winX,0.9*winY);
+ progressAnimTex.setPosition(0.9*winX,0.9*winY);
progressAnimTex.setSize(0.1*winX);
//Cycle every this many seconds
progressAnimTex.setRepeatTime(6.0f);
@@ -294,15 +311,20 @@ void Scene::draw(bool noUpdateCam)
glPopMatrix();
-
- //Now draw 2D overlays
- if(!lockInteract&& lastHovered != (unsigned int)(-1) )
- drawHoverOverlay();
- drawOverlays();
+
+ //Only draw 2D components if we
+ // are using normal camera
+ if(!noUpdateCam)
+ {
+ //Now draw 2D overlays
+ if(!lockInteract&& lastHovered != (unsigned int)(-1) )
+ drawHoverOverlay();
- //Draw progress, if needed
- drawProgressAnim();
+ drawOverlays(noUpdateCam);
+ //Draw progress, if needed
+ drawProgressAnim();
+ }
}
void Scene::drawObjectVector(const vector<const DrawableObj*> &drawObjs, bool &lightsOn, bool drawOpaques) const
@@ -351,50 +373,84 @@ void Scene::drawObjectVector(const vector<const DrawableObj*> &drawObjs, bool &l
}
+
+
+#ifdef DEBUG
+ //Ensure that the gl matrix sizes are correctly restored
+ int curDepth[3];
+ int oldMatMode;
+ curDepth[0] = glCurStackDepth(GL_MODELVIEW_STACK_DEPTH);
+ curDepth[1] = glCurStackDepth(GL_PROJECTION_STACK_DEPTH);
+ curDepth[2] = glCurStackDepth(GL_TEXTURE_STACK_DEPTH);
+ glGetIntegerv( GL_MATRIX_MODE, &oldMatMode);
+#endif
drawObjs[ui]->draw();
+
+#ifdef DEBUG
+ ASSERT(curDepth[0] == glCurStackDepth(GL_MODELVIEW_STACK_DEPTH));
+ ASSERT(curDepth[1] == glCurStackDepth(GL_PROJECTION_STACK_DEPTH));
+ ASSERT(curDepth[2] == glCurStackDepth(GL_TEXTURE_STACK_DEPTH));
+ ASSERT(curDepth[0] && curDepth[1] && curDepth[2]);
+ int newMatMode;
+ glGetIntegerv( GL_MATRIX_MODE, &newMatMode);
+ ASSERT(oldMatMode == newMatMode);
+#endif
}
}
-void Scene::drawOverlays() const
+void Scene::drawOverlays(bool noUpdateCam) const
{
//Custom projection matrix
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
glDisable(GL_LIGHTING);
+ glDisable(GL_DEPTH_TEST);
//Set the opengl camera state back into modelview mode
- gluOrtho2D(0, outWinAspect, 1.0, 0);
-
-
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
+ if(!noUpdateCam)
+ {
+ //clear projection and o modle matricies
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ gluOrtho2D(0, outWinAspect, 1.0, 0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ }
- glDisable(GL_DEPTH_TEST);
for(unsigned int ui=0;ui<refObjects.size();ui++)
{
if(refObjects[ui]->isOverlay())
+ {
refObjects[ui]->draw();
+ }
}
for(unsigned int ui=0;ui<objects.size();ui++)
{
if(objects[ui]->isOverlay())
+ {
objects[ui]->draw();
+ }
}
- glEnable(GL_DEPTH_TEST);
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
+ if(!noUpdateCam)
+ {
+ //op our modelview matrix
+ glPopMatrix();
+
+ //ppop projection atrix
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ //return to modelview mode
+ glMatrixMode(GL_MODELVIEW);
+ }
- glMatrixMode(GL_MODELVIEW);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
}
void Scene::drawHoverOverlay()
@@ -504,14 +560,14 @@ void Scene::drawHoverOverlay()
if(foundKeyTex)
{
//Make room for keyTex
- binderIcons.setPos((0.93+SPACING)*winX,ICON_SIZE*winY*(1+(float)iconNum));
- keyIcons.setPos(0.93*winX,ICON_SIZE*winY*(1+(float)iconNum));
- mouseIcons.setPos((0.93-SPACING)*winX,ICON_SIZE*winY*(1+(float)iconNum));
+ binderIcons.setPosition((0.93+SPACING)*winX,ICON_SIZE*winY*(1+(float)iconNum));
+ keyIcons.setPosition(0.93*winX,ICON_SIZE*winY*(1+(float)iconNum));
+ mouseIcons.setPosition((0.93-SPACING)*winX,ICON_SIZE*winY*(1+(float)iconNum));
}
else
{
- binderIcons.setPos(0.95*winX,ICON_SIZE*winY*(1+(float)iconNum));
- mouseIcons.setPos(0.90*winX,ICON_SIZE*winY*(1+(float)iconNum));
+ binderIcons.setPosition(0.95*winX,ICON_SIZE*winY*(1+(float)iconNum));
+ mouseIcons.setPosition(0.90*winX,ICON_SIZE*winY*(1+(float)iconNum));
}
binderIcons.draw();
diff --git a/src/gl/scene.h b/src/gl/scene.h
index 2b1783e..2057216 100644
--- a/src/gl/scene.h
+++ b/src/gl/scene.h
@@ -123,8 +123,6 @@ class Scene
///!Draw the hover overlays
void drawHoverOverlay();
- //!Draw the normal overlays
- void drawOverlays() const;
void drawProgressAnim() const;
@@ -153,6 +151,8 @@ class Scene
//!Draw the objects in the active window. May adjust cameras and compute bounding as needed.
void draw(bool noUpdateCam=false);
+ //!Draw the normal overlays
+ void drawOverlays(bool noCamUpdate=false) const;
//!clear rendering vectors
void clearAll();
@@ -162,7 +162,9 @@ class Scene
void clearRefObjs();
//!Clear object bindings vector
void clearBindings();
-
+
+ //!Do we have overlay items?
+ bool hasOverlays() const;
//!Obtain the scene's light coordinates in camera relative space
// requires an array os size 4 (xyzw)
diff --git a/src/gl/textures.h b/src/gl/textures.h
index 7e7162a..b89b0db 100644
--- a/src/gl/textures.h
+++ b/src/gl/textures.h
@@ -22,6 +22,15 @@
#include "common/basics.h"
+#ifdef CreateDialog
+#undef CreateDialog
+#endif
+
+#ifdef Yield
+#undef Yield
+#endif
+
+
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
diff --git a/src/gl/tr.cpp b/src/gl/tr.cpp
index 79a1c95..f3a8880 100644
--- a/src/gl/tr.cpp
+++ b/src/gl/tr.cpp
@@ -1,7 +1,24 @@
//Tile Rendering Library,
// http://www.mesa3d.org/brianp/TR.html
-// GNU GPL 2+
+/*
+ TR Tile rendering library
+ Copyright (C) 1997 Brian Paul
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
/* $Id: tr.c,v 1.9 1998/01/29 16:56:54 brianp Exp $ */
@@ -43,11 +60,11 @@
* Copyright (C) Brian Paul
*/
+#include "common/assertion.h"
-#include <assert.h>
#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
+#include <cstdlib>
+
#ifdef WIN32
#include <windows.h>
#endif
@@ -112,8 +129,8 @@ static void Setup(TRcontext *tr)
tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
tr->CurrentTile = 0;
- assert(tr->Columns >= 0);
- assert(tr->Rows >= 0);
+ ASSERT(tr->Columns >= 0);
+ ASSERT(tr->Rows >= 0);
}
@@ -145,11 +162,11 @@ void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
if (!tr)
return;
- assert(border >= 0);
- assert(width >= 1);
- assert(height >= 1);
- assert(width >= 2*border);
- assert(height >= 2*border);
+ ASSERT(border >= 0);
+ ASSERT(width >= 1);
+ ASSERT(height >= 1);
+ ASSERT(width >= 2*border);
+ ASSERT(height >= 2*border);
tr->TileBorder = border;
tr->TileWidth = width;
@@ -324,8 +341,8 @@ void trBeginTile(TRcontext *tr)
/* This should never happen */
abort();
}
- assert(tr->CurrentRow < tr->Rows);
- assert(tr->CurrentColumn < tr->Columns);
+ ASSERT(tr->CurrentRow < tr->Rows);
+ ASSERT(tr->CurrentColumn < tr->Columns);
border = tr->TileBorder;
@@ -377,7 +394,7 @@ int trEndTile(TRcontext *tr)
if (!tr)
return 0;
- assert(tr->CurrentTile>=0);
+ ASSERT(tr->CurrentTile>=0);
/* be sure OpenGL rendering is finished */
glFlush();
@@ -484,10 +501,6 @@ void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
-#ifdef DEBUG
- if (glGetError())
- printf("GL error!\n");
-#endif
}
}
diff --git a/src/gl/tr.h b/src/gl/tr.h
index ef5f303..835b41b 100644
--- a/src/gl/tr.h
+++ b/src/gl/tr.h
@@ -1,6 +1,25 @@
/* $Id: tr.h,v 1.5 1997/07/21 17:34:07 brianp Exp $ */
/*
+ TR Tile rendering library
+ Copyright (C) 1997 Brian Paul
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
* $Log: tr.h,v $
* Revision 1.5 1997/07/21 17:34:07 brianp
* added tile borders, incremented version to 1.1
@@ -20,6 +39,8 @@
*/
+
+
/*
* Tiled Rendering library
* Version 1.1
diff --git a/src/gui/dialogs/ExportPos.cpp b/src/gui/dialogs/ExportPos.cpp
index 6592f26..dc21e1f 100644
--- a/src/gui/dialogs/ExportPos.cpp
+++ b/src/gui/dialogs/ExportPos.cpp
@@ -72,17 +72,17 @@ ExportPosDialog::ExportPosDialog(wxWindow* parent, int id, const wxString& title
haveRefreshed=false;
exportVisible=true;
// begin wxGlade: ExportPosDialog::ExportPosDialog
- lblExport = new wxStaticText(this, wxID_ANY, wxTRANS("Export:"));
- radioVisible = new wxRadioButton(this,ID_RADIO_VISIBLE , wxTRANS("Visible"));
- radioSelection = new wxRadioButton(this,ID_RADIO_SELECTION , wxTRANS("Selected Data"));
+ lblExport = new wxStaticText(this, wxID_ANY, TRANS("Export:"));
+ radioVisible = new wxRadioButton(this,ID_RADIO_VISIBLE , TRANS("Visible"));
+ radioSelection = new wxRadioButton(this,ID_RADIO_SELECTION , TRANS("Selected Data"));
treeData = new wxTreeCtrl(this, ID_TREE_FILTERS, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_NO_LINES|wxTR_HIDE_ROOT|wxTR_DEFAULT_STYLE|wxSUNKEN_BORDER);
- lblAvailableData = new wxStaticText(this, wxID_ANY, wxTRANS("Available Data"));
+ lblAvailableData = new wxStaticText(this, wxID_ANY, TRANS("Available Data"));
listAvailable = new wxListCtrl(this, ID_LIST_AVAILABLE, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER|wxLC_VRULES);
btnAddData = new wxButton(this, ID_BTN_ADDDATA, wxT(">"));
btnAddNode = new wxButton(this,ID_BTN_ADDNODE, wxT(">>"));
btnAddAll = new wxButton(this, ID_BTN_ADDALL, wxT(">>>"));
panel_2 = new wxPanel(this, wxID_ANY);
- label_4 = new wxStaticText(this, wxID_ANY, wxTRANS("Selection"));
+ label_4 = new wxStaticText(this, wxID_ANY, TRANS("Selection"));
listSelected = new wxListCtrl(this, ID_LIST_SELECTED, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
btnSave = new wxButton(this, wxID_SAVE, wxEmptyString);
btnCancel = new wxButton(this, wxID_CANCEL, wxEmptyString);
@@ -107,11 +107,11 @@ ExportPosDialog::ExportPosDialog(wxWindow* parent, int id, const wxString& title
//--
//Add columns to report listviews
- listSelected->InsertColumn(0,wxTRANS("Index"));
- listSelected->InsertColumn(1,wxTRANS("Count"));
+ listSelected->InsertColumn(0,TRANS("Index"));
+ listSelected->InsertColumn(1,TRANS("Count"));
- listAvailable->InsertColumn(0,wxTRANS("Index"));
- listAvailable->InsertColumn(1,wxTRANS("Count"));
+ listAvailable->InsertColumn(0,TRANS("Index"));
+ listAvailable->InsertColumn(1,TRANS("Count"));
}
ExportPosDialog::~ExportPosDialog()
@@ -217,13 +217,13 @@ void ExportPosDialog::OnTreeFiltersSelChanged(wxTreeEvent &event)
(unsigned char)(ionData->g*255),(unsigned char)(ionData->b*255));
//Add the item using the index as a str
stream_cast(label,ui);
- listAvailable->InsertItem(ui,wxStr(label));
+ listAvailable->InsertItem(ui,(label));
size_t basicCount;
basicCount=ionData->getNumBasicObjects();
stream_cast(label,basicCount);
- listAvailable->SetItem(ui,1,wxStr(label));
+ listAvailable->SetItem(ui,1,(label));
listAvailable->SetItemBackgroundColour(ui,c);
@@ -359,13 +359,13 @@ void ExportPosDialog::updateSelectedList()
(unsigned char)(ionData->b*255));
//Add the item using the index as a str
stream_cast(label,idx);
- listSelected->InsertItem(idx,wxStr(label));
+ listSelected->InsertItem(idx,(label));
size_t basicCount;
basicCount=ionData->getNumBasicObjects();
stream_cast(label,basicCount);
- listSelected->SetItem(idx,1,wxStr(label));
+ listSelected->SetItem(idx,1,(label));
listSelected->SetItemBackgroundColour(idx,c);
@@ -454,14 +454,14 @@ void ExportPosDialog::getExportVec(std::vector<const FilterStreamData * > &v) co
void ExportPosDialog::set_properties()
{
// begin wxGlade: ExportPosDialog::set_properties
- SetTitle(wxTRANS("Export Pos Data"));
+ SetTitle(TRANS("Export Pos Data"));
// end wxGlade
- treeData->SetToolTip(wxTRANS("Tree of filters, select leaves to show ion data."));
+ treeData->SetToolTip(TRANS("Tree of filters, select leaves to show ion data."));
- btnAddAll->SetToolTip(wxTRANS("Add all data from all filters"));
- btnAddNode->SetToolTip(wxTRANS("Add all data from currently selected filter"));
- btnAddData->SetToolTip(wxTRANS("Add selected data from currently selected filter"));
+ btnAddAll->SetToolTip(TRANS("Add all data from all filters"));
+ btnAddNode->SetToolTip(TRANS("Add all data from currently selected filter"));
+ btnAddData->SetToolTip(TRANS("Add selected data from currently selected filter"));
radioVisible->SetValue(TRUE);
}
diff --git a/src/gui/dialogs/ExportRngDialog.cpp b/src/gui/dialogs/ExportRngDialog.cpp
index 423583b..800389a 100644
--- a/src/gui/dialogs/ExportRngDialog.cpp
+++ b/src/gui/dialogs/ExportRngDialog.cpp
@@ -37,9 +37,9 @@ ExportRngDialog::ExportRngDialog(wxWindow* parent, int id, const wxString& title
wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
{
// begin wxGlade: ExportRngDialog::ExportRngDialog
- lblRanges = new wxStaticText(this, wxID_ANY, wxTRANS("Range Sources"));
+ lblRanges = new wxStaticText(this, wxID_ANY, TRANS("Range Sources"));
listRanges = new wxListCtrl(this, ID_LIST_ACTIVATE, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
- label_3 = new wxStaticText(this, wxID_ANY, wxTRANS("Details"));
+ label_3 = new wxStaticText(this, wxID_ANY, TRANS("Details"));
gridDetails = new wxGrid(this, wxID_ANY);
btnOK = new wxButton(this, wxID_SAVE, wxEmptyString);
btnCancel = new wxButton(this, wxID_CANCEL, wxEmptyString);
@@ -50,9 +50,9 @@ ExportRngDialog::ExportRngDialog(wxWindow* parent, int id, const wxString& title
// end wxGlade
//Add columns to report listviews
- listRanges->InsertColumn(0,wxTRANS("Source Filter"));
- listRanges->InsertColumn(1,wxTRANS("Ions"));
- listRanges->InsertColumn(2,wxTRANS("Ranges"));
+ listRanges->InsertColumn(0,TRANS("Source Filter"));
+ listRanges->InsertColumn(1,TRANS("Ions"));
+ listRanges->InsertColumn(2,TRANS("Ranges"));
}
@@ -85,17 +85,17 @@ void ExportRngDialog::updateGrid(unsigned int index)
gridDetails->DeleteRows(0,gridDetails->GetNumberRows());
gridDetails->AppendCols(3);
- gridDetails->SetColLabelValue(0,wxTRANS("Param"));
- gridDetails->SetColLabelValue(1,wxTRANS("Value"));
- gridDetails->SetColLabelValue(2,wxTRANS("Value2"));
+ gridDetails->SetColLabelValue(0,TRANS("Param"));
+ gridDetails->SetColLabelValue(1,TRANS("Value"));
+ gridDetails->SetColLabelValue(2,TRANS("Value2"));
unsigned int nRows;
nRows=rangeData->getRange().getNumIons()+rangeData->getRange().getNumRanges() + 4;
gridDetails->AppendRows(nRows);
- gridDetails->SetCellValue(0,0,wxTRANS("Ion Name"));
- gridDetails->SetCellValue(0,1,wxTRANS("Num Ranges"));
+ gridDetails->SetCellValue(0,0,TRANS("Ion Name"));
+ gridDetails->SetCellValue(0,1,TRANS("Num Ranges"));
unsigned int row=1;
std::string tmpStr;
@@ -106,16 +106,16 @@ void ExportRngDialog::updateGrid(unsigned int index)
{
//Use format
// ION NAME | NUMBER OF RANGES
- gridDetails->SetCellValue(row,0,wxStr(rangeData->getRange().getName(ui)));
+ gridDetails->SetCellValue(row,0,(rangeData->getRange().getName(ui)));
stream_cast(tmpStr,rangeData->getRange().getNumRanges(ui));
- gridDetails->SetCellValue(row,1,wxStr(tmpStr));
+ gridDetails->SetCellValue(row,1,(tmpStr));
row++;
}
row++;
- gridDetails->SetCellValue(row,0,wxTRANS("Ion"));
- gridDetails->SetCellValue(row,1,wxTRANS("Range Start"));
- gridDetails->SetCellValue(row,2,wxTRANS("Range end"));
+ gridDetails->SetCellValue(row,0,TRANS("Ion"));
+ gridDetails->SetCellValue(row,1,TRANS("Range Start"));
+ gridDetails->SetCellValue(row,2,TRANS("Range end"));
row++;
maxNum=rangeData->getRange().getNumRanges();
@@ -127,13 +127,13 @@ void ExportRngDialog::updateGrid(unsigned int index)
rngPair=rangeData->getRange().getRange(ui);
ionID=rangeData->getRange().getIonID(ui);
gridDetails->SetCellValue(row,0,
- wxStr(rangeData->getRange().getName(ionID)));
+ (rangeData->getRange().getName(ionID)));
stream_cast(tmpStr,rngPair.first);
- gridDetails->SetCellValue(row,1,wxStr(tmpStr));
+ gridDetails->SetCellValue(row,1,(tmpStr));
stream_cast(tmpStr,rngPair.second);
- gridDetails->SetCellValue(row,2,wxStr(tmpStr));
+ gridDetails->SetCellValue(row,2,(tmpStr));
row++;
}
@@ -148,8 +148,8 @@ void ExportRngDialog::OnSave(wxCommandEvent &event)
EndModal(wxID_CANCEL);
//create a file chooser for later.
- wxFileDialog *wxF = new wxFileDialog(this,wxTRANS("Save pos..."), wxT(""),
- wxT(""),wxTRANS("ORNL format RNG (*.rng)|*.rng|All Files (*)|*"),wxFD_SAVE);
+ wxFileDialog *wxF = new wxFileDialog(this,TRANS("Save pos..."), wxT(""),
+ wxT(""),TRANS("ORNL format RNG (*.rng)|*.rng|All Files (*)|*"),wxFD_SAVE);
//Show, then check for user cancelling export dialog
if(wxF->ShowModal() == wxID_CANCEL)
{
@@ -166,8 +166,8 @@ void ExportRngDialog::OnSave(wxCommandEvent &event)
std::string errString;
errString=TRANS("Unable to save. Check output destination can be written to.");
- wxMessageDialog *wxD =new wxMessageDialog(this,wxStr(errString)
- ,wxTRANS("Save error"),wxOK|wxICON_ERROR);
+ wxMessageDialog *wxD =new wxMessageDialog(this,(errString)
+ ,TRANS("Save error"),wxOK|wxICON_ERROR);
wxD->ShowModal();
wxD->Destroy();
return;
@@ -217,15 +217,15 @@ void ExportRngDialog::updateRangeList()
rangeData=(RangeFileFilter *)rngFilters[ui];
std::string tmpStr;
long itemIndex;
- itemIndex=listRanges->InsertItem(0, wxStr(rangeData->getUserString()));
+ itemIndex=listRanges->InsertItem(0, (rangeData->getUserString()));
unsigned int nIons,nRngs;
nIons = rangeData->getRange().getNumIons();
nRngs = rangeData->getRange().getNumIons();
stream_cast(tmpStr,nIons);
- listRanges->SetItem(itemIndex, 1, wxStr(tmpStr));
+ listRanges->SetItem(itemIndex, 1, (tmpStr));
stream_cast(tmpStr,nRngs);
- listRanges->SetItem(itemIndex, 2, wxStr(tmpStr));
+ listRanges->SetItem(itemIndex, 2, (tmpStr));
}
}
@@ -233,14 +233,14 @@ void ExportRngDialog::updateRangeList()
void ExportRngDialog::set_properties()
{
// begin wxGlade: ExportRngDialog::set_properties
- SetTitle(wxTRANS("Export Range"));
+ SetTitle(TRANS("Export Range"));
gridDetails->CreateGrid(0, 0);
gridDetails->SetRowLabelSize(0);
gridDetails->SetColLabelSize(0);
- listRanges->SetToolTip(wxTRANS("List of rangefiles in filter tree"));
+ listRanges->SetToolTip(TRANS("List of rangefiles in filter tree"));
gridDetails->EnableEditing(false);
- gridDetails->SetToolTip(wxTRANS("Detailed view of selected range"));
+ gridDetails->SetToolTip(TRANS("Detailed view of selected range"));
// end wxGlade
}
diff --git a/src/gui/dialogs/StashDialog.cpp b/src/gui/dialogs/StashDialog.cpp
index accfc58..23b5987 100644
--- a/src/gui/dialogs/StashDialog.cpp
+++ b/src/gui/dialogs/StashDialog.cpp
@@ -20,6 +20,7 @@
#include "wx/wxcommon.h"
#include "wx/wxcomponents.h"
+#include "wx/propertyGridUpdater.h"
#include "common/translation.h"
#include "./backend/viscontrol.h"
@@ -42,19 +43,23 @@ StashDialog::StashDialog(wxWindow* parent, int id, const wxString& title, const
wxDialog(parent, id, title, pos, size, style)
{
// begin wxGlade: StashDialog::StashDialog
- label_5 = new wxStaticText(this, wxID_ANY, wxTRANS("Stashes"));
+ label_5 = new wxStaticText(this, wxID_ANY, TRANS("Stashes"));
listStashes = new wxListCtrl(this, ID_LIST_STASH, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
btnRemove = new wxButton(this, wxID_REMOVE, wxEmptyString);
- label_6 = new wxStaticText(this, wxID_ANY, wxTRANS("Stashed Tree"));
+ label_6 = new wxStaticText(this, wxID_ANY, TRANS("Stashed Tree"));
treeFilters = new wxTreeCtrl(this, ID_TREE_FILTERS, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_NO_LINES|wxTR_DEFAULT_STYLE|wxSUNKEN_BORDER|wxTR_HIDE_ROOT);
- label_7 = new wxStaticText(this, wxID_ANY, wxTRANS("Properties"));
- gridProperties = new wxCustomPropGrid(this, ID_GRID_FILTER);
+ label_7 = new wxStaticText(this, wxID_ANY, TRANS("Properties"));
+ gridProperties = new wxPropertyGrid(this, ID_GRID_FILTER);
btnOK = new wxButton(this, wxID_OK, wxEmptyString);
+
+ //Due to a bug in wx, empty reports throw an assertion
+ // 'unknown list item format", when there are no columns
+ listStashes->InsertColumn(0,TRANS("Stash Name"));
+ listStashes->InsertColumn(1,TRANS("Filter Count"));
set_properties();
do_layout();
// end wxGlade
- gridProperties->CreateGrid(0, 2);
}
@@ -71,7 +76,7 @@ BEGIN_EVENT_TABLE(StashDialog, wxDialog)
EVT_BUTTON(wxID_REMOVE, StashDialog::OnBtnRemove)
EVT_LIST_ITEM_SELECTED(ID_LIST_STASH, StashDialog::OnListSelected)
EVT_TREE_SEL_CHANGED(ID_TREE_FILTERS, StashDialog::OnTreeSelChange)
- EVT_GRID_CMD_EDITOR_SHOWN(ID_GRID_FILTER,StashDialog::OnGridEditor)
+ EVT_PG_CHANGING(ID_GRID_FILTER,StashDialog::OnGridEditor)
// end wxGlade
END_EVENT_TABLE();
@@ -83,18 +88,21 @@ void StashDialog::setVisController(VisController *s)
void StashDialog::set_properties()
{
// begin wxGlade: StashDialog::set_properties
- SetTitle(wxTRANS("Stashed Trees"));
+ SetTitle(TRANS("Stashed Trees"));
SetSize(wxSize(600, 430));
- btnRemove->SetToolTip(wxTRANS("Erase stashed item"));
- treeFilters->SetToolTip(wxTRANS("Filter view for current stash"));
- gridProperties->SetToolTip(wxTRANS("Settings for selected filter in current stash"));
- listStashes->SetToolTip(wxTRANS("Available stashes"));
+ btnRemove->SetToolTip(TRANS("Erase stashed item"));
+ treeFilters->SetToolTip(TRANS("Filter view for current stash"));
+ gridProperties->SetToolTip(TRANS("Settings for selected filter in current stash"));
+ listStashes->SetToolTip(TRANS("Available stashes"));
// end wxGlade
}
-void StashDialog::OnGridEditor(wxGridEvent &evt)
+void StashDialog::OnGridEditor(wxPropertyGridEvent &evt)
{
+ //Silence error mesages
+ evt.SetValidationFailureBehavior(0);
+
evt.Veto();
}
@@ -146,12 +154,11 @@ void StashDialog::updateList()
visControl->getStashes(stashes);
//Clear the existing list
- listStashes->ClearAll();
+ listStashes->Freeze();
+ listStashes->DeleteAllItems();
//Fill it with "stash" entries
//Add columns to report listviews
- listStashes->InsertColumn(0,wxTRANS("Stash Name"),3);
- listStashes->InsertColumn(1,wxTRANS("Filter Count"),1);
for (unsigned int ui=0; ui<stashes.size(); ui++)
{
string strTmp;
@@ -159,24 +166,24 @@ void StashDialog::updateList()
long itemIdx;
//First item is the stash name
- itemIdx = listStashes->InsertItem(ui,wxStr(stashes[ui].first));
+ itemIdx = listStashes->InsertItem(ui,(stashes[ui].first));
//Second column is num filters
visControl->getStashTree(stashes[ui].second,t);
stream_cast(strTmp,t.size());
- listStashes->SetItem(ui,1,wxStr(strTmp));
+ listStashes->SetItem(itemIdx,1,(strTmp));
//Set the stash ID as the list data item
//this is the key to the stash val
listStashes->SetItemData(itemIdx,stashes[ui].second);
}
-
+ listStashes->Thaw();
}
void StashDialog::updateGrid()
{
- gridProperties->clear();
+ gridProperties->Clear();
if(!treeFilters->GetCount())
return;
//Get the selection from the current tree
@@ -214,31 +221,9 @@ void StashDialog::updateGrid()
}
ASSERT(targetFilter);
-
- FilterPropGroup p;
- targetFilter->getProperties(p);
- gridProperties->clearKeys();
- gridProperties->setNumGroups(p.numGroups());
- //Create the keys for the property grid to do its thing
- for(unsigned int ui=0;ui<p.numGroups();ui++)
- {
- vector<FilterProperty> propGrouping;
- p.getGroup(ui,propGrouping);
+ updateFilterPropertyGrid(gridProperties,targetFilter,"");
- for(size_t uj=0;uj<propGrouping.size();uj++)
- {
- gridProperties->addKey(propGrouping[uj].name,ui,
- propGrouping[uj].key,
- propGrouping[uj].type,
- propGrouping[uj].data,
- propGrouping[uj].helpText);
- }
- }
-
- //Let the property grid layout what it needs to
- gridProperties->propertyLayout();
-
}
bool StashDialog::getStashIdFromList(unsigned int &stashId)
@@ -326,7 +311,7 @@ void StashDialog::updateTree()
//This will use the user label or the type string.
tid=treeFilters->AppendItem(treeIDs.top(),
- wxStr((*filtIt)->getUserString()));
+ ((*filtIt)->getUserString()));
treeFilters->SetItemData(tid,new wxTreeUint(pos));
pos++;
diff --git a/src/gui/dialogs/StashDialog.h b/src/gui/dialogs/StashDialog.h
index 8be7b5c..fda4183 100644
--- a/src/gui/dialogs/StashDialog.h
+++ b/src/gui/dialogs/StashDialog.h
@@ -23,6 +23,7 @@
#include <wx/wx.h>
#include <wx/treectrl.h>
#include <wx/grid.h>
+#include <wx/propgrid/propgrid.h>
// end wxGlade
@@ -67,7 +68,7 @@ protected:
wxStaticText* label_6;
wxTreeCtrl* treeFilters;
wxStaticText* label_7;
- wxCustomPropGrid* gridProperties;
+ wxPropertyGrid* gridProperties;
wxButton* btnOK;
// end wxGlade
@@ -77,7 +78,7 @@ public:
virtual void OnListKeyDown(wxListEvent &event); // wxGlade: <event_handler>
virtual void OnListSelected(wxListEvent &event); // wxGlade: <event_handler>
virtual void OnTreeSelChange(wxTreeEvent &event); // wxGlade: <event_handler>
- virtual void OnGridEditor(wxGridEvent &event);
+ virtual void OnGridEditor(wxPropertyGridEvent &event);
virtual void OnBtnRemove(wxCommandEvent &event);
void ready();
diff --git a/src/gui/dialogs/animateFilterDialog.cpp b/src/gui/dialogs/animateFilterDialog.cpp
index 3b95109..c98b803 100644
--- a/src/gui/dialogs/animateFilterDialog.cpp
+++ b/src/gui/dialogs/animateFilterDialog.cpp
@@ -19,6 +19,7 @@
#include "animateFilterDialog.h"
#include "resolutionDialog.h"
+#include "wx/propertyGridUpdater.h"
#include "./animateSubDialogs/realKeyFrameDialog.h"
@@ -148,31 +149,31 @@ ExportAnimationDialog::ExportAnimationDialog(wxWindow* parent, int id, const wxS
splitPaneFilter = new wxSplitterWindow(filterViewPane, ID_SPLIT_FILTERVIEW, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_BORDER);
filterRightPane = new wxPanel(splitPaneFilter, wxID_ANY);
filterLeftPane = new wxPanel(splitPaneFilter, wxID_ANY);
- keyFramesSizer_staticbox = new wxStaticBox(filterRightPane, -1, wxTRANS("Key frames"));
- outputDataSizer_staticbox = new wxStaticBox(frameViewPane, -1, wxTRANS("Output Data"));
- filterPropertySizer_staticbox = new wxStaticBox(filterLeftPane, -1, wxTRANS("Filters and properties"));
+ keyFramesSizer_staticbox = new wxStaticBox(filterRightPane, -1, TRANS("Key frames"));
+ outputDataSizer_staticbox = new wxStaticBox(frameViewPane, -1, TRANS("Output Data"));
+ filterPropertySizer_staticbox = new wxStaticBox(filterLeftPane, -1, TRANS("Filters and properties"));
filterTreeCtrl =new wxTreeCtrl(filterLeftPane,ID_FILTER_TREE_CTRL , wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_NO_LINES|wxTR_HIDE_ROOT|wxTR_DEFAULT_STYLE|wxSUNKEN_BORDER|wxTR_EDIT_LABELS);
- propertyGrid = new wxCustomPropGrid(filterLeftPane, ID_PROPERTY_GRID);
+ propertyGrid = new wxPropertyGrid(filterLeftPane, ID_PROPERTY_GRID);
animationGrid = new wxGrid(filterRightPane, ID_ANIMATION_GRID_CTRL);
keyFrameRemoveButton = new wxButton(filterRightPane, wxID_REMOVE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
- labelWorkDir = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Dir : "));
+ labelWorkDir = new wxStaticText(frameViewPane, wxID_ANY, TRANS("Dir : "));
textWorkDir = new wxTextCtrl(frameViewPane, ID_TEXTBOX_WORKDIR, wxEmptyString);
buttonWorkDir = new wxButton(frameViewPane, wxID_OPEN, wxEmptyString);
- checkOutOnlyChanged = new wxCheckBox(frameViewPane, ID_CHECK_ONLYDATACHANGE, wxTRANS("Output only when refresh required"));
+ checkOutOnlyChanged = new wxCheckBox(frameViewPane, ID_CHECK_ONLYDATACHANGE, TRANS("Output only when refresh required"));
outputDataSepLine = new wxStaticLine(frameViewPane, wxID_ANY);
- labelDataType = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Data Types:"));
- checkImageOutput = new wxCheckBox(frameViewPane, ID_CHECK_IMAGE_OUT, wxTRANS("3D Images"));
- lblImageName = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("File Suffix: "));
+ labelDataType = new wxStaticText(frameViewPane, wxID_ANY, TRANS("Data Types:"));
+ checkImageOutput = new wxCheckBox(frameViewPane, ID_CHECK_IMAGE_OUT, TRANS("3D Images"));
+ lblImageName = new wxStaticText(frameViewPane, wxID_ANY, TRANS("File Suffix: "));
textImageName = new wxTextCtrl(frameViewPane, ID_TEXTBOX_IMAGEPREFIX, wxEmptyString);
- labelImageSize = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Size : "));
+ labelImageSize = new wxStaticText(frameViewPane, wxID_ANY, TRANS("Size : "));
textImageSize = new wxTextCtrl(frameViewPane, ID_TEXTBOX_IMAGESIZE, wxEmptyString, wxDefaultPosition,wxDefaultSize, wxTE_READONLY );
- buttonImageSize = new wxButton(frameViewPane, ID_BUTTON_IMAGE_RES, wxTRANS("..."));
- checkPoints = new wxCheckBox(frameViewPane, ID_CHECK_POINT_OUT, wxTRANS("Point data"));
- checkPlotData = new wxCheckBox(frameViewPane, ID_CHECK_PLOT_OUT, wxTRANS("Plots"));
- checkVoxelData = new wxCheckBox(frameViewPane, ID_CHECK_VOXEL_OUT, wxTRANS("Voxel data"));
- checkRangeData = new wxCheckBox(frameViewPane, ID_CHECK_RANGE_OUT, wxTRANS("Range files"));
- labelRangeFormat = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Format"));
+ buttonImageSize = new wxButton(frameViewPane, ID_BUTTON_IMAGE_RES, TRANS("..."));
+ checkPoints = new wxCheckBox(frameViewPane, ID_CHECK_POINT_OUT, TRANS("Point data"));
+ checkPlotData = new wxCheckBox(frameViewPane, ID_CHECK_PLOT_OUT, TRANS("Plots"));
+ checkVoxelData = new wxCheckBox(frameViewPane, ID_CHECK_VOXEL_OUT, TRANS("Voxel data"));
+ checkRangeData = new wxCheckBox(frameViewPane, ID_CHECK_RANGE_OUT, TRANS("Range files"));
+ labelRangeFormat = new wxStaticText(frameViewPane, wxID_ANY, TRANS("Format"));
//Workaround for wx bug http://trac.wxwidgets.org/ticket/4398
wxSortedArrayString rangeNames;
@@ -183,12 +184,12 @@ ExportAnimationDialog::ExportAnimationDialog(wxWindow* parent, int id, const wxS
//construct translation->comboRange_choices offset.
rangeMap[TRANS(str)] = ui;
//Add to filter name wxArray
- wxString wxStrTrans = wxTRANS(str);
+ wxString wxStrTrans = TRANS(str);
rangeNames.Add(wxStrTrans);
}
comboRangeFormat = new wxChoice(frameViewPane, ID_COMBO_RANGE_TYPE, wxDefaultPosition, wxDefaultSize, rangeNames);
static_line_1 = new wxStaticLine(frameViewPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
- labelFrame = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Frame"));
+ labelFrame = new wxStaticText(frameViewPane, wxID_ANY, TRANS("Frame"));
frameSlider = new wxSlider(frameViewPane, ID_FRAME_SLIDER, 0, 0, 1);
textFrame = new wxTextCtrl(frameViewPane, ID_FRAME_TEXTBOX, wxEmptyString);
framePropGrid = new wxGrid(frameViewPane, ID_FILTER_PROPERTY_VALUE_GRID);
@@ -201,16 +202,13 @@ ExportAnimationDialog::ExportAnimationDialog(wxWindow* parent, int id, const wxS
// end wxGlade
-#if wxCHECK_VERSION(2,9,0)
//Manually tuned splitter parameters
splitPaneFilter->SetMinimumPaneSize(220);
int w, h;
GetClientSize(&w,&h);
float sashFrac=0.4;
-
splitPaneFilter->SetSashPosition((int)(sashFrac*w));
-#endif
programmaticEvent=true;
@@ -243,8 +241,9 @@ ExportAnimationDialog::~ExportAnimationDialog()
BEGIN_EVENT_TABLE(ExportAnimationDialog, wxDialog)
// begin wxGlade: ExportAnimationDialog::event_table
EVT_TREE_SEL_CHANGED(ID_FILTER_TREE_CTRL, ExportAnimationDialog::OnFilterTreeCtrlSelChanged)
- EVT_GRID_CMD_EDITOR_SHOWN(ID_PROPERTY_GRID, ExportAnimationDialog::OnFilterGridCellEditorShow)
- EVT_GRID_CMD_EDITOR_SHOWN(ID_ANIMATION_GRID_CTRL, ExportAnimationDialog::OnFrameGridCellEditorShow)
+ EVT_PG_SELECTED(ID_PROPERTY_GRID, ExportAnimationDialog::OnFilterGridCellSelected)
+ EVT_PG_CHANGING(ID_PROPERTY_GRID, ExportAnimationDialog::OnFilterGridCellChanging)
+ EVT_TREE_SEL_CHANGED(ID_FILTER_TREE_CTRL, ExportAnimationDialog::OnFilterTreeCtrlSelChanged)
EVT_GRID_CMD_EDITOR_SHOWN(ID_FILTER_TREE_CTRL, ExportAnimationDialog::OnAnimateGridCellEditorShow)
EVT_SPLITTER_UNSPLIT(ID_SPLIT_FILTERVIEW, ExportAnimationDialog::OnFilterViewUnsplit)
EVT_BUTTON(wxID_REMOVE, ExportAnimationDialog::OnButtonKeyFrameRemove)
@@ -273,7 +272,7 @@ void ExportAnimationDialog::setDefImSize(unsigned int w, unsigned int h)
string sFirst,sSecond;
stream_cast(sFirst,imageWidth);
stream_cast(sSecond,imageHeight);
- textImageSize->SetValue(wxStr(string(sFirst+string("x")+sSecond)));
+ textImageSize->SetValue((string(sFirst+string("x")+sSecond)));
imageSizeOK=true;
}
@@ -397,7 +396,6 @@ void ExportAnimationDialog::prepare()
upWxTreeCtrl(*filterTree,filterTreeCtrl,filterMap,
dummyVec,NULL);
- update();
}
void ExportAnimationDialog::updateFilterViewGrid()
@@ -426,17 +424,17 @@ void ExportAnimationDialog::updateFilterViewGrid()
filtProp=filtPropGroup.getPropValue(frameProps.getPropertyKey());
animationGrid->SetCellValue(ui,CELL_FILTERNAME,
- wxStr(filterPtr->getUserString()));
+ (filterPtr->getUserString()));
animationGrid->SetCellValue(ui,CELL_PROPERTYNAME,
- wxStr(filtProp.name));
+ (filtProp.name));
animationGrid->SetCellValue(ui,CELL_KEYINTERPMODE,
- wxCStr(INTERP_NAME[frameProps.getInterpMode()]));
+ (INTERP_NAME[frameProps.getInterpMode()]));
string str;
stream_cast(str,frameProps.getMinFrame());
- animationGrid->SetCellValue(ui,CELL_STARTFRAME, wxStr(str));
+ animationGrid->SetCellValue(ui,CELL_STARTFRAME, (str));
stream_cast(str,frameProps.getMaxFrame());
- animationGrid->SetCellValue(ui,CELL_ENDFRAME, wxStr(str));
+ animationGrid->SetCellValue(ui,CELL_ENDFRAME, (str));
}
//Check for conflicting rows in the animation dialog,
@@ -505,11 +503,11 @@ void ExportAnimationDialog::updateFrameViewGrid()
//Modify the grid properties with the appropriate data
framePropGrid->SetCellValue(ui,FRAME_CELL_FILTERNAME,
- wxStr(filterName));
+ (filterName));
framePropGrid->SetCellValue(ui,FRAME_CELL_PROPNAME,
- wxStr(propertyName));
+ (propertyName));
framePropGrid->SetCellValue(ui,FRAME_CELL_VALUE,
- wxStr(animatedValue));
+ (animatedValue));
}
}
@@ -531,7 +529,7 @@ void ExportAnimationDialog::updateFrameViewSlider()
stream_cast(textMax,propertyAnimator.getMaxFrame());
textCurrent= (textCurrent + std::string("/") + textMax);
- textFrame->SetValue( wxStr(textCurrent));
+ textFrame->SetValue( (textCurrent));
programmaticEvent=false;
@@ -594,7 +592,7 @@ void ExportAnimationDialog::OnFrameViewSlider(wxScrollEvent &event)
stream_cast(tmp,frameSlider->GetMax());
frameText+=tmp;
- textFrame->SetValue( wxStr(frameText));
+ textFrame->SetValue( (frameText));
currentFrame=sliderVal;
updateFrameViewGrid();
@@ -625,34 +623,39 @@ void ExportAnimationDialog::OnFilterTreeCtrlSelChanged(wxTreeEvent &event)
{
wxTreeItemData *parentData=filterTreeCtrl->GetItemData(id);
updateFilterPropertyGrid(propertyGrid,
- filterMap[((wxTreeUint *)parentData)->value]);
+ filterMap[((wxTreeUint *)parentData)->value],"");
}
event.Skip();
}
-
-void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
+void ExportAnimationDialog::OnFilterGridCellChanging(wxPropertyGridEvent &event)
{
+ event.SetValidationFailureBehavior(0);
event.Veto();
- wxTreeItemId id=filterTreeCtrl->GetSelection();;
+}
- if(id ==filterTreeCtrl->GetRootItem() || !id.IsOk())
- return;
+void ExportAnimationDialog::OnFilterGridCellSelected(wxPropertyGridEvent &event)
+{
+ event.Veto();
+ wxTreeItemId tId=filterTreeCtrl->GetSelection();;
- unsigned int key;
- key=propertyGrid->getKeyFromRow(event.GetRow());
+ if(tId ==filterTreeCtrl->GetRootItem() || !tId.IsOk())
+ return;
//Get the filter ID value
size_t filterId;
- wxTreeItemId tId = filterTreeCtrl->GetSelection();
- if(!tId.IsOk())
- return;
-
wxTreeItemData *tData=filterTreeCtrl->GetItemData(tId);
filterId = ((wxTreeUint *)tData)->value;
+ //grab tyhe key from the property grid
+ size_t key;
+ std::string keyStr;
+ keyStr=event.GetProperty()->GetName();
+ stream_cast(key,keyStr);
+
+
const Filter *f;
f=filterMap.at(filterId);
@@ -671,7 +674,7 @@ void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
{
case PROPERTY_TYPE_BOOL:
{
- wxTextEntryDialog *teD = new wxTextEntryDialog(this,wxTRANS("transition frame"),wxTRANS("Frame count"),
+ wxTextEntryDialog *teD = new wxTextEntryDialog(this,TRANS("transition frame"),TRANS("Frame count"),
wxT("0"),(long int)wxOK|wxCANCEL);
std::string s;
@@ -743,7 +746,7 @@ void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
case PROPERTY_TYPE_COLOUR:
{
ColourKeyFrameDialog *colDlg = new ColourKeyFrameDialog(this,
- wxID_ANY,wxTRANS("Key frame : Colour")) ;
+ wxID_ANY,TRANS("Key frame : Colour")) ;
if( colDlg->ShowModal() != wxID_OK)
{
colDlg->Destroy();
@@ -796,8 +799,8 @@ void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
{
sd->Destroy();
wxMessageDialog *wxD =new wxMessageDialog(this,
- wxTRANS("File existed, but was unable to read or interpret file contents."),
- wxTRANS("String load failed"),wxICON_ERROR|wxOK);
+ TRANS("File existed, but was unable to read or interpret file contents."),
+ TRANS("String load failed"),wxICON_ERROR|wxOK);
wxD->ShowModal();
wxD->Destroy();
@@ -818,7 +821,7 @@ void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
case PROPERTY_TYPE_REAL:
{
RealKeyFrameDialog<float> *r = new RealKeyFrameDialog<float>(this,
- wxID_ANY,wxTRANS("Keyframe : decimal"));
+ wxID_ANY,TRANS("Keyframe : decimal"));
if(!getRealKeyFrame(frameProp,filterProp,r))
return;
frameProp.setInterpMode(r->getTransitionMode());
@@ -827,7 +830,7 @@ void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
case PROPERTY_TYPE_INTEGER:
{
RealKeyFrameDialog<int> *r = new RealKeyFrameDialog<int>(this,
- wxID_ANY,wxTRANS("Keyframe : integer"));
+ wxID_ANY,TRANS("Keyframe : integer"));
if(!getRealKeyFrame(frameProp,filterProp,r))
return;
frameProp.setInterpMode(r->getTransitionMode());
@@ -836,7 +839,7 @@ void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
case PROPERTY_TYPE_POINT3D:
{
RealKeyFrameDialog<Point3D> *r = new RealKeyFrameDialog<Point3D>(this,
- wxID_ANY,wxTRANS("Keyframe : 3D Point"));
+ wxID_ANY,TRANS("Keyframe : 3D Point"));
if(!getRealKeyFrame(frameProp,filterProp,r))
return;
//Animator needs special Linear ramping code, so select that
@@ -961,7 +964,7 @@ void ExportAnimationDialog::OnOutputDirText(wxCommandEvent &event)
void ExportAnimationDialog::OnButtonWorkDir(wxCommandEvent &event)
{
//Pop up a directory dialog, to choose the base path for the new folder
- wxDirDialog *wxD = new wxDirDialog(this, wxTRANS("Select or create new folder"),
+ wxDirDialog *wxD = new wxDirDialog(this, TRANS("Select or create new folder"),
wxFileSelectorDefaultWildcardStr, wxFD_SAVE);
unsigned int res;
@@ -1043,7 +1046,7 @@ void ExportAnimationDialog::OnBtnResolution(wxCommandEvent &event)
string s;
s=sWidth+"x" + sHeight;
- textImageSize->SetValue(wxStr(s));
+ textImageSize->SetValue((s));
r->Destroy();
}
@@ -1141,39 +1144,36 @@ void ExportAnimationDialog::getPathMapping(vector<pair<string,size_t> > &mapping
void ExportAnimationDialog::set_properties()
{
// begin wxGlade: ExportAnimationDialog::set_properties
- SetTitle(wxTRANS("Export Animation"));
- filterTreeCtrl->SetToolTip(wxTRANS("Select filter"));
- propertyGrid->CreateGrid(0, 2);
- propertyGrid->SetColLabelValue(0, wxTRANS("Property"));
- propertyGrid->SetColLabelValue(1, wxTRANS("Value"));
- propertyGrid->SetToolTip(wxTRANS("Select property"));
+ SetTitle(TRANS("Export Animation"));
+ filterTreeCtrl->SetToolTip(TRANS("Select filter"));
+ propertyGrid->SetToolTip(TRANS("Select property"));
animationGrid->CreateGrid(0, 5);
- animationGrid->SetColLabelValue(0, wxTRANS("Filter"));
- animationGrid->SetColLabelValue(1, wxTRANS("Property"));
- animationGrid->SetColLabelValue(2, wxTRANS("Mode"));
- animationGrid->SetColLabelValue(3, wxTRANS("Start Frame"));
- animationGrid->SetColLabelValue(4, wxTRANS("End Frame"));
- animationGrid->SetToolTip(wxTRANS("Keyframe table"));
- keyFrameRemoveButton->SetToolTip(wxTRANS("Remove the selected keyframe from the table"));
- textWorkDir->SetToolTip(wxTRANS("Enter where the animation frames will be exported to"));
- buttonWorkDir->SetToolTip(wxTRANS("Browse to directory where the animation frames will be exported to"));
+ animationGrid->SetColLabelValue(0, TRANS("Filter"));
+ animationGrid->SetColLabelValue(1, TRANS("Property"));
+ animationGrid->SetColLabelValue(2, TRANS("Mode"));
+ animationGrid->SetColLabelValue(3, TRANS("Start Frame"));
+ animationGrid->SetColLabelValue(4, TRANS("End Frame"));
+ animationGrid->SetToolTip(TRANS("Keyframe table"));
+ keyFrameRemoveButton->SetToolTip(TRANS("Remove the selected keyframe from the table"));
+ textWorkDir->SetToolTip(TRANS("Enter where the animation frames will be exported to"));
+ buttonWorkDir->SetToolTip(TRANS("Browse to directory where the animation frames will be exported to"));
checkImageOutput->SetValue(1);
- textImageName->SetToolTip(wxTRANS("Title for files, result will be saved as #-name.png, where # is image number."));
- textImageSize->SetToolTip(wxTRANS("Target resolution (image size)"));
+ textImageName->SetToolTip(TRANS("Title for files, result will be saved as #-name.png, where # is image number."));
+ textImageSize->SetToolTip(TRANS("Target resolution (image size)"));
comboRangeFormat->SetSelection(-1);
- frameSlider->SetToolTip(wxTRANS("Select frame for property display"));
- textFrame->SetToolTip(wxTRANS("Enter frame number to change frame (eg 1/20)"));
- checkPoints->SetToolTip(wxTRANS("Save point data (POS files) in output folder?"));
- checkPlotData->SetToolTip(wxTRANS("Save plots (as text files) in output folder?"));
- checkVoxelData->SetToolTip(wxTRANS("Save voxel data (raw files) in output folder?"));
- checkRangeData->SetToolTip(wxTRANS("Save range files in output folder?"));
+ frameSlider->SetToolTip(TRANS("Select frame for property display"));
+ textFrame->SetToolTip(TRANS("Enter frame number to change frame (eg 1/20)"));
+ checkPoints->SetToolTip(TRANS("Save point data (POS files) in output folder?"));
+ checkPlotData->SetToolTip(TRANS("Save plots (as text files) in output folder?"));
+ checkVoxelData->SetToolTip(TRANS("Save voxel data (raw files) in output folder?"));
+ checkRangeData->SetToolTip(TRANS("Save range files in output folder?"));
framePropGrid->CreateGrid(0, 3);
- framePropGrid->SetColLabelValue(0, wxTRANS("Filter"));
- framePropGrid->SetColLabelValue(1, wxTRANS("Property"));
- framePropGrid->SetColLabelValue(2, wxTRANS("Value"));
- framePropGrid->SetToolTip(wxTRANS("Animation parameters for current frame"));
- cancelButton->SetToolTip(wxTRANS("Abort animation"));
- okButton->SetToolTip(wxTRANS("Run Animation"));
+ framePropGrid->SetColLabelValue(0, TRANS("Filter"));
+ framePropGrid->SetColLabelValue(1, TRANS("Property"));
+ framePropGrid->SetColLabelValue(2, TRANS("Value"));
+ framePropGrid->SetToolTip(TRANS("Animation parameters for current frame"));
+ cancelButton->SetToolTip(TRANS("Abort animation"));
+ okButton->SetToolTip(TRANS("Run Animation"));
// end wxGlade
}
@@ -1244,8 +1244,8 @@ void ExportAnimationDialog::do_layout()
propGridSizer->Add(framePropGrid, 1, wxEXPAND, 0);
frameViewSizer->Add(propGridSizer, 2, wxALL|wxEXPAND, 3);
frameViewPane->SetSizer(frameViewSizer);
- viewNotebook->AddPage(filterViewPane, wxTRANS("Filter view"));
- viewNotebook->AddPage(frameViewPane, wxTRANS("Frame view"));
+ viewNotebook->AddPage(filterViewPane, TRANS("Filter view"));
+ viewNotebook->AddPage(frameViewPane, TRANS("Frame view"));
animateSizer->Add(viewNotebook, 1, wxEXPAND, 0);
globalButtonSizer->Add(20, 1, 1, wxEXPAND, 0);
globalButtonSizer->Add(cancelButton, 0, wxALL|wxALIGN_BOTTOM, 3);
diff --git a/src/gui/dialogs/animateFilterDialog.h b/src/gui/dialogs/animateFilterDialog.h
index 49fa856..1f4cdac 100644
--- a/src/gui/dialogs/animateFilterDialog.h
+++ b/src/gui/dialogs/animateFilterDialog.h
@@ -181,7 +181,7 @@ protected:
wxStaticBox* keyFramesSizer_staticbox;
wxStaticBox* filterPropertySizer_staticbox;
wxTreeCtrl* filterTreeCtrl;
- wxCustomPropGrid* propertyGrid;
+ wxPropertyGrid* propertyGrid;
wxPanel* filterLeftPane;
wxGrid* animationGrid;
wxButton* keyFrameRemoveButton;
@@ -221,7 +221,8 @@ protected:
public:
virtual void OnFilterTreeCtrlSelChanged(wxTreeEvent &event); // wxGlade: <event_handler>
- virtual void OnFilterGridCellEditorShow(wxGridEvent &event); // wxGlade: <event_handler>
+ virtual void OnFilterGridCellChanging(wxPropertyGridEvent &event); // wxGlade: <event_handler>
+ virtual void OnFilterGridCellSelected(wxPropertyGridEvent &event); // wxGlade: <event_handler>
virtual void OnAnimateGridCellEditorShow(wxGridEvent &event); // wxGlade: <event_handler>
virtual void OnFrameGridCellEditorShow(wxGridEvent &event); // wxGlade: <event_handler>
virtual void OnButtonKeyFrameRemove(wxCommandEvent &event); // wxGlade: <event_handler>
diff --git a/src/gui/dialogs/animateSubDialogs/choiceKeyFrameDialog.cpp b/src/gui/dialogs/animateSubDialogs/choiceKeyFrameDialog.cpp
index 147f1f9..2f16b25 100644
--- a/src/gui/dialogs/animateSubDialogs/choiceKeyFrameDialog.cpp
+++ b/src/gui/dialogs/animateSubDialogs/choiceKeyFrameDialog.cpp
@@ -82,7 +82,7 @@ void ChoiceKeyFrameDialog::buildCombo(size_t defaultChoice)
comboChoice->Clear();
for(size_t ui=0;ui<choiceStrings.size();ui++)
- comboChoice->Append(wxStr(choiceStrings[ui]));
+ comboChoice->Append((choiceStrings[ui]));
comboChoice->SetSelection(defaultChoice);
}
diff --git a/src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp b/src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp
index f640e72..25a0b9c 100644
--- a/src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp
+++ b/src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp
@@ -53,23 +53,23 @@ ColourKeyFrameDialog::ColourKeyFrameDialog(wxWindow* parent, int id, const wxStr
wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX)
{
// begin wxGlade: ColourKeyFrameDialog::ColourKeyFrameDialog
- sizerMainArea_staticbox = new wxStaticBox(this, -1, wxTRANS("Keyframe Data"));
- labelTransition = new wxStaticText(this, wxID_ANY, wxTRANS("Transition"));
+ sizerMainArea_staticbox = new wxStaticBox(this, -1, TRANS("Keyframe Data"));
+ labelTransition = new wxStaticText(this, wxID_ANY, TRANS("Transition"));
//FIXME: THis is declared in animator.h - use that def.
const wxString comboTransition_choices[] = {
- wxTRANS("Step"),
- wxTRANS("Ramp")
+ TRANS("Step"),
+ TRANS("Ramp")
};
comboTransition = new wxComboBox(this, ID_COMBO_TRANSITION, wxT(""), wxDefaultPosition, wxDefaultSize, 2, comboTransition_choices, wxCB_DROPDOWN|wxCB_READONLY);
- labelFrameStart = new wxStaticText(this, wxID_ANY, wxTRANS("Start Frame"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+ labelFrameStart = new wxStaticText(this, wxID_ANY, TRANS("Start Frame"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
textFrameStart = new wxTextCtrl(this, ID_TEXT_FRAME_START, wxEmptyString);
- labelFrameEnd = new wxStaticText(this, wxID_ANY, wxTRANS("End Frame"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+ labelFrameEnd = new wxStaticText(this, wxID_ANY, TRANS("End Frame"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
textFrameEnd = new wxTextCtrl(this, ID_TEXT_FRAME_END, wxEmptyString);
verticalLine = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
- labelStartVal = new wxStaticText(this, wxID_ANY, wxTRANS("Initial Value"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
- btnStartColour = new wxButton(this, ID_BTN_START_VALUE, wxTRANS("startColour"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
- labelFinalVal = new wxStaticText(this, wxID_ANY, wxTRANS("Final Value"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
- btnEndColour = new wxButton(this, ID_BTN_FINAL_VALUE, wxTRANS("endColour"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
+ labelStartVal = new wxStaticText(this, wxID_ANY, TRANS("Initial Value"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+ btnStartColour = new wxButton(this, ID_BTN_START_VALUE, TRANS("startColour"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
+ labelFinalVal = new wxStaticText(this, wxID_ANY, TRANS("Final Value"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+ btnEndColour = new wxButton(this, ID_BTN_FINAL_VALUE, TRANS("endColour"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
buttonCancel = new wxButton(this, wxID_CANCEL, wxEmptyString);
buttonOK = new wxButton(this, wxID_OK, wxEmptyString);
@@ -114,16 +114,14 @@ size_t ColourKeyFrameDialog::getEndFrame() const
std::string ColourKeyFrameDialog::getEndValue() const
{
ASSERT(transitionMode!=TRANSITION_STEP);
- std::string s;
- genColString(endRed,endGreen,endBlue,s);
- return s;
+ ColourRGBA rgb(endRed,endGreen,endBlue);
+ return rgb.rgbString();
}
std::string ColourKeyFrameDialog::getStartValue() const
{
- std::string s;
- genColString(startRed,startGreen,startBlue,s);
- return s;
+ ColourRGBA rgb(startRed,startGreen,startBlue);
+ return rgb.rgbString();
}
void ColourKeyFrameDialog::OnComboTransition(wxCommandEvent &event)
@@ -234,10 +232,10 @@ void ColourKeyFrameDialog::updateButtonColours()
void ColourKeyFrameDialog::set_properties()
{
// begin wxGlade: ColourKeyFrameDialog::set_properties
- SetTitle(wxTRANS("Key Frame : Colour"));
+ SetTitle(TRANS("Key Frame : Colour"));
comboTransition->SetSelection(-1);
- btnStartColour->SetToolTip(wxTRANS("Colour at the start of the transtition"));
- btnEndColour->SetToolTip(wxTRANS("Colour at end of transition"));
+ btnStartColour->SetToolTip(TRANS("Colour at the start of the transtition"));
+ btnEndColour->SetToolTip(TRANS("Colour at end of transition"));
// end wxGlade
}
diff --git a/src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp b/src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp
index 5586a69..559288c 100644
--- a/src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp
+++ b/src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp
@@ -42,12 +42,12 @@ StringKeyFrameDialog::StringKeyFrameDialog(wxWindow* parent, int id, const wxStr
wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
{
// begin wxGlade: StringKeyFrameDialog::StringKeyFrameDialog
- labelStartFrame = new wxStaticText(this, wxID_ANY, wxTRANS("Start Frame: "));
+ labelStartFrame = new wxStaticText(this, wxID_ANY, TRANS("Start Frame: "));
textStartFrame = new wxTextCtrl(this, ID_TEXT_START_FRAME, wxEmptyString);
- radioFromFile = new wxRadioButton(this, ID_RADIO_FROM_FILE, wxTRANS("From File"));
+ radioFromFile = new wxRadioButton(this, ID_RADIO_FROM_FILE, TRANS("From File"));
textFilename = new wxTextCtrl(this, ID_TEXT_FROM_FILE, wxEmptyString);
btnChooseFile = new wxButton(this, wxID_OPEN, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
- radioFromTable = new wxRadioButton(this, ID_RADIO_FROM_TABLE, wxTRANS("From Table"));
+ radioFromTable = new wxRadioButton(this, ID_RADIO_FROM_TABLE, TRANS("From Table"));
gridStrings = new wxGrid(this, ID_GRID_STRINGS);
btnStringAdd = new wxButton(this, wxID_ADD, wxEmptyString);
btnRemove = new wxButton(this, wxID_REMOVE, wxEmptyString);
@@ -63,7 +63,7 @@ StringKeyFrameDialog::StringKeyFrameDialog(wxWindow* parent, int id, const wxStr
startFrameOK=filenameOK=false;
string s;
stream_cast(s,startFrame);
- textStartFrame->SetValue(wxStr(s));
+ textStartFrame->SetValue((s));
radioFromFile->SetValue(true);
@@ -78,11 +78,7 @@ BEGIN_EVENT_TABLE(StringKeyFrameDialog, wxDialog)
EVT_TEXT(ID_TEXT_FROM_FILE, StringKeyFrameDialog::OnTextFilename)
EVT_BUTTON(wxID_OPEN, StringKeyFrameDialog::OnBtnChooseFile)
EVT_RADIOBUTTON(ID_RADIO_FROM_TABLE, StringKeyFrameDialog::OnTableRadio)
-#if wxCHECK_VERSION(2,9,0)
EVT_GRID_CMD_CELL_CHANGED(ID_GRID_STRINGS, StringKeyFrameDialog::OnGridCellChange)
-#else
- EVT_GRID_CMD_CELL_CHANGE(ID_GRID_STRINGS, StringKeyFrameDialog::OnGridCellChange)
-#endif
EVT_GRID_CMD_EDITOR_SHOWN(ID_GRID_STRINGS, StringKeyFrameDialog::OnGridEditorShown)
EVT_BUTTON(wxID_ADD, StringKeyFrameDialog::OnBtnAdd)
EVT_BUTTON(wxID_REMOVE, StringKeyFrameDialog::OnBtnRemove)
@@ -105,8 +101,8 @@ void StringKeyFrameDialog::buildGrid()
gridStrings->DeleteRows(0,gridStrings->GetNumberRows());
gridStrings->AppendCols(2);
- gridStrings->SetColLabelValue(0,wxTRANS("Frame"));
- gridStrings->SetColLabelValue(1,wxTRANS("Value"));
+ gridStrings->SetColLabelValue(0,TRANS("Frame"));
+ gridStrings->SetColLabelValue(1,TRANS("Value"));
gridStrings->AppendRows(valueStrings.size());
@@ -120,8 +116,8 @@ void StringKeyFrameDialog::buildGrid()
stream_cast(pos,ui+startFrame);
//set the frame-value pair
- gridStrings->SetCellValue(ui,0,wxStr(pos));
- gridStrings->SetCellValue(ui,1,wxStr(valueStrings[ui]));
+ gridStrings->SetCellValue(ui,0,(pos));
+ gridStrings->SetCellValue(ui,1,(valueStrings[ui]));
}
gridStrings->EndBatch();
}
@@ -241,8 +237,8 @@ void StringKeyFrameDialog::OnGridEditorShown(wxGridEvent &event)
void StringKeyFrameDialog::OnBtnChooseFile(wxCommandEvent &event)
{
//Pop up a directory dialog, to choose the base path for the new folder
- wxFileDialog *wxD = new wxFileDialog(this,wxTRANS("Select text file..."), wxT(""),
- wxT(""),wxTRANS("Text files (*.txt)|*.txt;|All Files (*)|*"),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
+ wxFileDialog *wxD = new wxFileDialog(this,TRANS("Select text file..."), wxT(""),
+ wxT(""),TRANS("Text files (*.txt)|*.txt;|All Files (*)|*"),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
unsigned int res;
res = wxD->ShowModal();
@@ -343,22 +339,22 @@ void StringKeyFrameDialog::OnBtnRemove(wxCommandEvent &event)
void StringKeyFrameDialog::set_properties()
{
// begin wxGlade: StringKeyFrameDialog::set_properties
- SetTitle(wxTRANS("String Keyframes"));
+ SetTitle(TRANS("String Keyframes"));
SetSize(wxSize(542, 412));
- SetToolTip(wxTRANS("Frame at which to start string sequence"));
- textStartFrame->SetToolTip(wxTRANS("Frame offset for data start"));
- textFilename->SetToolTip(wxTRANS("File to use as string data source, one value per row"));
- btnChooseFile->SetToolTip(wxTRANS("Select file to use as data source"));
- radioFromTable->SetToolTip(wxTRANS("Use table below for data source"));
+ SetToolTip(TRANS("Frame at which to start string sequence"));
+ textStartFrame->SetToolTip(TRANS("Frame offset for data start"));
+ textFilename->SetToolTip(TRANS("File to use as string data source, one value per row"));
+ btnChooseFile->SetToolTip(TRANS("Select file to use as data source"));
+ radioFromTable->SetToolTip(TRANS("Use table below for data source"));
gridStrings->CreateGrid(0, 2);
- gridStrings->SetColLabelValue(0, wxTRANS("Frame"));
+ gridStrings->SetColLabelValue(0, TRANS("Frame"));
gridStrings->SetColSize(0, 1);
- gridStrings->SetColLabelValue(1, wxTRANS("Value"));
+ gridStrings->SetColLabelValue(1, TRANS("Value"));
gridStrings->SetColSize(1, 3);
- btnStringAdd->SetToolTip(wxTRANS("Add new data rows to table, hold shift/cmd to insert multiple rows"));
- btnRemove->SetToolTip(wxTRANS("Remove selected strings from table"));
- btnCancel->SetToolTip(wxTRANS("Abort value selection and return to previous window"));
- btnOK->SetToolTip(wxTRANS("Accept data values"));
+ btnStringAdd->SetToolTip(TRANS("Add new data rows to table, hold shift/cmd to insert multiple rows"));
+ btnRemove->SetToolTip(TRANS("Remove selected strings from table"));
+ btnCancel->SetToolTip(TRANS("Abort value selection and return to previous window"));
+ btnOK->SetToolTip(TRANS("Accept data values"));
// end wxGlade
}
diff --git a/src/gui/dialogs/autosaveDialog.cpp b/src/gui/dialogs/autosaveDialog.cpp
index b358920..0ed075c 100644
--- a/src/gui/dialogs/autosaveDialog.cpp
+++ b/src/gui/dialogs/autosaveDialog.cpp
@@ -36,7 +36,7 @@ AutosaveDialog::AutosaveDialog(wxWindow* parent, int id, const wxString& title,
// begin wxGlade: AutosaveDialog::AutosaveDialog
const wxString *listStates_choices = NULL;
listStates = new wxListBox(this, ID_LIST_STATES, wxDefaultPosition, wxDefaultSize, 0, listStates_choices, wxLB_SINGLE|wxLB_NEEDED_SB);
- btnRemoveAll = new wxButton(this, ID_REMOVE_ALL, wxTRANS("Remove &All"));
+ btnRemoveAll = new wxButton(this, ID_REMOVE_ALL, TRANS("Remove &All"));
btnCancel = new wxButton(this, wxID_CANCEL, wxEmptyString);
btnOK = new wxButton(this, wxID_OK, wxEmptyString);
@@ -114,13 +114,13 @@ void AutosaveDialog::OnOK(wxCommandEvent &event)
void AutosaveDialog::setItems( const std::vector<std::string> &newItems)
{
for(size_t ui=0;ui<newItems.size();ui++)
- listStates->Insert(wxStr(newItems[ui]),ui);
+ listStates->Insert((newItems[ui]),ui);
}
void AutosaveDialog::set_properties()
{
// begin wxGlade: AutosaveDialog::set_properties
- SetTitle(wxTRANS("Restore state?"));
+ SetTitle(TRANS("Restore state?"));
// end wxGlade
}
@@ -130,7 +130,7 @@ void AutosaveDialog::do_layout()
// begin wxGlade: AutosaveDialog::do_layout
wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizer_2 = new wxBoxSizer(wxHORIZONTAL);
- wxStaticText* labelHeader = new wxStaticText(this, wxID_ANY, wxTRANS("Multiple autosave states were found; would you like to restore one?"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+ wxStaticText* labelHeader = new wxStaticText(this, wxID_ANY, TRANS("Multiple autosave states were found; would you like to restore one?"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
sizer_1->Add(labelHeader, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 8);
sizer_1->Add(listStates, 1, wxALL|wxEXPAND, 8);
sizer_2->Add(btnRemoveAll, 0, wxLEFT|wxBOTTOM, 8);
diff --git a/src/gui/dialogs/filterErrorDialog.cpp b/src/gui/dialogs/filterErrorDialog.cpp
index c4ac665..0b8b192 100644
--- a/src/gui/dialogs/filterErrorDialog.cpp
+++ b/src/gui/dialogs/filterErrorDialog.cpp
@@ -34,12 +34,12 @@ FilterErrorDialog::FilterErrorDialog(wxWindow* parent, int id, const wxString& t
// begin wxGlade: FilterErrorDialog::FilterErrorDialog
textErrorMessage = new wxTextCtrl(this, wxID_ANY, wxEmptyString,wxDefaultPosition,wxDefaultSize,wxTE_MULTILINE|wxTE_READONLY);
bitmapError = new wxStaticBitmap(this, wxID_ANY, wxArtProvider::GetBitmap(wxART_ERROR));
- labelError = new wxStaticText(this, wxID_ANY, wxTRANS("Error"));
+ labelError = new wxStaticText(this, wxID_ANY, TRANS("Error"));
bitmapWarning = new wxStaticBitmap(this, wxID_ANY,wxArtProvider::GetBitmap(wxART_WARNING));
- labelWarning = new wxStaticText(this, wxID_ANY, wxTRANS("Warning"));
+ labelWarning = new wxStaticText(this, wxID_ANY, TRANS("Warning"));
btnOK = new wxButton(this, wxID_OK, wxEmptyString);
- SetTitle(wxTRANS("Filter Errors"));
+ SetTitle(TRANS("Filter Errors"));
set_properties();
do_layout();
// end wxGlade
@@ -49,7 +49,7 @@ FilterErrorDialog::FilterErrorDialog(wxWindow* parent, int id, const wxString& t
void FilterErrorDialog::set_properties()
{
// begin wxGlade: FilterErrorDialog::set_properties
- SetTitle(wxTRANS("Filter Errors"));
+ SetTitle(TRANS("Filter Errors"));
SetSize(wxSize(551, 414));
// end wxGlade
}
@@ -65,7 +65,7 @@ void FilterErrorDialog::SetText(const std::vector<string> &text)
}
textErrorMessage->Clear();
- textErrorMessage->AppendText(wxStr(bigMessage));
+ textErrorMessage->AppendText((bigMessage));
}
void FilterErrorDialog::do_layout()
diff --git a/src/gui/dialogs/prefDialog.cpp b/src/gui/dialogs/prefDialog.cpp
index 066381c..e482e79 100644
--- a/src/gui/dialogs/prefDialog.cpp
+++ b/src/gui/dialogs/prefDialog.cpp
@@ -26,6 +26,7 @@
#include "wx/wxcommon.h"
#include "wx/wxcomponents.h"
+#include "wx/propertyGridUpdater.h"
#include <wx/colordlg.h>
@@ -69,47 +70,43 @@ PrefDialog::PrefDialog(wxWindow* parent, int id, const wxString& title, const wx
notePrefPanels_pane_3 = new wxPanel(notePrefPanels, wxID_ANY);
panelStartup = new wxPanel(notePrefPanels, wxID_ANY);
panelFilters = new wxPanel(notePrefPanels, wxID_ANY);
- sizer_2_staticbox = new wxStaticBox(panelStartup, -1, wxTRANS("Panel Display"));
+ sizer_2_staticbox = new wxStaticBox(panelStartup, -1, TRANS("Panel Display"));
#ifndef DISABLE_ONLINE_UPDATE
- updateSizer_staticbox = new wxStaticBox(panelStartup, -1, wxTRANS("Online Updates"));
+ updateSizer_staticbox = new wxStaticBox(panelStartup, -1, TRANS("Online Updates"));
#endif
- sizer_7_staticbox = new wxStaticBox(notePrefPanels_pane_3, wxID_ANY, wxTRANS("Startup"));
- sizerCamSpeed_staticbox = new wxStaticBox(notePrefPanels_pane_3, -1, wxTRANS("Camera Speed"));
- filterPropSizer_staticbox = new wxStaticBox(panelFilters, -1, wxTRANS("Filter Defaults"));
- lblFilters = new wxStaticText(panelFilters, wxID_ANY, wxTRANS("Available Filters"));
+ sizer_7_staticbox = new wxStaticBox(notePrefPanels_pane_3, wxID_ANY, TRANS("Startup"));
+ sizerCamSpeed_staticbox = new wxStaticBox(notePrefPanels_pane_3, -1, TRANS("Camera Speed"));
+ lblFilters = new wxStaticText(panelFilters, wxID_ANY, TRANS("Available Filters"));
listFilters = new wxListBox(panelFilters, ID_LIST_FILTERS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_SORT);
- filterGridProperties = new wxCustomPropGrid(panelFilters, ID_GRID_PROPERTIES);
- filterBtnResetAllFilters = new wxButton(panelFilters, ID_BTN_RESET_FILTER_ALL, wxTRANS("Reset All"));
- filterResetDefaultFilter = new wxButton(panelFilters, ID_BTN_RESET_FILTER, wxTRANS("Reset"));
+ filterGridProperties =new wxPropertyGrid(panelFilters, ID_GRID_PROPERTIES,
+ wxDefaultPosition,wxDefaultSize,PROPERTY_GRID_STYLE);
+ filterGridProperties->SetExtraStyle(PROPERTY_GRID_EXTRA_STYLE);
+ filterBtnResetAllFilters = new wxButton(panelFilters, ID_BTN_RESET_FILTER_ALL, TRANS("Reset All"));
+ filterResetDefaultFilter = new wxButton(panelFilters, ID_BTN_RESET_FILTER, TRANS("Reset"));
const wxString comboPanelStartMode_choices[] = {
- wxNTRANS("Show all panels"),
- wxNTRANS("Remember last"),
- wxNTRANS("Show Selected")
+ NTRANS("Show all panels"),
+ NTRANS("Remember last"),
+ NTRANS("Show Selected")
};
comboPanelStartMode = new wxComboBox(panelStartup, ID_START_COMBO_PANEL, wxT(""), wxDefaultPosition, wxDefaultSize, 3, comboPanelStartMode_choices, wxCB_SIMPLE|wxCB_DROPDOWN|wxCB_READONLY);
- chkControl = new wxCheckBox(panelStartup, ID_START_CHECK_CONTROL, wxTRANS("Control Pane"));
- chkRawData = new wxCheckBox(panelStartup, ID_START_CHECK_RAWDATA, wxTRANS("Raw Data Panel"));
- chkPlotlist = new wxCheckBox(panelStartup, ID_START_CHECK_PLOTLIST, wxTRANS("Plot List"));
+ chkControl = new wxCheckBox(panelStartup, ID_START_CHECK_CONTROL, TRANS("Control Pane"));
+ chkRawData = new wxCheckBox(panelStartup, ID_START_CHECK_RAWDATA, TRANS("Raw Data Panel"));
+ chkPlotlist = new wxCheckBox(panelStartup, ID_START_CHECK_PLOTLIST, TRANS("Plot List"));
#ifndef DISABLE_ONLINE_UPDATE
- checkAllowOnlineUpdate = new wxCheckBox(panelStartup, wxID_ANY, wxTRANS("Periodically notify about available updates"));
+ checkAllowOnlineUpdate = new wxCheckBox(panelStartup, wxID_ANY, TRANS("Periodically notify about available updates"));
#endif
- chkPreferOrtho = new wxCheckBox(notePrefPanels_pane_3, wxID_ANY, wxTRANS("Prefer orthographic at startup"));
- lblMoveSpeed = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, wxTRANS("Move Rate"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
- labelSlowCamMoveRate = new wxStaticText(notePrefPanels_pane_3,wxID_ANY, wxTRANS("(slow)"));
+ chkPreferOrtho = new wxCheckBox(notePrefPanels_pane_3, wxID_ANY, TRANS("Prefer orthographic at startup"));
+ lblMoveSpeed = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, TRANS("Move Rate"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+ labelSlowCamMoveRate = new wxStaticText(notePrefPanels_pane_3,wxID_ANY, TRANS("(slow)"));
sliderCamMoveRate = new wxSlider(notePrefPanels_pane_3, ID_MOUSE_MOVE_SLIDER, 25, 1, 400,wxDefaultPosition,wxDefaultSize,wxSL_HORIZONTAL|wxSL_LABELS);
- labelFastCamMoveRate = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, wxTRANS("(fast)"));
- lblZoomSpeed = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, wxTRANS("Zoom Rate"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
- labelSlowCamZoomRate = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, wxTRANS("(slow)"));
+ labelFastCamMoveRate = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, TRANS("(fast)"));
+ lblZoomSpeed = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, TRANS("Zoom Rate"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+ labelSlowCamZoomRate = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, TRANS("(slow)"));
sliderCamZoomRate = new wxSlider(notePrefPanels_pane_3, ID_MOUSE_ZOOM_SLIDER, 25, 1, 400,wxDefaultPosition,wxDefaultSize,wxSL_HORIZONTAL|wxSL_LABELS);
- labelSlowFastZoomRate = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, wxTRANS("(fast)"));
+ labelSlowFastZoomRate = new wxStaticText(notePrefPanels_pane_3, wxID_ANY, TRANS("(fast)"));
btnOK = new wxButton(this, wxID_OK, wxEmptyString);
btnCancel = new wxButton(this, wxID_CANCEL, wxEmptyString);
- filterGridProperties->CreateGrid(0, 2);
- filterGridProperties->EnableDragRowSize(false);
- filterGridProperties->SetColLabelValue(0, wxTRANS("Param"));
- filterGridProperties->SetColLabelValue(1, wxTRANS("Value"));
-
bool enable=(comboPanelStartMode->GetSelection() == STARTUP_COMBO_SELECT_SPECIFY);
chkRawData->Enable(enable);
@@ -120,6 +117,8 @@ PrefDialog::PrefDialog(wxWindow* parent, int id, const wxString& title, const wx
programmaticEvent=false;
curFilter=0;
+ backFilterPropGrid=0;
+
set_properties();
do_layout();
// end wxGlade
@@ -133,18 +132,14 @@ PrefDialog::~PrefDialog()
BEGIN_EVENT_TABLE(PrefDialog, wxDialog)
// begin wxGlade: PrefDialog::event_table
EVT_LISTBOX(ID_LIST_FILTERS, PrefDialog::OnFilterListClick)
-#if wxCHECK_VERSION(2,9,0)
- EVT_GRID_CMD_CELL_CHANGED(ID_GRID_PROPERTIES, PrefDialog::OnFilterCellChange)
-#else
- EVT_GRID_CMD_CELL_CHANGE(ID_GRID_PROPERTIES, PrefDialog::OnFilterCellChange)
-#endif
- EVT_GRID_CMD_EDITOR_SHOWN(ID_GRID_PROPERTIES,PrefDialog::OnFilterGridCellEditorShow)
+ EVT_PG_CHANGING(ID_GRID_PROPERTIES, PrefDialog::OnFilterCellChange)
EVT_BUTTON(ID_BTN_RESET_FILTER,PrefDialog::OnResetFilterButton)
EVT_BUTTON(ID_BTN_RESET_FILTER_ALL,PrefDialog::OnResetFilterAllButton)
EVT_COMBOBOX(ID_START_COMBO_PANEL, PrefDialog::OnStartupPanelCombo)
EVT_CHECKBOX(ID_CHECK_PREFER_ORTHO, PrefDialog::OnCheckPreferOrtho)
EVT_COMMAND_SCROLL(ID_MOUSE_ZOOM_SLIDER, PrefDialog::OnMouseZoomSlider)
EVT_COMMAND_SCROLL(ID_MOUSE_MOVE_SLIDER, PrefDialog::OnMouseMoveSlider)
+ EVT_IDLE(PrefDialog::OnIdle)
// end wxGlade
END_EVENT_TABLE();
@@ -157,7 +152,7 @@ void PrefDialog::createFilterListing()
vector<size_t> v;
for(size_t ui=0;ui<filterDefaults.size();ui++)
{
- s=wxStr(filterDefaults[ui]->typeString());
+ s=(filterDefaults[ui]->typeString());
v.push_back(filterDefaults[ui]->getType());
listFilters->Append(s);
}
@@ -172,7 +167,7 @@ void PrefDialog::createFilterListing()
//This is a bit of a hack, but it works.
Filter *t;
t=makeFilter(ui);
- s = wxStr(t->typeString());
+ s = (t->typeString());
listFilters->Append(s);
delete t;
}
@@ -224,6 +219,19 @@ void PrefDialog::setFilterDefaults(const vector<Filter *> &defs)
filterDefaults[ui]=defs[ui]->cloneUncached();
}
+
+void PrefDialog::OnIdle(wxIdleEvent &evt)
+{
+ //This is required due to a bug in wx's propertygrid
+ // see wx bug #16222
+ if(backFilterPropGrid)
+ {
+ delete backFilterPropGrid;
+ backFilterPropGrid=0;
+
+ }
+}
+
void PrefDialog::OnFilterListClick(wxCommandEvent &event)
{
@@ -259,8 +267,9 @@ void PrefDialog::OnFilterListClick(wxCommandEvent &event)
}
-void PrefDialog::OnFilterCellChange(wxGridEvent &event)
+void PrefDialog::OnFilterCellChange(wxPropertyGridEvent &event)
{
+ event.SetValidationFailureBehavior(0);
//Disallow programmatic event from causing filter update (stack loop->overflow)
if(programmaticEvent)
{
@@ -269,102 +278,33 @@ void PrefDialog::OnFilterCellChange(wxGridEvent &event)
}
//Grab the changed value
- std::string value;
- int row=event.GetRow();
- value = stlStr(filterGridProperties->GetCellValue(
- row,1));
- programmaticEvent=true;
+ std::string value,keyStr;
+ value = getPropValueFromEvent(event);
+
+ size_t key;
+ keyStr=event.GetProperty()->GetName();
+ stream_cast(key,keyStr);
bool needUpdate;
- curFilter->setProperty(filterGridProperties->getKeyFromRow(row),
- value,needUpdate);
+ curFilter->setProperty(key,value,needUpdate);
if(find(filterDefaults.begin(),filterDefaults.end(),
curFilter) == filterDefaults.end())
filterDefaults.push_back(curFilter);
+
+ //Build the new property grid in an aside,
+ // due to wx bug,
+ backFilterPropGrid= new wxPropertyGrid(panelFilters,ID_GRID_PROPERTIES,
+ wxDefaultPosition,wxDefaultSize,PROPERTY_GRID_STYLE);
+ filterGridProperties->SetExtraStyle(PROPERTY_GRID_EXTRA_STYLE);
+ std::swap(backFilterPropGrid,filterGridProperties);
updateFilterProp(curFilter);
- programmaticEvent=false;
-}
-
-
-
-//This function modifies the properties before showing the cell content editor.T
-//This is needed only for certain data types (colours, bools) other data types are edited
-//using the default editor and modified using ::OnGridFilterPropertyChange
-void PrefDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
-{
- //Find where the event occurred (cell & property)
- const GRID_PROPERTY *item=0;
-
- unsigned int key;
- key=filterGridProperties->getKeyFromRow(event.GetRow());
-
- item=filterGridProperties->getProperty(key);
-
- bool needUpdate;
- switch(item->type)
- {
- case PROPERTY_TYPE_BOOL:
- {
- std::string s;
- //Toggle the property in the grid
- if(item->data == "0")
- s= "1";
- else
- s="0";
- curFilter->setProperty(key,s,needUpdate);
-
- event.Veto();
-
- updateFilterProp(curFilter);
- break;
- }
- case PROPERTY_TYPE_COLOUR:
- {
- //Show a wxColour choose dialog.
- wxColourData d;
-
- unsigned char r,g,b,a;
- parseColString(item->data,r,g,b,a);
-
- d.SetColour(wxColour(r,g,b,a));
- wxColourDialog *colDg=new wxColourDialog(this->GetParent(),&d);
-
-
- if( colDg->ShowModal() == wxID_OK)
- {
- wxColour c;
- //Change the colour
- c=colDg->GetColourData().GetColour();
-
- std::string s;
- genColString(c.Red(),c.Green(),c.Blue(),s);
-
- //Pass the new colour to the viscontrol system, which updates
- //the filters
- curFilter->setProperty(key,s,needUpdate);
- }
-
- //Set the filter property
- //Disallow direct editing of the grid cell
- event.Veto();
-
-
- updateFilterProp(curFilter);
- break;
- }
- case PROPERTY_TYPE_CHOICE:
- break;
- default:
- //we will handle this after the user has edited the cell contents
- break;
- }
- //Add to the modified filter defaults as needed
- if(find(filterDefaults.begin(),filterDefaults.end(),
- curFilter) == filterDefaults.end())
- filterDefaults.push_back(curFilter);
+ do_filtergrid_prop_layout();
+
+ //reforce layout code
+ programmaticEvent=false;
}
void PrefDialog::OnResetFilterButton(wxCommandEvent &evt)
@@ -431,39 +371,19 @@ void PrefDialog::updateFilterProp(const Filter *f)
if(!(f->canBeHazardous()))
{
filterGridProperties->Enable(true);
- updateFilterPropertyGrid(filterGridProperties,f);
+ updateFilterPropertyGrid(filterGridProperties,f,"");
}
else
{
//If the filter is potentially hazardous,
//then we will disallow editing of the properties.
//and give a notice to that effect
- filterGridProperties->BeginBatch();
+ filterGridProperties->Freeze();
filterGridProperties->Enable(false);
- wxGridCellAttr *readOnlyColAttr=new wxGridCellAttr;
-
- //Empty the grid
- //then fill it up with a note.
- if(filterGridProperties->GetNumberCols())
- filterGridProperties->DeleteCols(0,filterGridProperties->GetNumberCols());
- if(filterGridProperties->GetNumberRows())
- filterGridProperties->DeleteRows(0,filterGridProperties->GetNumberRows());
-
- filterGridProperties->AppendRows(1);
- filterGridProperties->AppendCols(1);
- filterGridProperties->AutoSizeColumn(0,true);
- filterGridProperties->SetColAttr(0,readOnlyColAttr);
- filterGridProperties->SetColLabelValue(0,wxTRANS("Notice"));
-
- filterGridProperties->SetCellValue(0,0,
- wxTRANS("For security reasons, defaults are not modifiable for this filter"));
-
- filterGridProperties->EndBatch();
-
- //Set the column size so you can see the message
- filterGridProperties->SetColSize(0, filterGridProperties->GetSize().GetWidth()
- - filterGridProperties->GetScrollThumb(wxVERTICAL) - 15);
-
+ filterGridProperties->Clear();
+ filterGridProperties->Append(new wxPropertyCategory(string("Not Editable for security reasons")));
+ filterGridProperties->Thaw();
+
}
}
@@ -493,17 +413,17 @@ void PrefDialog::setStartupCheckboxEnables(unsigned int value)
switch(value)
{
case STARTUP_COMBO_SELECT_SHOW_ALL:
- comboPanelStartMode->SetToolTip(wxTRANS("Show all panels when starting program"));
+ comboPanelStartMode->SetToolTip(TRANS("Show all panels when starting program"));
break;
case STARTUP_COMBO_SELECT_REMEMBER:
- comboPanelStartMode->SetToolTip(wxTRANS("Show panels visible at last shutdown when starting program"));
+ comboPanelStartMode->SetToolTip(TRANS("Show panels visible at last shutdown when starting program"));
chkRawData->SetValue(true);
chkControl->SetValue(true);
chkPlotlist->SetValue(true);
break;
case STARTUP_COMBO_SELECT_SPECIFY:
- comboPanelStartMode->SetToolTip(wxTRANS("Show selected panels when starting program"));
+ comboPanelStartMode->SetToolTip(TRANS("Show selected panels when starting program"));
break;
default:
ASSERT(false);
@@ -552,19 +472,19 @@ void PrefDialog::OnMouseMoveSlider(wxScrollEvent &event)
void PrefDialog::set_properties()
{
// begin wxGlade: PrefDialog::set_properties
- SetTitle(wxTRANS("Preferences"));
+ SetTitle(TRANS("Preferences"));
SetSize(wxSize(640, 487));
- comboPanelStartMode->SetToolTip(wxTRANS("Set the method of panel layout when starting the program"));
+ comboPanelStartMode->SetToolTip(TRANS("Set the method of panel layout when starting the program"));
comboPanelStartMode->SetSelection(0);
#ifndef DISABLE_ONLINE_UPDATE
- checkAllowOnlineUpdate->SetToolTip(wxTRANS("Lets the program check the internet to see if updates to the program version are available, then notifies you about updates now and again."));
+ checkAllowOnlineUpdate->SetToolTip(TRANS("Lets the program check the internet to see if updates to the program version are available, then notifies you about updates now and again."));
#endif
- chkPreferOrtho->SetToolTip(wxTRANS("By default, use an orthographic camera at startup. State files will override this preference."));
- sliderCamMoveRate->SetToolTip(wxTRANS("Camera translation, orbit and swivel rates. "));
- sliderCamZoomRate->SetToolTip(wxTRANS("Camera zooming rate."));
+ chkPreferOrtho->SetToolTip(TRANS("By default, use an orthographic camera at startup. State files will override this preference."));
+ sliderCamMoveRate->SetToolTip(TRANS("Camera translation, orbit and swivel rates. "));
+ sliderCamZoomRate->SetToolTip(TRANS("Camera zooming rate."));
- filterResetDefaultFilter->SetToolTip(wxTRANS("Reset the filter initial values back to program defaults"));
- filterBtnResetAllFilters->SetToolTip(wxTRANS("Reset all filter initial values back to program defaults"));
+ filterResetDefaultFilter->SetToolTip(TRANS("Reset the filter initial values back to program defaults"));
+ filterBtnResetAllFilters->SetToolTip(TRANS("Reset all filter initial values back to program defaults"));
// end wxGlade
}
@@ -589,22 +509,8 @@ void PrefDialog::do_layout()
wxStaticBoxSizer* sizer_2 = new wxStaticBoxSizer(sizer_2_staticbox, wxVERTICAL);
wxBoxSizer* sizer_3 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_4 = new wxBoxSizer(wxVERTICAL);
- filterPropSizer_staticbox->Lower();
- wxStaticBoxSizer* filterPropSizer = new wxStaticBoxSizer(filterPropSizer_staticbox, wxHORIZONTAL);
- wxBoxSizer* filterRightSideSizer = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* resetButtonSizer = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* filterLeftSizer = new wxBoxSizer(wxVERTICAL);
- filterLeftSizer->Add(lblFilters, 0, 0, 0);
- filterLeftSizer->Add(listFilters, 1, wxEXPAND, 0);
- filterPropSizer->Add(filterLeftSizer, 1, wxEXPAND, 0);
- filterPropSizer->Add(20, 20, 0, 0, 0);
- filterRightSideSizer->Add(filterGridProperties, 1, wxEXPAND, 0);
- resetButtonSizer->Add(filterBtnResetAllFilters, 0, 0, 0);
- resetButtonSizer->Add(filterResetDefaultFilter, 0, 0, 0);
- resetButtonSizer->Add(20, 20, 1, 0, 0);
- filterRightSideSizer->Add(resetButtonSizer, 0, wxEXPAND, 0);
- filterPropSizer->Add(filterRightSideSizer, 2, wxEXPAND, 0);
- panelFilters->SetSizer(filterPropSizer);
+ do_filtergrid_prop_layout();
+// filterPropSizer_staticbox->Lower();
#if defined(__WIN32) || defined(__WIN64)
sizer_2->Add(comboPanelStartMode, 0, wxBOTTOM|wxFIXED_MINSIZE, 4);
#else
@@ -650,9 +556,9 @@ void PrefDialog::do_layout()
sizerCamSpeed->AddStretchSpacer();
sizer_5->Add(sizerCamSpeed, 1, wxEXPAND, 0);
notePrefPanels_pane_3->SetSizer(sizer_5);
- notePrefPanels->AddPage(panelFilters, wxTRANS("Pref"));
- notePrefPanels->AddPage(panelStartup, wxTRANS("Startup"));
- notePrefPanels->AddPage(notePrefPanels_pane_3, wxTRANS("Camera"));
+ notePrefPanels->AddPage(panelFilters, TRANS("Filt. Default"));
+ notePrefPanels->AddPage(panelStartup, TRANS("Startup"));
+ notePrefPanels->AddPage(notePrefPanels_pane_3, TRANS("Camera"));
panelSizer->Add(notePrefPanels, 2, wxEXPAND, 0);
exitButtonSizer->Add(20, 20, 1, wxEXPAND, 0);
exitButtonSizer->Add(btnOK, 0, wxTOP, 8);
@@ -664,3 +570,27 @@ void PrefDialog::do_layout()
// end wxGlade
}
+void PrefDialog::do_filtergrid_prop_layout()
+{
+ panelFilters->SetSizer(NULL);
+ wxBoxSizer* filterPropSizer = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* filterRightSideSizer = new wxBoxSizer(wxVERTICAL);
+ wxBoxSizer* resetButtonSizer = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* filterLeftSizer = new wxBoxSizer(wxVERTICAL);
+
+ filterLeftSizer->Add(lblFilters, 0, 0, 0);
+ filterLeftSizer->Add(listFilters, 1, wxEXPAND, 0);
+ filterPropSizer->Add(filterLeftSizer, 1, wxEXPAND, 0);
+ filterPropSizer->Add(20, 20, 0, 0, 0);
+ filterRightSideSizer->Add(filterGridProperties, 1, wxEXPAND, 0);
+ resetButtonSizer->Add(filterBtnResetAllFilters, 0, 0, 0);
+ resetButtonSizer->Add(filterResetDefaultFilter, 0, 0, 0);
+ resetButtonSizer->Add(20, 20, 1, 0, 0);
+ filterRightSideSizer->Add(resetButtonSizer, 0, wxEXPAND, 0);
+ filterPropSizer->Add(filterRightSideSizer, 2, wxEXPAND, 0);
+ panelFilters->SetSizer(filterPropSizer);
+
+ panelFilters->Fit();
+ panelFilters->Layout();
+}
+
diff --git a/src/gui/dialogs/prefDialog.h b/src/gui/dialogs/prefDialog.h
index a219f12..6991786 100644
--- a/src/gui/dialogs/prefDialog.h
+++ b/src/gui/dialogs/prefDialog.h
@@ -73,7 +73,7 @@ protected:
wxStaticBox* filterPropSizer_staticbox;
wxStaticText* lblFilters;
wxListBox* listFilters;
- wxCustomPropGrid* filterGridProperties;
+ wxPropertyGrid* filterGridProperties,*backFilterPropGrid;
wxButton* filterBtnResetAllFilters;
wxButton* filterResetDefaultFilter;
wxPanel* panelFilters;
@@ -107,11 +107,11 @@ public:
// end wxGlade
PrefDialog(wxWindow* parent, int id=wxID_ANY, const wxString& title=wxT("Preferences"), const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
virtual ~PrefDialog();
- virtual void OnFilterCellChange(wxGridEvent &event); // wxGlade: <event_handler>
+ virtual void OnFilterCellChange(wxPropertyGridEvent &event); // wxGlade: <event_handler>
virtual void OnFilterListClick(wxCommandEvent &event); // wxGlade: <event_handler>
- virtual void OnFilterGridCellEditorShow(wxGridEvent &event); // wxGlade: <event_handler>
virtual void OnResetFilterButton(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnResetFilterAllButton(wxCommandEvent &event); // wxGlade: <event_handler>
+ virtual void OnIdle(wxIdleEvent &evt);
//set the filter defaults. note that the incoming pointers are cloned, and control is NOT transferred to this class
void setFilterDefaults(const std::vector<Filter * > &defs);
@@ -141,6 +141,9 @@ public:
void OnMouseMoveSlider(wxScrollEvent &event);
void OnMouseZoomSlider(wxScrollEvent &event);
+ //Force a re-layout of the filter property grid
+ void do_filtergrid_prop_layout();
+
void initialise();
void cleanup();
}; // wxGlade: end class
diff --git a/src/gui/dialogs/rangeEditDialog.cpp b/src/gui/dialogs/rangeEditDialog.cpp
index 87426f9..f865e91 100644
--- a/src/gui/dialogs/rangeEditDialog.cpp
+++ b/src/gui/dialogs/rangeEditDialog.cpp
@@ -215,7 +215,7 @@ RangeEditorDialog::RangeEditorDialog(wxWindow* parent, int id, const wxString& t
gridRanges = new wxGrid(noteLeftRanges, ID_GRID_RANGES);
btnRangeIonAdd = new wxButton(noteLeftRanges,wxID_ADD, wxEmptyString);
btnRangeIonRemove = new wxButton(noteLeftRanges, wxID_REMOVE, wxEmptyString);
- checkShowOverlay = new wxCheckBox(noteLeftOverlay, ID_CHECK_SHOW_OVERLAY, wxTRANS("Show Overlays"));
+ checkShowOverlay = new wxCheckBox(noteLeftOverlay, ID_CHECK_SHOW_OVERLAY, TRANS("Show Overlays"));
textOverlayCmpnt = new wxTextCtrl(noteLeftOverlay, ID_TEXT_FILTER_CMPNT, wxEmptyString,
wxDefaultPosition,wxDefaultSize,wxTE_PROCESS_ENTER);
listOverlay = new wxCheckListBox(noteLeftOverlay, ID_LIST_OVERLAY, wxDefaultPosition, wxDefaultSize, 0);
@@ -240,26 +240,16 @@ RangeEditorDialog::RangeEditorDialog(wxWindow* parent, int id, const wxString& t
checkShowOverlay->SetValue(true);
haveSetTextFocus=false;
- textOverlayCmpnt->SetValue(wxTRANS("e.g. H2O"));
+ textOverlayCmpnt->SetValue(TRANS("e.g. H2O"));
-#if wxCHECK_VERSION(2, 9, 0)
textOverlayCmpnt->Bind(wxEVT_SET_FOCUS, &RangeEditorDialog::OnTextOverlaySetFocus, this);
-#else
- textOverlayCmpnt->Connect(wxID_ANY,
- wxEVT_SET_FOCUS,
- wxFocusEventHandler(RangeEditorDialog::OnTextOverlaySetFocus), NULL, this);
-#endif
}
RangeEditorDialog::~RangeEditorDialog()
{
-#if wxCHECK_VERSION(2, 9, 0)
textOverlayCmpnt->Unbind(wxEVT_SET_FOCUS, &RangeEditorDialog::OnTextOverlaySetFocus, this);
-#else
- textOverlayCmpnt->Disconnect();
-#endif
}
@@ -272,13 +262,8 @@ BEGIN_EVENT_TABLE(RangeEditorDialog, wxDialog)
EVT_TEXT(ID_TEXT_FILTER_CMPNT,RangeEditorDialog::OnTextOverlay)
EVT_TEXT_ENTER(ID_TEXT_FILTER_CMPNT,RangeEditorDialog::OnTextOverlayEnter)
EVT_CHECKBOX(ID_CHECK_SHOW_OVERLAY, RangeEditorDialog::OnCheckShowOverlay)
-#if wxCHECK_VERSION(2,9,0)
EVT_GRID_CMD_CELL_CHANGED(ID_GRID_RANGES, RangeEditorDialog::OnGridRangesCellChange)
EVT_GRID_CMD_CELL_CHANGED(ID_GRID_IONS, RangeEditorDialog::OnGridIonsCellChange)
-#else
- EVT_GRID_CMD_CELL_CHANGE(ID_GRID_RANGES, RangeEditorDialog::OnGridRangesCellChange)
- EVT_GRID_CMD_CELL_CHANGE(ID_GRID_IONS, RangeEditorDialog::OnGridIonsCellChange)
-#endif
EVT_GRID_CMD_CELL_LEFT_CLICK(ID_GRID_RANGES,RangeEditorDialog::OnGridRangeClick)
EVT_GRID_CMD_CELL_LEFT_CLICK(ID_GRID_IONS,RangeEditorDialog::OnGridIonClick)
EVT_GRID_CMD_EDITOR_SHOWN(ID_GRID_RANGES,RangeEditorDialog::OnGridRangesEditorShown)
@@ -288,7 +273,7 @@ BEGIN_EVENT_TABLE(RangeEditorDialog, wxDialog)
EVT_CHECKLISTBOX(ID_LIST_OVERLAY, RangeEditorDialog::OnListOverlayCheck)
EVT_BUTTON(wxID_OK, RangeEditorDialog::OnBtnOK)
EVT_BUTTON(wxID_CANCEL, RangeEditorDialog::OnBtnCancel)
- EVT_SPLITTER_UNSPLIT(ID_SPLIT_LEFTRIGHT, RangeEditorDialog::OnSashVerticalUnsplit)
+ EVT_SPLITTER_DCLICK(ID_SPLIT_LEFTRIGHT, RangeEditorDialog::OnSashVerticalDClick)
// end wxGlade
END_EVENT_TABLE();
@@ -518,7 +503,7 @@ void RangeEditorDialog::generateListEntries()
unsigned int plotID;
plotID = plotIDs[ui];
- std::wstring title;
+ std::string title;
title=plotWrap.getTitle(plotID);
//Only use plots from spectra
@@ -528,7 +513,7 @@ void RangeEditorDialog::generateListEntries()
//Append the plot to the list in the user interface,
// with the plot Id embeded in the element
int idx;
- idx=listPlots->Append(wxStr(title));
+ idx=listPlots->Append((title));
listToPlotIDs[idx]=plotIDs[ui];
}
@@ -549,7 +534,7 @@ void RangeEditorDialog::generateOverlayList(const vector<OVERLAY_DATA> &overlays
for(size_t ui=0;ui<overlays.size();ui++)
{
- listOverlay->Insert(wxStr(overlays[ui].title),ui);
+ listOverlay->Insert((overlays[ui].title),ui);
listOverlay->Check(ui,overlays[ui].enabled);
}
@@ -572,10 +557,10 @@ void RangeEditorDialog::generateIonEntries(size_t rowVisibleHint)
gridIons->DeleteRows(0,gridIons->GetNumberRows());
gridIons->AppendCols(4);
- gridIons->SetColLabelValue(ION_COL_PLOT,wxTRANS("Plot"));
- gridIons->SetColLabelValue(ION_COL_SHORTNAME,wxTRANS("Short Name"));
- gridIons->SetColLabelValue(ION_COL_LONGNAME,wxTRANS("Long Name"));
- gridIons->SetColLabelValue(ION_COL_COLOUR,wxTRANS("Colour"));
+ gridIons->SetColLabelValue(ION_COL_PLOT,TRANS("Plot"));
+ gridIons->SetColLabelValue(ION_COL_SHORTNAME,TRANS("Short Name"));
+ gridIons->SetColLabelValue(ION_COL_LONGNAME,TRANS("Long Name"));
+ gridIons->SetColLabelValue(ION_COL_COLOUR,TRANS("Colour"));
//--
@@ -594,7 +579,7 @@ void RangeEditorDialog::generateIonEntries(size_t rowVisibleHint)
}
- std::wstring title;
+ std::string title;
title=plotWrap.getTitle(curPlot);
//Colour to use for incomplete ions/ranges
@@ -613,12 +598,12 @@ void RangeEditorDialog::generateIonEntries(size_t rowVisibleHint)
gridIonIds[uj]=curIonRow;
gridIons->SetCellValue(curIonRow,
- ION_COL_PLOT,wxStr(title));
+ ION_COL_PLOT,(title));
gridIons->SetCellValue(curIonRow,
- ION_COL_SHORTNAME,wxStr(currentRange->getName(uj)));
+ ION_COL_SHORTNAME,(currentRange->getName(uj)));
gridIons->SetCellValue(curIonRow,
- ION_COL_LONGNAME,wxStr(currentRange->getName(uj,false)));
+ ION_COL_LONGNAME,(currentRange->getName(uj,false)));
//set the colour
wxGridCellAttr *attr = gridIons->GetOrCreateCellAttr(curIonRow,ION_COL_COLOUR);
@@ -641,12 +626,12 @@ void RangeEditorDialog::generateIonEntries(size_t rowVisibleHint)
for(size_t ui=0;ui<incompleteIons.size();ui++)
{
gridIons->SetCellValue(curIonRow,
- ION_COL_PLOT,wxStr(title));
+ ION_COL_PLOT,(title));
gridIons->SetCellValue(curIonRow,
- ION_COL_SHORTNAME,wxStr(incompleteIons[ui].getShortName()));
+ ION_COL_SHORTNAME,(incompleteIons[ui].getShortName()));
gridIons->SetCellValue(curIonRow,
- ION_COL_LONGNAME,wxStr(incompleteIons[ui].getLongName()));
+ ION_COL_LONGNAME,(incompleteIons[ui].getLongName()));
//set the colour
wxGridCellAttr *attr = gridIons->GetOrCreateCellAttr(curIonRow,ION_COL_COLOUR);
@@ -706,10 +691,10 @@ void RangeEditorDialog::generateRangeEntries(size_t rowVisibleHint)
gridRanges->DeleteRows(0,gridRanges->GetNumberRows());
gridRanges->AppendCols(4);
- gridRanges->SetColLabelValue(0,wxTRANS("Plot"));
- gridRanges->SetColLabelValue(1,wxTRANS("Ion"));
- gridRanges->SetColLabelValue(2,wxTRANS("Start"));
- gridRanges->SetColLabelValue(3,wxTRANS("End"));
+ gridRanges->SetColLabelValue(0,TRANS("Plot"));
+ gridRanges->SetColLabelValue(1,TRANS("Ion"));
+ gridRanges->SetColLabelValue(2,TRANS("Start"));
+ gridRanges->SetColLabelValue(3,TRANS("End"));
//---
gridRangeIds.clear();
@@ -730,7 +715,7 @@ void RangeEditorDialog::generateRangeEntries(size_t rowVisibleHint)
wxColour incomplColour;
//A light blue colour
incomplColour.Set(162,162,255);
- std::wstring title;
+ std::string title;
title=plotWrap.getTitle(curPlot);
//Fill in the range grid
@@ -745,14 +730,14 @@ void RangeEditorDialog::generateRangeEntries(size_t rowVisibleHint)
std::string ionName;
ionName=currentRange->getName(currentRange->getIonID((unsigned int)ui));
- gridRanges->SetCellValue(curRangeRow,RNG_COL_PLOT,wxStr(title));
- gridRanges->SetCellValue(curRangeRow,RNG_COL_PARENT_ION,wxStr(ionName));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_PLOT,(title));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_PARENT_ION,(ionName));
std::string tmpStr;
stream_cast(tmpStr,rangeBound.first);
- gridRanges->SetCellValue(curRangeRow,RNG_COL_START,wxStr(tmpStr));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_START,(tmpStr));
stream_cast(tmpStr,rangeBound.second);
- gridRanges->SetCellValue(curRangeRow,RNG_COL_END,wxStr(tmpStr));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_END,(tmpStr));
curRangeRow++;
}
@@ -769,14 +754,14 @@ void RangeEditorDialog::generateRangeEntries(size_t rowVisibleHint)
std::string ionName;
ionName=incompleteRanges[ui].getIonName();
- gridRanges->SetCellValue(curRangeRow,RNG_COL_PLOT,wxStr(title));
- gridRanges->SetCellValue(curRangeRow,RNG_COL_PARENT_ION,wxStr(ionName));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_PLOT,(title));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_PARENT_ION,(ionName));
std::string tmpStr;
stream_cast(tmpStr,incompleteRanges[ui].getStart());
- gridRanges->SetCellValue(curRangeRow,RNG_COL_START,wxStr(tmpStr));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_START,(tmpStr));
stream_cast(tmpStr,incompleteRanges[ui].getEnd());
- gridRanges->SetCellValue(curRangeRow,RNG_COL_END,wxStr(tmpStr));
+ gridRanges->SetCellValue(curRangeRow,RNG_COL_END,(tmpStr));
for(size_t uj=0;uj<RNG_COL_ENUM_END; uj++)
gridRanges->SetCellBackgroundColour(curRangeRow,uj,incomplColour);
@@ -1268,16 +1253,11 @@ void RangeEditorDialog::OnBtnRangeIonAdd(wxCommandEvent &event)
!gridRanges->GetNumberRows() || !gridIons->GetNumberRows())
{
wxArrayString wxStrs;
- wxStrs.Add(wxCStr("Ion"));
- wxStrs.Add(wxCStr("Range"));
-
-#if wxCHECK_VERSION(2, 9, 0)
- wxSingleChoiceDialog *wxD = new wxSingleChoiceDialog(this, wxTRANS("Range or ion?"),
- wxTRANS("Select type to add"),wxStrs,(void **)NULL,wxDEFAULT_DIALOG_STYLE|wxOK|wxCENTRE);
-#else
- wxSingleChoiceDialog *wxD = new wxSingleChoiceDialog(this, wxTRANS("Range or ion?"),
- wxTRANS("Select type to add"),wxStrs,NULL,wxDEFAULT_DIALOG_STYLE|wxOK|wxCENTRE);
-#endif
+ wxStrs.Add(("Ion"));
+ wxStrs.Add(("Range"));
+
+ wxSingleChoiceDialog *wxD = new wxSingleChoiceDialog(this, TRANS("Range or ion?"),
+ TRANS("Select type to add"),wxStrs,(void **)NULL,wxDEFAULT_DIALOG_STYLE|wxOK|wxCENTRE);
wxD->ShowModal();
@@ -1438,7 +1418,7 @@ void RangeEditorDialog::OnListOverlayKeyDown(wxListEvent &event)
plotPanel->Refresh();
}
-void RangeEditorDialog::OnSashVerticalUnsplit(wxSplitterEvent &event)
+void RangeEditorDialog::OnSashVerticalDClick(wxSplitterEvent &event)
{
event.Veto();
}
@@ -1558,16 +1538,16 @@ void RangeEditorDialog::OnTextOverlayEnter(wxCommandEvent &event)
void RangeEditorDialog::set_properties()
{
// begin wxGlade: RangeEditorDialog::set_properties
- SetTitle(wxTRANS("Range Editor"));
+ SetTitle(TRANS("Range Editor"));
gridRanges->CreateGrid(0, 3);
gridIons->CreateGrid(0, 3);
- checkShowOverlay->SetToolTip(wxTRANS("Enable or disable all overlays"));
- listOverlay->SetToolTip(wxTRANS("Entered overlays, use delete to remove"));
- listPlots->SetToolTip(wxTRANS("Available plots for ranging"));
- textOverlayCmpnt->SetToolTip(wxTRANS("Enter species to display as overlay, e.g. SiO2"));
- gridRanges->SetToolTip(wxTRANS("Editable ranges"));
- gridIons->SetToolTip(wxTRANS("Editable ions"));
+ checkShowOverlay->SetToolTip(TRANS("Enable or disable all overlays"));
+ listOverlay->SetToolTip(TRANS("Entered overlays, use delete to remove"));
+ listPlots->SetToolTip(TRANS("Available plots for ranging"));
+ textOverlayCmpnt->SetToolTip(TRANS("Enter species to display as overlay, e.g. SiO2"));
+ gridRanges->SetToolTip(TRANS("Editable ranges"));
+ gridIons->SetToolTip(TRANS("Editable ions"));
// end wxGlade
}
@@ -1602,9 +1582,9 @@ void RangeEditorDialog::do_layout()
sizerOverlay->Add(sizerOverlayContainer, 1, wxEXPAND, 0);
sizerOverlayPane->Add(sizerOverlay, 1, wxEXPAND, 0);
noteLeftOverlay->SetSizer(sizerOverlayPane);
- notebookLeft->AddPage(noteLeftPlots, wxTRANS("Plots"));
- notebookLeft->AddPage(noteLeftRanges, wxTRANS("Ranges"));
- notebookLeft->AddPage(noteLeftOverlay, wxTRANS("Overlay"));
+ notebookLeft->AddPage(noteLeftPlots, TRANS("Plots"));
+ notebookLeft->AddPage(noteLeftRanges, TRANS("Ranges"));
+ notebookLeft->AddPage(noteLeftOverlay, TRANS("Overlay"));
sizerNote->Add(notebookLeft, 1, wxEXPAND, 0);
panelSplitLeft->SetSizer(sizerNote);
sizerRight->Add(plotPanel, 1, wxEXPAND, 0);
diff --git a/src/gui/dialogs/rangeEditDialog.h b/src/gui/dialogs/rangeEditDialog.h
index c7a09fc..94c30ea 100644
--- a/src/gui/dialogs/rangeEditDialog.h
+++ b/src/gui/dialogs/rangeEditDialog.h
@@ -210,7 +210,7 @@ public:
virtual void OnCheckShowOverlay(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnBtnOK(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnBtnCancel(wxCommandEvent &event); // wxGlade: <event_handler>
- virtual void OnSashVerticalUnsplit(wxSplitterEvent &event); // wxGlade: <event_handler>
+ virtual void OnSashVerticalDClick(wxSplitterEvent &event); // wxGlade: <event_handler>
virtual void OnListOverlayCheck(wxCommandEvent &event);
virtual void OnListOverlayKeyDown(wxListEvent &event);
virtual void OnTextOverlay(wxCommandEvent &event);
diff --git a/src/gui/dialogs/resolutionDialog.cpp b/src/gui/dialogs/resolutionDialog.cpp
index 6b8631b..da66edd 100644
--- a/src/gui/dialogs/resolutionDialog.cpp
+++ b/src/gui/dialogs/resolutionDialog.cpp
@@ -42,26 +42,17 @@ ResolutionDialog::ResolutionDialog(wxWindow* parent, int id, const wxString& tit
wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
{
// begin wxGlade: ResolutionDialog::ResolutionDialog
- labelWidth = new wxStaticText(this, wxID_ANY, wxTRANS("Width :"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+ labelWidth = new wxStaticText(this, wxID_ANY, TRANS("Width :"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
textWidth = new wxTextCtrl(this, ID_TEXT_WIDTH, wxT(""));
- labelHeight = new wxStaticText(this, wxID_ANY, wxTRANS("Height :"));
+ labelHeight = new wxStaticText(this, wxID_ANY, TRANS("Height :"));
textHeight = new wxTextCtrl(this, ID_TEXT_HEIGHT, wxT(""));
static_line_2 = new wxStaticLine(this, wxID_ANY);
- btnReset = new wxButton(this, ID_RESET, wxTRANS("Reset"));
+ btnReset = new wxButton(this, ID_RESET, TRANS("Reset"));
btnOK = new wxButton(this, wxID_OK, wxEmptyString);
button_2 = new wxButton(this, wxID_CANCEL, wxEmptyString);
-#if wxCHECK_VERSION(2, 9, 0)
textWidth->Bind(wxEVT_MOUSEWHEEL, &ResolutionDialog::OnMouseWheelWidth, this);
textHeight->Bind(wxEVT_MOUSEWHEEL, &ResolutionDialog::OnMouseWheelHeight, this);
-#else
- textWidth->Connect(wxID_ANY, wxEVT_MOUSEWHEEL,
- wxMouseEventHandler(ResolutionDialog::OnMouseWheelWidth),NULL,this);
- textHeight->Connect(wxID_ANY, wxEVT_MOUSEWHEEL,
- wxMouseEventHandler(ResolutionDialog::OnMouseWheelHeight),NULL,this);
-#endif
-
-
set_properties();
do_layout();
@@ -99,10 +90,10 @@ void ResolutionDialog::setRes(unsigned int w, unsigned int h, bool asReset)
std::string s;
stream_cast(s,w);
- textWidth->SetValue(wxStr(s));
+ textWidth->SetValue((s));
stream_cast(s,h);
- textHeight->SetValue(wxStr(s));
+ textHeight->SetValue((s));
resWidth=w;
resHeight=h;
@@ -136,7 +127,7 @@ void ResolutionDialog::OnTextWidth(wxCommandEvent &event)
if(textStr.find_first_not_of("0123456789")!=std::string::npos )
{
stream_cast(textStr,resWidth);
- textWidth->SetValue(wxStr(textStr));
+ textWidth->SetValue((textStr));
programmaticEvent--;
return;
}
@@ -158,7 +149,7 @@ void ResolutionDialog::OnTextWidth(wxCommandEvent &event)
resHeight=(unsigned int)(width*aspect);
stream_cast(textStr,resHeight);
- textHeight->SetValue(wxStr(textStr));
+ textHeight->SetValue((textStr));
updateImage();
@@ -183,7 +174,7 @@ void ResolutionDialog::OnTextHeight(wxCommandEvent &event)
if(textStr.find_first_not_of("0123456789")!=std::string::npos )
{
stream_cast(textStr,resHeight);
- textHeight->SetValue(wxStr(textStr));
+ textHeight->SetValue((textStr));
programmaticEvent--;
return;
}
@@ -206,7 +197,7 @@ void ResolutionDialog::OnTextHeight(wxCommandEvent &event)
resWidth=(unsigned int)(height/aspect);
stream_cast(textStr,resWidth);
- textWidth->SetValue(wxStr(textStr));
+ textWidth->SetValue((textStr));
updateImage();
@@ -268,7 +259,7 @@ void ResolutionDialog::OnMouseWheelWidth(wxMouseEvent &event)
std::string textStr;
resHeight=(unsigned int)(resWidth*aspect);
stream_cast(textStr,resHeight);
- textHeight->SetValue(wxStr(textStr));
+ textHeight->SetValue((textStr));
updateImage();
programmaticEvent--;
@@ -313,7 +304,7 @@ void ResolutionDialog::OnMouseWheelHeight(wxMouseEvent &event)
std::string textStr;
resWidth=(unsigned int)(resHeight/aspect);
stream_cast(textStr,resWidth);
- textWidth->SetValue(wxStr(textStr));
+ textWidth->SetValue((textStr));
updateImage();
programmaticEvent--;
@@ -334,20 +325,15 @@ void ResolutionDialog::finishDialog()
//programmatic event counter should be decremented to zero
ASSERT(!programmaticEvent);
-#if wxCHECK_VERSION(2, 9, 0)
- textWidth->Unbind(wxEVT_MOUSEWHEEL, &ResolutionDialog::OnMouseWheelWidth, this);
- textHeight->Unbind(wxEVT_MOUSEWHEEL, &ResolutionDialog::OnMouseWheelHeight, this);
-#else
- textWidth->Disconnect();
- textHeight->Disconnect();
-#endif
+ textWidth->Unbind(wxEVT_MOUSEWHEEL, &ResolutionDialog::OnMouseWheelWidth, this);
+ textHeight->Unbind(wxEVT_MOUSEWHEEL, &ResolutionDialog::OnMouseWheelHeight, this);
EndModal(wxID_OK);
}
void ResolutionDialog::set_properties()
{
// begin wxGlade: ResolutionDialog::set_properties
- SetTitle(wxTRANS("Resolution Selection"));
+ SetTitle(TRANS("Resolution Selection"));
// end wxGlade
}
diff --git a/src/gui/glPane.cpp b/src/gui/glPane.cpp
index 030241d..8f66c3f 100644
--- a/src/gui/glPane.cpp
+++ b/src/gui/glPane.cpp
@@ -23,7 +23,6 @@
#include "common/stringFuncs.h"
#include "gl/select.h"
-#include "gl/tr.h"
#include "glPane.h"
@@ -67,7 +66,6 @@ EVT_RIGHT_DOWN(BasicGLPane::mouseDown)
EVT_LEAVE_WINDOW(BasicGLPane::mouseLeftWindow)
EVT_SIZE(BasicGLPane::resized)
EVT_KEY_DOWN(BasicGLPane::keyPressed)
-EVT_CHAR(BasicGLPane::charEvent)
EVT_KEY_UP(BasicGLPane::keyReleased)
EVT_MOUSEWHEEL(BasicGLPane::mouseWheelMoved)
EVT_PAINT(BasicGLPane::render)
@@ -89,12 +87,7 @@ int attribList[] = {WX_GL_RGBA,
1,
0,0};
-BasicGLPane::BasicGLPane(wxWindow* parent) :
-#if wxCHECK_VERSION(2,9,0)
-wxGLCanvas(parent, wxID_ANY, attribList)
-#else
-wxGLCanvas(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"),attribList)
-#endif
+BasicGLPane::BasicGLPane(wxWindow* parent) : wxGLCanvas(parent, wxID_ANY, attribList)
{
haveCameraUpdates=false;
applyingDevice=false;
@@ -102,9 +95,7 @@ wxGLCanvas(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas
keyDoubleTapTimer=new wxTimer(this,ID_KEYPRESS_TIMER);
lastKeyDoubleTap=(unsigned int)-1;
-#if wxCHECK_VERSION(2,9,0)
context=0;
-#endif
mouseMoveFactor=mouseZoomFactor=1.0f;
dragging=false;
@@ -121,15 +112,7 @@ BasicGLPane::~BasicGLPane()
bool BasicGLPane::displaySupported() const
{
-#if wxCHECK_VERSION(2,9,0)
return IsDisplaySupported(attribList);
-#else
- ASSERT(false);
- //Lets hope so. If its not, then its just going to fail anyway.
- //If it is, then returning false would simply create a roadblock.
- //Either way, you shouldn't get here.
- return true;
-#endif
}
void BasicGLPane::setSceneInteractionAllowed(bool enabled)
@@ -226,16 +209,6 @@ void BasicGLPane::forceRedraw()
wxPaintEvent ptEvent;
wxPostEvent(this,ptEvent);
- //Hack to fix panel redraw commands not working under windows
- //--
-#if defined(__WIN32) || defined(__WIN64)
- wxYield();
-
- Hide();
- Show();
-
-#endif
- //--
}
// some useful events to use
@@ -271,21 +244,13 @@ void BasicGLPane::mouseMoved(wxMouseEvent& event)
if(wxm.ShiftDown())
keyFlags|=FLAG_SHIFT;
-#if wxCHECK_VERSION(2,9,0)
if(wxm.LeftIsDown())
mouseFlags|= SELECT_BUTTON_LEFT;
if(wxm.RightIsDown())
mouseFlags|= SELECT_BUTTON_RIGHT;
if(wxm.MiddleIsDown())
mouseFlags|= SELECT_BUTTON_MIDDLE;
-#else
- if(wxm.LeftDown())
- mouseFlags|= SELECT_BUTTON_LEFT;
- if(wxm.RightDown())
- mouseFlags|= SELECT_BUTTON_RIGHT;
- if(wxm.MiddleDown())
- mouseFlags|= SELECT_BUTTON_MIDDLE;
-#endif
+
//We can get a mouse move event which reports no buttons before a mouse-up event,
//this occurs frequently under windows, but sometimes under GTK
if(!mouseFlags)
@@ -465,7 +430,6 @@ void BasicGLPane::mouseDown(wxMouseEvent& event)
Refresh();
}
- event.Skip();
}
void BasicGLPane::mouseWheelMoved(wxMouseEvent& event)
@@ -489,7 +453,6 @@ void BasicGLPane::mouseWheelMoved(wxMouseEvent& event)
haveCameraUpdates=true;
Refresh();
- event.Skip();
}
void BasicGLPane::mouseReleased(wxMouseEvent& event)
@@ -540,7 +503,6 @@ void BasicGLPane::mouseReleased(wxMouseEvent& event)
dragging=false;
Refresh();
- event.Skip();
}
@@ -582,7 +544,6 @@ void BasicGLPane::mouseLeftWindow(wxMouseEvent& event)
dragging=false;
}
}
- event.Skip();
}
void BasicGLPane::keyPressed(wxKeyEvent& event)
@@ -600,11 +561,7 @@ void BasicGLPane::keyPressed(wxKeyEvent& event)
// needs to be control in apple as cmd-space open spotlight
unsigned int keyMask;
#ifdef __APPLE__
- #if wxCHECK_VERSION(2,9,0)
keyMask = (event.RawControlDown() ? 1 : 0);
- #else
- keyMask = (event.ControlDown() ? 1 : 0);
- #endif
#else
keyMask = (event.CmdDown() ? 1 : 0);
#endif
@@ -667,7 +624,7 @@ void BasicGLPane::keyPressed(wxKeyEvent& event)
currentScene.ensureVisible(visibleDir);
- parentStatusBar->SetStatusText(wxTRANS("Use shift/ctrl-space or double tap to alter reset axis"));
+ parentStatusBar->SetStatusText(TRANS("Use shift/ctrl-space or double tap to alter reset axis"));
parentStatusBar->SetBackgroundColour(*wxCYAN)
;
parentStatusTimer->Start(statusDelay,wxTIMER_ONE_SHOT);
@@ -676,8 +633,9 @@ void BasicGLPane::keyPressed(wxKeyEvent& event)
}
}
break;
+ default:
+ event.Skip();
}
- event.Skip();
}
void BasicGLPane::setGlClearColour(float r, float g, float b)
@@ -728,24 +686,15 @@ void BasicGLPane::keyReleased(wxKeyEvent& event)
break;
}
default:
- ;
+ event.Skip();
}
Refresh();
- event.Skip();
}
-void BasicGLPane::charEvent(wxKeyEvent& event)
-{
-
-}
-
void BasicGLPane::resized(wxSizeEvent& evt)
{
-#if !wxCHECK_VERSION(2,9,0)
- wxGLCanvas::OnSize(evt);
-#endif
prepare3DViewport(0,0,getWidth(),getHeight());
wxClientDC *dc=new wxClientDC(this);
Refresh();
@@ -810,15 +759,12 @@ void BasicGLPane::render( wxPaintEvent& evt )
if (!IsShown())
return;
-#if wxCHECK_VERSION(2,9,0)
if(!context)
{
context = new wxGLContext(this);
SetCurrent(*context);
}
-#else
- wxGLCanvas::SetCurrent();
-#endif
+
if(!paneInitialised)
{
paneInitialised=true;
@@ -848,6 +794,28 @@ void BasicGLPane::updateClearColour()
bClear,1.0f);
}
+TRcontext *BasicGLPane::generateTileContext(unsigned int width, unsigned int height, unsigned char *imageBuffer, bool alpha) const
+{
+ int panelWidth,panelHeight;
+ GetClientSize(&panelWidth,&panelHeight);
+
+ //Create TR library tile context
+ TRcontext *tr = trNew();
+ //Tile size
+ trTileSize(tr,panelWidth,panelHeight,0);
+ //Set overall image size
+ trImageSize(tr, width, height);
+ //Set buffer for overall image
+ if(alpha)
+ trImageBuffer(tr, GL_RGBA, GL_UNSIGNED_BYTE, imageBuffer);
+ else
+ trImageBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, imageBuffer);
+ //Set the row order for the image
+ trRowOrder(tr, TR_BOTTOM_TO_TOP);
+
+ return tr;
+}
+
bool BasicGLPane::saveImage(unsigned int width, unsigned int height,
const char *filename, bool showProgress, bool needPostPaint)
{
@@ -863,33 +831,29 @@ bool BasicGLPane::saveImage(unsigned int width, unsigned int height,
//create new image
wxImage *image = new wxImage(width,height);
- //We cannot seem to draw outside the current viewport.
- //in a cross platform manner.
- //fall back to stitching the image together by hand
- int panelWidth,panelHeight;
- GetClientSize(&panelWidth,&panelHeight);
unsigned char *imageBuffer= (unsigned char*) malloc(3*(width)*height);
+ if(!imageBuffer)
+ return false;
+
glLoadIdentity();
- //Create TR library tile context
- TRcontext *tr = trNew();
const Camera *cm = currentScene.getActiveCam();
- //Initialise tile data
- {
- //Tile size
- trTileSize(tr,panelWidth,panelHeight,0);
- //Set overall image size
- trImageSize(tr, width, height);
- //Set buffer for overall image
- trImageBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, imageBuffer);
- //Set the row order for the image
- trRowOrder(tr, TR_BOTTOM_TO_TOP);
+ //We cannot seem to draw outside the current viewport.
+ //in a cross platform manner.
+ //fall back to stitching the image together by hand
+ //Initialise tile data
+ TRcontext *tr;
//Inform the tiling system about our camera config
+ float farPlane;
+ float aspect=currentScene.getAspect();
+
+ {
+ tr=generateTileContext(width,height, imageBuffer);
BoundCube bc = currentScene.getBound();
- float farPlane = 1.5*bc.getMaxDistanceToBox(cm->getOrigin());
+ farPlane = 1.5*bc.getMaxDistanceToBox(cm->getOrigin());
if(cm->getProjectionMode() == PROJECTION_MODE_PERSPECTIVE)
{
@@ -907,69 +871,86 @@ bool BasicGLPane::saveImage(unsigned int width, unsigned int height,
}
else
{
- float aspect=currentScene.getAspect();
- float orthoScale=cm->getOrthoScale();
+ float orthoScale = cm->getOrthoScale();
trOrtho(tr,-orthoScale*aspect,orthoScale*aspect,
-orthoScale,orthoScale,0.0f,farPlane);
}
}
-
- //Obtain tile count
- unsigned int nRow,nCol;
+ //Obtain tile count from the renderer & init progress
+ //--
+ unsigned int totalTiles;
+ {
+ unsigned int nRow,nCol,nPass;
nRow=trGet(tr,TR_ROWS);
nCol=trGet(tr,TR_COLUMNS);
+ if(currentScene.hasOverlays())
+ nPass = 2;
+ else
+ nPass=1;
- wxProgressDialog *wxD=0;
-
+ totalTiles=nRow*nCol*nPass;
+ }
- //Only show progress for multiple tiles
- std::string tmpStr,tmpStrTwo;
- stream_cast(tmpStrTwo,nRow*nCol);
-
- showProgress=showProgress && ( nRow*nCol > 1);
+ wxProgressDialog *wxD=0;
+ showProgress=showProgress && ( totalTiles > 1);
if(showProgress)
{
- wxD = new wxProgressDialog(wxTRANS("Image progress"),
- wxTRANS("Rendering tiles..."), nRow*nCol);
+ wxD = new wxProgressDialog(TRANS("Image progress"),
+ TRANS("Rendering tiles..."), totalTiles);
- wxD->Show();
}
+ //--
+
+
+ //We have to do two passes. First we have to
+ // do a 3D pass, then we have to separately
+ // draw the overlays.
+
+ // As we have 2 cameras, one for the normal scene
+ // and one for the overlay, we build the images,
+ // then merge the images, rather than trying to composite the entire scene in situ.
+
+ //PASS 1:
+ //--------------
//HACK: Flip the all but scene's light z coordinate
// for some reason, the frustrum has an inversion
// somwhere in the coordinate system, and I can't find it!
// inverting the tile frustrum ends up with the depth test
// also inverting.
+ const bool FLIP_LIGHT_HACK=true;
+ //x,y,z and w axis.
+ const bool IMPORTANT_AXIS[4]={true,false,true,false};
+
+ //opengl lighthas 4
float oldLightPos[4];
- currentScene.getLightPos(oldLightPos);
- const int UNTRANS_AXIS=2;
- for(size_t ui=0;ui<3;ui++)
+ if(FLIP_LIGHT_HACK)
{
- if(ui == UNTRANS_AXIS)
- continue;
-
- oldLightPos[ui]=-oldLightPos[ui];
-
+ currentScene.getLightPos(oldLightPos);
+ float newLightPos[4];
+ for(size_t ui=0;ui<4;ui++)
+ {
+ if(IMPORTANT_AXIS[ui])
+ newLightPos[ui]=oldLightPos[ui];
+ else
+ newLightPos[ui]=-oldLightPos[ui];
+
+ }
+ currentScene.setLightPos(newLightPos);
}
- currentScene.setLightPos(oldLightPos);
+ if(showProgress)
+ wxD->Show();
- //Loop through the tiles
+ //Loop through the tiles/
+ // note that 2D overlays will not be drawn in this pass
unsigned int thisTileNum=0;
int haveMoreTiles=1;
while(haveMoreTiles)
{
-
-
thisTileNum++;
- //tell user which image tile we are making from the total image
- stream_cast(tmpStr,thisTileNum);
- tmpStr = std::string(TRANS("Tile ")) + tmpStr + std::string(TRANS(" of ")) + tmpStrTwo + "...";
- //Update progress bar, if required
- if(showProgress)
- wxD->Update(thisTileNum,wxStr(tmpStr));
//Manually set the camera
//--
@@ -987,32 +968,97 @@ bool BasicGLPane::saveImage(unsigned int width, unsigned int height,
glPopMatrix();
+ //ending the tile copies
+ // data
haveMoreTiles=trEndTile(tr);
+
+ if(showProgress)
+ wxD->Update(thisTileNum);
}
- //re-set light coordinates
- for(size_t ui=0;ui<3;ui++)
+ if(FLIP_LIGHT_HACK)
{
- if (ui == UNTRANS_AXIS)
- continue;
- oldLightPos[ui]=-oldLightPos[ui];
+ //re-set light coordinates
+ currentScene.setLightPos(oldLightPos);
}
- currentScene.setLightPos(oldLightPos);
- if(showProgress)
- wxD->Destroy();
trDelete(tr);
//Transfer pointer to image, which will perform free-ing of the buffer
image->SetData(imageBuffer);
-
//HACK : Tiling function returns upside-down image. Fix in post-process
// argument is to set mirror axis such that x axis is unchanged
*image=image->Mirror(false);
+ //--------------
+
+ //PASS 2
+ //--------------
+
+ if(currentScene.hasOverlays())
+ {
+ //alllocate RGBA (4-channel) image
+ imageBuffer= (unsigned char*) malloc(4*(width)*height);
+ if(!imageBuffer)
+ return false;
+
+
+ tr=generateTileContext(width,height,imageBuffer,true);
+ trOrtho(tr,0.0f,aspect,
+ 0.0f,1.0f,-1.0f,1.0f);
+
+
+ haveMoreTiles=1;
+
+
+ float rClear,gClear,bClear;
+ currentScene.getBackgroundColour(rClear,gClear,bClear);
+ glClearColor( rClear, gClear,
+ bClear,0.0f);
+
+ //I am unclear why, but the faces are reversed
+ glDisable(GL_CULL_FACE);
+ while(haveMoreTiles)
+ {
+ thisTileNum++;
+ //Start the tile
+ trBeginTile(tr);
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ currentScene.drawOverlays(true);
+ //ending the tile copies
+ // data
+ haveMoreTiles=trEndTile(tr);
+
+ if(showProgress)
+ wxD->Update(thisTileNum);
+ }
+ glEnable(GL_CULL_FACE);
+ //restore the GL clear colour
+ updateClearColour();
+
+ ///unpack the tile buffer into a wx image
+ wxImage imageOverlay(width,height);
+ imageOverlay.InitAlpha();
+
+ //FIXME: HACK - using "blue screen" effect
+ //don't use background as mask colour.
+ // use depth buffer or gl alpha
+ unsigned char mask[3] = {(unsigned char)rClear*255.0f,
+ (unsigned char)gClear*255.0f,(unsigned char)bClear*255.0f};
+ copyRGBAtoWXImage(width,height,imageBuffer,imageOverlay,mask);
+
+ free(imageBuffer);
+
+ combineWxImage(*image,imageOverlay);
+ }
+
+ //--------------
+ bool isOK=image->SaveFile(filename,wxBITMAP_TYPE_PNG);
- bool isOK=image->SaveFile(wxCStr(filename),wxBITMAP_TYPE_PNG);
+ if(showProgress)
+ wxD->Destroy();
+
delete image;
if (needPostPaint) {
@@ -1038,8 +1084,8 @@ bool BasicGLPane::saveImageSequence(unsigned int resX, unsigned int resY, unsign
ASSERT(!currentScene.haveTempCam());
std::string outFile;
- wxProgressDialog *wxD = new wxProgressDialog(wxTRANS("Animation progress"),
- wxTRANS("Rendering sequence..."), nFrames,this,wxPD_CAN_ABORT|wxPD_APP_MODAL );
+ wxProgressDialog *wxD = new wxProgressDialog(TRANS("Animation progress"),
+ TRANS("Rendering sequence..."), nFrames,this,wxPD_CAN_ABORT|wxPD_APP_MODAL );
wxD->Show();
std::string tmpStr,tmpStrTwo;
@@ -1078,7 +1124,7 @@ bool BasicGLPane::saveImageSequence(unsigned int resX, unsigned int resY, unsign
stream_cast(tmpStr,ui+1);
//Tell user which image from the animation we are saving
tmpStr = std::string(TRANS("Saving Image ")) + tmpStr + std::string(TRANS(" of ")) + tmpStrTwo + "...";
- if(!wxD->Update(ui,wxStr(tmpStr)))
+ if(!wxD->Update(ui,tmpStr))
break;
Refresh();
diff --git a/src/gui/glPane.h b/src/gui/glPane.h
index 5499d9e..aca3737 100644
--- a/src/gui/glPane.h
+++ b/src/gui/glPane.h
@@ -20,6 +20,7 @@
#include "gl/scene.h"
+#include "gl/tr.h"
#include <wx/glcanvas.h>
#include <wx/timer.h>
@@ -29,9 +30,7 @@ class BasicGLPane : public wxGLCanvas
{
private:
-#if wxCHECK_VERSION(2,9,0)
wxGLContext *context;
-#endif
wxStatusBar *parentStatusBar;
wxTimer *parentStatusTimer;
@@ -76,6 +75,12 @@ private:
unsigned int lastKeyDoubleTap;
wxTimer *keyDoubleTapTimer;
+
+ //build a TR tile context to allow drawing the image in chunks.
+ // width and height are the output image size.
+ // wantAlpha is used if we want to retrieve the alpha (transpar.) channel
+ TRcontext *generateTileContext(unsigned int width, unsigned int height,
+ unsigned char *buffer, bool wantAlpha=false) const;
public:
bool displaySupported() const;
diff --git a/src/gui/glade-skeleton/animateFilterDialog.wxg b/src/gui/glade-skeleton/animateFilterDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/animateSubDialogs/choiceKeyFrameDialog.wxg b/src/gui/glade-skeleton/animateSubDialogs/choiceKeyFrameDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/animateSubDialogs/colourChooserDialog.wxg b/src/gui/glade-skeleton/animateSubDialogs/colourChooserDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/animateSubDialogs/realKeyFrameDialog.wxg b/src/gui/glade-skeleton/animateSubDialogs/realKeyFrameDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/animateSubDialogs/stringKeyFrameDialog.wxg b/src/gui/glade-skeleton/animateSubDialogs/stringKeyFrameDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/autosaveDialog.wxg b/src/gui/glade-skeleton/autosaveDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/errorDialog.wxg b/src/gui/glade-skeleton/errorDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/mainWindow.wxg b/src/gui/glade-skeleton/mainWindow.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/preferencesDialog.wxg b/src/gui/glade-skeleton/preferencesDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/glade-skeleton/resDialog.wxg b/src/gui/glade-skeleton/resDialog.wxg
old mode 100755
new mode 100644
diff --git a/src/gui/mainFrame.cpp b/src/gui/mainFrame.cpp
index fbe36f9..ea4aab7 100644
--- a/src/gui/mainFrame.cpp
+++ b/src/gui/mainFrame.cpp
@@ -1,4 +1,20 @@
+/*
+ * mainFrame.cpp - Main 3Depict window
+ * Copyright (C) 2014, D Haley
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifdef __APPLE__
//FIXME: workaround for UI layout under apple platform
@@ -32,11 +48,7 @@ enum
#include <wx/stdpaths.h>
#include <wx/tipdlg.h>
-#if wxCHECK_VERSION(2, 9, 0)
- #include <wx/utils.h> // Needed for wxLaunchDefaultApplication
-#else
- #include <wx/mimetype.h> //Needed for GetOpenCommand
-#endif
+#include <wx/utils.h> // Needed for wxLaunchDefaultApplication
//Custom program dialog windows
#include "gui/dialogs/StashDialog.h" //Stash editor
@@ -59,6 +71,8 @@ enum
#include "backend/filters/dataLoad.h"
+#include "wx/propertyGridUpdater.h"
+
using std::pair;
using std::max;
@@ -89,7 +103,13 @@ const float BASELINE_SHIFT_FACTOR=0.0002f;
const char *cameraIntroString=NTRANS("New camera name...");
-const char *stashIntroString=NTRANS("New stash name....");
+const char *stashIntroString=NTRANS("New stash name...");
+#if (defined(__WIN32) || defined(__WIN64))
+//Being non-empty string causes segfault under wine. Don't know why
+const char *ADD_FILTER_TEXT="";
+#else
+const char *ADD_FILTER_TEXT=NTRANS("New Filter...");
+#endif
//Name of autosave state file. MUST end in .xml middle
const char *AUTOSAVE_PREFIX= "autosave.";
@@ -118,7 +138,7 @@ const char * comboFilters_choices[FILTER_DROP_COUNT] =
NTRANS("Spectrum"),
NTRANS("Range File"),
NTRANS("Spat. Analysis"),
- NTRANS("Voxelisation")
+ NTRANS("Voxelisation"),
};
//Mapping between filter ID and combo position
@@ -136,10 +156,11 @@ const unsigned int comboFiltersTypeMapping[FILTER_DROP_COUNT] = {
FILTER_TYPE_SPECTRUMPLOT,
FILTER_TYPE_RANGEFILE,
FILTER_TYPE_SPATIAL_ANALYSIS,
- FILTER_TYPE_VOXELS
+ FILTER_TYPE_VOXELS,
};
//----
+
//Constant identifiers for binding events in wxwidgets "event table"
enum {
@@ -346,12 +367,13 @@ void clearWxTreeImages(wxTreeCtrl *t)
MainWindowFrame::MainWindowFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
wxFrame(parent, id, title, pos, size, style)
{
+ COMPILE_ASSERT( (THREEDEP_ARRAYSIZE(comboFilters_choices) + 1 ) == FILTER_TYPE_ENUM_END);
+
initedOK=false;
plotUpdates=false;
programmaticEvent=false;
fullscreenState=0;
verCheckThread=0;
- lastMessageType=MESSAGE_NONE;
lastProgressData.reset();
//Set up the program icon handler
@@ -400,21 +422,7 @@ MainWindowFrame::MainWindowFrame(wxWindow* parent, int id, const wxString& title
panelTop = new BasicGLPane(splitTopBottom);
-#if wxCHECK_VERSION(2,9,0)
glPanelOK = panelTop->displaySupported();
-#else
- #if defined(__WXGTK20__)
- //I had to work this out by studying the construtor, and then testing simultaneously
- //on a broken and working Gl install. booyah.
- glPanelOK=panelTop->m_glWidget;
- #elif defined(__WIN32) || defined(__WIN64) || defined(__APPLE__)
- //I hope this works. I'm not 100% sure -- I can't seem to reliably break my GL under windows.
- glPanelOK=panelTop->GetContext();
- #else
- //lets just hope it worked.
- glPanelOK=true;
- #endif
-#endif
if(!glPanelOK)
{
@@ -441,106 +449,106 @@ TRANS("Unable to initialise the openGL (3D) panel. Program cannot start. Please
MainFrame_Menu = new wxMenuBar();
fileMenu = new wxMenu();
- fileMenu->Append(ID_FILE_OPEN, wxTRANS("&Open...\tCtrl+O"), wxTRANS("Open state file"), wxITEM_NORMAL);
- fileMenu->Append(ID_FILE_MERGE, wxTRANS("&Merge...\tCtrl+Shift+O"), wxTRANS("Merge other file"), wxITEM_NORMAL);
+ fileMenu->Append(ID_FILE_OPEN, TRANS("&Open...\tCtrl+O"), TRANS("Open state file"), wxITEM_NORMAL);
+ fileMenu->Append(ID_FILE_MERGE, TRANS("&Merge...\tCtrl+Shift+O"), TRANS("Merge other file"), wxITEM_NORMAL);
recentFilesMenu=new wxMenu();
recentHistory->UseMenu(recentFilesMenu);
- fileMenu->AppendSubMenu(recentFilesMenu,wxTRANS("&Recent"));
- fileSave = fileMenu->Append(ID_FILE_SAVE, wxTRANS("&Save\tCtrl+S"), wxTRANS("Save state to file"), wxITEM_NORMAL);
+ fileMenu->AppendSubMenu(recentFilesMenu,TRANS("&Recent"));
+ fileSave = fileMenu->Append(ID_FILE_SAVE, TRANS("&Save\tCtrl+S"), TRANS("Save state to file"), wxITEM_NORMAL);
fileSave->Enable(false);
- fileMenu->Append(ID_FILE_SAVEAS, wxTRANS("Save &As...\tCtrl+Shift+S"), wxTRANS("Save current state to new file"), wxITEM_NORMAL);
+ fileMenu->Append(ID_FILE_SAVEAS, TRANS("Save &As...\tCtrl+Shift+S"), TRANS("Save current state to new file"), wxITEM_NORMAL);
fileMenu->AppendSeparator();
fileExport = new wxMenu();
- fileExport->Append(ID_FILE_EXPORT_PLOT, wxTRANS("&Plot...\tCtrl+P"), wxTRANS("Export Current Plot"), wxITEM_NORMAL);
- fileExport->Append(ID_FILE_EXPORT_IMAGE, wxTRANS("&Image...\tCtrl+I"), wxTRANS("Export Current 3D View"), wxITEM_NORMAL);
- fileExport->Append(ID_FILE_EXPORT_IONS, wxTRANS("Ion&s...\tCtrl+N"), wxTRANS("Export Ion Data"), wxITEM_NORMAL);
- fileExport->Append(ID_FILE_EXPORT_RANGE, wxTRANS("Ran&ges...\tCtrl+G"), wxTRANS("Export Range Data"), wxITEM_NORMAL);
- fileExport->Append(ID_FILE_EXPORT_FILTER_ANIMATION, wxTRANS("&Animate Filters...\tCtrl+A"), wxTRANS("Export Animated Filter"), wxITEM_NORMAL);
- fileExport->Append(ID_FILE_EXPORT_ANIMATION, wxTRANS("Ani&mate Camera...\tCtrl+M"), wxTRANS("Export Animated Camera"), wxITEM_NORMAL);
- fileExport->Append(ID_FILE_EXPORT_PACKAGE, wxTRANS("Pac&kage...\tCtrl+K"), wxTRANS("Export analysis package"), wxITEM_NORMAL);
-
- fileMenu->AppendSubMenu(fileExport,wxTRANS("&Export"));
+ fileExport->Append(ID_FILE_EXPORT_PLOT, TRANS("&Plot...\tCtrl+P"), TRANS("Export Current Plot"), wxITEM_NORMAL);
+ fileExport->Append(ID_FILE_EXPORT_IMAGE, TRANS("&Image...\tCtrl+I"), TRANS("Export Current 3D View"), wxITEM_NORMAL);
+ fileExport->Append(ID_FILE_EXPORT_IONS, TRANS("Ion&s...\tCtrl+N"), TRANS("Export Ion Data"), wxITEM_NORMAL);
+ fileExport->Append(ID_FILE_EXPORT_RANGE, TRANS("Ran&ges...\tCtrl+G"), TRANS("Export Range Data"), wxITEM_NORMAL);
+ fileExport->Append(ID_FILE_EXPORT_FILTER_ANIMATION, TRANS("&Animate Filters...\tCtrl+A"), TRANS("Export Animated Filter"), wxITEM_NORMAL);
+ fileExport->Append(ID_FILE_EXPORT_ANIMATION, TRANS("Ani&mate Camera...\tCtrl+M"), TRANS("Export Animated Camera"), wxITEM_NORMAL);
+ fileExport->Append(ID_FILE_EXPORT_PACKAGE, TRANS("Pac&kage...\tCtrl+K"), TRANS("Export analysis package"), wxITEM_NORMAL);
+
+ fileMenu->AppendSubMenu(fileExport,TRANS("&Export"));
fileMenu->AppendSeparator();
#ifdef __APPLE__
- fileMenu->Append(ID_FILE_EXIT, wxTRANS("&Quit\tCtrl+Q"), wxTRANS("Exit Program"), wxITEM_NORMAL);
+ fileMenu->Append(ID_FILE_EXIT, TRANS("&Quit\tCtrl+Q"), TRANS("Exit Program"), wxITEM_NORMAL);
#else
- fileMenu->Append(ID_FILE_EXIT, wxTRANS("E&xit"), wxTRANS("Exit Program"), wxITEM_NORMAL);
+ fileMenu->Append(ID_FILE_EXIT, TRANS("E&xit"), TRANS("Exit Program"), wxITEM_NORMAL);
#endif
- MainFrame_Menu->Append(fileMenu, wxTRANS("&File"));
+ MainFrame_Menu->Append(fileMenu, TRANS("&File"));
wxMenu* wxglade_tmp_menu_1 = new wxMenu();
wxglade_tmp_menu_1->Append(ID_VIEW_BACKGROUND,
- wxTRANS("&Background Colour...\tCtrl+B"),wxTRANS("Change background colour"));
+ TRANS("&Background Colour...\tCtrl+B"),TRANS("Change background colour"));
wxglade_tmp_menu_1->AppendSeparator(); //Separator
#ifndef __APPLE__
checkMenuControlPane= wxglade_tmp_menu_1->Append(ID_VIEW_CONTROL_PANE,
- wxTRANS("&Control Pane\tF2"), wxTRANS("Toggle left control pane"), wxITEM_CHECK);
+ TRANS("&Control Pane\tF2"), TRANS("Toggle left control pane"), wxITEM_CHECK);
#else
checkMenuControlPane= wxglade_tmp_menu_1->Append(ID_VIEW_CONTROL_PANE,
- wxTRANS("&Control Pane\tAlt+C"), wxTRANS("Toggle left control pane"), wxITEM_CHECK);
+ TRANS("&Control Pane\tAlt+C"), TRANS("Toggle left control pane"), wxITEM_CHECK);
#endif
checkMenuControlPane->Check();
#ifndef __APPLE__
checkMenuRawDataPane= wxglade_tmp_menu_1->Append(ID_VIEW_RAW_DATA_PANE,
- wxTRANS("&Raw Data Pane\tF3"), wxTRANS("Toggle raw data pane (bottom)"), wxITEM_CHECK);
+ TRANS("&Raw Data Pane\tF3"), TRANS("Toggle raw data pane (bottom)"), wxITEM_CHECK);
#else
checkMenuRawDataPane= wxglade_tmp_menu_1->Append(ID_VIEW_RAW_DATA_PANE,
- wxTRANS("&Raw Data Pane\tAlt+R"), wxTRANS("Toggle raw data pane (bottom)"), wxITEM_CHECK);
+ TRANS("&Raw Data Pane\tAlt+R"), TRANS("Toggle raw data pane (bottom)"), wxITEM_CHECK);
#endif
checkMenuRawDataPane->Check();
#ifndef __APPLE__
- checkMenuSpectraList=wxglade_tmp_menu_1->Append(ID_VIEW_SPECTRA, wxTRANS("&Plot List\tF4"),wxTRANS("Toggle plot list"), wxITEM_CHECK);
+ checkMenuSpectraList=wxglade_tmp_menu_1->Append(ID_VIEW_SPECTRA, TRANS("&Plot List\tF4"),TRANS("Toggle plot list"), wxITEM_CHECK);
#else
- checkMenuSpectraList=wxglade_tmp_menu_1->Append(ID_VIEW_SPECTRA, wxTRANS("&Plot List\tAlt+P"),wxTRANS("Toggle plot list"), wxITEM_CHECK);
+ checkMenuSpectraList=wxglade_tmp_menu_1->Append(ID_VIEW_SPECTRA, TRANS("&Plot List\tAlt+P"),TRANS("Toggle plot list"), wxITEM_CHECK);
#endif
checkMenuSpectraList->Check();
wxglade_tmp_menu_1->AppendSeparator(); //Separator
wxMenu* viewPlot= new wxMenu();
- checkViewLegend=viewPlot->Append(ID_VIEW_PLOT_LEGEND,wxTRANS("&Legend\tCtrl+L"),wxTRANS("Toggle Legend display"),wxITEM_CHECK);
+ checkViewLegend=viewPlot->Append(ID_VIEW_PLOT_LEGEND,TRANS("&Legend\tCtrl+L"),TRANS("Toggle Legend display"),wxITEM_CHECK);
checkViewLegend->Check();
- wxglade_tmp_menu_1->AppendSubMenu(viewPlot,wxTRANS("P&lot..."));
- checkViewWorldAxis=wxglade_tmp_menu_1->Append(ID_VIEW_WORLDAXIS,wxTRANS("&Axis\tCtrl+Shift+I"),wxTRANS("Toggle World Axis display"),wxITEM_CHECK);
+ wxglade_tmp_menu_1->AppendSubMenu(viewPlot,TRANS("P&lot..."));
+ checkViewWorldAxis=wxglade_tmp_menu_1->Append(ID_VIEW_WORLDAXIS,TRANS("&Axis\tCtrl+Shift+I"),TRANS("Toggle World Axis display"),wxITEM_CHECK);
checkViewWorldAxis->Check();
wxglade_tmp_menu_1->AppendSeparator(); //Separator
#ifndef __APPLE__
- menuViewFullscreen=wxglade_tmp_menu_1->Append(ID_VIEW_FULLSCREEN, wxTRANS("&Fullscreen mode\tF11"),wxTRANS("Next fullscreen mode: with toolbars"));
+ menuViewFullscreen=wxglade_tmp_menu_1->Append(ID_VIEW_FULLSCREEN, TRANS("&Fullscreen mode\tF11"),TRANS("Next fullscreen mode: with toolbars"));
#else
- menuViewFullscreen=wxglade_tmp_menu_1->Append(ID_VIEW_FULLSCREEN, wxTRANS("&Fullscreen mode\tCtrl+Shift+F"),wxTRANS("Next fullscreen mode: with toolbars"));
+ menuViewFullscreen=wxglade_tmp_menu_1->Append(ID_VIEW_FULLSCREEN, TRANS("&Fullscreen mode\tCtrl+Shift+F"),TRANS("Next fullscreen mode: with toolbars"));
#endif
wxMenu *Edit = new wxMenu();
- editUndoMenuItem = Edit->Append(ID_EDIT_UNDO,wxTRANS("&Undo\tCtrl+Z"));
+ editUndoMenuItem = Edit->Append(ID_EDIT_UNDO,TRANS("&Undo\tCtrl+Z"));
editUndoMenuItem->Enable(false);
- editRedoMenuItem = Edit->Append(ID_EDIT_REDO,wxTRANS("&Redo\tCtrl+Y"));
+ editRedoMenuItem = Edit->Append(ID_EDIT_REDO,TRANS("&Redo\tCtrl+Y"));
editRedoMenuItem->Enable(false);
Edit->AppendSeparator();
- editRangeMenuItem=Edit->Append(ID_EDIT_RANGE,wxTRANS("&Range"));
+ editRangeMenuItem=Edit->Append(ID_EDIT_RANGE,TRANS("&Range"));
editRangeMenuItem->Enable(false);
Edit->AppendSeparator();
- Edit->Append(ID_EDIT_PREFERENCES,wxTRANS("&Preferences"));
+ Edit->Append(ID_EDIT_PREFERENCES,TRANS("&Preferences"));
- MainFrame_Menu->Append(Edit, wxTRANS("&Edit"));
+ MainFrame_Menu->Append(Edit, TRANS("&Edit"));
- MainFrame_Menu->Append(wxglade_tmp_menu_1, wxTRANS("&View"));
+ MainFrame_Menu->Append(wxglade_tmp_menu_1, TRANS("&View"));
wxMenu* Help = new wxMenu();
- Help->Append(ID_HELP_HELP, wxTRANS("&Help...\tCtrl+H"), wxTRANS("Show help files and documentation"), wxITEM_NORMAL);
- Help->Append(ID_HELP_CONTACT, wxTRANS("&Contact..."), wxTRANS("Open contact page"), wxITEM_NORMAL);
+ Help->Append(ID_HELP_HELP, TRANS("&Help...\tCtrl+H"), TRANS("Show help files and documentation"), wxITEM_NORMAL);
+ Help->Append(ID_HELP_CONTACT, TRANS("&Contact..."), TRANS("Open contact page"), wxITEM_NORMAL);
Help->AppendSeparator();
- Help->Append(ID_HELP_ABOUT, wxTRANS("&About..."), wxTRANS("Information about this program"), wxITEM_NORMAL);
- MainFrame_Menu->Append(Help, wxTRANS("&Help"));
+ Help->Append(ID_HELP_ABOUT, TRANS("&About..."), TRANS("Information about this program"), wxITEM_NORMAL);
+ MainFrame_Menu->Append(Help, TRANS("&Help"));
SetMenuBar(MainFrame_Menu);
- lblSettings = new wxStaticText(noteData, wxID_ANY, wxTRANS("Stashed Filters"));
+ lblSettings = new wxStaticText(noteData, wxID_ANY, TRANS("Stashed Filters"));
- comboStash = new wxComboBox(noteData, ID_COMBO_STASH, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN|wxTE_PROCESS_ENTER|SAFE_CB_SORT);
+ comboStash = new wxComboBox(noteData, ID_COMBO_STASH, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN|wxTE_PROCESS_ENTER|wxCB_SORT);
btnStashManage = new wxButton(noteData, ID_BTN_STASH_MANAGE, wxT("..."),wxDefaultPosition,wxSize(28,28));
- filteringLabel = new wxStaticText(noteData, wxID_ANY, wxTRANS("New Filters"));
+ filteringLabel = new wxStaticText(noteData, wxID_ANY, TRANS("New Filters"));
//Workaround for wx bug http://trac.wxwidgets.org/ticket/4398
@@ -554,103 +562,107 @@ TRANS("Unable to initialise the openGL (3D) panel. Program cannot start. Please
//construct translation->comboFilters_choices offset.
filterMap[TRANS(str)] = ui;
//Add to filter name wxArray
- wxString wxStrTrans = wxTRANS(str);
+ wxString wxStrTrans = TRANS(str);
filterNames.Add(wxStrTrans);
}
+
- comboFilters = new wxComboBox(filterTreePane, ID_COMBO_FILTER, wxT(""), wxDefaultPosition, wxDefaultSize, filterNames, wxCB_DROPDOWN|wxCB_READONLY|SAFE_CB_SORT);
-
+ comboFilters = new wxComboBox(filterTreePane, ID_COMBO_FILTER, TRANS(ADD_FILTER_TEXT),
+ wxDefaultPosition, wxDefaultSize, filterNames, wxCB_DROPDOWN|wxCB_SORT);
+ comboFilters->Enable(false);
treeFilters = new TextTreeCtrl(filterTreePane, ID_TREE_FILTERS, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_NO_LINES|wxTR_HIDE_ROOT|wxTR_DEFAULT_STYLE|wxSUNKEN_BORDER|wxTR_EDIT_LABELS);
vector<string> msgs;
msgs.push_back("No data loaded:");
msgs.push_back("open file, then add filters");
treeFilters->setMessages(msgs);
- lastRefreshLabel = new wxStaticText(filterTreePane, wxID_ANY, wxTRANS("Last Outputs"));
+ lastRefreshLabel = new wxStaticText(filterTreePane, wxID_ANY, TRANS("Last Outputs"));
listLastRefresh = new wxListCtrl(filterTreePane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
- checkAutoUpdate = new wxCheckBox(filterTreePane, ID_CHECK_AUTOUPDATE, wxTRANS("Auto Refresh"));
+ checkAutoUpdate = new wxCheckBox(filterTreePane, ID_CHECK_AUTOUPDATE, TRANS("Auto Refresh"));
refreshButton = new wxButton(filterTreePane, wxID_REFRESH, wxEmptyString);
btnFilterTreeExpand= new wxButton(filterTreePane, ID_BTN_EXPAND, wxT("▼"),wxDefaultPosition,wxSize(30,30));
btnFilterTreeCollapse = new wxButton(filterTreePane, ID_BTN_COLLAPSE, wxT("▲"),wxDefaultPosition,wxSize(30,30));
btnFilterTreeErrs = new wxBitmapButton(filterTreePane,ID_BTN_FILTERTREE_ERRS,wxArtProvider::GetBitmap(wxART_INFORMATION),wxDefaultPosition,wxSize(40,40));
- propGridLabel = new wxStaticText(filterPropertyPane, wxID_ANY, wxTRANS("Filter settings"));
- gridFilterPropGroup = new wxCustomPropGrid(filterPropertyPane, ID_GRID_FILTER_PROPERTY);
- labelCameraName = new wxStaticText(noteCamera, wxID_ANY, wxTRANS("Camera Name"));
+ propGridLabel = new wxStaticText(filterPropertyPane, wxID_ANY, TRANS("Filter settings"));
+ gridFilterPropGroup = new wxPropertyGrid(filterPropertyPane, ID_GRID_FILTER_PROPERTY,wxDefaultPosition,wxDefaultSize,PROPERTY_GRID_STYLE);
+ gridFilterPropGroup->SetExtraStyle(PROPERTY_GRID_EXTRA_STYLE);
+ labelCameraName = new wxStaticText(noteCamera, wxID_ANY, TRANS("Camera Name"));
comboCamera = new wxComboBox(noteCamera, ID_COMBO_CAMERA, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN|wxTE_PROCESS_ENTER );
buttonRemoveCam = new wxButton(noteCamera, wxID_REMOVE, wxEmptyString);
cameraNamePropertySepStaticLine = new wxStaticLine(noteCamera, wxID_ANY);
- gridCameraProperties = new wxCustomPropGrid(noteCamera, ID_GRID_CAMERA_PROPERTY);
+ gridCameraProperties = new wxPropertyGrid(noteCamera,ID_GRID_CAMERA_PROPERTY,
+ wxDefaultPosition,wxDefaultSize,PROPERTY_GRID_STYLE);
#ifndef APPLE_EFFECTS_WORKAROUND
- checkPostProcessing = new wxCheckBox(notePost, ID_EFFECT_ENABLE, wxTRANS("3D Post-processing"));
+ checkPostProcessing = new wxCheckBox(notePost, ID_EFFECT_ENABLE, TRANS("3D Post-processing"));
#endif
- checkFxCrop = new wxCheckBox(noteFxPanelCrop, ID_EFFECT_CROP_ENABLE, wxTRANS("Enable Cropping"));
+ checkFxCrop = new wxCheckBox(noteFxPanelCrop, ID_EFFECT_CROP_ENABLE, TRANS("Enable Cropping"));
const wxString comboFxCropAxisOne_choices[] = {
- wxTRANS("x-y"),
- wxTRANS("x-z"),
- wxTRANS("y-x"),
- wxTRANS("y-z"),
- wxTRANS("z-x"),
- wxTRANS("z-y")
+ TRANS("x-y"),
+ TRANS("x-z"),
+ TRANS("y-x"),
+ TRANS("y-z"),
+ TRANS("z-x"),
+ TRANS("z-y")
};
comboFxCropAxisOne = new wxComboBox(noteFxPanelCrop, ID_EFFECT_CROP_AXISONE_COMBO, wxT(""), wxDefaultPosition, wxDefaultSize, 6, comboFxCropAxisOne_choices, wxCB_SIMPLE|wxCB_DROPDOWN|wxCB_READONLY);
panelFxCropOne = new CropPanel(noteFxPanelCrop, ID_EFFECT_CROP_AXISONE_COMBO,
wxDefaultPosition,wxDefaultSize,wxEXPAND);
const wxString comboFxCropAxisTwo_choices[] = {
- wxTRANS("x-y"),
- wxTRANS("x-z"),
- wxTRANS("y-x"),
- wxTRANS("y-z"),
- wxTRANS("z-x"),
- wxTRANS("z-y")
+ TRANS("x-y"),
+ TRANS("x-z"),
+ TRANS("y-x"),
+ TRANS("y-z"),
+ TRANS("z-x"),
+ TRANS("z-y")
};
comboFxCropAxisTwo = new wxComboBox(noteFxPanelCrop, ID_EFFECT_CROP_AXISTWO_COMBO, wxT(""), wxDefaultPosition, wxDefaultSize, 6, comboFxCropAxisTwo_choices, wxCB_SIMPLE|wxCB_DROPDOWN|wxCB_READONLY);
panelFxCropTwo = new CropPanel(noteFxPanelCrop, ID_EFFECT_CROP_AXISTWO_COMBO,wxDefaultPosition,wxDefaultSize,wxEXPAND);
- checkFxCropCameraFrame = new wxCheckBox(noteFxPanelCrop,ID_EFFECT_CROP_CHECK_COORDS,wxTRANS("Use camera coordinates"));
- labelFxCropDx = new wxStaticText(noteFxPanelCrop, wxID_ANY, wxTRANS("dX"));
+ checkFxCropCameraFrame = new wxCheckBox(noteFxPanelCrop,ID_EFFECT_CROP_CHECK_COORDS,TRANS("Use camera coordinates"));
+ labelFxCropDx = new wxStaticText(noteFxPanelCrop, wxID_ANY, TRANS("dX"));
textFxCropDx = new wxTextCtrl(noteFxPanelCrop, ID_EFFECT_CROP_TEXT_DX, wxEmptyString);
- labelFxCropDy = new wxStaticText(noteFxPanelCrop, wxID_ANY, wxTRANS("dY"));
+ labelFxCropDy = new wxStaticText(noteFxPanelCrop, wxID_ANY, TRANS("dY"));
textFxCropDy = new wxTextCtrl(noteFxPanelCrop, ID_EFFECT_CROP_TEXT_DY, wxEmptyString);
- labelFxCropDz = new wxStaticText(noteFxPanelCrop, wxID_ANY, wxTRANS("dZ"));
+ labelFxCropDz = new wxStaticText(noteFxPanelCrop, wxID_ANY, TRANS("dZ"));
textFxCropDz = new wxTextCtrl(noteFxPanelCrop, ID_EFFECT_CROP_TEXT_DZ, wxEmptyString);
- checkFxEnableStereo = new wxCheckBox(noteFxPanelStereo, ID_EFFECT_STEREO_ENABLE, wxTRANS("Enable Anaglyphic Stereo"));
- checkFxStereoLensFlip= new wxCheckBox(noteFxPanelStereo, ID_EFFECT_STEREO_LENSFLIP, wxTRANS("Flip Channels"));
- lblFxStereoMode = new wxStaticText(noteFxPanelStereo, wxID_ANY, wxTRANS("Anaglyph Mode"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+ checkFxEnableStereo = new wxCheckBox(noteFxPanelStereo, ID_EFFECT_STEREO_ENABLE, TRANS("Enable Anaglyphic Stereo"));
+ checkFxStereoLensFlip= new wxCheckBox(noteFxPanelStereo, ID_EFFECT_STEREO_LENSFLIP, TRANS("Flip Channels"));
+ lblFxStereoMode = new wxStaticText(noteFxPanelStereo, wxID_ANY, TRANS("Anaglyph Mode"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
const wxString comboFxStereoMode_choices[] = {
- wxTRANS("Red-Blue"),
- wxTRANS("Red-Green"),
- wxTRANS("Red-Cyan"),
- wxTRANS("Green-Magenta"),
+ TRANS("Red-Blue"),
+ TRANS("Red-Green"),
+ TRANS("Red-Cyan"),
+ TRANS("Green-Magenta"),
};
comboFxStereoMode = new wxComboBox(noteFxPanelStereo, ID_EFFECT_STEREO_COMBO, wxT(""), wxDefaultPosition, wxDefaultSize, 4, comboFxStereoMode_choices, wxCB_DROPDOWN|wxCB_SIMPLE|wxCB_READONLY);
bitmapFxStereoGlasses = new wxStaticBitmap(noteFxPanelStereo, wxID_ANY, wxNullBitmap);
- labelFxStereoBaseline = new wxStaticText(noteFxPanelStereo, wxID_ANY, wxTRANS("Baseline Separation"));
+ labelFxStereoBaseline = new wxStaticText(noteFxPanelStereo, wxID_ANY, TRANS("Baseline Separation"));
sliderFxStereoBaseline = new wxSlider(noteFxPanelStereo,ID_EFFECT_STEREO_BASELINE_SLIDER, 20, 0, 100);
- labelAppearance = new wxStaticText(noteTools, wxID_ANY, wxTRANS("Appearance"));
- checkAlphaBlend = new wxCheckBox(noteTools,ID_CHECK_ALPHA , wxTRANS("Smooth && translucent objects"));
+ labelAppearance = new wxStaticText(noteTools, wxID_ANY, TRANS("Appearance"));
+ checkAlphaBlend = new wxCheckBox(noteTools,ID_CHECK_ALPHA , TRANS("Smooth && translucent objects"));
checkAlphaBlend->SetValue(true);
- checkLighting = new wxCheckBox(noteTools, ID_CHECK_LIGHTING, wxTRANS("3D lighting"));
+ checkLighting = new wxCheckBox(noteTools, ID_CHECK_LIGHTING, TRANS("3D lighting"));
checkLighting->SetValue(true);
static_line_1 = new wxStaticLine(noteTools, wxID_ANY);
- labelPerformance = new wxStaticText(noteTools, wxID_ANY, wxTRANS("Performance"));
- checkWeakRandom = new wxCheckBox(noteTools, ID_CHECK_WEAKRANDOM, wxTRANS("Fast and weak randomisation."));
+ labelPerformance = new wxStaticText(noteTools, wxID_ANY, TRANS("Performance"));
+ checkWeakRandom = new wxCheckBox(noteTools, ID_CHECK_WEAKRANDOM, TRANS("Fast and weak randomisation."));
checkWeakRandom->SetValue(true);
- checkLimitOutput = new wxCheckBox(noteTools, ID_CHECK_LIMIT_POINT_OUT, wxTRANS("Limit Output Pts"));
+ checkLimitOutput = new wxCheckBox(noteTools, ID_CHECK_LIMIT_POINT_OUT, TRANS("Limit Output Pts"));
checkLimitOutput->SetValue((visControl.getIonDisplayLimit() !=0));
std::string tmpStr;
stream_cast(tmpStr,visControl.getIonDisplayLimit());
- textLimitOutput = new wxTextCtrl(noteTools, ID_TEXT_LIMIT_POINT_OUT, wxStr(tmpStr),
+ textLimitOutput = new wxTextCtrl(noteTools, ID_TEXT_LIMIT_POINT_OUT, (tmpStr),
wxDefaultPosition,wxDefaultSize,wxTE_PROCESS_ENTER );
- checkCaching = new wxCheckBox(noteTools, ID_CHECK_CACHING, wxTRANS("Filter caching"));
+ checkCaching = new wxCheckBox(noteTools, ID_CHECK_CACHING, TRANS("Filter caching"));
checkCaching->SetValue(true);
- labelMaxRamUsage = new wxStaticText(noteTools, wxID_ANY, wxTRANS("Max. Ram usage (%)"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+ labelMaxRamUsage = new wxStaticText(noteTools, wxID_ANY, TRANS("Max. Ram usage (%)"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
spinCachePercent = new wxSpinCtrl(noteTools, ID_SPIN_CACHEPERCENT, wxT("50"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 100);
panelView = new wxPanel(panelTop, ID_PANEL_VIEW);
panelSpectra = new MathGLPane(splitterSpectra, wxID_ANY);
- plotListLabel = new wxStaticText(window_2_pane_2, wxID_ANY, wxTRANS("Plot List"));
- plotList = new wxListBox(window_2_pane_2, ID_LIST_PLOTS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_MULTIPLE|wxLB_NEEDED_SB|wxLB_SORT);
+ plotListLabel = new wxStaticText(window_2_pane_2, wxID_ANY, TRANS("Plot List"));
+ plotList = new wxListBox(window_2_pane_2, ID_LIST_PLOTS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_MULTIPLE|wxLB_NEEDED_SB);
gridRawData = new CopyGrid(noteRaw, ID_GRID_RAW_DATA);
btnRawDataSave = new wxButton(noteRaw, wxID_SAVE, wxEmptyString);
btnRawDataClip = new wxButton(noteRaw, wxID_COPY, wxEmptyString);
@@ -662,6 +674,8 @@ TRANS("Unable to initialise the openGL (3D) panel. Program cannot start. Please
set_properties();
do_layout();
+ backCameraPropGrid=0;
+ backFilterPropGrid=0;
//Disable post-processing
#ifndef APPLE_EFFECTS_WORKAROUND
checkPostProcessing->SetValue(false);
@@ -702,8 +716,8 @@ TRANS("Unable to initialise the openGL (3D) panel. Program cannot start. Please
splitterSpectra->SetSashGravity(0.82);
//Last Refresh box
- listLastRefresh->InsertColumn(0,wxTRANS("Type"));
- listLastRefresh->InsertColumn(1,wxTRANS("Num"));
+ listLastRefresh->InsertColumn(0,TRANS("Type"));
+ listLastRefresh->InsertColumn(1,TRANS("Num"));
//Set callback for mathgl plot
panelSpectra->registerUpdateHandler(this,
@@ -718,32 +732,23 @@ TRANS("Unable to initialise the openGL (3D) panel. Program cannot start. Please
if(configFile.read() == CONFIG_ERR_BADFILE)
{
- textConsoleOut->AppendText(wxTRANS("Warning: Your configuration file appears to be invalid:\n"));
- wxString wxS = wxTRANS("\tConfig Load: ");
- wxS+= wxStr( configFile.getErrMessage());
+ textConsoleOut->AppendText(TRANS("Warning: Your configuration file appears to be invalid:\n"));
+ wxString wxS = TRANS("\tConfig Load: ");
+ wxS+= ( configFile.getErrMessage());
textConsoleOut->AppendText(wxS);
}
else
restoreConfigDefaults();
-
- //Attempt to load the auto-save file, if it exists
- //-----------------
- checkReloadAutosave();
- //-----------------
-
//Try to set the window size to a nice size
SetSize(getNiceWindowSize());
-
initedOK=true;
- updateTimer->Start(UPDATE_TIMER_DELAY,wxTIMER_CONTINUOUS);
- autoSaveTimer->Start(AUTOSAVE_DELAY*1000,wxTIMER_CONTINUOUS);
#ifndef DISABLE_ONLINE_UPDATE
wxDateTime datetime = wxDateTime::Today();
@@ -795,28 +800,26 @@ MainWindowFrame::~MainWindowFrame()
//wxwidgets can crash if objects are ->Connect-ed in
// wxWindowBase::DestroyChildren(), so Disconnect before destructing
-#if wxCHECK_VERSION(2, 9, 0)
comboCamera->Unbind(wxEVT_SET_FOCUS, &MainWindowFrame::OnComboCameraSetFocus, this);
comboStash->Unbind(wxEVT_SET_FOCUS, &MainWindowFrame::OnComboStashSetFocus, this);
noteDataView->Unbind(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &MainWindowFrame::OnNoteDataView, this);
treeFilters->Unbind(wxEVT_KEY_DOWN,&MainWindowFrame::OnTreeKeyDown,this);
-#else
- noteDataView->Disconnect();
- comboStash->Disconnect();
- comboCamera->Disconnect();
-#endif
}
+void MainWindowFrame::finaliseStartup()
+{
+ updateTimer->Start(UPDATE_TIMER_DELAY,wxTIMER_CONTINUOUS);
+ autoSaveTimer->Start(AUTOSAVE_DELAY*1000,wxTIMER_CONTINUOUS);
+}
+
BEGIN_EVENT_TABLE(MainWindowFrame, wxFrame)
- EVT_GRID_CMD_EDITOR_SHOWN(ID_GRID_FILTER_PROPERTY,MainWindowFrame::OnFilterGridCellEditorShow)
- EVT_GRID_CMD_EDITOR_HIDDEN(ID_GRID_FILTER_PROPERTY,MainWindowFrame::OnFilterGridCellEditorHide)
- EVT_GRID_CMD_EDITOR_SHOWN(ID_GRID_CAMERA_PROPERTY,MainWindowFrame::OnCameraGridCellEditorShow)
- EVT_GRID_CMD_EDITOR_HIDDEN(ID_GRID_CAMERA_PROPERTY,MainWindowFrame::OnCameraGridCellEditorHide)
EVT_TIMER(ID_STATUS_TIMER,MainWindowFrame::OnStatusBarTimer)
EVT_TIMER(ID_PROGRESS_TIMER,MainWindowFrame::OnProgressTimer)
EVT_TIMER(ID_UPDATE_TIMER,MainWindowFrame::OnUpdateTimer)
EVT_TIMER(ID_AUTOSAVE_TIMER,MainWindowFrame::OnAutosaveTimer)
+ EVT_IDLE(MainWindowFrame::OnIdle)
+
EVT_SPLITTER_UNSPLIT(ID_SPLIT_TOP_BOTTOM, MainWindowFrame::OnRawDataUnsplit)
EVT_SPLITTER_UNSPLIT(ID_SPLIT_LEFTRIGHT, MainWindowFrame::OnControlUnsplit)
EVT_SPLITTER_UNSPLIT(ID_SPLIT_SPECTRA, MainWindowFrame::OnSpectraUnsplit)
@@ -864,9 +867,6 @@ BEGIN_EVENT_TABLE(MainWindowFrame, wxFrame)
EVT_TEXT_ENTER(ID_COMBO_STASH, MainWindowFrame::OnComboStashEnter)
EVT_COMBOBOX(ID_COMBO_STASH, MainWindowFrame::OnComboStash)
EVT_TREE_END_DRAG(ID_TREE_FILTERS, MainWindowFrame::OnTreeEndDrag)
-#if !defined(WX_TREE_WORKAROUND)
- EVT_TREE_KEY_DOWN(ID_TREE_FILTERS, MainWindowFrame::OnTreeKeyDown)
-#endif
EVT_TREE_SEL_CHANGING(ID_TREE_FILTERS, MainWindowFrame::OnTreeSelectionPreChange)
EVT_TREE_SEL_CHANGED(ID_TREE_FILTERS, MainWindowFrame::OnTreeSelectionChange)
EVT_TREE_DELETE_ITEM(ID_TREE_FILTERS, MainWindowFrame::OnTreeDeleteItem)
@@ -874,13 +874,9 @@ BEGIN_EVENT_TABLE(MainWindowFrame, wxFrame)
EVT_BUTTON(ID_BTN_EXPAND, MainWindowFrame::OnBtnExpandTree)
EVT_BUTTON(ID_BTN_COLLAPSE, MainWindowFrame::OnBtnCollapseTree)
EVT_BUTTON(ID_BTN_FILTERTREE_ERRS, MainWindowFrame::OnBtnFilterTreeErrs)
-#if wxCHECK_VERSION(2,9,0)
- EVT_GRID_CMD_CELL_CHANGED(ID_GRID_FILTER_PROPERTY, MainWindowFrame::OnGridFilterPropertyChange)
- EVT_GRID_CMD_CELL_CHANGED(ID_GRID_CAMERA_PROPERTY, MainWindowFrame::OnGridCameraPropertyChange)
-#else
- EVT_GRID_CMD_CELL_CHANGE(ID_GRID_FILTER_PROPERTY, MainWindowFrame::OnGridFilterPropertyChange)
- EVT_GRID_CMD_CELL_CHANGE(ID_GRID_CAMERA_PROPERTY, MainWindowFrame::OnGridCameraPropertyChange)
-#endif
+ EVT_PG_CHANGING(ID_GRID_FILTER_PROPERTY, MainWindowFrame::OnGridFilterPropertyChange)
+ EVT_PG_CHANGING(ID_GRID_CAMERA_PROPERTY, MainWindowFrame::OnGridCameraPropertyChange)
+ EVT_PG_DOUBLE_CLICK(ID_GRID_FILTER_PROPERTY, MainWindowFrame::OnGridFilterDClick)
EVT_TEXT(ID_COMBO_CAMERA, MainWindowFrame::OnComboCameraText)
EVT_TEXT_ENTER(ID_COMBO_CAMERA, MainWindowFrame::OnComboCameraEnter)
EVT_CHECKBOX(ID_CHECK_ALPHA, MainWindowFrame::OnCheckAlpha)
@@ -890,7 +886,7 @@ BEGIN_EVENT_TABLE(MainWindowFrame, wxFrame)
EVT_SPINCTRL(ID_SPIN_CACHEPERCENT, MainWindowFrame::OnCacheRamUsageSpin)
EVT_COMBOBOX(ID_COMBO_CAMERA, MainWindowFrame::OnComboCamera)
EVT_COMBOBOX(ID_COMBO_FILTER, MainWindowFrame::OnComboFilter)
- EVT_TEXT_ENTER(ID_COMBO_FILTER, MainWindowFrame::OnComboFilterEnter)
+ EVT_TEXT(ID_COMBO_FILTER, MainWindowFrame::OnComboFilterText)
EVT_BUTTON(ID_BTN_STASH_MANAGE, MainWindowFrame::OnButtonStashDialog)
EVT_BUTTON(wxID_REMOVE, MainWindowFrame::OnButtonRemoveCam)
EVT_LISTBOX(ID_LIST_PLOTS, MainWindowFrame::OnSpectraListbox)
@@ -918,6 +914,21 @@ BEGIN_EVENT_TABLE(MainWindowFrame, wxFrame)
END_EVENT_TABLE();
+void MainWindowFrame::OnIdle(wxIdleEvent &evt)
+{
+ if(backFilterPropGrid)
+ {
+ delete backFilterPropGrid;
+ backFilterPropGrid=0;
+ }
+
+ if(backCameraPropGrid)
+ {
+ delete backCameraPropGrid;
+ backCameraPropGrid=0;
+ }
+}
+
unsigned int MainWindowFrame::guessFileType(const std::string &dataFile)
{
@@ -926,7 +937,7 @@ unsigned int MainWindowFrame::guessFileType(const std::string &dataFile)
wxFileName fname;
wxString volume,path,name,ext;
bool hasExt;
- fname.SplitPath(wxStr(dataFile),&volume,
+ fname.SplitPath((dataFile),&volume,
&path,&name,&ext, &hasExt);
//Test the extension to determine what we will do
@@ -971,8 +982,8 @@ void MainWindowFrame::checkAskSaveState()
if(visControl.hasStateData() && visControl.stateModifyLevel() >=STATE_MODIFIED_ANCILLARY)
{
wxMessageDialog wxD (this,
- wxTRANS("Current state has not been saved, would you like to save it now?")
- ,wxTRANS("State changed"),wxYES_NO|wxICON_QUESTION|wxYES_DEFAULT );
+ TRANS("Current state has not been saved, would you like to save it now?")
+ ,TRANS("State changed"),wxYES_NO|wxICON_QUESTION|wxYES_DEFAULT );
wxD.SetAffirmativeId(wxID_YES);
wxD.SetEscapeId(wxID_NO);
@@ -1011,8 +1022,8 @@ void MainWindowFrame::OnFileOpen(wxCommandEvent &event)
}
//Load a file, either a state file, or a new pos file
- wxFileDialog wxF(this,wxTRANS("Select Data or State File..."), wxT(""),
- wxT(""),wxStr(totalStr),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
+ wxFileDialog wxF(this,TRANS("Select Data or State File..."), wxT(""),
+ wxT(""),(totalStr),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
//Show the file dialog
if( (wxF.ShowModal() == wxID_CANCEL))
@@ -1021,11 +1032,13 @@ void MainWindowFrame::OnFileOpen(wxCommandEvent &event)
//See if the user would like to save state, if we are opening a state file
// which will overwrite our current state
std::string filePath = stlStr(wxF.GetPath());
- if(guessFileType(filePath) == FILE_TYPE_XML)
+ if(guessFileType(filePath) == FILE_OPEN_TYPE_XML)
checkAskSaveState();
-
-
+ //Force an update with an empty scene
+ visControl.clear();
+ doSceneUpdate();
+
textConsoleOut->Clear();
//Get vis controller to update tree control to match internal
// structure. Retain tree selection & visibility if we currently
@@ -1065,8 +1078,8 @@ void MainWindowFrame::OnFileMerge(wxCommandEvent &event)
return;
//Load a file, either a state file, or a new pos file, or text file
- wxFileDialog wxF(this,wxTRANS("Select Data or State File..."), wxT(""),
- wxT(""),wxTRANS("3Depict file (*.xml, *.pos,*.txt)|*.xml;*.pos;*.txt|POS File (*.pos)|*.pos|XML State File (*.xml)|*.xml|All Files (*)|*"),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
+ wxFileDialog wxF(this,TRANS("Select Data or State File..."), wxT(""),
+ wxT(""),TRANS("3Depict file (*.xml, *.pos,*.txt)|*.xml;*.pos;*.txt|POS File (*.pos)|*.pos|XML State File (*.xml)|*.xml|All Files (*)|*"),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
//Show the file dialog
if( (wxF.ShowModal() == wxID_CANCEL))
@@ -1096,6 +1109,7 @@ void MainWindowFrame::OnDropFiles(const wxArrayString &files, int x, int y)
//Try opening the files as range (if ext. agrees)
// or as
bool loaded =false;
+ bool rangeLoaded=false;
for(unsigned int ui=0;ui<files.Count();ui++)
{
string ext;
@@ -1134,7 +1148,7 @@ void MainWindowFrame::OnDropFiles(const wxArrayString &files, int x, int y)
if(rng.openGuessFormat(s.c_str()))
{
rangeOK=true;
-
+ rangeLoaded=true;
//Load rangefile & construct filter
RangeFileFilter *f;
@@ -1143,9 +1157,12 @@ void MainWindowFrame::OnDropFiles(const wxArrayString &files, int x, int y)
f->setRangeData(rng);
f->setRangeFilename(s.c_str());
- //Get the parent filter pointer
+ //Add the filter, using the seelcted
+ // item as the parent
visControl.addFilter(f,false,filterId);
+ //update the tree control
+ visControl.updateWxTreeCtrl(treeFilters);
}
else
{
@@ -1155,6 +1172,7 @@ void MainWindowFrame::OnDropFiles(const wxArrayString &files, int x, int y)
//refresh (when we treat this as a pos file).
//FIXME: Something needs to go here... A queue for messages?
}
+
}
}
//---
@@ -1185,6 +1203,9 @@ void MainWindowFrame::OnDropFiles(const wxArrayString &files, int x, int y)
#endif
}
+ if(loaded || rangeLoaded)
+ doSceneUpdate();
+
if(files.Count())
{
//If we are using the default camera,
@@ -1211,7 +1232,7 @@ bool MainWindowFrame::loadFile(const wxString &fileStr, bool merge,bool noUpdate
{
std::string str;
str=ss.str();
- textConsoleOut->AppendText(wxStr(str));
+ textConsoleOut->AppendText((str));
//Note that the parent window must be NULL
// if the parent window is not visible (eg autosave startup)
wxWindow *parentWin=NULL;
@@ -1227,8 +1248,8 @@ bool MainWindowFrame::loadFile(const wxString &fileStr, bool merge,bool noUpdate
if(visControl.hasHazardousContents())
{
wxMessageDialog wxD(this,
- wxTRANS("This state file contains filters that can be unsafe to run\nDo you wish to remove these before continuing?.")
- ,wxTRANS("Security warning"),wxYES_NO|wxICON_WARNING|wxYES_DEFAULT );
+ TRANS("This state file contains filters that can be unsafe to run\nDo you wish to remove these before continuing?.")
+ ,TRANS("Security warning"),wxYES_NO|wxICON_WARNING|wxYES_DEFAULT );
wxD.SetAffirmativeId(wxID_YES);
wxD.SetEscapeId(wxID_NO);
@@ -1253,7 +1274,7 @@ bool MainWindowFrame::loadFile(const wxString &fileStr, bool merge,bool noUpdate
for(unsigned int ui=1;ui<camNames.size();ui++)
{
//Do not delete as this will be deleted by wx
- comboCamera->Append(wxStr(camNames[ui]),
+ comboCamera->Append((camNames[ui]),
(wxClientData *)new wxListUint(ui));
//If this is the active cam (1) set the selection and (2) remember
//the ID
@@ -1265,19 +1286,19 @@ bool MainWindowFrame::loadFile(const wxString &fileStr, bool merge,bool noUpdate
if(camNames.size() > 1)
{
//Use the remembered ID to update the grid.
- visControl.updateCamPropertyGrid(gridCameraProperties,
+ visControl.updateCameraPropGrid(gridCameraProperties,
visControl.getActiveCamId());
}
else
{
//Reset the camera property fields & combo box
- gridCameraProperties->clear();
- comboCamera->SetValue(wxCStr(TRANS(cameraIntroString)));
+ gridCameraProperties->Clear();
+ comboCamera->SetValue((TRANS(cameraIntroString)));
}
}
//reset the stash combo box
- comboStash->SetValue(wxCStr(TRANS(stashIntroString)));
+ comboStash->SetValue((TRANS(stashIntroString)));
//Check to see if we have any effects that we need to enable
@@ -1304,11 +1325,11 @@ bool MainWindowFrame::loadFile(const wxString &fileStr, bool merge,bool noUpdate
{
wxListUint *u;
u = new wxListUint(stashList[ui].second);
- comboStash->Append(wxStr(stashList[ui].first),(wxClientData *)u);
+ comboStash->Append((stashList[ui].first),(wxClientData *)u);
ASSERT(comboStash->GetClientObject(comboStash->GetCount()-1));
}
- gridFilterPropGroup->clear();
+ gridFilterPropGroup->Clear();
}
else
@@ -1378,13 +1399,13 @@ void MainWindowFrame::OnRecentFile(wxCommandEvent &event)
else
{
//See if the user wants to save the current state
- if(guessFileType(stlStr(f)) == FILE_TYPE_XML)
+ if(guessFileType(stlStr(f)) == FILE_OPEN_TYPE_XML)
checkAskSaveState();
-
- if(loadFile(f))
+
+ loadOK=loadFile(f);
+ if(loadOK)
{
- if(loadOK)
- statusMessage(TRANS("Loaded file."),MESSAGE_INFO);
+ statusMessage(TRANS("Loaded file."),MESSAGE_INFO);
panelTop->forceRedraw();
}
}
@@ -1398,6 +1419,10 @@ void MainWindowFrame::OnRecentFile(wxCommandEvent &event)
}
setSaveStatus();
+
+ //make sure camera is properly centred
+ if(visControl.numCams() == 1)
+ visControl.ensureSceneVisible(3);
}
}
@@ -1409,7 +1434,7 @@ void MainWindowFrame::OnFileSave(wxCommandEvent &event)
//Save menu should not be selectable if there is no file to save to.
ASSERT(!saveFilename.empty());
//If the file does not exist, use saveas instead
- if( saveFilename.empty() || !wxFileExists(wxStr(saveFilename)))
+ if( saveFilename.empty() || !wxFileExists((saveFilename)))
{
OnFileSaveAs(event);
return;
@@ -1425,7 +1450,7 @@ void MainWindowFrame::OnFileSave(wxCommandEvent &event)
{
//Update the recent files, and the menu.
configFile.addRecentFile(saveFilename);
- recentHistory->AddFileToHistory(wxStr(saveFilename));
+ recentHistory->AddFileToHistory((saveFilename));
std::string tmpStr;
tmpStr= std::string("Saved state: ") + saveFilename;
@@ -1446,8 +1471,8 @@ void MainWindowFrame::OnFileExportPlot(wxCommandEvent &event)
return;
}
- wxFileDialog wxF(this,wxTRANS("Save plot..."), wxT(""),
- wxT(""),wxTRANS("By Extension (svg,png)|*.svg;*.png|Scalable Vector Graphics File (*.svg)|*.svg|PNG File (*.png)|*.png|All Files (*)|*"),wxFD_SAVE);
+ wxFileDialog wxF(this,TRANS("Save plot..."), wxT(""),
+ wxT(""),TRANS("By Extension (svg,png)|*.svg;*.png|Scalable Vector Graphics File (*.svg)|*.svg|PNG File (*.png)|*.png|All Files (*)|*"),wxFD_SAVE);
if( wxF.ShowModal() == wxID_CANCEL)
return;
@@ -1498,11 +1523,11 @@ void MainWindowFrame::OnFileExportPlot(wxCommandEvent &event)
const char *descriptions[] = {"PNG File", "Scalable Vector Graphic",""};
wxArrayString wxStrs;
for(size_t ui=0;ui<EXT_NONE;ui++)
- wxStrs.Add(wxCStr(descriptions[ui]));
+ wxStrs.Add((descriptions[ui]));
- wxSingleChoiceDialog wxD(this,wxTRANS("Select type for save"),
- wxTRANS("Choose file type"),wxStrs);
+ wxSingleChoiceDialog wxD(this,TRANS("Select type for save"),
+ TRANS("Choose file type"),wxStrs);
if(wxD.ShowModal() == wxID_CANCEL)
return;
@@ -1522,7 +1547,7 @@ void MainWindowFrame::OnFileExportPlot(wxCommandEvent &event)
else if (strExt == "png")
{
//Show a resolution chooser dialog
- ResolutionDialog d(this,wxID_ANY,wxTRANS("Choose resolution"));
+ ResolutionDialog d(this,wxID_ANY,TRANS("Choose resolution"));
int plotW,plotH;
panelSpectra->GetClientSize(&plotW,&plotH);
@@ -1556,16 +1581,30 @@ void MainWindowFrame::OnFileExportPlot(wxCommandEvent &event)
void MainWindowFrame::OnFileExportImage(wxCommandEvent &event)
{
- wxFileDialog wxF(this,wxTRANS("Save Image..."), wxT(""),
- wxT(""),wxTRANS("PNG File (*.png)|*.png|All Files (*)|*"),wxFD_SAVE);
+ wxFileDialog wxF(this,TRANS("Save Image..."), wxT(""),
+ wxT(""),TRANS("PNG File (*.png)|*.png|All Files (*)|*"),wxFD_SAVE);
+ std::string dataFile;
+ do
+ {
- if( (wxF.ShowModal() == wxID_CANCEL))
- return;
+ if( (wxF.ShowModal() == wxID_CANCEL))
+ return;
- std::string dataFile = stlStr(wxF.GetPath());
+ dataFile=stlStr(wxF.GetPath());
+
+ //ask user for confirm if file exists
+ if(!wxFileExists(wxF.GetPath()))
+ break;
+
+ wxMessageDialog wxMd(this,TRANS("File already exists. Overwrite?"),
+ TRANS("Overwrite?"),wxYES_NO|wxICON_WARNING);
+
+ if( wxMd.ShowModal() == wxID_YES)
+ break;
+ } while(true);
//Show a resolution chooser dialog
- ResolutionDialog d(this,wxID_ANY,wxTRANS("Choose resolution"));
+ ResolutionDialog d(this,wxID_ANY,TRANS("Choose resolution"));
//Use the current res as the dialog default
int w,h;
@@ -1594,14 +1633,14 @@ void MainWindowFrame::OnFileExportImage(wxCommandEvent &event)
void MainWindowFrame::OnFileExportVideo(wxCommandEvent &event)
{
- wxFileDialog wxF(this,wxTRANS("Save Image..."), wxT(""),
- wxT(""),wxTRANS("PNG File (*.png)|*.png|All Files (*)|*"),wxFD_SAVE);
+ wxFileDialog wxF(this,TRANS("Save Image..."), wxT(""),
+ wxT(""),TRANS("PNG File (*.png)|*.png|All Files (*)|*"),wxFD_SAVE);
if( (wxF.ShowModal() == wxID_CANCEL))
return;
//Show a resolution chooser dialog
- ResolutionDialog d(this,wxID_ANY,wxTRANS("Choose resolution"));
+ ResolutionDialog d(this,wxID_ANY,TRANS("Choose resolution"));
//Use the current res as the dialog default
int w,h;
@@ -1633,7 +1672,7 @@ void MainWindowFrame::OnFileExportVideo(wxCommandEvent &event)
///TODO: This is nasty and hackish. We should present a nice,
//well laid out dialog for frame count (show angular increment)
- wxTextEntryDialog teD(this,wxTRANS("Number of frames"),wxTRANS("Frame count"),
+ wxTextEntryDialog teD(this,TRANS("Number of frames"),TRANS("Frame count"),
wxT("180"),(long int)wxOK|wxCANCEL);
unsigned int numFrames=0;
@@ -1680,7 +1719,7 @@ void MainWindowFrame::setLockUI(bool locking=true,
{
case WINDOW_LOCK_REFRESH:
{
- comboFilters->Enable(!locking);
+ comboFilters->Enable(!locking && visControl.numFilters());
refreshButton->Enable(!locking && visControl.numFilters());;
btnFilterTreeErrs->Enable(!locking);
@@ -1867,8 +1906,8 @@ void MainWindowFrame::OnFileExportFilterVideo(wxCommandEvent &event)
//Display modal progress dialog
//--
wxProgressDialog *prog;
- prog = new wxProgressDialog(wxTRANS("Animating"),
- wxTRANS("Performing refresh"),numFrames,this,wxPD_CAN_ABORT|wxPD_APP_MODAL );
+ prog = new wxProgressDialog(TRANS("Animating"),
+ TRANS("Performing refresh"),numFrames,this,wxPD_CAN_ABORT|wxPD_APP_MODAL );
prog->Show();
//--
@@ -2156,10 +2195,10 @@ void MainWindowFrame::OnFileExportPackage(wxCommandEvent &event)
}
//This could be nicer, or reordered
- wxTextEntryDialog wxTD(this,wxTRANS("Package name"),
- wxTRANS("Package directory name"),wxT(""),wxOK|wxCANCEL);
+ wxTextEntryDialog wxTD(this,TRANS("Package name"),
+ TRANS("Package directory name"),wxT(""),wxOK|wxCANCEL);
- wxTD.SetValue(wxTRANS("AnalysisPackage"));
+ wxTD.SetValue(TRANS("AnalysisPackage"));
if(wxTD.ShowModal() == wxID_CANCEL)
return;
@@ -2172,8 +2211,8 @@ void MainWindowFrame::OnFileExportPackage(wxCommandEvent &event)
wxDirDialog wxD(this);
res = wxD.ShowModal();
- wxMessageDialog wxMesD(this,wxTRANS("Package folder already exists, won't overwrite.")
- ,wxTRANS("Not available"),wxOK|wxICON_ERROR);
+ wxMessageDialog wxMesD(this,TRANS("Package folder already exists, won't overwrite.")
+ ,TRANS("Not available"),wxOK|wxICON_ERROR);
while(res != wxID_CANCEL)
{
@@ -2198,8 +2237,8 @@ void MainWindowFrame::OnFileExportPackage(wxCommandEvent &event)
//Check to see that the folder actually exists
if(!wxMkdir(folder))
{
- wxMessageDialog wxMesD(this,wxTRANS("Package folder creation failed\ncheck writing to this location is possible.")
- ,wxTRANS("Folder creation failed"),wxOK|wxICON_ERROR);
+ wxMessageDialog wxMesD(this,TRANS("Package folder creation failed\ncheck writing to this location is possible.")
+ ,TRANS("Folder creation failed"),wxOK|wxICON_ERROR);
wxMesD.ShowModal();
return;
}
@@ -2218,8 +2257,8 @@ void MainWindowFrame::OnFileExportPackage(wxCommandEvent &event)
else
{
//Copy the files in the mapping
- wxProgressDialog wxP(wxTRANS("Copying"),
- wxTRANS("Copying referenced files"),fileMapping.size());
+ wxProgressDialog wxP(TRANS("Copying"),
+ TRANS("Copying referenced files"),fileMapping.size());
wxP.Show();
for(map<string,string>::iterator it=fileMapping.begin();
@@ -2273,7 +2312,7 @@ void MainWindowFrame::OnFileExportPackage(wxCommandEvent &event)
}
else
{
- copyError=!wxCopyFile(wxStr(it->second),folder+wxStr(it->first));
+ copyError=!wxCopyFile((it->second),folder+(it->first));
}
if(copyError)
@@ -2287,10 +2326,10 @@ void MainWindowFrame::OnFileExportPackage(wxCommandEvent &event)
wxString s;
- s=wxString(wxTRANS("Saved package: ")) + folder;
+ s=wxString(TRANS("Saved package: ")) + folder;
if(wantDebugPack)
{
- s+=wxCStr(" (debug mode)");
+ s+=(" (debug mode)");
}
statusMessage(stlStr(s).c_str(),MESSAGE_INFO);
}
@@ -2310,12 +2349,12 @@ void MainWindowFrame::OnFileExportIons(wxCommandEvent &event)
visControl.switchoutFilterTree(f);
//Load up the export dialog
- ExportPosDialog *exportDialog=new ExportPosDialog(this,wxID_ANY,wxTRANS("Export"));
+ ExportPosDialog *exportDialog=new ExportPosDialog(this,wxID_ANY,TRANS("Export"));
exportDialog->initialiseData(f);
//create a file chooser for later.
- wxFileDialog wxF(this,wxTRANS("Save pos..."), wxT(""),
- wxT(""),wxTRANS("POS Data (*.pos)|*.pos|All Files (*)|*"),wxFD_SAVE);
+ wxFileDialog wxF(this,TRANS("Save pos..."), wxT(""),
+ wxT(""),TRANS("POS Data (*.pos)|*.pos|All Files (*)|*"),wxFD_SAVE);
//If the user cancels the file chooser,
//drop them back into the export dialog.
@@ -2343,8 +2382,8 @@ void MainWindowFrame::OnFileExportIons(wxCommandEvent &event)
//Check file already exists (no overwrite without asking)
if(wxFileExists(wxF.GetPath()))
{
- wxMessageDialog wxD(this,wxTRANS("File already exists, overwrite?")
- ,wxTRANS("Overwrite?"),wxOK|wxCANCEL|wxICON_QUESTION);
+ wxMessageDialog wxD(this,TRANS("File already exists, overwrite?")
+ ,TRANS("Overwrite?"),wxOK|wxCANCEL|wxICON_QUESTION);
if(wxD.ShowModal() == wxID_CANCEL)
{
@@ -2400,7 +2439,7 @@ void MainWindowFrame::OnFileExportRange(wxCommandEvent &event)
MESSAGE_ERROR);
return;
}
- ExportRngDialog *rngDialog = new ExportRngDialog(this,wxID_ANY,wxTRANS("Export Ranges"),
+ ExportRngDialog *rngDialog = new ExportRngDialog(this,wxID_ANY,TRANS("Export Ranges"),
wxDefaultPosition,wxSize(600,400));
vector<const Filter *> rangeData;
@@ -2423,8 +2462,8 @@ void MainWindowFrame::OnFileExportRange(wxCommandEvent &event)
void MainWindowFrame::OnFileSaveAs(wxCommandEvent &event)
{
//Show a file save dialog
- wxFileDialog wxF(this,wxTRANS("Save state..."), wxT(""),
- wxT(""),wxTRANS("XML state file (*.xml)|*.xml|All Files (*)|*"),wxFD_SAVE);
+ wxFileDialog wxF(this,TRANS("Save state..."), wxT(""),
+ wxT(""),TRANS("XML state file (*.xml)|*.xml|All Files (*)|*"),wxFD_SAVE);
//Show, then check for user cancelling dialog
if( (wxF.ShowModal() == wxID_CANCEL))
@@ -2441,8 +2480,8 @@ void MainWindowFrame::OnFileSaveAs(wxCommandEvent &event)
//Check file already exists (no overwrite without asking)
if(wxFileExists(wxF.GetPath()))
{
- wxMessageDialog wxD(this,wxTRANS("File already exists, overwrite?")
- ,wxTRANS("Overwrite?"),wxOK|wxCANCEL|wxICON_QUESTION);
+ wxMessageDialog wxD(this,TRANS("File already exists, overwrite?")
+ ,TRANS("Overwrite?"),wxOK|wxCANCEL|wxICON_QUESTION);
if(wxD.ShowModal() == wxID_CANCEL)
return;
@@ -2465,8 +2504,8 @@ void MainWindowFrame::OnFileSaveAs(wxCommandEvent &event)
//and if so, do any of our filters
if(visControl.usingRelPaths() && visControl.hasStateOverrides())
{
- wxMessageDialog wxD(this,wxTRANS("Files have been referred to using relative paths. Keep relative paths?")
- ,wxTRANS("Overwrite?"),wxYES|wxNO|wxICON_QUESTION);
+ wxMessageDialog wxD(this,TRANS("Files have been referred to using relative paths. Keep relative paths?")
+ ,TRANS("Overwrite?"),wxYES|wxNO|wxICON_QUESTION);
wxD.SetEscapeId(wxID_NO);
wxD.SetAffirmativeId(wxID_YES);
@@ -2496,7 +2535,7 @@ void MainWindowFrame::OnFileSaveAs(wxCommandEvent &event)
//Update the recent files, and the menu.
configFile.addRecentFile(dataFile);
- recentHistory->AddFileToHistory(wxStr(dataFile));
+ recentHistory->AddFileToHistory((dataFile));
dataFile=std::string(TRANS("Saved state: ")) + dataFile;
statusMessage(dataFile.c_str(),MESSAGE_INFO);
@@ -2536,7 +2575,7 @@ void MainWindowFrame::OnEditUndo(wxCommandEvent &event)
}
else
{
- gridFilterPropGroup->clear();
+ gridFilterPropGroup->Clear();
updateLastRefreshBox();
}
@@ -2564,7 +2603,7 @@ void MainWindowFrame::OnEditRedo(wxCommandEvent &event)
}
else
{
- gridFilterPropGroup->clear();
+ gridFilterPropGroup->Clear();
updateLastRefreshBox();
}
@@ -2575,7 +2614,7 @@ void MainWindowFrame::OnEditRedo(wxCommandEvent &event)
void MainWindowFrame::OnEditRange(wxCommandEvent &event)
{
- RangeEditorDialog *r = new RangeEditorDialog(this,wxID_ANY,wxTRANS("Range editor"));
+ RangeEditorDialog *r = new RangeEditorDialog(this,wxID_ANY,TRANS("Range editor"));
r->setPlotWrapper(*(visControl.getPlotWrapper()));
@@ -2812,64 +2851,23 @@ void MainWindowFrame::OnHelpHelp(wxCommandEvent &event)
if(!s.size())
s=locateDataFile("3depict-manual.pdf");
+ //FIXME: under windows, currently we use "manual.pdf"
+ if(!s.size())
+ s=locateDataFile("manual.pdf");
//If we found it, use the default program associated with that data file
bool launchedOK=false;
- if( wxFileExists(wxStr(s)) && s.size())
+ if( wxFileExists((s)) && s.size())
{
//we found the manual. Launch the default handler.
-#if wxCHECK_VERSION(2, 9, 0)
- launchedOK=wxLaunchDefaultApplication(wxStr(s));
-#else
- //its a bit more convoluted for earlier versions of wx.
- //we have to try xdg-open or open for Linux and mac respectively
- //for windows, we need to use the wxWidgets GetOpenCommand
-
- long appPID;
-
- #if defined(__linux__)
- //Try xdg-open first
- wxString str;
- str= wxT("xdg-open ");
- str+=wxStr(s);
- appPID=wxExecute(str,wxEXEC_ASYNC);
- launchedOK=(appPID!=0);
- #elif defined(__APPLE__)
- //Try open first
- wxString str;
- str= wxT("open ");
- str+=wxStr(s);
- appPID=wxExecute(str,wxEXEC_ASYNC);
- launchedOK=(appPID!=0);
- #endif
-
- //No luck still? Try wx's quirky GetOpenCommand
- if(!launchedOK)
- {
- wxString command;
- //Sigh. In version < 2.9; wx uses the mime-type
- //manager to wrap up the construction
- //of wxFileType object (private constructor).
- //so we can't just *make* a wxFileType
- //we have to derive one from a "mime-type manager".
- //the only way to do this is from the file extension
- //or by passing the mime-string.
- wxMimeTypesManager m;
- wxFileType *t;
-
- t=m.GetFileTypeFromExtension(wxT("pdf"));
- command=t->GetOpenCommand(wxStr(s));
- appPID=wxExecute(command,wxEXEC_ASYNC);
- launchedOK=(appPID!=0);
- }
-#endif
+ launchedOK=wxLaunchDefaultApplication((s));
}
//Still no go? Give up and launch a browser.
if(!launchedOK)
{
std::string helpFileLocation("http://threedepict.sourceforge.net/documentation.html");
- wxLaunchDefaultBrowser(wxStr(helpFileLocation),wxBROWSER_NEW_WINDOW);
+ wxLaunchDefaultBrowser((helpFileLocation),wxBROWSER_NEW_WINDOW);
statusMessage(TRANS("Manual not found locally. Launching web browser"),MESSAGE_INFO);
}
@@ -2878,7 +2876,7 @@ void MainWindowFrame::OnHelpHelp(wxCommandEvent &event)
void MainWindowFrame::OnHelpContact(wxCommandEvent &event)
{
std::string contactFileLocation("http://threedepict.sourceforge.net/contact.html");
- wxLaunchDefaultBrowser(wxStr(contactFileLocation),wxBROWSER_NEW_WINDOW);
+ wxLaunchDefaultBrowser((contactFileLocation),wxBROWSER_NEW_WINDOW);
statusMessage(TRANS("Opening contact page in external web browser"),MESSAGE_INFO);
}
@@ -2896,7 +2894,7 @@ void MainWindowFrame::OnButtonStashDialog(wxCommandEvent &event)
return;
}
- StashDialog *s = new StashDialog(this,wxID_ANY,wxTRANS("Filter Stashes"));
+ StashDialog *s = new StashDialog(this,wxID_ANY,TRANS("Filter Stashes"));
s->setVisController(&visControl);
s->ready();
s->ShowModal();
@@ -2912,7 +2910,7 @@ void MainWindowFrame::OnButtonStashDialog(wxCommandEvent &event)
{
wxListUint *u;
u = new wxListUint(stashVec[ui].second);
- comboStash->Append(wxStr(stashVec[ui].first),(wxClientData *)u);
+ comboStash->Append((stashVec[ui].first),(wxClientData *)u);
ASSERT(comboStash->GetClientObject(comboStash->GetCount()-1));
}
@@ -2923,9 +2921,9 @@ void MainWindowFrame::OnButtonStashDialog(wxCommandEvent &event)
void MainWindowFrame::OnHelpAbout(wxCommandEvent &event)
{
wxAboutDialogInfo info;
- info.SetName(wxCStr(PROGRAM_NAME));
- info.SetVersion(wxCStr(PROGRAM_VERSION));
- info.SetDescription(wxTRANS("Quick and dirty analysis for point data."));
+ info.SetName((PROGRAM_NAME));
+ info.SetVersion((PROGRAM_VERSION));
+ info.SetDescription(TRANS("Quick and dirty analysis for point data."));
info.SetWebSite(wxT("https://sourceforge.net/apps/phpbb/threedepict/"));
info.AddDeveloper(wxT("D. Haley"));
@@ -2935,7 +2933,7 @@ void MainWindowFrame::OnHelpAbout(wxCommandEvent &event)
info.AddArtist(_T("Thanks go to all who have developed the libraries that I use, which make this program possible.\n This includes the wxWidgets team, Alexy Balakin (MathGL), the FTGL and freetype people, the GNU Scientific Library contributors, the tree.h guy (Kasper Peeters) and more."));
- info.AddArtist(wxString(wxTRANS("Compiled with wx Version: " )) +
+ info.AddArtist(wxString(TRANS("Compiled with wx Version: " )) +
wxString(wxSTRINGIZE_T(wxVERSION_STRING)));
wxArrayString s;
@@ -3002,7 +3000,7 @@ void MainWindowFrame::OnComboStashEnter(wxCommandEvent &event)
}
unsigned int n =visControl.stashFilters(filterId,userText.c_str());
- n=comboStash->Append(wxStr(userText),(wxClientData *)new wxListUint(n));
+ n=comboStash->Append((userText),(wxClientData *)new wxListUint(n));
ASSERT(comboStash->GetClientObject(n));
statusMessage(TRANS("Created new filter tree stash"),MESSAGE_INFO);
@@ -3043,6 +3041,11 @@ void MainWindowFrame::OnComboStashEnter(wxCommandEvent &event)
comboStash->SetValue(wxT(""));
}
+void MainWindowFrame::OnComboFilterText(wxCommandEvent &event)
+{
+ //prevent user from modifying text
+ comboFilters->ChangeValue(TRANS(ADD_FILTER_TEXT));
+}
void MainWindowFrame::OnComboStash(wxCommandEvent &event)
{
@@ -3161,18 +3164,15 @@ void MainWindowFrame::OnTreeSelectionChange(wxTreeEvent &event)
size_t filterId;
if(!getTreeFilterId(treeFilters->GetSelection(),filterId))
{
- gridFilterPropGroup->clear();
+ gridFilterPropGroup->Clear();
return;
}
+ comboFilters->Enable();
visControl.updateFilterPropGrid(gridFilterPropGroup, filterId);
updateLastRefreshBox();
-
-#if !wxCHECK_VERSION(2,9,0)
- treeFilters->Fit();
-#endif
panelTop->forceRedraw();
}
@@ -3183,13 +3183,18 @@ void MainWindowFrame::updateLastRefreshBox()
size_t filterId;
if(!getTreeFilterId(treeFilters->GetSelection(),filterId))
return;
- //retrieve the current active filter
- const Filter *f= visControl.getFilterById(filterId);
-
+
+ if(!visControl.getNumFilters())
+ {
+ listLastRefresh->DeleteAllItems();
+ return;
+ }
//Prevent update flicker by disabling interaction
listLastRefresh->Freeze();
-
listLastRefresh->DeleteAllItems();
+
+ //retrieve the current active filter
+ const Filter *f= visControl.getFilterById(filterId);
for(unsigned int ui=0;ui<NUM_STREAM_TYPES; ui++)
{
//Add items to the listbox in the form "type" "count"
@@ -3201,8 +3206,8 @@ void MainWindowFrame::updateLastRefreshBox()
{
long index;
stream_cast(n,numOut);
- index=listLastRefresh->InsertItem(0,wxCStr(TRANS(STREAM_NAMES[ui])));
- listLastRefresh->SetItem(index,1,wxStr(n));
+ index=listLastRefresh->InsertItem(0,(TRANS(STREAM_NAMES[ui])));
+ listLastRefresh->SetItem(index,1,(n));
}
}
listLastRefresh->Thaw();
@@ -3228,9 +3233,10 @@ void MainWindowFrame::OnTreeDeleteItem(wxTreeEvent &event)
event.Veto();
return;
}
- //This event is only generated programatically,
- //Currently it *purposely* does nothing in the
- //not updating case
+ //This event is only generated programatically,
+ // we do not have to handle the direct deletion.
+
+ listLastRefresh->DeleteAllItems();
}
void MainWindowFrame::OnTreeBeginLabelEdit(wxTreeEvent &event)
@@ -3371,10 +3377,6 @@ void MainWindowFrame::OnBtnFilterTreeErrs(wxCommandEvent &event)
}
-//There appears to be a bug in MSW wx 3.0. Key down events don't work
-// in MSW (including in the wx official samples). To work around, use generic
-// KEY_DOWN event
-#if defined(WX_TREE_WORKAROUND)
void MainWindowFrame::OnTreeKeyDown(wxKeyEvent &event)
{
if(currentlyUpdatingScene)
@@ -3417,7 +3419,7 @@ void MainWindowFrame::OnTreeKeyDown(wxKeyEvent &event)
//Remove the item from the Tree
visControl.removeFilterSubtree(((wxTreeUint *)tData)->value);
//Clear property grid
- gridFilterPropGroup->clear();
+ gridFilterPropGroup->Clear();
if(parent !=treeFilters->GetRootItem())
{
ASSERT(parent.IsOk()); // should be - base node should always exist.
@@ -3455,93 +3457,14 @@ void MainWindowFrame::OnTreeKeyDown(wxKeyEvent &event)
}
}
-#else
-void MainWindowFrame::OnTreeKeyDown(wxTreeEvent &event)
+void MainWindowFrame::OnGridFilterPropertyChange(wxPropertyGridEvent &event)
{
- if(currentlyUpdatingScene)
- {
- event.Veto();
- return;
- }
- const wxKeyEvent k = event.GetKeyEvent();
- switch(k.GetKeyCode())
- {
- case WXK_BACK:
- case WXK_DELETE:
- {
- wxTreeItemId id;
-
- if(!treeFilters->GetCount())
- return;
-
- id=treeFilters->GetSelection();
-
- if(!id.IsOk() || id == treeFilters->GetRootItem())
- return;
-
-
- //TODO: Refactor out wxTreeItem... code, into separate routine
- // that only spits out viscontrol Ids
- //Rebuild the tree control, ensuring that the parent is visible,
- //if it has a parent (recall root node of wx control is hidden)
-
- //Get the parent & its data
- wxTreeItemId parent = treeFilters->GetItemParent(id);
- wxTreeItemData *parentData=treeFilters->GetItemData(parent);
-
- //Ask viscontrol to ensure that the parent stays persistently
- // visible when next rebuilding the tree control
- visControl.setWxTreeFilterViewPersistence(
- ((wxTreeUint*)parentData)->value);
-
- //Tree data contains unique identifier for vis control to do matching
- wxTreeItemData *tData=treeFilters->GetItemData(id);
- //Remove the item from the Tree
- visControl.removeFilterSubtree(((wxTreeUint *)tData)->value);
- //Clear property grid
- gridFilterPropGroup->clear();
- if(parent !=treeFilters->GetRootItem())
- {
- ASSERT(parent.IsOk()); // should be - base node should always exist.
-
- //Ensure that the parent stays visible
- visControl.setWxTreeFilterViewPersistence(
- ((wxTreeUint*)parentData)->value);
- visControl.updateWxTreeCtrl(treeFilters);
-
- //OK, so those old Id s are no longer valid,
- //as we just rebuilt the tree. We need new ones
- //Parent is now selected
- parent=treeFilters->GetSelection();
- parentData=treeFilters->GetItemData(parent);
-
-
- //Update the filter property grid with the parent's data
- visControl.updateFilterPropGrid(gridFilterPropGroup,
- ((wxTreeUint *)parentData)->value);
- }
- else
- {
- if(parent.IsOk())
- visControl.updateWxTreeCtrl(treeFilters);
- }
+ //Silence error mesages
+ // we will handle validation in the backend
+ event.SetValidationFailureBehavior(0);
- //Force a scene update, independent of if autoUpdate is enabled.
- doSceneUpdate();
-
- break;
- }
- default:
- event.Skip();
- }
-}
-#endif
-
-void MainWindowFrame::OnGridFilterPropertyChange(wxGridEvent &event)
-{
-
if(programmaticEvent || currentlyUpdatingScene || visControl.isRefreshing())
{
event.Veto();
@@ -3550,12 +3473,7 @@ void MainWindowFrame::OnGridFilterPropertyChange(wxGridEvent &event)
programmaticEvent=true;
//Should only be in the second col
- ASSERT(event.GetCol()==1);
-
- std::string value;
- value = stlStr(gridFilterPropGroup->GetCellValue(
- event.GetRow(),1));
-
+
size_t filterId;
if(!getTreeFilterId(treeFilters->GetSelection(),filterId))
{
@@ -3564,10 +3482,19 @@ void MainWindowFrame::OnGridFilterPropertyChange(wxGridEvent &event)
}
+
+ //Obtain the key/value pairing that we are about to set
+ std::string newValue,keyStr;
+ newValue=getPropValueFromEvent(event);
+
+ size_t key;
+ keyStr=event.GetProperty()->GetName();
+ stream_cast(key,keyStr);
+
+ //Try to apply the new value
bool needUpdate;
- int row=event.GetRow();
if(!visControl.setFilterProperty(filterId,
- gridFilterPropGroup->getKeyFromRow(row),value,needUpdate))
+ key,newValue,needUpdate))
{
event.Veto();
programmaticEvent=false;
@@ -3580,13 +3507,30 @@ void MainWindowFrame::OnGridFilterPropertyChange(wxGridEvent &event)
else
clearWxTreeImages(treeFilters);
- visControl.updateFilterPropGrid(gridFilterPropGroup,filterId);
+ //See wx bug #16222 - cannot modify a property grid's contents
+ // from a change event. Must work in a side-objectm then swap
+ //--
+ backFilterPropGrid= new wxPropertyGrid(filterPropertyPane,ID_GRID_FILTER_PROPERTY,
+ wxDefaultPosition,wxDefaultSize,PROPERTY_GRID_STYLE);
+ backFilterPropGrid->SetExtraStyle(PROPERTY_GRID_EXTRA_STYLE);
+
+
+ visControl.updateFilterPropGrid(backFilterPropGrid,filterId,
+ stlStr(gridFilterPropGroup->SaveEditableState()));
+
+ std::swap(backFilterPropGrid,gridFilterPropGroup);
+ do_filtergrid_prop_layout();
+ //--
- Layout();
programmaticEvent=false;
}
-void MainWindowFrame::OnGridCameraPropertyChange(wxGridEvent &event)
+void MainWindowFrame::OnGridFilterDClick(wxPropertyGridEvent &event)
+{
+ Refresh();
+}
+
+void MainWindowFrame::OnGridCameraPropertyChange(wxPropertyGridEvent &event)
{
if(programmaticEvent)
@@ -3596,14 +3540,48 @@ void MainWindowFrame::OnGridCameraPropertyChange(wxGridEvent &event)
}
programmaticEvent=true;
- //Should only be in the second col
- ASSERT(event.GetCol()==1);
+
+ std::string eventType,newValue;
+ eventType=event.GetValue().GetType();
+ if(eventType == "long")
+ {
+ //Either integer property or enum
+ //integer property
+ wxLongLong ll;
+ ll=event.GetValue().GetLong();
+
+ const wxPGChoices &choices = event.GetProperty()->GetChoices();
+ if(!choices.IsOk())
+ {
+ stream_cast(newValue,ll);
+ }
+ else
+ {
+ //So wx makes life har dhere. We need to do a dance to get the selection
+ // as a string
+ unsigned int ul;
+ ul=ll.ToLong();
+
+ wxArrayString arrStr;
+ arrStr=choices.GetLabels();
+ newValue=arrStr[ul];
+ }
+ }
+ else
+ {
+ //We don't need colour props in camera
+ // not implemented
+ ASSERT(eventType != "wxColour");
+ newValue = event.GetValue().GetString();
+ }
+
- std::string value;
- value = stlStr(gridCameraProperties->GetCellValue(
- event.GetRow(),1));
+ std::string keyStr;
+ size_t key;
+ keyStr=event.GetProperty()->GetName();
+ stream_cast(key,keyStr);
- //Get the camera ID value (long song and dance that it is)
+ //Get the camera ID value
wxListUint *l;
int n = comboCamera->FindString(comboCamera->GetValue());
if(n == wxNOT_FOUND)
@@ -3618,23 +3596,27 @@ void MainWindowFrame::OnGridCameraPropertyChange(wxGridEvent &event)
size_t cameraId;
cameraId = l->value;
- int row=event.GetRow();
- if(visControl.setCamProperties(cameraId,gridCameraProperties->getKeyFromRow(row),value))
- visControl.updateCamPropertyGrid(gridCameraProperties,cameraId);
- else
- event.Veto();
+ //Set property
+ visControl.setCamProperties(cameraId,key,newValue);
+ //FIXME :Need to send the ne grid, not the old, due to wx bug
+ //See wx bug #16222 - cannot modify a property grid's contents
+ // from a change event. Must work in a side-objectm then swap
+ //--
+ backCameraPropGrid= new wxPropertyGrid(noteCamera,ID_GRID_CAMERA_PROPERTY,
+ wxDefaultPosition,wxDefaultSize,PROPERTY_GRID_STYLE);
+ backCameraPropGrid->SetExtraStyle(PROPERTY_GRID_EXTRA_STYLE);
+
+ visControl.updateCameraPropGrid(backCameraPropGrid,cameraId);
+
+ std::swap(backCameraPropGrid,gridCameraProperties);
+ do_cameragrid_prop_layout();
+
+ //Ensure that the GL panel shows latest cam orientation
panelTop->forceRedraw();
programmaticEvent=false;
-
-
}
-void MainWindowFrame::OnCameraGridCellEditorHide(wxGridEvent &e)
-{
- //Unlock the camera combo, now that we have finished editing
- comboCamera->Enable(true);
-}
void MainWindowFrame::OnComboCameraText(wxCommandEvent &event)
{
@@ -3678,7 +3660,7 @@ void MainWindowFrame::OnComboCameraEnter(wxCommandEvent &event)
statusMessage(s.c_str(),MESSAGE_INFO);
//refresh the camera property grid
- visControl.updateCamPropertyGrid(gridCameraProperties ,l->value);
+ visControl.updateCameraPropGrid(gridCameraProperties ,l->value);
setSaveStatus();
@@ -3697,7 +3679,7 @@ void MainWindowFrame::OnComboCameraEnter(wxCommandEvent &event)
statusMessage(s.c_str(),MESSAGE_INFO);
visControl.setCam(u);
- visControl.updateCamPropertyGrid(gridCameraProperties,u);
+ visControl.updateCameraPropGrid(gridCameraProperties,u);
panelTop->forceRedraw();
setSaveStatus();
@@ -3712,7 +3694,7 @@ void MainWindowFrame::OnComboCamera(wxCommandEvent &event)
- visControl.updateCamPropertyGrid(gridCameraProperties,l->value);
+ visControl.updateCameraPropGrid(gridCameraProperties,l->value);
std::string s = std::string(TRANS("Restored camera: ") ) +stlStr(comboCamera->GetValue());
statusMessage(s.c_str(),MESSAGE_INFO);
@@ -3765,6 +3747,7 @@ void MainWindowFrame::OnComboFilterEnter(wxCommandEvent &event)
OnComboFilter(event);
}
+
void MainWindowFrame::OnComboFilter(wxCommandEvent &event)
{
if(currentlyUpdatingScene)
@@ -3777,6 +3760,9 @@ void MainWindowFrame::OnComboFilter(wxCommandEvent &event)
statusMessage(TRANS("Select an item from the filter tree before choosing a new filter"));
else
statusMessage(TRANS("Load data source (file->open) before choosing a new filter"));
+
+ comboFilters->SetSelection(wxNOT_FOUND);
+ comboFilters->ChangeValue(TRANS(ADD_FILTER_TEXT));
return;
}
@@ -3797,8 +3783,8 @@ void MainWindowFrame::OnComboFilter(wxCommandEvent &event)
case FILTER_TYPE_RANGEFILE:
{
///Prompt user for file
- wxFileDialog wxF(this,wxTRANS("Select RNG File..."),wxT(""),wxT(""),
- wxTRANS("Range Files (*rng; *env; *rrng)|*rng;*env;*rrng|RNG File (*.rng)|*.rng|Environment File (*.env)|*.env|RRNG Files (*.rrng)|*.rrng|All Files (*)|*"),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
+ wxFileDialog wxF(this,TRANS("Select RNG File..."),wxT(""),wxT(""),
+ TRANS(RANGEFILE_WX_CONSTANT),wxFD_OPEN|wxFD_FILE_MUST_EXIST);
if( (wxF.ShowModal() == wxID_CANCEL))
@@ -3854,7 +3840,8 @@ void MainWindowFrame::OnComboFilter(wxCommandEvent &event)
if(haveErr)
{
//Clear the combo box
- comboFilters->SetValue(wxT(""));
+ comboFilters->SetSelection(wxNOT_FOUND);
+ comboFilters->ChangeValue(TRANS(ADD_FILTER_TEXT));
return;
}
@@ -3862,7 +3849,8 @@ void MainWindowFrame::OnComboFilter(wxCommandEvent &event)
if(checkAutoUpdate->GetValue())
doSceneUpdate();
- comboFilters->SetValue(wxT(""));
+ comboFilters->SetSelection(wxNOT_FOUND);
+ comboFilters->ChangeValue(TRANS(ADD_FILTER_TEXT));
}
@@ -3880,7 +3868,7 @@ bool MainWindowFrame::doSceneUpdate()
statusMessage("",MESSAGE_NONE);
- noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,wxTRANS("Cons."));
+ noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,TRANS("Cons."));
//Disable tree filters,refresh button and undo
setLockUI(true);
@@ -3892,6 +3880,7 @@ bool MainWindowFrame::doSceneUpdate()
//Set focus on the main frame itself, so that we can catch escape key presses
SetFocus();
+ wxBusyCursor busyCursor;
unsigned int errCode=visControl.refreshFilterTree();
progressTimer->Stop();
@@ -3946,13 +3935,13 @@ bool MainWindowFrame::doSceneUpdate()
//Add (or hide) a little "Star" to inform the user there is some info available
if(textConsoleOut->IsEmpty() || noteDataView->GetSelection()==NOTE_CONSOLE_PAGE_OFFSET)
- noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,wxTRANS("Cons."));
+ noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,TRANS("Cons."));
else
{
#if defined(__WIN32) || defined(__WIN64)
- noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,wxTRANS("*Cons."));
+ noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,TRANS("*Cons."));
#else
- noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,wxTRANS("§Cons."));
+ noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,TRANS("§Cons."));
#endif
}
@@ -4024,25 +4013,36 @@ void MainWindowFrame::setFilterTreeAnalysisImages()
//apply the filter->icon mapping
setWxTreeImages(treeFilters,iconSettings);
-#if defined(__WIN32) || defined(__WIN64)
- //HACK: Under MSW, force button to correct positioning, by forcing a relayout
-#if !wxCHECK_VERSION(2,9,0)
- treeFilters->GetParent()->Layout();
-#endif
-#endif
}
void MainWindowFrame::OnStatusBarTimer(wxTimerEvent &event)
{
- for(unsigned int ui=0; ui<3; ui++)
+ if(statusQueue.empty())
{
+ //clear the status bar colour, then wipe the status text from each field
MainFrame_statusbar->SetBackgroundColour(wxNullColour);
- MainFrame_statusbar->SetStatusText(wxT(""),ui);
- }
-
-
- //Stop the status timer, just in case
- statusTimer->Stop();
+ for(unsigned int ui=0; ui<3; ui++)
+ MainFrame_statusbar->SetStatusText(wxT(""),ui);
+
+ //Stop the status timer, as we are done
+ statusTimer->Stop();
+ }
+ else
+ {
+ //update the status bar with the next
+ // message
+ std::string msg,tmpStr;
+ if(statusQueue.size() > 1)
+ {
+ stream_cast(tmpStr,statusQueue.size());
+ msg = tmpStr + string(" ") + TRANS("msgs");
+ msg+=" : ";
+ }
+ msg+= statusQueue.front().second,
+ showStatusMessage(msg.c_str(),
+ statusQueue.front().first);
+ statusQueue.pop_front();
+ }
}
void MainWindowFrame::OnProgressTimer(wxTimerEvent &event)
@@ -4056,7 +4056,7 @@ void MainWindowFrame::OnAutosaveTimer(wxTimerEvent &event)
//with the title "autosave.xml"
//
- wxString filePath = wxStr(configFile.getConfigDir());
+ wxString filePath = (configFile.getConfigDir());
unsigned int pid;
pid = wxGetProcessId();
@@ -4064,8 +4064,8 @@ void MainWindowFrame::OnAutosaveTimer(wxTimerEvent &event)
std::string pidStr;
stream_cast(pidStr,pid);
- filePath+=wxFileName::GetPathSeparator()+ wxCStr(AUTOSAVE_PREFIX) + wxStr(pidStr) +
- wxCStr(AUTOSAVE_SUFFIX);
+ filePath+=wxFileName::GetPathSeparator()+ string(AUTOSAVE_PREFIX) + (pidStr) +
+ string(AUTOSAVE_SUFFIX);
//Save to the autosave file
std::string s;
s= stlStr(filePath);
@@ -4155,7 +4155,7 @@ void MainWindowFrame::OnUpdateTimer(wxTimerEvent &event)
wxListUint *l;
l =(wxListUint*) comboCamera->GetClientObject(n);
- visControl.updateCamPropertyGrid(gridCameraProperties,l->value);
+ visControl.updateCameraPropGrid(gridCameraProperties,l->value);
}
panelTop->clearCameraUpdates();
@@ -4185,50 +4185,79 @@ void MainWindowFrame::OnUpdateTimer(wxTimerEvent &event)
void MainWindowFrame::statusMessage(const char *message, unsigned int type)
{
- bool sendMessage=true;
+
+ if(type == MESSAGE_NONE)
+ {
+ statusTimer->Stop();
+ statusQueue.clear();
+
+ //clear the status bar colour, then wipe the status text from each field
+ MainFrame_statusbar->SetBackgroundColour(wxNullColour);
+ for(unsigned int ui=0; ui<3; ui++)
+ MainFrame_statusbar->SetStatusText(wxT(""),ui);
+
+ }
+ else
+ {
+ if(statusTimer->IsRunning())
+ {
+ //go through and strip
+ // other hints
+ for(list<pair<unsigned int,string> >::iterator it=statusQueue.begin();
+ it!=statusQueue.end(); )
+ {
+ if(it->first != MESSAGE_HINT)
+ {
+ ++it;
+ continue;
+ }
+
+ it=statusQueue.erase(it);
+ }
+
+ //Emplace our message
+ statusQueue.push_back(make_pair(type,message));
+
+ //keep only unique messages
+ list<pair<unsigned int,string> >::iterator tmpIt;
+ tmpIt= std::unique(statusQueue.begin(),statusQueue.end());
+ statusQueue.erase(tmpIt,statusQueue.end());
+
+ if(!statusQueue.empty())
+ showStatusMessage(statusQueue.begin()->second.c_str(),statusQueue.begin()->first);
+
+
+ }
+ else
+ {
+ showStatusMessage(message,type);
+ statusTimer->Start(STATUS_TIMER_DELAY);
+ }
+ }
+}
+
+void MainWindowFrame::showStatusMessage(const char *message, unsigned int type)
+{
+ //Wx does not support statusbar colouring under MSW
+ // using this can result in visual oddness
+ #if !(defined(__WIN32) || defined(__WIN64))
switch(type)
{
case MESSAGE_ERROR:
- //Wx does not support statusbar colouring under MSW
- // using this can result in visual oddness
- #if !(defined(__WIN32) || defined(__WIN64))
MainFrame_statusbar->SetBackgroundColour(*wxGREEN);
- #endif
break;
case MESSAGE_INFO:
- //Wx does not support statusbar colouring under MSW, and using this can result in visual oddness
- #if !(defined(__WIN32) || defined(__WIN64))
MainFrame_statusbar->SetBackgroundColour(*wxCYAN);
- #endif
break;
case MESSAGE_HINT:
- break;
- //Pseudo-messages
- case MESSAGE_NONE:
- // No actions needed, just supply the message
- ASSERT( string(message)== string(""));
MainFrame_statusbar->SetBackgroundColour(wxNullColour);
break;
- case MESSAGE_NONE_BUT_HINT:
- ASSERT( string(message)== string(""));
- //we need to clear any messages other than "hintMessage"
- sendMessage=(lastMessageType==MESSAGE_HINT);
- break;
default:
ASSERT(false);
}
-
- lastMessageType=type;
+ #endif
- if(sendMessage)
- {
- MainFrame_statusbar->SetStatusText(wxCStr(message),0);
- for(size_t ui=1;ui<3; ui++)
- {
- MainFrame_statusbar->SetStatusText(wxT(""),ui);
- }
- }
- statusTimer->Start(STATUS_TIMER_DELAY,wxTIMER_ONE_SHOT);
+ MainFrame_statusbar->SetStatusText((message),0);
}
void MainWindowFrame::updateProgressStatus()
@@ -4317,8 +4346,8 @@ void MainWindowFrame::updateProgressStatus()
MainFrame_statusbar->SetBackgroundColour(wxNullColour);
MainFrame_statusbar->SetStatusText(wxT(""),0);
- MainFrame_statusbar->SetStatusText(wxStr(progressString),1);
- MainFrame_statusbar->SetStatusText(wxStr(filterProg),2);
+ MainFrame_statusbar->SetStatusText((progressString),1);
+ MainFrame_statusbar->SetStatusText((filterProg),2);
}
@@ -4397,15 +4426,15 @@ void MainWindowFrame::updatePostEffects()
float delta;
delta=bcTmp.getBound(0,1)-bcTmp.getBound(0,0);
stream_cast(s,delta);
- textFxCropDx->SetValue(wxStr(s));
+ textFxCropDx->SetValue((s));
delta=bcTmp.getBound(1,1)-bcTmp.getBound(1,0);
stream_cast(s,delta);
- textFxCropDy->SetValue(wxStr(s));
+ textFxCropDy->SetValue((s));
delta=bcTmp.getBound(2,1)-bcTmp.getBound(2,0);
stream_cast(s,delta);
- textFxCropDz->SetValue(wxStr(s));
+ textFxCropDz->SetValue((s));
}
else
{
@@ -4554,76 +4583,18 @@ void MainWindowFrame::OnViewFullscreen(wxCommandEvent &event)
programmaticEvent=true;
- //Toggle fullscreen, leave the menubar & statusbar visible
-
-#ifdef __APPLE__
- switch(fullscreenState)
- {
- case 0:
- ShowFullScreen(true,wxFULLSCREEN_NOTOOLBAR);
- menuViewFullscreen->SetHelp(wxTRANS("Next Fullscreen mode: none"));
- break;
- case 1:
- menuViewFullscreen->SetHelp(wxTRANS("Next Fullscreen mode: complete"));
- ShowFullScreen(false);
- break;
- case 2:
- menuViewFullscreen->SetHelp(wxTRANS("Next Fullscreen mode: none"));
- ShowFullScreen(true);
- break;
- case 3:
- menuViewFullscreen->SetHelp(wxTRANS("Next Fullscreen mode: with toolbars"));
- ShowFullScreen(false);
- break;
-
- default:
- ASSERT(false);
-
- }
- fullscreenState++;
- fullscreenState%=4;
-#elif __LINUX__
-
- switch(fullscreenState)
- {
- case 0:
- ShowFullScreen(true,wxFULLSCREEN_NOTOOLBAR);
- statusMessage(TRANS("Next Mode: No fullscreen"),MESSAGE_HINT);
- break;
- case 1:
- ShowFullScreen(false);
- statusMessage(TRANS("Next Mode: fullscreen w/o toolbar"),MESSAGE_HINT);
- break;
- case 2:
- ShowFullScreen(true);
- statusMessage(TRANS("Next Mode: fullscreen with toolbar"),MESSAGE_HINT);
- break;
- default:
- ASSERT(false);
- }
- fullscreenState++;
- fullscreenState%=3;
-#else
+ ShowFullScreen(!fullscreenState);
+ fullscreenState=(fullscreenState+1)%2;
- switch(fullscreenState)
- {
- case 0:
- ShowFullScreen(true);
- break;
- case 1:
- ShowFullScreen(false);
- break;
- default:
- ASSERT(false);
- }
- fullscreenState++;
- fullscreenState%=2;
-#endif
programmaticEvent=false;
}
void MainWindowFrame::OnButtonRefresh(wxCommandEvent &event)
{
+ //TODO: Remove this line when wx bug 16222 is fixed
+ if(!gridCameraProperties || !gridFilterPropGroup)
+ return;
+
if(currentlyUpdatingScene || visControl.isRefreshing())
return;
@@ -4632,7 +4603,6 @@ void MainWindowFrame::OnButtonRefresh(wxCommandEvent &event)
if(wxm.ShiftDown())
{
visControl.purgeFilterCache();
- statusMessage("",MESSAGE_NONE);
}
else
{
@@ -4657,10 +4627,6 @@ void MainWindowFrame::OnFilterPropDoubleClick(wxSplitterEvent &event)
void MainWindowFrame::OnControlSplitMove(wxSplitterEvent &event)
{
- //Set the grid an event so that it can adapt the grid margins to fit
- wxGridEvent gridEvent(ID_GRID_RAW_DATA,wxEVT_GRID_LABEL_LEFT_DCLICK,NULL);
- wxPostEvent(gridFilterPropGroup,gridEvent);
-
//For some reason, the damage rectangle is not updated
// for the tree ctrl
treeFilters->Refresh();
@@ -4694,207 +4660,6 @@ void MainWindowFrame::OnSpectraUnsplit(wxSplitterEvent &event)
configFile.setPanelEnabled(CONFIG_STARTUPPANEL_PLOTLIST,false);
}
-//This function modifies the properties before showing the cell content editor.
-//This is needed only for certain data types (colours, bools) other data types are edited
-//using the default editor and modified using ::OnGridFilterPropertyChange
-void MainWindowFrame::OnFilterGridCellEditorShow(wxGridEvent &event)
-{
-
- if(programmaticEvent )
- {
- event.Skip();
- return;
- }
-
-
- //Find where the event occurred (cell & property)
- const GRID_PROPERTY *item;
-
- unsigned int key;
- key=gridFilterPropGroup->getKeyFromRow(event.GetRow());
-
- item=gridFilterPropGroup->getProperty(key);
-
- //Remove any icons that show filter errors or warning state
- clearWxTreeImages(treeFilters);
-
- bool needUpdate=false;
-
- //If this occurs at run-time, then just abort, otherwise throw error
- ASSERT(treeFilters->GetSelection() != treeFilters->GetRootItem());
- if(treeFilters->GetSelection() == treeFilters->GetRootItem())
- return;
-
- //Get the filter ID value
- size_t filterId;
- if(!getTreeFilterId(treeFilters->GetSelection(),filterId))
- return;
-
- switch(item->type)
- {
- case PROPERTY_TYPE_BOOL:
- {
- std::string s;
- //Toggle the property in the grid
- if(item->data == "0")
- s= "1";
- else
- s="0";
- visControl.setFilterProperty(filterId,key,s,needUpdate);
-
- event.Veto();
- break;
- }
- case PROPERTY_TYPE_COLOUR:
- {
- //Show a wxColour choose dialog.
- wxColourData d;
-
- unsigned char r,g,b,a;
- parseColString(item->data,r,g,b,a);
-
- d.SetColour(wxColour(r,g,b,a));
- wxColourDialog *colDg=new wxColourDialog(this->GetParent(),&d);
-
-
- if( colDg->ShowModal() == wxID_OK)
- {
- wxColour c;
- //Change the colour
- c=colDg->GetColourData().GetColour();
-
- std::string s;
- genColString(c.Red(),c.Green(),c.Blue(),s);
-
- //Pass the new colour to the viscontrol system, which updates
- //the filters
- visControl.setFilterProperty(filterId,key,s,needUpdate);
- }
-
- //Set the filter property
- //Disallow direct editing of the grid cell
- event.Veto();
-
- break;
- }
- default:
- {
- //we will handle this after the user has edited the cell contents
- //but we must lock controls that can alter the active filter, and thereby changing the
- // filter grid in the meantime
- setLockUI(true,WINDOW_LOCK_PROPEDIT);
- break;
- }
- }
-
- if(needUpdate)
- {
- visControl.updateFilterPropGrid(gridFilterPropGroup,filterId);
-
- if(checkAutoUpdate->GetValue())
- doSceneUpdate();
- else
- clearWxTreeImages(treeFilters);
- }
-
- setSaveStatus();
-}
-
-void MainWindowFrame::OnFilterGridCellEditorHide(wxGridEvent &event)
-{
- //re-enable the controls that were locked during OnFilterGridCellEditorShow
- setLockUI(false,WINDOW_LOCK_PROPEDIT);
-}
-
-void MainWindowFrame::OnCameraGridCellEditorShow(wxGridEvent &event)
-{
- if(programmaticEvent)
- {
- event.Skip();
- return;
- }
- //Find where the event occurred (cell & property)
- const GRID_PROPERTY *item;
-
- unsigned int key;
- key=gridCameraProperties->getKeyFromRow(event.GetRow());
-
- item=gridCameraProperties->getProperty(key);
-
- //Get the camera ID
- wxListUint *l;
- int n = comboCamera->FindString(comboCamera->GetValue());
- if( n == wxNOT_FOUND)
- return;
-
- l =(wxListUint*) comboCamera->GetClientObject(n);
- if(!l)
- return;
-
- size_t camUniqueID=l->value;
-
-
- switch(item->type)
- {
- case PROPERTY_TYPE_BOOL:
- {
- std::string s;
- //Toggle the property in the grid
- if(item->data == "0")
- s= "1";
- else
- s="0";
- visControl.setCamProperties(camUniqueID,key,s);
-
- //For some reason this does not redraw neatly. Force a redraw
- visControl.updateCamPropertyGrid(gridCameraProperties,camUniqueID);
-
- event.Veto();
- break;
- }
- case PROPERTY_TYPE_COLOUR:
- {
- //Show a wxColour choose dialog.
- wxColourData d;
-
- unsigned char r,g,b,a;
- parseColString(item->data,r,g,b,a);
-
- d.SetColour(wxColour(r,g,b,a));
- wxColourDialog *colDg=new wxColourDialog(this->GetParent(),&d);
-
-
- if( colDg->ShowModal() == wxID_OK)
- {
- wxColour c;
- //Change the colour
- c=colDg->GetColourData().GetColour();
-
- std::string s;
- genColString(c.Red(),c.Green(),c.Blue(),s);
-
- //Pass the new colour to the viscontrol system, which updates
- //the filters
- visControl.setCamProperties(camUniqueID,key,s);
- }
-
- //Set the filter property
- //Disallow direct editing of the grid cell
- event.Veto();
-
- break;
- }
- default:
- //we will handle this after the user has edited the cell contents
- //Lock the camera combo, so the user can't alter the camera data while we are using the editor
- comboCamera->Enable(false);
- break;
- }
-
- panelTop->forceRedraw();
-
- setSaveStatus();
-}
void MainWindowFrame::OnButtonGridCopy(wxCommandEvent &event)
{
@@ -4903,11 +4668,7 @@ void MainWindowFrame::OnButtonGridCopy(wxCommandEvent &event)
void MainWindowFrame::OnButtonGridSave(wxCommandEvent &event)
{
-#if wxCHECK_VERSION(2,9,0)
if(!gridRawData->GetNumberRows()||!gridRawData->GetNumberCols())
-#else
- if(!gridRawData->GetRows()||!gridRawData->GetCols())
-#endif
{
statusMessage(TRANS("No data to save"),MESSAGE_ERROR);
return;
@@ -5036,7 +4797,7 @@ void MainWindowFrame::OnButtonRemoveCam(wxCommandEvent &event)
programmaticEvent=true;
comboCamera->SetValue(wxT(""));
- gridCameraProperties->clear();
+ gridCameraProperties->Clear();
programmaticEvent=false;
setSaveStatus();
@@ -5054,12 +4815,10 @@ void MainWindowFrame::OnSpectraListbox(wxCommandEvent &event)
//Spin through the selected items
for(unsigned int ui=0;ui<plotList->GetCount(); ui++)
{
- wxListUint *l;
unsigned int plotID;
//Retrieve the uniqueID
- l=(wxListUint*)plotList->GetClientObject(ui);
- plotID = l->value;
+ plotID = visControl.getPlotID(ui);
panelSpectra->setPlotVisible(plotID,plotList->IsSelected(ui));
@@ -5087,8 +4846,8 @@ void MainWindowFrame::OnClose(wxCloseEvent &event)
else
{
wxMessageDialog wxD(this,
- wxTRANS("Waiting for refresh to abort. Exiting could lead to the program backgrounding. Exit anyway? "),
- wxTRANS("Confirmation request"),wxOK|wxCANCEL|wxICON_ERROR);
+ TRANS("Waiting for refresh to abort. Exiting could lead to the program backgrounding. Exit anyway? "),
+ TRANS("Confirmation request"),wxOK|wxCANCEL|wxICON_ERROR);
if(wxD.ShowModal() != wxID_OK)
{
@@ -5107,8 +4866,8 @@ void MainWindowFrame::OnClose(wxCloseEvent &event)
{
//Prompt for close
wxMessageDialog wxD(this,
- wxTRANS("Are you sure you wish to exit 3Depict?"),\
- wxTRANS("Confirmation request"),wxOK|wxCANCEL|wxICON_ERROR);
+ TRANS("Are you sure you wish to exit 3Depict?"),\
+ TRANS("Confirmation request"),wxOK|wxCANCEL|wxICON_ERROR);
if(wxD.ShowModal() != wxID_OK)
{
event.Veto();
@@ -5129,8 +4888,8 @@ void MainWindowFrame::OnClose(wxCloseEvent &event)
pid=wxGetProcessId();
stream_cast(pidStr,pid);
- wxString filePath =wxStr(configFile.getConfigDir());
- filePath+=wxCStr("/") + wxCStr(AUTOSAVE_PREFIX) + wxStr(pidStr)+ wxCStr(AUTOSAVE_SUFFIX);
+ wxString filePath =(configFile.getConfigDir());
+ filePath+=string("/") + string(AUTOSAVE_PREFIX) + pidStr+ string(AUTOSAVE_SUFFIX);
if(wxFileExists(filePath))
wxRemoveFile(filePath);
@@ -5346,7 +5105,7 @@ void MainWindowFrame::restoreConfigDefaults()
configFile.getRecentFiles(strVec);
for(unsigned int ui=0; ui<strVec.size(); ui++)
- recentHistory->AddFileToHistory(wxStr(strVec[ui]));
+ recentHistory->AddFileToHistory((strVec[ui]));
//Set the mouse zoom speeds
float zoomRate,moveRate;
@@ -5364,11 +5123,21 @@ void MainWindowFrame::restoreConfigDefaults()
std::string s;
stream_cast(s,configFile.getMaxPoints());
- textLimitOutput->SetValue(wxStr(s));
+ textLimitOutput->SetValue((s));
visControl.setIonDisplayLimit(configFile.getMaxPoints());
}
+
+ if(configFile.getWantStartupOrthoCam())
+ {
+ visControl.setCamProperties(visControl.getActiveCamId(),
+ CAMERA_KEY_LOOKAT_PROJECTIONMODE,TRANS("Orthogonal"));
+ }
+}
+
+void MainWindowFrame::checkShowTips()
+{
//Show startup tip dialog as needed
if(configFile.wantStartupTips())
{
@@ -5377,13 +5146,12 @@ void MainWindowFrame::restoreConfigDefaults()
if(!tipFile.empty())
{
const unsigned int ROUGH_NUMBER_TIPS=22;
- bool wantTipsAgain;
- wxTipProvider *tipProvider = wxCreateFileTipProvider(wxStr(tipFile),
+ wxTipProvider *tipProvider = wxCreateFileTipProvider((tipFile),
(size_t) ((float)rand()/(float)RAND_MAX*(float)ROUGH_NUMBER_TIPS));
if(tipProvider)
{
- wantTipsAgain=wxShowTip(this, tipProvider);
+ bool wantTipsAgain=wxShowTip(this, tipProvider);
delete tipProvider;
configFile.setWantStartupTips(wantTipsAgain);
}
@@ -5395,12 +5163,6 @@ void MainWindowFrame::restoreConfigDefaults()
WARN(false,"Tip file not found at startup, but user wanted it...");
}
}
-
- if(configFile.getWantStartupOrthoCam())
- {
- visControl.setCamProperties(visControl.getActiveCamId(),
- CAMERA_KEY_LOOKAT_PROJECTIONMODE,TRANS("Orthogonal"));
- }
}
void MainWindowFrame::restoreConfigPanelDefaults()
@@ -5415,7 +5177,9 @@ void MainWindowFrame::restoreConfigPanelDefaults()
{
splitLeftRight->Unsplit(panelLeft);
checkMenuControlPane->Check(false);
-
+ }
+ else
+ {
val=configFile.getLeftRightSashPos();
if(val > std::numeric_limits<float>::epsilon())
{
@@ -5485,33 +5249,24 @@ void MainWindowFrame::restoreConfigPanelDefaults()
void MainWindowFrame::SetCommandLineFiles(wxArrayString &files)
{
- //WX Bug: Re-entrancy can occur during modal dialog display due to timers
- // disable timer before showing dialog
- updateTimer->Stop();
- autoSaveTimer->Stop();
textConsoleOut->Clear();
+ bool loadedOK=false;
//Load them up as data.
for(unsigned int ui=0;ui<files.size();ui++)
- loadFile(files[ui],true);
-
-
- if(files.GetCount())
{
- //OK, we got here, so it must be loaded.
- requireFirstUpdate=false;
+ loadedOK|=loadFile(files[ui],true);
}
- //Restart timers
- updateTimer->Start(UPDATE_TIMER_DELAY,wxTIMER_CONTINUOUS);
- autoSaveTimer->Start(AUTOSAVE_DELAY*1000,wxTIMER_CONTINUOUS);
+ requireFirstUpdate=loadedOK;
+
}
void MainWindowFrame::OnNoteDataView(wxNotebookEvent &evt)
{
//Get rid of the console page
if(evt.GetSelection() == NOTE_CONSOLE_PAGE_OFFSET)
- noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,wxTRANS("Cons."));
+ noteDataView->SetPageText(NOTE_CONSOLE_PAGE_OFFSET,TRANS("Cons."));
//Keep processing
evt.Skip();
@@ -5556,8 +5311,8 @@ void MainWindowFrame::OnCheckUpdatesThread(wxCommandEvent &evt)
void MainWindowFrame::checkReloadAutosave()
{
- wxString configDirPath =wxStr(configFile.getConfigDir());
- configDirPath+=wxCStr("/") ;
+ wxString configDirPath =(configFile.getConfigDir());
+ configDirPath+=("/") ;
if(!wxDirExists(configDirPath))
return;
@@ -5568,7 +5323,7 @@ void MainWindowFrame::checkReloadAutosave()
std::string s;
s=std::string(AUTOSAVE_PREFIX) +
std::string("*") + std::string(AUTOSAVE_SUFFIX);
- wxString fileMask = wxStr(s);
+ wxString fileMask = (s);
wxDir::GetAllFiles(configDirPath,dirListing,fileMask,wxDIR_FILES);
@@ -5631,10 +5386,10 @@ void MainWindowFrame::checkReloadAutosave()
if(autosaveNamePIDMap.size() == 1)
{
//If we have exactly one autosave, ask the user about loading it
- wxString filePath=wxStr(autosaveNamePIDMap.begin()->first);
+ wxString filePath=(autosaveNamePIDMap.begin()->first);
wxMessageDialog wxD(this,
- wxTRANS("An auto-save state was found, would you like to restore it?.")
- ,wxTRANS("Autosave"),wxCANCEL|wxOK|wxICON_QUESTION|wxYES_DEFAULT );
+ TRANS("An auto-save state was found, would you like to restore it?.")
+ ,TRANS("Autosave"),wxCANCEL|wxOK|wxICON_QUESTION|wxYES_DEFAULT );
if(wxD.ShowModal()!= wxID_CANCEL)
{
@@ -5669,7 +5424,7 @@ void MainWindowFrame::checkReloadAutosave()
for(map<string,unsigned int>::iterator it=autosaveNamePIDMap.begin();
it!=autosaveNamePIDMap.end();++it)
{
- time_t timeStamp=wxFileModificationTime(wxStr(it->first));
+ time_t timeStamp=wxFileModificationTime((it->first));
filenamesAndTimes.push_back(make_pair(timeStamp,it->first));
}
@@ -5711,7 +5466,7 @@ void MainWindowFrame::checkReloadAutosave()
std::string tmpStr;
tmpStr =filenamesAndTimes[dlg->getSelectedItem()].second;
- if(loadFile(wxStr(tmpStr),false,true))
+ if(loadFile((tmpStr),false,true))
{
//Prevent the program from allowing save menu usage
//into autosave file
@@ -5747,7 +5502,7 @@ void MainWindowFrame::checkReloadAutosave()
std::string tmpDir;
tmpDir = configFile.getConfigDir() + stlStr(wxFileName::GetPathSeparator())
+string("oldAutosave");
- wxString wxtmpDir=wxStr(tmpDir);
+ wxString wxtmpDir=(tmpDir);
//Build the old autosave dir if needed
if(removeFiles.size() && !doErase)
@@ -5770,16 +5525,16 @@ void MainWindowFrame::checkReloadAutosave()
{
//move the autosave file elsewhere after loading it
std::string baseDir = tmpDir+ stlStr(wxFileName::GetPathSeparator());
- wxtmpDir=wxStr(baseDir);
+ wxtmpDir=(baseDir);
//make a backup if needed
if(!doErase)
{
- wxFileName fileNaming(wxStr(removeFiles[ui]));
- wxCopyFile(wxStr(removeFiles[ui]),wxtmpDir+fileNaming.GetFullName());
+ wxFileName fileNaming((removeFiles[ui]));
+ wxCopyFile((removeFiles[ui]),wxtmpDir+fileNaming.GetFullName());
}
//if the copy works or not, just delete the autsave anyway
- wxRemoveFile(wxStr(removeFiles[ui]));
+ wxRemoveFile((removeFiles[ui]));
}
}
@@ -5830,63 +5585,54 @@ wxSize MainWindowFrame::getNiceWindowSize() const
void MainWindowFrame::set_properties()
{
// begin wxGlade: MainWindowFrame::set_properties
- SetTitle(wxCStr(PROGRAM_NAME));
+ SetTitle((PROGRAM_NAME));
comboFilters->SetSelection(-1);
- comboFilters->SetToolTip(wxTRANS("List of available filters"));
+ comboFilters->SetToolTip(TRANS("List of available filters"));
#ifdef __APPLE__
- treeFilters->SetToolTip(wxTRANS("Tree - drag to move items, hold ⌘ for copy. Tap delete to remove items"));
+ treeFilters->SetToolTip(TRANS("Tree - drag to move items, hold ⌘ for copy. Tap delete to remove items"));
#else
- treeFilters->SetToolTip(wxTRANS("Tree - drag to move items, hold Ctrl for copy. Tap delete to remove items."));
+ treeFilters->SetToolTip(TRANS("Tree - drag to move items, hold Ctrl for copy. Tap delete to remove items."));
#endif
- checkAutoUpdate->SetToolTip(wxTRANS("Enable/Disable automatic updates of data when filter change takes effect"));
+ checkAutoUpdate->SetToolTip(TRANS("Enable/Disable automatic updates of data when filter change takes effect"));
checkAutoUpdate->SetValue(true);
- checkAlphaBlend->SetToolTip(wxTRANS("Enable/Disable \"Alpha blending\" (transparency) in rendering system. Blending is used to smooth objects (avoids artefacts known as \"jaggies\") and to make transparent surfaces. Disabling will provide faster rendering but look more blocky"));
- checkLighting->SetToolTip(wxTRANS("Enable/Disable lighting calculations in rendering, for objects that request this. Lighting provides important depth cues for objects comprised of 3D surfaces. Disabling may allow faster rendering in complex scenes"));
- checkWeakRandom->SetToolTip(wxTRANS("Enable/Disable weak randomisation (Galois linear feedback shift register). Strong randomisation uses a much slower random selection method, but provides better protection against inadvertent correlations, and is recommended for final analyses"));
-
- checkLimitOutput->SetToolTip(wxTRANS("Limit the number of points that can be displayed in the 3D scene. Does not affect filter tree calculations. Disabling this can severely reduce performance, due to large numbers of points being visible at once."));
- checkCaching->SetToolTip(wxTRANS("Enable/Disable caching of intermediate results during filter updates. Disabling caching will use less system RAM, though changes to any filter property will cause the entire filter tree to be recomputed, greatly slowing computations"));
-
- gridFilterPropGroup->CreateGrid(0, 2);
- gridFilterPropGroup->EnableDragRowSize(false);
- gridFilterPropGroup->SetColLabelValue(0, wxTRANS("Property"));
- gridFilterPropGroup->SetColLabelValue(1, wxTRANS("Value"));
- gridCameraProperties->CreateGrid(4, 2);
- gridCameraProperties->EnableDragRowSize(false);
- gridCameraProperties->SetSelectionMode(wxGrid::wxGridSelectRows);
- gridCameraProperties->SetColLabelValue(0, wxTRANS("Property"));
- gridCameraProperties->SetColLabelValue(1, wxTRANS("Value"));
- gridCameraProperties->SetToolTip(wxTRANS("Camera data information"));
+ checkAlphaBlend->SetToolTip(TRANS("Enable/Disable \"Alpha blending\" (transparency) in rendering system. Blending is used to smooth objects (avoids artefacts known as \"jaggies\") and to make transparent surfaces. Disabling will provide faster rendering but look more blocky"));
+ checkLighting->SetToolTip(TRANS("Enable/Disable lighting calculations in rendering, for objects that request this. Lighting provides important depth cues for objects comprised of 3D surfaces. Disabling may allow faster rendering in complex scenes"));
+ checkWeakRandom->SetToolTip(TRANS("Enable/Disable weak randomisation (Galois linear feedback shift register). Strong randomisation uses a much slower random selection method, but provides better protection against inadvertent correlations, and is recommended for final analyses"));
+
+ checkLimitOutput->SetToolTip(TRANS("Limit the number of points that can be displayed in the 3D scene. Does not affect filter tree calculations. Disabling this can severely reduce performance, due to large numbers of points being visible at once."));
+ checkCaching->SetToolTip(TRANS("Enable/Disable caching of intermediate results during filter updates. Disabling caching will use less system RAM, though changes to any filter property will cause the entire filter tree to be recomputed, greatly slowing computations"));
+
+ gridCameraProperties->SetToolTip(TRANS("Camera data information"));
noteCamera->SetScrollRate(10, 10);
#ifndef APPLE_EFFECTS_WORKAROUND
- checkPostProcessing->SetToolTip(wxTRANS("Enable/disable visual effects on final 3D output"));
+ checkPostProcessing->SetToolTip(TRANS("Enable/disable visual effects on final 3D output"));
#endif
- checkFxCrop->SetToolTip(wxTRANS("Enable cropping post-process effect"));
+ checkFxCrop->SetToolTip(TRANS("Enable cropping post-process effect"));
comboFxCropAxisOne->SetSelection(0);
comboFxCropAxisTwo->SetSelection(0);
- checkFxEnableStereo->SetToolTip(wxTRANS("Colour based 3D effect enable/disable - requires appropriate colour filter 3D glasses."));
- comboFxStereoMode->SetToolTip(wxTRANS("Glasses colour mode"));
+ checkFxEnableStereo->SetToolTip(TRANS("Colour based 3D effect enable/disable - requires appropriate colour filter 3D glasses."));
+ comboFxStereoMode->SetToolTip(TRANS("Glasses colour mode"));
comboFxStereoMode->SetSelection(0);
- sliderFxStereoBaseline->SetToolTip(wxTRANS("Level of separation between left and right images, which sets 3D depth to visual distortion tradeoff"));
+ sliderFxStereoBaseline->SetToolTip(TRANS("Level of separation between left and right images, which sets 3D depth to visual distortion tradeoff"));
gridRawData->CreateGrid(10, 2);
gridRawData->EnableEditing(false);
gridRawData->EnableDragRowSize(false);
- gridRawData->SetColLabelValue(0, wxTRANS("X"));
- gridRawData->SetColLabelValue(1, wxTRANS("Y"));
- btnRawDataSave->SetToolTip(wxTRANS("Save raw data to file"));
- btnRawDataClip->SetToolTip(wxTRANS("Copy raw data to clipboard"));
- btnStashManage->SetToolTip(wxTRANS("Manage \"stashed\" data."));
- textConsoleOut->SetToolTip(wxTRANS("Program text output"));
- comboCamera->SetToolTip(wxTRANS("Select active camera, or type to create new named camera"));
- buttonRemoveCam->SetToolTip(wxTRANS("Remove the selected camera"));
- checkFxCropCameraFrame->SetToolTip(wxTRANS("Perform cropping from coordinate frame of camera"));
- spinCachePercent->SetToolTip(wxTRANS("Set the maximum amount of RAM to use in order to speed repeat computations"));
- btnFilterTreeCollapse->SetToolTip(wxTRANS("Collapse the filter tree"));
- btnFilterTreeExpand->SetToolTip(wxTRANS("Expand the filter tree"));
- refreshButton->SetToolTip (wxTRANS("Process the filter tree, hold shift to purge cached filter data"));
+ gridRawData->SetColLabelValue(0, TRANS("X"));
+ gridRawData->SetColLabelValue(1, TRANS("Y"));
+ btnRawDataSave->SetToolTip(TRANS("Save raw data to file"));
+ btnRawDataClip->SetToolTip(TRANS("Copy raw data to clipboard"));
+ btnStashManage->SetToolTip(TRANS("Manage \"stashed\" data."));
+ textConsoleOut->SetToolTip(TRANS("Program text output"));
+ comboCamera->SetToolTip(TRANS("Select active camera, or type to create new named camera"));
+ buttonRemoveCam->SetToolTip(TRANS("Remove the selected camera"));
+ checkFxCropCameraFrame->SetToolTip(TRANS("Perform cropping from coordinate frame of camera"));
+ spinCachePercent->SetToolTip(TRANS("Set the maximum amount of RAM to use in order to speed repeat computations"));
+ btnFilterTreeCollapse->SetToolTip(TRANS("Collapse the filter tree"));
+ btnFilterTreeExpand->SetToolTip(TRANS("Expand the filter tree"));
+ refreshButton->SetToolTip (TRANS("Process the filter tree, hold shift to purge cached filter data"));
// end wxGlade
//
@@ -5903,23 +5649,11 @@ void MainWindowFrame::set_properties()
refreshButton->Enable(false);
-#if wxCHECK_VERSION(2, 9, 0)
comboCamera->Bind(wxEVT_SET_FOCUS, &MainWindowFrame::OnComboCameraSetFocus, this);
comboStash->Bind(wxEVT_SET_FOCUS, &MainWindowFrame::OnComboStashSetFocus, this);
noteDataView->Bind(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &MainWindowFrame::OnNoteDataView, this);
treeFilters->Bind(wxEVT_KEY_DOWN,&MainWindowFrame::OnTreeKeyDown, this); //Only required for 2.9
-#else
- comboCamera->Connect(wxID_ANY,
- wxEVT_SET_FOCUS,
- wxFocusEventHandler(MainWindowFrame::OnComboCameraSetFocus), NULL, this);
- comboStash->Connect(wxID_ANY,
- wxEVT_SET_FOCUS,
- wxFocusEventHandler(MainWindowFrame::OnComboStashSetFocus), NULL, this);
- noteDataView->Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
- wxNotebookEventHandler(MainWindowFrame::OnNoteDataView),NULL,this);
-
-#endif
- gridCameraProperties->clear();
+ gridCameraProperties->Clear();
int widths[] = {-4,-2,-1};
MainFrame_statusbar->SetStatusWidths(3,widths);
@@ -5948,10 +5682,7 @@ void MainWindowFrame::do_layout()
wxBoxSizer* topPanelSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizerFxCropRHS = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizerFxCropLHS = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* camPaneSizer = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* camTopRowSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* filterPaneSizer = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* filterPropGridSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* filterTreeLeftRightSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* filterRightOfTreeSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* filterMainCtrlSizer = new wxBoxSizer(wxVERTICAL);
@@ -5977,19 +5708,12 @@ void MainWindowFrame::do_layout()
btnFilterTreeErrs->Show(false);
filterTreeLeftRightSizer->Add(filterRightOfTreeSizer, 2, wxEXPAND, 0);
filterTreePane->SetSizer(filterTreeLeftRightSizer);
- filterPropGridSizer->Add(propGridLabel, 0, 0, 0);
- filterPropGridSizer->Add(gridFilterPropGroup, 1, wxLEFT|wxEXPAND, 4);
- filterPropertyPane->SetSizer(filterPropGridSizer);
+ do_filtergrid_prop_layout();
// filterSplitter->SplitHorizontally(filterTreePane, filterPropertyPane);//DISABLED This has to be done later to get the window to work.
filterPaneSizer->Add(filterSplitter, 1, wxEXPAND, 0);
noteData->SetSizer(filterPaneSizer);
- camPaneSizer->Add(labelCameraName, 0, 0, 0);
- camTopRowSizer->Add(comboCamera, 3, 0, 0);
- camTopRowSizer->Add(buttonRemoveCam, 0, wxLEFT|wxRIGHT, 2);
- camPaneSizer->Add(camTopRowSizer, 0, wxTOP|wxBOTTOM|wxEXPAND, 4);
- camPaneSizer->Add(cameraNamePropertySepStaticLine, 0, wxEXPAND, 0);
- camPaneSizer->Add(gridCameraProperties, 1, wxEXPAND, 0);
- noteCamera->SetSizer(camPaneSizer);
+ do_cameragrid_prop_layout();
+
#ifndef APPLE_EFFECTS_WORKAROUND
postProcessSizer->Add(checkPostProcessing, 0, wxALL, 5);
#endif
@@ -6026,8 +5750,8 @@ void MainWindowFrame::do_layout()
sizerFxStereo->Add(sizerSetereoBaseline, 0, wxEXPAND, 0);
sizerFxStereo->Add(checkFxStereoLensFlip, 0, wxLEFT, 5);
noteFxPanelStereo->SetSizer(sizerFxStereo);
- noteEffects->AddPage(noteFxPanelCrop, wxTRANS("Crop"));
- noteEffects->AddPage(noteFxPanelStereo, wxTRANS("Stereo"));
+ noteEffects->AddPage(noteFxPanelCrop, TRANS("Crop"));
+ noteEffects->AddPage(noteFxPanelStereo, TRANS("Stereo"));
postProcessSizer->Add(noteEffects, 1, wxEXPAND, 0);
notePost->SetSizer(postProcessSizer);
sizerTools->Add(labelAppearance, 0, wxTOP, 3);
@@ -6044,10 +5768,10 @@ void MainWindowFrame::do_layout()
sizerToolsRamUsage->Add(spinCachePercent, 0, 0, 5);
sizerTools->Add(sizerToolsRamUsage, 1, wxTOP|wxEXPAND, 5);
noteTools->SetSizer(sizerTools);
- notebookControl->AddPage(noteData, wxTRANS("Data"));
- notebookControl->AddPage(noteCamera, wxTRANS("Cam"));
- notebookControl->AddPage(notePost, wxTRANS("Post"));
- notebookControl->AddPage(noteTools, wxTRANS("Tools"));
+ notebookControl->AddPage(noteData, TRANS("Data"));
+ notebookControl->AddPage(noteCamera, TRANS("Cam"));
+ notebookControl->AddPage(notePost, TRANS("Post"));
+ notebookControl->AddPage(noteTools, TRANS("Tools"));
sizerLeft->Add(notebookControl, 1, wxLEFT|wxBOTTOM|wxEXPAND, 2);
panelLeft->SetSizer(sizerLeft);
topPanelSizer->Add(panelView, 1, wxEXPAND, 0);
@@ -6064,9 +5788,9 @@ void MainWindowFrame::do_layout()
noteRaw->SetSizer(rawDataGridSizer);
textConsoleSizer->Add(textConsoleOut, 1, wxEXPAND, 0);
noteDataViewConsole->SetSizer(textConsoleSizer);
- noteDataView->AddPage(splitterSpectra, wxTRANS("Plot"));
- noteDataView->AddPage(noteRaw, wxTRANS("Raw"));
- noteDataView->AddPage(noteDataViewConsole, wxTRANS("Cons."));
+ noteDataView->AddPage(splitterSpectra, TRANS("Plot"));
+ noteDataView->AddPage(noteRaw, TRANS("Raw"));
+ noteDataView->AddPage(noteDataViewConsole, TRANS("Cons."));
splitTopBottom->SplitHorizontally(panelTop, noteDataView);
rightPanelSizer->Add(splitTopBottom, 1, wxEXPAND, 0);
panelRight->SetSizer(rightPanelSizer);
@@ -6085,9 +5809,44 @@ void MainWindowFrame::do_layout()
//Set the combo text
haveSetComboCamText=false;
- comboCamera->SetValue(wxCStr(TRANS(cameraIntroString)));
+ comboCamera->SetValue((TRANS(cameraIntroString)));
haveSetComboStashText=false;
- comboStash->SetValue(wxCStr(TRANS(stashIntroString)));
+ comboStash->SetValue((TRANS(stashIntroString)));
}
+void MainWindowFrame::do_filtergrid_prop_layout()
+{
+ wxBoxSizer* filterPropGridSizer = new wxBoxSizer(wxVERTICAL);
+
+ filterPropGridSizer->Add(propGridLabel, 0, 0, 0);
+ filterPropGridSizer->Add(gridFilterPropGroup, 1, wxLEFT|wxEXPAND, 4);
+ filterPropertyPane->SetSizer(filterPropGridSizer);
+ filterPropertyPane->Fit();
+ filterPropGridSizer->Fit(filterPropertyPane);
+
+ Layout();
+ filterSplitter->UpdateSize();
+
+}
+
+void MainWindowFrame::do_cameragrid_prop_layout()
+{
+ wxBoxSizer* camPaneSizer = new wxBoxSizer(wxVERTICAL);
+ wxBoxSizer* camTopRowSizer = new wxBoxSizer(wxHORIZONTAL);
+
+ camPaneSizer->Add(labelCameraName, 0, 0, 0);
+ camTopRowSizer->Add(comboCamera, 3, 0, 0);
+ camTopRowSizer->Add(buttonRemoveCam, 0, wxLEFT|wxRIGHT, 2);
+ camPaneSizer->Add(camTopRowSizer, 0, wxTOP|wxBOTTOM|wxEXPAND, 4);
+ camPaneSizer->Add(cameraNamePropertySepStaticLine, 0, wxEXPAND, 0);
+ camPaneSizer->Add(gridCameraProperties, 1, wxEXPAND, 0);
+
+ noteCamera->SetSizer(camPaneSizer);
+ noteCamera->Fit();
+ //camPaneSizer->Fit();
+
+ noteCamera->Layout();
+
+ //noteCamera->UpdateSize();
+}
diff --git a/src/gui/mainFrame.h b/src/gui/mainFrame.h
index 1e9fa28..57b73f2 100644
--- a/src/gui/mainFrame.h
+++ b/src/gui/mainFrame.h
@@ -28,9 +28,8 @@
#include <wx/dnd.h>
#include <wx/grid.h>
#include <wx/treectrl.h>
-#if wxCHECK_VERSION(2,9,0)
+#include <wx/propgrid/propgrid.h>
#include <wx/filehistory.h>
-#endif
// end wxGlade
//Local stuff
@@ -46,10 +45,6 @@
#ifndef THREEDEPICT_H
#define THREEDEPICT_H
-//Workaround for keypress not detected under MSW wx3.0 and apple
-#if wxCHECK_VERSION(2,9,0) && ( defined(__WIN32) || defined(__WIN64) || defined(__APPLE__)) || wxCHECK_VERSION(3,0,0)
-#define WX_TREE_WORKAROUND
-#endif
class FileDropTarget;
@@ -57,9 +52,8 @@ enum
{
MESSAGE_ERROR=1,
MESSAGE_INFO,
- MESSAGE_HINT,
- MESSAGE_NONE_BUT_HINT,
- MESSAGE_NONE
+ MESSAGE_HINT, //lowest priority message in the queue. Only one HINT can be in queue at a time
+ MESSAGE_NONE // pseudo-message to wipe all messages
};
class MainWindowFrame: public wxFrame {
@@ -88,8 +82,15 @@ private:
void set_properties();
void do_layout();
// end wxGlade
+ //Force a re-layout of the filter property grid
+ void do_filtergrid_prop_layout();
+ //Force a re-layout of the camera property grid
+ void do_cameragrid_prop_layout();
- //!Give a message in the satus bar
+ //!Queue up a status message for display
+ void showStatusMessage(const char *message, unsigned int messageType=MESSAGE_ERROR);
+
+ //!Queue up a status message for display
void statusMessage(const char *message, unsigned int messageType=MESSAGE_ERROR);
//!Update the progress information in the status bar
@@ -141,9 +142,6 @@ private:
//!Did the main frame's constructor complete OK?
bool initedOK;
- //The type of status message last sent to user
- unsigned int lastMessageType;
-
//Pointer to version check thread, occasionally initialised at startup to
// check online for new program updates
VersionCheckThread *verCheckThread;
@@ -154,6 +152,10 @@ private:
//TODO: Refactor - remove me.
// True if there are pending updates for the mahthgl window
bool plotUpdates;
+
+ //List of pending messages to show in status bar
+ // first int is priority (eg MESSAGE_ERROR), string is message
+ list<pair<unsigned int, std::string > > statusQueue;
protected:
wxTimer *statusTimer;
wxTimer *progressTimer;
@@ -194,7 +196,8 @@ protected:
wxBitmapButton* btnFilterTreeErrs;
wxPanel* filterTreePane;
wxStaticText* propGridLabel;
- wxCustomPropGrid* gridFilterPropGroup;
+ wxPropertyGrid* gridFilterPropGroup;
+ wxPropertyGrid *backFilterPropGrid;
wxPanel* filterPropertyPane;
wxSplitterWindow* filterSplitter;
wxPanel* noteData;
@@ -202,7 +205,8 @@ protected:
wxComboBox* comboCamera;
wxButton* buttonRemoveCam;
wxStaticLine* cameraNamePropertySepStaticLine;
- wxCustomPropGrid* gridCameraProperties;
+ wxPropertyGrid* gridCameraProperties;
+ wxPropertyGrid* backCameraPropGrid;
wxScrolledWindow* noteCamera;
wxCheckBox* checkPostProcessing;
wxCheckBox* checkFxCrop;
@@ -287,11 +291,7 @@ public:
virtual void OnComboStashEnter(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnComboStash(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnTreeEndDrag(wxTreeEvent &event); // wxGlade: <event_handler>
-#if defined(WX_TREE_WORKAROUND)
virtual void OnTreeKeyDown(wxKeyEvent &event); // wxGlade: <event_handler>
-#else
- virtual void OnTreeKeyDown(wxTreeEvent &event); // wxGlade: <event_handler>
-#endif
virtual void OnTreeSelectionPreChange(wxTreeEvent &event); // wxGlade: <event_handler>
virtual void OnTreeSelectionChange(wxTreeEvent &event); // wxGlade: <event_handler>
virtual void OnTreeDeleteItem(wxTreeEvent &event); // wxGlade: <event_handler>
@@ -301,7 +301,8 @@ public:
virtual void OnBtnFilterTreeErrs(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnComboCameraText(wxCommandEvent &event); // wxGlade: <event_handler>
- virtual void OnGridFilterPropertyChange(wxGridEvent &event); // wxGlade: <event_handler>
+ virtual void OnGridFilterPropertyChange(wxPropertyGridEvent &event); // wxGlade: <event_handler>
+ virtual void OnGridFilterDClick(wxPropertyGridEvent &event); // wxGlade: <event_handler>
virtual void OnComboCameraEnter(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnComboCamera(wxCommandEvent &event); // wxGlade: <event_handler>
@@ -334,12 +335,9 @@ public:
virtual void OnComboFilterEnter(wxCommandEvent &event); //
virtual void OnComboFilter(wxCommandEvent &event); //
+ virtual void OnComboFilterText(wxCommandEvent &event); // wxGlade: <event_handler>
virtual void OnStatusBarTimer(wxTimerEvent &event); //
- virtual void OnFilterGridCellEditorShow(wxGridEvent &event); //
- virtual void OnFilterGridCellEditorHide(wxGridEvent &event); //
- virtual void OnCameraGridCellEditorShow(wxGridEvent &event); //
- virtual void OnCameraGridCellEditorHide(wxGridEvent &event); //
virtual void OnProgressTimer(wxTimerEvent &event);
virtual void OnProgressAbort(wxCommandEvent &event);
virtual void OnViewFullscreen(wxCommandEvent &event);
@@ -361,7 +359,7 @@ public:
virtual void OnComboCameraSetFocus(wxFocusEvent &evt);
virtual void OnComboStashSetFocus(wxFocusEvent &evt);
virtual void OnNoteDataView(wxNotebookEvent &evt);
- virtual void OnGridCameraPropertyChange(wxGridEvent &event); // wxGlade: <event_handler>
+ virtual void OnGridCameraPropertyChange(wxPropertyGridEvent &event); // wxGlade: <event_handler>
virtual void OnFileExportVideo(wxCommandEvent &event);
virtual void OnFileExportFilterVideo(wxCommandEvent &event);
@@ -375,6 +373,7 @@ public:
virtual void OnAutosaveTimer(wxTimerEvent &evt);
virtual void OnCheckUpdatesThread(wxCommandEvent &evt);
+ virtual void OnIdle(wxIdleEvent &evt);
virtual void SetCommandLineFiles(wxArrayString &files);
virtual void updateLastRefreshBox();
@@ -382,6 +381,10 @@ public:
//return type of file, based upon heuristic check
static unsigned int guessFileType(const std::string &file);
+
+ //Check to see if the user wants a tip file
+ void checkShowTips();
+
//See if the user wants to save the current state
void checkAskSaveState();
@@ -397,6 +400,8 @@ public:
void onPanelSpectraUpdate() {plotUpdates=true;} ;
bool initOK() const {return initedOK;}
+
+ void finaliseStartup();
//This is isolated from the layout code, due to "bug" 4815 in wx. The splitter window
//does not know how to choose a good size until the window is shown
diff --git a/src/gui/mathglPane.cpp b/src/gui/mathglPane.cpp
index f6259e4..664c846 100644
--- a/src/gui/mathglPane.cpp
+++ b/src/gui/mathglPane.cpp
@@ -24,16 +24,13 @@
#include "wx/wxcommon.h"
#include "common/translation.h"
+#include "backend/plot.h"
#ifndef pow10
#define pow10(x) pow(10,x)
#endif
-#ifdef USE_MGL2
- #include <mgl2/canvas_wnd.h>
-#else
- #include <mgl/mgl_eps.h>
-#endif
+#include <mgl2/canvas_wnd.h>
//Panning speed modifier
const float MGL_PAN_SPEED=2.0f;
@@ -51,7 +48,7 @@ enum
};
//Do the particular enums require a redraw?
-const bool MOUSE_ACTION_NEEDS_REDRAW[] = { false,true,true};
+const bool MOUSE_ACTION_NEEDS_REDRAW[] = { false,true,true,false};
enum
{
@@ -100,7 +97,7 @@ enum
MathGLPane::MathGLPane(wxWindow* parent, int id) :
wxPanel(parent, id, wxDefaultPosition, wxDefaultSize)
{
- COMPILE_ASSERT(THREEDEP_ARRAYSIZE(MOUSE_ACTION_NEEDS_REDRAW) == MOUSE_MODE_ENUM_END);
+ COMPILE_ASSERT(THREEDEP_ARRAYSIZE(MOUSE_ACTION_NEEDS_REDRAW) == MOUSE_MODE_ENUM_END + 1);
COMPILE_ASSERT(THREEDEP_ARRAYSIZE(mglTextureFile) == PLOT_TEXTURE_ENUM_END);
hasResized=true;
@@ -127,6 +124,28 @@ MathGLPane::~MathGLPane()
}
+void MathGLPane::setPanCoords() const
+{
+ float xMin,xMax,yMin,yMax;
+ thePlot->getBounds(xMin,xMax,yMin,yMax);
+
+ float pEndX, pStartX,dummy;
+ toPlotCoords(draggingCurrent.x,draggingCurrent.y,pEndX,dummy);
+ toPlotCoords(draggingStart.x,draggingStart.y,pStartX,dummy);
+
+ float offX = pEndX-pStartX;
+
+ //This is not needed if re-using mgl object!
+ // - not sure why!
+ //offX*=xMax-xMin;
+
+ //Modify for speed
+ offX*=MGL_PAN_SPEED;
+
+ thePlot->setBounds(origPanMinX+offX/2,+origPanMaxX + offX/2.0,
+ yMin,yMax);
+}
+
bool MathGLPane::readyForInput() const
{
return (thePlot && gr &&
@@ -144,19 +163,11 @@ unsigned int MathGLPane::getAxisMask(int x, int y) const
unsigned int retVal=0;
-#ifdef USE_MGL2
if(mglCurX < gr->Self()->GetOrgX('x'))
retVal |=AXIS_POSITION_LOW_X;
if(mglCurY < gr->Self()->GetOrgY('y'))
retVal |=AXIS_POSITION_LOW_Y;
-#else
- if(mglCurX < gr->Org.x)
- retVal |=AXIS_POSITION_LOW_X;
-
- if(mglCurY < gr->Org.y)
- retVal |=AXIS_POSITION_LOW_Y;
-#endif
if(!retVal)
retVal=AXIS_POSITION_INTERIOR;
@@ -227,7 +238,7 @@ void MathGLPane::render(wxPaintEvent &event)
int clientW,clientH;
GetClientSize(&clientW,&clientH);
- wxString str=wxTRANS("No plots selected.");
+ wxString str=TRANS("No plots selected.");
dc->GetMultiLineTextExtent(str,&w,&h);
dc->DrawText(str,(clientW-w)/2, (clientH-h)/2);
@@ -246,23 +257,17 @@ void MathGLPane::render(wxPaintEvent &event)
if(!gr || hasChanged || hasResized ||
MOUSE_ACTION_NEEDS_REDRAW[mouseDragMode])
{
- //TODO: There appears to be a bug in mathgl
- // where attempting to clear the plot with ->SetSize()
- // causes objects to become zero sized (eg ticks).
- // using a brand "new" plot entity bypasses this
- // at some computational cost.
- // Need to make a minimal example.
-
//clear the plot drawing entity
if(!gr)
{
-#ifdef USE_MGL2
- gr = new mglGraph(0,w,h);
-#else
- gr = new mglGraphZB(w,h);
+ gr = new mglGraph(0,w,h);
+#ifdef __APPLE__
+ //apparenty bug in mgl under osx - font wont load,
+ // use random string to force fallback
+ gr->LoadFont("asdfrandom");
#endif
}
- else
+ else
{
gr->SetSize(w,h);
}
@@ -270,46 +275,25 @@ void MathGLPane::render(wxPaintEvent &event)
//change the plot by panningOneD it before we draw.
//if we need to
if(mouseDragMode==MOUSE_MODE_DRAG_PAN)
- {
- float xMin,xMax,yMin,yMax;
- thePlot->getBounds(xMin,xMax,yMin,yMax);
-
- float pEndX, pStartX,dummy;
- toPlotCoords(draggingCurrent.x,draggingCurrent.y,pEndX,dummy);
- toPlotCoords(draggingStart.x,draggingStart.y,pStartX,dummy);
-
- float offX = pEndX-pStartX;
-
- //This is not needed if re-using mgl object!
- // - not sure why!
- //offX*=xMax-xMin;
-
- //Modify for speed
- offX*=MGL_PAN_SPEED;
-
- thePlot->setBounds(origPanMinX+offX/2,+origPanMaxX + offX/2.0,
- yMin,yMax);
- }
+ setPanCoords();
//Draw the plot
- thePlot->drawPlot(gr,plotIsLogarithmic);
+ thePlot->drawPlot(gr,plotIsLogarithmic);
+#ifdef DEBUG
+ if(strlen(gr->Message()))
+ {
+ cerr << "Mathgl reports error:" << gr->Message() << endl;
+ }
+#endif
thePlot->resetChange();
hasResized=false;
//Copy the plot's memory buffer into a wxImage object, then draw it
- #ifdef USE_MGL2
char *rgbdata = (char*)malloc(w*h*3);
gr->GetRGB((char*)rgbdata,w*h*3);
- imageCacheBmp=wxImage(w,h,(unsigned char*)rgbdata,true);
+ imageCacheBmp=wxBitmap(wxImage(w,h,(unsigned char*)rgbdata,true));
free(rgbdata);
- #else
- unsigned char *tmp;
- tmp=const_cast<unsigned char*>(gr->GetBits());
- wxImage imTmp;
- imTmp=wxImage(w,h,tmp,true);
- imageCacheBmp=wxBitmap(imTmp);
- #endif
}
dc->DrawBitmap(wxBitmap(imageCacheBmp),0,0);
@@ -485,13 +469,9 @@ bool MathGLPane::getRegionUnderCursor(const wxPoint &mousePos, unsigned int &pl
return false;
//Only allow range interaction within the plot bb
-#ifdef USE_MGL2
if(pMouse.x > gr->Self()->Max.x || pMouse.x < gr->Self()->Min.x)
return false;
-#else
- if(pMouse.x > gr->Max.x || pMouse.x < gr->Min.x)
- return false;
-#endif
+
//check if we actually have a region
if(!thePlot->getRegionIdAtPosition(pMouse.x,pMouse.y,plotId,regionId))
return false;
@@ -613,7 +593,7 @@ void MathGLPane::oneDMouseDownAction(bool leftDown,bool middleDown,
thePlot->getRegion(plotId,regionId,r);
//TODO: Implement a more generic region handler?
- ASSERT(thePlot->plotType(plotId) == PLOT_TYPE_ONED);
+ ASSERT(thePlot->plotType(plotId) == PLOT_MODE_1D);
float mglStartX,mglStartY;
toPlotCoords(draggingStart.x, draggingStart.y,mglStartX,mglStartY);
@@ -643,6 +623,35 @@ void MathGLPane::oneDMouseDownAction(bool leftDown,bool middleDown,
}
+void MathGLPane::twoDMouseDownAction(bool leftDown,bool middleDown,
+ bool alternateDown, int dragX,int dragY)
+{
+ ASSERT(thePlot->getNumVisible());
+
+ float xMin,xMax,yMin,yMax;
+ thePlot->getBounds(xMin,xMax,yMin,yMax);
+
+ //Set the interaction mode
+ if(leftDown && !alternateDown )
+ {
+ draggingStart = wxPoint(dragX,dragY);
+ mouseDragMode=MOUSE_MODE_DRAG;
+ }
+
+
+ if( (leftDown && alternateDown) || middleDown)
+ {
+ mouseDragMode=MOUSE_MODE_DRAG_PAN;
+ draggingStart = wxPoint(dragX,dragY);
+
+ origPanMinX=xMin;
+ origPanMaxX=xMax;
+ origPanMinY=yMin;
+ origPanMaxY=yMax;
+ }
+
+}
+
void MathGLPane::leftMouseDown(wxMouseEvent& event)
{
if(!readyForInput())
@@ -659,16 +668,21 @@ void MathGLPane::leftMouseDown(wxMouseEvent& event)
event.GetPosition().x < 0 || event.GetPosition().y < 0)
return;
- switch(thePlot->getVisibleType())
+ switch(thePlot->getVisibleMode())
{
- case PLOT_TYPE_ONED:
+ case PLOT_MODE_1D:
oneDMouseDownAction(event.LeftDown(),false,
event.ShiftDown(),
event.GetPosition().x,
event.GetPosition().y);
break;
- case PLOT_TYPE_ENUM_END:
+ case PLOT_MODE_2D:
+ case PLOT_MODE_ENUM_END:
//Do nothing
+ twoDMouseDownAction(event.LeftDown(),false,
+ event.ShiftDown(),
+ event.GetPosition().x,
+ event.GetPosition().y);
break;
default:
ASSERT(false);
@@ -689,15 +703,15 @@ void MathGLPane::middleMouseDown(wxMouseEvent &event)
if(!w || !h)
return;
- switch(thePlot->getVisibleType())
+ switch(thePlot->getVisibleMode())
{
- case PLOT_TYPE_ONED:
+ case PLOT_MODE_1D:
oneDMouseDownAction(false,event.MiddleDown(),
event.ShiftDown(),
event.GetPosition().x,
event.GetPosition().y);
break;
- case PLOT_TYPE_ENUM_END:
+ case PLOT_MODE_ENUM_END:
//Do nothing
break;
default:
@@ -942,12 +956,9 @@ void MathGLPane::updateDragPos(const wxPoint &draggingEnd) const
mglPoint cA;
-#ifdef USE_MGL2
cA.x=gr->Self()->GetOrgX('x');
cA.y=gr->Self()->GetOrgY('y');
-#else
- cA=gr->Org;
-#endif
+
float currentAxisX,currentAxisY;
currentAxisX=cA.x;
currentAxisY=cA.y;
@@ -968,13 +979,8 @@ void MathGLPane::updateDragPos(const wxPoint &draggingEnd) const
//left of X-Axis event
//Reset the axes such that the
//zoom is only along one dimension (y)
-#ifdef USE_MGL2
pStart.x = gr->Self()->Min.x;
pEnd.x = gr->Self()->Max.x;
-#else
- pStart.x = gr->Min.x;
- pEnd.x = gr->Max.x;
-#endif
}
}
else if(pStart.y < currentAxisY && pEnd.y < currentAxisY )
@@ -985,13 +991,8 @@ void MathGLPane::updateDragPos(const wxPoint &draggingEnd) const
//below Y axis event
//Reset the axes such that the
//zoom is only along one dimension (x)
-#ifdef USE_MGL2
pStart.y = gr->Self()->Min.y;
pEnd.y = gr->Self()->Max.y;
-#else
- pStart.y = gr->Min.y;
- pEnd.y = gr->Max.y;
-#endif
}
@@ -1053,11 +1054,7 @@ unsigned int MathGLPane::savePNG(const std::string &filename,
ASSERT(filename.size());
try
{
-#ifdef USE_MGL2
gr = new mglGraph(0, width,height);
-#else
- gr = new mglGraphZB(width,height);
-#endif
}
catch(std::bad_alloc)
{
@@ -1065,41 +1062,25 @@ unsigned int MathGLPane::savePNG(const std::string &filename,
return MGLPANE_ERR_BADALLOC;
}
-#ifdef USE_MGL2
gr->SetWarn(0,"");
-#else
- char *mglWarnMsgBuf=new char[1024];
- *mglWarnMsgBuf=0;
- gr->SetWarn(0);
- gr->Message=mglWarnMsgBuf;
-#endif
+
bool dummy;
thePlot->drawPlot(gr,dummy);
gr->WritePNG(filename.c_str());
bool doWarn;
-#ifdef USE_MGL2
doWarn=gr->GetWarn();
-#else
- doWarn=gr->WarnCode;
-#endif
+
if(doWarn)
{
-#ifdef USE_MGL2
lastMglErr= gr->Self()->Mess;
-#else
- lastMglErr=mglWarnMsgBuf;
- delete[] mglWarnMsgBuf;
-#endif
+
delete gr;
gr=0;
return MGLPANE_ERR_MGLWARN;
}
-#ifndef USE_MGL2
- delete[] mglWarnMsgBuf;
-#endif
delete gr;
gr=0;
//Hack. mathgl does not return an error value from its writer
@@ -1124,28 +1105,13 @@ unsigned int MathGLPane::saveSVG(const std::string &filename)
ASSERT(filename.size());
-#ifdef USE_MGL2
mglGraph *grS;
grS = new mglGraph();
-#else
- mglGraphPS *grS;
-
- //Width and height are not *really* important per se,
- //since this is scale-less data.
- grS = new mglGraphPS(1024,768);
-#endif
bool dummy;
thePlot->drawPlot(grS,dummy);
-#ifdef USE_MGL2
grS->SetWarn(0,"");
-#else
- char *mglWarnMsgBuf=new char[1024];
- *mglWarnMsgBuf=0;
- grS->SetWarn(0);
- grS->Message=mglWarnMsgBuf;
-#endif
//Mathgl does not set locale prior to writing SVG
// do this by hand
@@ -1155,20 +1121,11 @@ unsigned int MathGLPane::saveSVG(const std::string &filename)
bool doWarn;
-#ifdef USE_MGL2
doWarn=grS->GetWarn();
-#else
- doWarn=grS->WarnCode;
-#endif
if(doWarn)
{
-#ifdef USE_MGL2
lastMglErr=grS->Self()->Mess;
-#else
- lastMglErr=mglWarnMsgBuf;
- delete[] mglWarnMsgBuf;
-#endif
delete grS;
grS=0;
return MGLPANE_ERR_MGLWARN;
@@ -1330,8 +1287,8 @@ void MathGLPane::drawInteractOverlay(wxDC *dc) const
//---------
string labelText;
labelText = r.getName();
- wxSize textSize=dc->GetTextExtent(wxStr(labelText));
- dc->DrawText(wxStr(labelText),curMouse.x-textSize.GetWidth()/2,
+ wxSize textSize=dc->GetTextExtent((labelText));
+ dc->DrawText((labelText),curMouse.x-textSize.GetWidth()/2,
h/2-(textSize.GetHeight() + 1.5*ARROW_SIZE));
//---------
}
@@ -1354,35 +1311,43 @@ void MathGLPane::drawInteractOverlay(wxDC *dc) const
}
const float THUMB_FRACTION=0.1;
+ const unsigned int MIN_THUMB_SIZE=10;
unsigned int thumbSize=THUMB_FRACTION*std::min(h,w);
- for(size_t ui=0;ui<textureIDs.size();ui++)
+
+
+ if(thumbSize > MIN_THUMB_SIZE)
{
- size_t textureID;
- textureID = textureIDs[ui];
- ASSERT(textureID < PLOT_TEXTURE_ENUM_END);
- std::string filename;
- filename=locateDataFile(mglTextureFile[textureID]);
-
- //Need to draw a picture
- wxImage img;
- if(wxFileExists(wxStr(filename)) && img.LoadFile(wxStr(filename) ))
+ for(size_t ui=0;ui<textureIDs.size();ui++)
{
- int position[2];
- float tmp;
-
- img.Rescale(thumbSize,thumbSize,wxIMAGE_QUALITY_HIGH);
+ size_t textureID;
+ textureID = textureIDs[ui];
- wxBitmap bmp(img);
- //Draw in upper right, by one fraction
- tmp= (1.0-1.5*THUMB_FRACTION);
- position[0] = tmp*w;
-
- //Compute the vertical spacing for each icon
- position[1] = (1.0-(tmp - 2.0*(float)ui*THUMB_FRACTION))*h;
-
- dc->DrawBitmap(img,position[0],position[1]);
+ ASSERT(textureID < PLOT_TEXTURE_ENUM_END);
+ std::string filename;
+ filename=locateDataFile(mglTextureFile[textureID]);
+
+
+ //Need to draw a picture
+ wxImage img;
+ if(wxFileExists((filename)) && img.LoadFile((filename) ))
+ {
+ int position[2];
+ float tmp;
+
+ img.Rescale(thumbSize,thumbSize,wxIMAGE_QUALITY_HIGH);
+
+ wxBitmap bmp(img);
+ //Draw in upper right, by one fraction
+ tmp= (1.0-1.5*THUMB_FRACTION);
+ position[0] = tmp*w;
+
+ //Compute the vertical spacing for each icon
+ position[1] = (1.0-(tmp - 2.0*(float)ui*THUMB_FRACTION))*h;
+
+ dc->DrawBitmap(img,position[0],position[1]);
+ }
}
}
}
@@ -1408,13 +1373,8 @@ bool MathGLPane::toPlotCoords(int winX, int winY,float &resX, float &resY) const
if(plotIsLogarithmic)
{
float plotMinY,plotMaxY;
-#if USE_MGL2
plotMinY=gr->Self()->Min.y;
plotMaxY=gr->Self()->Max.y;
-#else
- plotMinY=gr->Min.y;
- plotMaxY=gr->Max.y;
-#endif
float proportion =(pt.y-plotMinY)/(plotMaxY-plotMinY);
float tmp = proportion*(log10(plotMaxY)-log10(plotMinY)) + log10(plotMinY);
@@ -1427,17 +1387,9 @@ bool MathGLPane::toPlotCoords(int winX, int winY,float &resX, float &resY) const
}
bool MathGLPane::toWinCoords(float plotX, float plotY, float &winX, float &winY) const
{
-#ifdef USE_MGL2
mglPoint tmp;
tmp=gr->CalcScr(mglPoint(plotX,plotY));
winX=tmp.x; winY=tmp.y;
-#else
-
- int iWinX,iWinY;
- iWinX=winX;
- iWinY=winY;
- gr->CalcScr(mglPoint(plotX,plotY),&iWinX,&iWinY);
-#endif
if(plotIsLogarithmic)
{
@@ -1467,7 +1419,7 @@ void MathGLPane::drawRegionDraggingOverlay(wxDC *dc) const
return;
- ASSERT(thePlot->plotType(startMousePlot) == PLOT_TYPE_ONED);
+ ASSERT(thePlot->plotType(startMousePlot) == PLOT_MODE_1D);
//See where extending the region is allowed up to.
thePlot->findRegionLimit(startMousePlot,startMouseRegion,
@@ -1483,7 +1435,7 @@ void MathGLPane::drawRegionDraggingOverlay(wxDC *dc) const
std::string str;
stream_cast(str,regionLimitX);
wxString wxs;
- wxs=wxStr(str);
+ wxs=(str);
wxCoord textW,textH;
dc->GetTextExtent(wxs,&textW,&textH);
@@ -1542,7 +1494,7 @@ void MathGLPane::drawRegionDraggingOverlay(wxDC *dc) const
{
//This needs to be extended to support more
//plot types.
- ASSERT(thePlot->plotType(startMousePlot) == PLOT_TYPE_ONED);
+ ASSERT(thePlot->plotType(startMousePlot) == PLOT_MODE_1D);
//Draw "ghost" limits markers for move,
//these appear as moving vertical bars to outline
diff --git a/src/gui/mathglPane.h b/src/gui/mathglPane.h
index 834541a..b98c22b 100644
--- a/src/gui/mathglPane.h
+++ b/src/gui/mathglPane.h
@@ -22,11 +22,6 @@
#include "backend/plot.h"
-#ifndef USE_MGL2
- #include <mgl/mgl_zb.h>
- #undef is_nan
-#endif
-
// begin wxGlade: ::extracode
// end wxGlade
@@ -68,6 +63,7 @@ private:
wxPoint draggingStart,draggingCurrent;
//!Original bounds during panning operations.
float origPanMinX, origPanMaxX; //1D and 2D actions
+ float origPanMinY, origPanMaxY; //2D actions
//!region used at mouse down
unsigned int startMouseRegion,startMousePlot,regionMoveType;
@@ -90,11 +86,8 @@ private:
bool plotIsLogarithmic;
//!Pointer to the mathgl renderer
-#ifdef USE_MGL2
mglGraph *gr;
-#else
- mglGraphZB *gr;
-#endif
+
//!Caching check vector for plot visibility
std::vector<unsigned int> lastVisible;
@@ -122,6 +115,13 @@ private:
//Action to perform when showing 1D plots and mouse down event occurs
void oneDMouseDownAction(bool leftDown,bool middleMouseDown,
bool alternateDown, int dragX,int dragY);
+
+ //Action to perform when showing 2D plots and mouse down event occurs
+ void twoDMouseDownAction(bool leftDown,bool middleMouseDown,
+ bool alternateDown, int dragX,int dragY);
+
+ //Update plot bounds with any user panning action
+ void setPanCoords() const;
bool readyForInput() const;
diff --git a/src/testing/filtertesting.cpp b/src/testing/filtertesting.cpp
index ab2cc0c..43038e5 100644
--- a/src/testing/filtertesting.cpp
+++ b/src/testing/filtertesting.cpp
@@ -157,7 +157,7 @@ bool filterCloneTests()
wxString wxs,tmpStr;
tmpStr=wxT("3Depict-unit-test-a");
- tmpStr=tmpStr+wxStr(f->getUserString());
+ tmpStr=tmpStr+(f->getUserString());
wxs= wxFileName::CreateTempFileName(tmpStr);
sOrig=stlStr(wxs);
@@ -176,7 +176,7 @@ bool filterCloneTests()
//write out file from cloned object
tmpStr=wxT("3Depict-unit-test-b");
- tmpStr=tmpStr+wxStr(f->getUserString());
+ tmpStr=tmpStr+(f->getUserString());
wxs= wxFileName::CreateTempFileName(tmpStr);
sClone=stlStr(wxs);
fileOut.open(sClone.c_str());
@@ -201,11 +201,7 @@ bool filterCloneTests()
wxArrayString stdOut;
long res;
-#if wxCHECK_VERSION(2,9,0)
- res=wxExecute(wxStr(command),stdOut, wxEXEC_BLOCK);
-#else
- res=wxExecute(wxStr(command),stdOut);
-#endif
+ res=wxExecute((command),stdOut, wxEXEC_BLOCK);
string comment = f->getUserString() + string(" Orig: ")+ sOrig + string (" Clone:") +sClone+
@@ -247,19 +243,16 @@ bool filterCloneTests()
g->writeState(fileOut,STATE_FORMAT_XML);
//Re-run diff
-#if wxCHECK_VERSION(2,9,0)
- res=wxExecute(wxStr(command),stdOut, wxEXEC_BLOCK);
-#else
- res=wxExecute(wxStr(command),stdOut);
-#endif
+ res=wxExecute((command),stdOut, wxEXEC_BLOCK);
+
comment = f->getUserString() + string("Orig: ")+ sOrig + string (" Clone:") +sClone+
string("Read-back filter output was different... (or diff not around?)");
TEST(res==0,comment.c_str());
}
//----
//clean up
- wxRemoveFile(wxStr(sOrig));
- wxRemoveFile(wxStr(sClone));
+ wxRemoveFile((sOrig));
+ wxRemoveFile((sClone));
delete f;
delete g;
@@ -428,15 +421,19 @@ bool filterTreeTests()
throw false;
TEST(!fTree.loadXML(nodePtr,cerr,""),"Tree load test");
+
+
+
+ xmlFreeDoc(doc);
//-----
}
catch(bool)
{
WARN(false,"Couldn't run XML reparse of output file - write permission?" );
- wxRemoveFile(wxStr(tmpName));
+ wxRemoveFile((tmpName));
return true;
}
- wxRemoveFile(wxStr(tmpName));
+ wxRemoveFile((tmpName));
}
else
{
@@ -502,7 +499,7 @@ bool filterRefreshNoOut()
TEST(outData.empty(),"External program refresh test");
fTree.safeDeleteFilterList(outData);
- wxRemoveFile(wxStr(strData));
+ wxRemoveFile((strData));
return true;
}
diff --git a/src/testing/mglTesting.cpp b/src/testing/mglTesting.cpp
index 006eded..5b54cd9 100644
--- a/src/testing/mglTesting.cpp
+++ b/src/testing/mglTesting.cpp
@@ -1,3 +1,21 @@
+/*
+ * mglTesting.cpp - unit testing implementation for mgl code
+ * Copyright (C) 2014, D Haley
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#ifdef DEBUG
#include <iostream>
#include <cstdlib>
@@ -8,7 +26,6 @@
#include "common/assertion.h"
-#ifdef USE_MGL2
#include <mgl2/canvas_wnd.h>
#include "common/basics.h"
@@ -19,6 +36,10 @@
// a reference image (if possible)
bool mglTest()
{
+ WARN(false,"Disabled until upstream fix propagates");
+ return true;
+
+
unsigned int w=1024,h=768;
mglGraph *grS;
grS = new mglGraph(0,w,h);
@@ -149,11 +170,4 @@ bool mglTest()
return true;
}
-#else
-bool mglTest()
-{
- WARN(false,"MGL tests not implemented for mgl 1.x");
- return true;
-}
-#endif
#endif
diff --git a/src/testing/mglTesting.h b/src/testing/mglTesting.h
index 3fb7f6d..a9da1d2 100644
--- a/src/testing/mglTesting.h
+++ b/src/testing/mglTesting.h
@@ -1,3 +1,21 @@
+/*
+ * mglTesting.h - unit testing implementation for mgl code
+ * Copyright (C) 2014, D Haley
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#ifndef MGLTESTING_H
#define MGLTESTING_H
diff --git a/src/testing/testing.cpp b/src/testing/testing.cpp
index 9f91575..9c711ec 100644
--- a/src/testing/testing.cpp
+++ b/src/testing/testing.cpp
@@ -31,8 +31,10 @@
#include "backend/state.h"
#include "backend/configFile.h"
#include "backend/filters/algorithms/binomial.h"
+#include "backend/filters/algorithms/K3DTree-mk2.h"
#include "backend/APT/ionhit.h"
#include "backend/APT/APTFileIO.h"
+#include "backend/APT/abundanceParser.h"
#include "common/stringFuncs.h"
#include "common/xmlHelper.h"
@@ -58,6 +60,8 @@ bool XMLTests();
//!Check to see if manifest contents can be found
bool locateDataTests();
+bool abundanceTests();
+
bool basicFunctionTests()
{
testStringFuncs();
@@ -110,6 +114,9 @@ bool runUnitTests()
cerr << "Running unit tests..." ;
+ if(!K3DMk2Tests())
+ return false;
+
if(!testIonHit())
return false;
@@ -117,9 +124,6 @@ bool runUnitTests()
if(!filterTests())
return false;
- if(!filterCloneTests())
- return false;
-
if(!rangeFileLoadTests())
return false;
@@ -130,9 +134,6 @@ bool runUnitTests()
if(!XMLTests())
return false;
- if(!filterTreeTests())
- return false;
-
if(!runVoxelTests())
return false;
@@ -151,6 +152,9 @@ bool runUnitTests()
if(!mglTest())
return false;
+ if(!abundanceTests())
+ return false;
+
cerr << " OK" << endl << endl;
return true;
@@ -164,7 +168,7 @@ bool rangeFileLoadTests()
bool haveDir=false;
for(unsigned int ui=0;ui<THREEDEP_ARRAYSIZE(TESTING_RESOURCE_DIRS);ui++)
{
- testDir=wxCStr(TESTING_RESOURCE_DIRS[ui]);
+ testDir=(TESTING_RESOURCE_DIRS[ui]);
if(wxDirExists(testDir))
{
haveDir=true;
@@ -189,7 +193,7 @@ bool rangeFileLoadTests()
std::string tmp;
tmp = std::string("*.") + rangeExts[ui];
- wxDir::GetAllFiles(testDir,&tmpArr,wxStr(tmp));
+ wxDir::GetAllFiles(testDir,&tmpArr,(tmp));
for(unsigned int uj=0;uj<tmpArr.GetCount();uj++)
arrayStr.Add(tmpArr[uj]);
tmpArr.clear();
@@ -247,7 +251,7 @@ bool rangeFileLoadTests()
fileLongname=stlStr(arrayStr[ui]);
wxFileName filename;
- filename=wxStr(fileLongname);
+ filename=(fileLongname);
//This returns the short name of the file. Yes, its badly named.
fileShortname=stlStr(filename.GetFullName());
{
@@ -326,7 +330,7 @@ bool rangeFileLoadTests()
wxFileName filename;
fileLongname=stlStr(arrayStr[ui]);
- filename=wxStr(fileLongname);
+ filename=(fileLongname);
fileShortname=stlStr(filename.GetFullName());
//Check to see that the auto-parser correctly identifies the type
@@ -336,7 +340,7 @@ bool rangeFileLoadTests()
errString="Range type detection : ";
errString+=fileLongname;
- if(!wxFileExists(wxStr(fileLongname)))
+ if(!wxFileExists((fileLongname)))
{
cerr << "File expected, but not found during test:" <<
fileLongname << endl;
@@ -493,6 +497,29 @@ bool locateDataTests()
}
}
+
+
+ return true;
+}
+
+bool abundanceTests()
+{
+ const char *ABUNDANCE_FILE="../data/naturalAbundance.xml";
+ ifstream f(ABUNDANCE_FILE);
+
+ //Check that abundance file exists
+ if(f)
+ {
+ f.close();
+ //run abundance tests
+ if(!AbundanceData::runUnitTests(ABUNDANCE_FILE))
+ return false;
+ }
+ else
+ {
+ WARN(false,"Unable to locate natural abundance file, skipping");
+ }
+
return true;
}
diff --git a/src/testing/testing.h b/src/testing/testing.h
index d3f7951..0b94768 100644
--- a/src/testing/testing.h
+++ b/src/testing/testing.h
@@ -23,6 +23,7 @@
#include "backend/filtertree.h"
#include "testing/mglTesting.h"
+
//Run all the built-in unit tests.
bool runUnitTests();
diff --git a/src/wx/propertyGridUpdater.cpp b/src/wx/propertyGridUpdater.cpp
new file mode 100644
index 0000000..228a54c
--- /dev/null
+++ b/src/wx/propertyGridUpdater.cpp
@@ -0,0 +1,320 @@
+/*
+ * propertyGridUpdater.cpp - Update a propertgy grid, using 3depict backend data
+ * Copyright (C) 2014 D Haley
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "propertyGridUpdater.h"
+
+#include "wxcommon.h"
+#include "common/stringFuncs.h"
+#include "common/basics.h"
+
+//For colour property
+#include <wx/propgrid/advprops.h>
+
+//workaround for decimal separator bug
+#include <wx/numformatter.h>
+
+
+void updateFilterPropertyGrid(wxPropertyGrid *g, const Filter *f, const string &stateString)
+{
+
+ ASSERT(f);
+ ASSERT(g);
+
+
+
+ FilterPropGroup p;
+ f->getProperties(p);
+#ifdef DEBUG
+ //If debugging, test self consistency
+ p.checkConsistent();
+#endif
+ g->Clear();
+ //Create the keys to add to the grid
+ for(size_t ui=0;ui<p.numGroups();ui++)
+ {
+ vector<FilterProperty> propGrouping;
+ p.getGroup(ui,propGrouping);
+
+ std::string title;
+ p.getGroupTitle(ui,title);
+
+ //Title must be present, or restorestate doesn't work correctly
+ ASSERT(!title.empty());
+
+ //Set the name that is to be displayed for this grouping
+ // of properties
+ g->Append(new wxPropertyCategory(string("") + title,title));
+
+
+ //Set the children of thies property
+ for(size_t uj=0;uj<propGrouping.size();uj++)
+ {
+ FilterProperty fp;
+ fp =propGrouping[uj];
+
+ std::string keyStr;
+ stream_cast(keyStr,fp.key);
+
+ wxPGProperty *pgp;
+ switch(fp.type)
+ {
+ case PROPERTY_TYPE_BOOL:
+ {
+ bool boolVal,decOK;
+ decOK=boolStrDec(fp.data,boolVal);
+ ASSERT(decOK);
+
+ pgp =new wxBoolProperty( fp.name, keyStr,
+ boolVal);
+ break;
+ };
+ case PROPERTY_TYPE_INTEGER:
+ {
+ long long iV;
+ stream_cast(iV,fp.data);
+
+ pgp =new wxIntProperty(fp.name,keyStr,iV);
+ break;
+ }
+ case PROPERTY_TYPE_REAL:
+ {
+ //workaround for bug in wxFloatProperty under non-english locales.
+ if(wxNumberFormatter::GetDecimalSeparator() == '.')
+ {
+ float fV;
+ stream_cast(fV,fp.data);
+ pgp =new wxFloatProperty(fp.name,keyStr,fV);
+ }
+ else
+ pgp =new wxStringProperty(fp.name,keyStr,fp.data);
+ break;
+ };
+ case PROPERTY_TYPE_POINT3D:
+ case PROPERTY_TYPE_STRING:
+ {
+ pgp =new wxStringProperty(fp.name,keyStr, fp.data);
+ break;
+ }
+ case PROPERTY_TYPE_CHOICE:
+ {
+ vector<string> choices;
+ unsigned int selected;
+ choiceStringToVector(fp.data,choices,selected);
+
+ wxPGChoices pgChoices;
+ for(unsigned int ui=0;ui<choices.size();ui++)
+ {
+ pgChoices.Add(choices[ui],ui);
+ }
+ pgp = new wxEnumProperty(fp.name,keyStr,pgChoices,selected);
+ break;
+ }
+ case PROPERTY_TYPE_COLOUR:
+ {
+ bool res;
+ ColourRGBA rgba;
+
+ res=rgba.parse(fp.data);
+
+ ASSERT(res);
+ pgp = new wxColourProperty(fp.name,keyStr,
+ wxColour(rgba.r(),rgba.g(),rgba.b()) ) ;
+ break;
+ }
+ case PROPERTY_TYPE_FILE:
+ {
+ pgp =new wxFileProperty(fp.name,keyStr, fp.data);
+
+ if(fp.dataSecondary.size())
+ pgp->SetAttribute(wxPG_FILE_WILDCARD,fp.dataSecondary);
+
+ break;
+ }
+ }
+
+ pgp->SetHelpString(fp.helpText);
+
+ g->Append(pgp);
+
+ switch(fp.type)
+ {
+ case PROPERTY_TYPE_BOOL:
+ {
+ g->SetPropertyEditor(pgp,wxPGEditor_CheckBox);
+ break;
+ }
+ default:
+ ;
+ }
+ }
+ }
+
+ //Restore the selected property, if possible
+ if(stateString.size())
+ g->RestoreEditableState(stateString);
+}
+
+void updateCameraPropertyGrid(wxPropertyGrid *g, const Camera *c)
+{
+ ASSERT(c);
+ ASSERT(g);
+
+ g->Clear();
+
+ //Obtain the properties of the currently active camera
+ CameraProperties p;
+ c->getProperties(p);
+
+ for(unsigned int ui=0;ui<p.props.size();ui++)
+ {
+ for(unsigned int uj=0;uj<p.props[ui].size();uj++)
+ {
+ CameraProperty camProp;
+ camProp=p.props[ui][uj];
+
+ string keyStr;
+ stream_cast(keyStr,camProp.key);
+
+ wxPGProperty *pgp;
+ switch(camProp.type)
+ {
+ case PROPERTY_TYPE_BOOL:
+ {
+
+ bool boolVal,decOK;
+ decOK=boolStrDec(camProp.data,boolVal);
+ ASSERT(decOK);
+
+ pgp =new wxBoolProperty( camProp.name, keyStr, boolVal);
+
+ break;
+ };
+ case PROPERTY_TYPE_INTEGER:
+ {
+ long long iV;
+ stream_cast(iV,camProp.data);
+
+ pgp =new wxIntProperty(camProp.name,keyStr,iV);
+ break;
+ }
+ case PROPERTY_TYPE_REAL:
+ {
+ float fV;
+ stream_cast(fV,camProp.data);
+ pgp =new wxFloatProperty(camProp.name,keyStr,fV);
+ break;
+ };
+ case PROPERTY_TYPE_POINT3D:
+ case PROPERTY_TYPE_STRING:
+ {
+ pgp =new wxStringProperty(camProp.name,keyStr, camProp.data);
+ break;
+ }
+ case PROPERTY_TYPE_CHOICE:
+ {
+ vector<string> choices;
+ unsigned int selected;
+ choiceStringToVector(camProp.data,choices,selected);
+
+ wxPGChoices pgChoices;
+ for(unsigned int ui=0;ui<choices.size();ui++)
+ {
+ pgChoices.Add(choices[ui],ui);
+ }
+ pgp = new wxEnumProperty(camProp.name,keyStr,pgChoices,selected);
+ break;
+ }
+ case PROPERTY_TYPE_COLOUR:
+ {
+ ColourRGBA rgba;
+ bool res;
+ res=rgba.parse(camProp.data);
+
+ ASSERT(res);
+ pgp = new wxColourProperty(camProp.name,keyStr,
+ wxColour(rgba.r(),rgba.g(),rgba.b()) ) ;
+ break;
+ }
+ }
+ g->Append(pgp);
+
+ switch(camProp.type)
+ {
+ case PROPERTY_TYPE_BOOL:
+ {
+ g->SetPropertyEditor(pgp,wxPGEditor_CheckBox);
+ break;
+ }
+ default:
+ ;
+ }
+
+ }
+ }
+}
+
+
+std::string getPropValueFromEvent(wxPropertyGridEvent &event)
+{
+ std::string newValue;
+
+ std::string eventType;
+ eventType=event.GetValue().GetType();
+ if(eventType == "wxColour")
+ {
+ wxColour col;
+ col << event.GetValue();
+ //Convert the colour to a string, so we can
+ // send it to the backend.
+ ColourRGBA rgba(col.Red(),col.Green(),col.Blue());
+ newValue=rgba.rgbString();
+ }
+ else if (eventType == "long")
+ {
+ //So wx is a bit confused here
+ // we can either be an integer property, OR
+ // we can be an enum property.
+
+ //integer property
+ wxLongLong ll;
+ ll=event.GetValue().GetLong();
+
+ const wxPGChoices &choices = event.GetProperty()->GetChoices();
+ if(!choices.IsOk())
+ {
+ stream_cast(newValue,ll);
+ }
+ else
+ {
+ //So wx makes life hard here. We need to do a dance to get the selection
+ // as a string
+ unsigned int ul;
+ ul=ll.ToLong();
+
+ wxArrayString arrStr;
+ arrStr=choices.GetLabels();
+ newValue=arrStr[ul];
+ }
+ }
+ else
+ {
+ newValue = event.GetValue().GetString();
+ }
+
+ return newValue;
+}
diff --git a/src/wx/propertyGridUpdater.h b/src/wx/propertyGridUpdater.h
new file mode 100644
index 0000000..aeddbb6
--- /dev/null
+++ b/src/wx/propertyGridUpdater.h
@@ -0,0 +1,43 @@
+/*
+ * propertyGridUpdater.h - Update a propertgy grid, using 3depict backend data
+ * Copyright (C) 2014 D Haley
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PROPERTYGRIDUPDATER_H
+#define PROPERTYGRIDUPDATER_H
+
+#include <wx/propgrid/propgrid.h>
+#include "backend/filter.h"
+
+#include <map>
+
+const long PROPERTY_GRID_STYLE= 0;
+const long PROPERTY_GRID_EXTRA_STYLE= wxPG_EX_HELP_AS_TOOLTIPS;
+
+//Build a property grid for the
+// The filter key is stored as a string in the property name, for
+// each grid item in the property.
+// Due to a wx bug, the grid cannot contain items and be shown
+// when passed ot this function
+// statestring contains the previous grid' state (also part of bug workaround)
+void updateFilterPropertyGrid(wxPropertyGrid *g, const Filter *f, const std::string &stateString);
+
+void updateCameraPropertyGrid(wxPropertyGrid *g, const Camera *c);
+
+//Convert the property grid value into a 3depict-usable string
+std::string getPropValueFromEvent(wxPropertyGridEvent &event);
+
+#endif
diff --git a/src/wx/wxcommon.cpp b/src/wx/wxcommon.cpp
index 9750c69..4a3be51 100644
--- a/src/wx/wxcommon.cpp
+++ b/src/wx/wxcommon.cpp
@@ -87,12 +87,18 @@ std::string locateDataFile(const char *name)
s+=name;
- if(wxFileExists(wxStr(s)))
+ if(wxFileExists((s)))
return s;
}
}
- else if(wxFileExists(wxStr(s)))
- return s;
+
+ std::string s;
+ s =name;
+
+ if(s.size() && wxFileExists((s)))
+ {
+ return string(name);
+ }
else
return std::string("");
#elif defined( __linux__)
@@ -115,7 +121,7 @@ std::string locateDataFile(const char *name)
{
s=std::string(possibleDirs[ui]) + name;
- if(wxFileExists(wxStr(s)))
+ if(wxFileExists((s)))
return s;
}
@@ -132,8 +138,10 @@ std::string locateDataFile(const char *name)
}
CFRelease(resourcesURL);
std::string s=std::string(path) + "/" + name;
- if(wxFileExists(wxStr(s)))
+ if(wxFileExists((s)))
return s;
+ else
+ return std::string("");
#else
// - Look in cwd
@@ -169,7 +177,7 @@ void *VersionCheckThread::Entry()
strUrl = std::string(RSS_FEED_LOCATION) + std::string("?progver=") + std::string(PROGRAM_VERSION) +
std::string("&os=") + stlStr(::wxGetOsDescription());
- wxURI uri(wxStr(strUrl));
+ wxURI uri((strUrl));
rssUrl = uri.BuildURI();
url.SetURL(rssUrl);
@@ -289,8 +297,8 @@ void *VersionCheckThread::Entry()
void wxErrMsg(wxWindow *win, const std::string &title, const std::string &mesg)
{
- wxMessageDialog *wxMesD =new wxMessageDialog(win,wxStr(mesg)
- ,wxStr(title),wxOK|wxICON_ERROR);
+ wxMessageDialog *wxMesD =new wxMessageDialog(win,(mesg)
+ ,(title),wxOK|wxICON_ERROR);
wxMesD->ShowModal();
wxMesD->Destroy();
}
@@ -305,11 +313,7 @@ bool processMatchesName(size_t processID, const std::string &procName)
wxArrayString stdOut;
long res;
-#if wxCHECK_VERSION(2,9,0)
res=wxExecute(wxT("ps ax"),stdOut, wxEXEC_BLOCK);
-#else
- res=wxExecute(wxT("ps ax"),stdOut);
-#endif
if(res !=0 )
return false;
@@ -338,7 +342,7 @@ bool processMatchesName(size_t processID, const std::string &procName)
procNameFound=pidFound=false;
for(unsigned int ui=0;ui<strVec.size(); ui++)
{
- wxFileName fName(wxStr(strVec[ui]));
+ wxFileName fName((strVec[ui]));
std::string maybeProcName;
maybeProcName = stlStr(fName.GetFullName());
@@ -465,6 +469,88 @@ bool processMatchesName(size_t processID, const std::string &procName)
}
#endif
+
+
+
+void copyRGBAtoWXImage(unsigned int width, unsigned int height,
+ const unsigned char *rgbaBuf, wxImage &image,
+ const unsigned char *mask)
+
+{
+ //wx image must have an alpha channel
+ ASSERT(image.HasAlpha());
+ ASSERT(image.GetWidth() == width &&
+ image.GetHeight() == height);
+
+ //FIXME: This will likely be very slow
+ const unsigned char *p=rgbaBuf;
+ for(unsigned int uj=0;uj<height;uj++)
+ {
+ for(unsigned int ui=0;ui<width;ui++)
+ {
+ image.SetRGB(ui,uj,*p, *(p+1), *(p+2));
+
+ if( (*p == *mask) &&
+ ( *(mask+1) == *(p+1)) &&
+ ( *(mask+2) == *(p+2)) )
+ image.SetAlpha(ui,uj,0);
+ else
+ image.SetAlpha(ui,uj,255);
+ p+=4;
+ }
+ }
+
+}
+
+void combineWxImage(wxImage &base, const wxImage &overlay)
+{
+ ASSERT(base.GetWidth() == overlay.GetWidth());
+ ASSERT(base.GetHeight() == overlay.GetHeight());
+ ASSERT(overlay.HasAlpha());
+ ASSERT(base.IsOk() && overlay.IsOk());
+
+
+ unsigned int width=base.GetWidth();
+ unsigned int height=base.GetHeight();
+
+
+ wxImage debugIm(width,height);
+ //Now loop through each pixel and perform
+ // combine operation
+ #pragma omp parallel for
+ for(unsigned int uj=0;uj<height;uj++)
+ {
+ unsigned char rgbIm[3],rgbaOv[4];
+ for(unsigned int ui=0;ui<width;ui++)
+ {
+ rgbaOv[3] = overlay.GetAlpha(ui,uj);
+
+ debugIm.SetRGB(ui,uj,rgbaOv[3], rgbaOv[3],rgbaOv[3]);
+ if(rgbaOv[3])
+ {
+ //obtain src rgb
+ rgbIm[0]=base.GetRed(ui,uj);
+ rgbIm[1]=base.GetGreen(ui,uj);
+ rgbIm[2]=base.GetBlue(ui,uj);
+ //obtain overlay rgb
+ rgbaOv[0]=overlay.GetRed(ui,uj);
+ rgbaOv[1]=overlay.GetGreen(ui,uj);
+ rgbaOv[2]=overlay.GetBlue(ui,uj);
+
+
+ for(unsigned int chan=0;chan<3;chan++)
+ {
+ rgbIm[chan] = (unsigned char) (float(255-rgbaOv[3])/255.0f*rgbIm[chan] + float(rgbaOv[3]/255.0f)*rgbaOv[chan]);
+ }
+
+ base.SetRGB(ui,uj,rgbIm[0],rgbIm[1],rgbIm[2]);
+ }
+ }
+ }
+
+ debugIm.SaveFile("debug.png",wxBITMAP_TYPE_PNG);
+}
+
TreePersistNode::TreePersistNode(const wxTreeCtrl *treeCtrl,wxTreeItemId t)
{
diff --git a/src/wx/wxcommon.h b/src/wx/wxcommon.h
index a4ee534..7d45756 100644
--- a/src/wx/wxcommon.h
+++ b/src/wx/wxcommon.h
@@ -1,6 +1,6 @@
/*
* wxcommon.h - Common wxwidgets header stuff
- * Copyright (C) 2013 D Haley
+ * Copyright (C) 2014 D Haley
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
#include "common/basics.h"
#include "backend/tree.hh"
-#define wxCStr(a) wxString(a,*wxConvCurrent)
-#define wxStr(a) wxString(a.c_str(),*wxConvCurrent)
-
//This function is adapted from
//http://www.creatis.insa-lyon.fr/software/public/creatools/bbtk/v0_9_2/doc/doxygen/bbtk/bbtkWx_8h-source.html
@@ -135,6 +132,13 @@ extern wxEventType RemoteUpdateAvailEvent;
//Return true IFF process ID and process name match running process
bool processMatchesName(size_t processID, const std::string &procName);
+//Copy data into a wx image from an unpadded RGBA block of given width/eight
+// image sould already have been initialised, with RGBA and size
+void copyRGBAtoWXImage(unsigned int width, unsigned int height,
+ const unsigned char *rgbaBuf, wxImage &image, const unsigned char *mask);
+
+//Combine an overlay using the alpha channel
+void combineWxImage(wxImage &base, const wxImage &overlay);
//!Remote version thread checker, downloads RSS file from remote system and then
// parses the file for the latest remote version number
diff --git a/src/wx/wxcomponents.cpp b/src/wx/wxcomponents.cpp
index ca72ced..57de867 100644
--- a/src/wx/wxcomponents.cpp
+++ b/src/wx/wxcomponents.cpp
@@ -89,7 +89,7 @@ void upWxTreeCtrl(const FilterTree &filterTree, wxTreeCtrl *t,
//This will use the user label or the type string.
tid=t->AppendItem(treeIDs.top(),
- wxStr((*filtIt)->getUserString()));
+ ((*filtIt)->getUserString()));
t->SetItemData(tid,new wxTreeUint(nextID));
@@ -165,480 +165,6 @@ std::string choiceStringToCommaDelim(std::string choiceString)
return retStr;
}
-BEGIN_EVENT_TABLE(wxCustomPropGrid, wxGrid)
- EVT_GRID_CELL_LEFT_CLICK(wxCustomPropGrid::OnCellLeftClick )
- EVT_GRID_LABEL_LEFT_DCLICK(wxCustomPropGrid::OnLabelDClick)
- EVT_MOTION(wxCustomPropGrid::OnMouseMove)
-END_EVENT_TABLE()
-
-wxCustomPropGrid::wxCustomPropGrid(wxWindow* parent, wxWindowID id,
- const wxPoint& pos , const wxSize& size , long style ) :
- wxGrid(parent, id, pos, size , style)
-{
- lastGridHoverCol=lastGridHoverRow=-1;
- //Perform wx event connecting/binding
-#if wxCHECK_VERSION(2, 9, 0)
- GetGridWindow()->Bind(wxEVT_MOTION, &wxCustomPropGrid::OnMouseMove, this);
-#else
- GetGridWindow()->Connect(wxID_ANY,
- wxEVT_MOTION, wxMouseEventHandler(wxCustomPropGrid::OnMouseMove), NULL, this);
-#endif
-}
-
-
-void wxCustomPropGrid::setGroupName(unsigned int set, const std::string &name)
-{
- ASSERT(set < sectionNames.size());
- sectionNames[set]=name;
-}
-
-void wxCustomPropGrid::OnSize(wxSizeEvent &event)
-{
-
-}
-
-void wxCustomPropGrid::OnLabelDClick(wxGridEvent &event)
-{
-#if wxCHECK_VERSION(2,9,0)
- if(!this->GetNumberCols())
-#else
- if(!this->GetCols())
-#endif
- return;
- wxSize s;
- s=this->GetSize();
- fitCols(s);
- SelectBlock(-1,-1,-1,-1); //Select empty block
-}
-
-void wxCustomPropGrid::fitCols(wxSize &size)
-{
- int wc = size.GetWidth()-this->GetScrollThumb(wxVERTICAL)-15;
- int colSize = this->GetColSize(0) ;
-
- //SetColSize complains with negative argument
- if(wc - colSize < 0)
- return;
-
- this->SetColSize(1, wc-colSize);
-
- Refresh();
-}
-
-wxCustomPropGrid::~wxCustomPropGrid()
-{
-#if wxCHECK_VERSION(2, 9, 0)
- GetGridWindow()->Unbind(wxEVT_MOTION, &wxCustomPropGrid::OnMouseMove, this);
-#else
- GetGridWindow()->Disconnect();
-#endif
-}
-
-//Function adapted from nomadsync.sourceforge.net (GPL)
-void wxGridCellChoiceRenderer::Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
- const wxRect& rectCell, int row, int col, bool isSelected)
-{
- wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
- // first calculate button size
- // don't draw outside the cell
- int nButtonWidth = 17;
- if (rectCell.height < 2) return;
- wxRect rectButton;
- rectButton.x = rectCell.x + rectCell.width - nButtonWidth;
- rectButton.y = rectCell.y + 1;
- int cell_rows, cell_cols;
- attr.GetSize(&cell_rows, &cell_cols);
- rectButton.width = nButtonWidth;
- if (cell_rows == 1)
- rectButton.height = rectCell.height-2;
- else
- rectButton.height = nButtonWidth;
-
- SetTextColoursAndFont(grid, attr, dc, isSelected);
- int hAlign, vAlign;
- attr.GetAlignment(&hAlign, &vAlign);
- // leave room for button
- wxRect rect = rectCell;
- rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth()-2);
- rect.Inflate(-1);
- grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign);
-
- // don't bother drawing if the cell is too small
- if (rectButton.height < 4 || rectButton.width < 4) return;
- // draw 3-d button
- wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
- dc.SetBrush(wxBrush(colourBackGround, wxSOLID));
- dc.SetPen(wxPen(colourBackGround, 1, wxSOLID));
- dc.DrawRectangle(rectButton);
- dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));
- dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(),
- rectButton.GetRight(), rectButton.GetBottom());
- dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(),
- rectButton.GetRight(), rectButton.GetTop()-1);
- dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW),
- 1, wxSOLID));
- dc.DrawLine(rectButton.GetLeft()+1, rectButton.GetBottom()-1,
- rectButton.GetRight()-1, rectButton.GetBottom()-1);
- dc.DrawLine(rectButton.GetRight()-1, rectButton.GetBottom()-1,
- rectButton.GetRight()-1, rectButton.GetTop());
- dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT),
- 1, wxSOLID));
- dc.DrawLine(rectButton.GetRight()-2, rectButton.GetTop()+1,
- rectButton.GetLeft()+1, rectButton.GetTop()+1);
- dc.DrawLine(rectButton.GetLeft()+1, rectButton.GetTop()+1,
- rectButton.GetLeft()+1, rectButton.GetBottom()-1);
- // Draw little triangle
- int nTriWidth = 7;
- int nTriHeight = 4;
- wxPoint point[3];
- point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth()-nTriWidth)/2,
- rectButton.GetTop()+(rectButton.GetHeight()-nTriHeight)/2);
- point[1] = wxPoint(point[0].x+nTriWidth-1, point[0].y);
- point[2] = wxPoint(point[0].x+3, point[0].y+nTriHeight-1);
- dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID));
- dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));
- dc.DrawPolygon(3, point);
- if (m_border == wxLAYOUT_TOP)
- {
- dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
- dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(),
- rectCell.GetLeft(), rectCell.GetTop());
- }
-}
-
-bool wxCustomPropGrid::isSeparatorRow(int row) const
-{
- //TODO: Consider moving to map, this does not scale well.
- // for now we have usually five or six items tho
- return std::find(sepRows.begin(),sepRows.end(),row)!=sepRows.end();
-}
-
-void wxCustomPropGrid::OnMouseMove(wxMouseEvent &event)
-{
-
- int xPos,yPos;
- int xMouse,yMouse;
- event.GetPosition(&xMouse,&yMouse);
-
- CalcUnscrolledPosition(xMouse,yMouse,&xPos,&yPos);
-
- int row,col;
- row=YToRow(yPos);
- col=XToCol(xPos);
-
- //Check if the column or row was different
- if(col != lastGridHoverCol || row != lastGridHoverRow)
- {
- lastGridHoverRow = row;
- lastGridHoverCol = col;
-
- //If we are hovering over a "spacer" row,
- //the null row, or not on the prop
- //column, then bail out
- if(isSeparatorRow(row) || row == -1 || col == 1)
- {
- GetGridWindow()->SetToolTip(NULL); //Hide the tooltip
- event.Skip();
- return;
- }
-
- //Set the help text based upon the group property
- const GRID_PROPERTY *p;
- p=getProperty(getKeyFromRow(row));
-
- GetGridWindow()->SetToolTip(wxStr(p->helpText));
- }
-
- event.Skip();
-}
-
-//Function adapted from nomadsync.sourceforge.net (GPL)
-void wxCustomPropGrid::OnCellLeftClick(wxGridEvent &ev)
-{
- // This forces the cell to go into edit mode directly
- m_waitForSlowClick = true;
- SetGridCursor(ev.GetRow(), ev.GetCol());
-
- // hack to prevent selection from being lost when click combobox
- if (ev.GetCol() == 0 && IsInSelection(ev.GetRow(), ev.GetCol()))
- {
- m_selection = NULL;
- }
- ev.Skip();
-}
-
-void wxCustomPropGrid::clear()
-{
- this->BeginBatch();
- //Empty the grid
- if(this->GetNumberCols())
- this->DeleteCols(0,this->GetNumberCols());
- if(this->GetNumberRows())
- this->DeleteRows(0,this->GetNumberRows());
-
-
- propertyKeys.clear();
- this->EndBatch();
-
- GetGridWindow()->SetToolTip(wxT(""));
- lastGridHoverRow=lastGridHoverCol=-1;
-}
-
-bool wxCustomPropGrid::isComboEditing()
-{
- bool retVal;
- retVal= IsCellEditControlEnabled();
-#if wxCHECK_VERSION(2,9,0)
- retVal = retVal &&getTypeFromRow(this->GetGridCursorRow()) == PROPERTY_TYPE_CHOICE;
-#else
- retVal = retVal && getTypeFromRow(this->GetCursorRow()) == PROPERTY_TYPE_CHOICE;
-#endif
- return retVal;
-};
-
-unsigned int wxCustomPropGrid::getTypeFromRow(int row) const
-{
- for(unsigned int ui=0;ui<propertyKeys.size();ui++)
- {
-
- for(unsigned int uj=0;uj<propertyKeys[ui].size();uj++)
- {
- if(propertyKeys[ui][uj].renderPosition == row)
- return propertyKeys[ui][uj].type;
- }
- }
-
- ASSERT(false);
- return 0; // Shut gcc up
-}
-
-void wxCustomPropGrid::clearKeys()
-{
- propertyKeys.clear();
- sectionNames.clear();
-}
-
-void wxCustomPropGrid::addKey(const std::string &name, unsigned int group,
- unsigned int newKey, unsigned int type, const std::string &data,
- const std::string &helpText)
-{
-
- GRID_PROPERTY newProp;
- newProp.key=newKey;
- newProp.type=type;
- newProp.name=name;
- newProp.data=data;
- newProp.helpText = helpText;
- propertyKeys[group].push_back(newProp);
-}
-
-//Layout the property vector
-void wxCustomPropGrid::propertyLayout()
-{
- this->BeginBatch();
-
- //Empty the grid
- if(this->GetNumberCols())
- this->DeleteCols(0,this->GetNumberCols());
- if(this->GetNumberRows())
- this->DeleteRows(0,this->GetNumberRows());
-
- this->AppendCols(2);
- this->SetColLabelValue(0,wxTRANS("Param"));
- this->SetColLabelValue(1,wxTRANS("Value"));
-
- sepRows.clear();
- sepRows.resize(propertyKeys.size());
- int rows=0;
- for (unsigned int ui=0; ui<propertyKeys.size(); ui++)
- {
- //One row for each property
- for (unsigned uj=0; uj<propertyKeys[ui].size(); uj++)
- propertyKeys[ui][uj].renderPosition=rows+uj;
-
- rows+=propertyKeys[ui].size();
-
- //One row for separator
- sepRows[ui] = rows;
- rows++;
- }
-
- //Remove last separator row.
- if (rows)
- rows--;
- this->AppendRows(rows);
-
- for (unsigned int ui=0; ui<propertyKeys.size(); ui++)
- {
- for (unsigned int uj=0; uj<propertyKeys[ui].size(); uj++)
- {
- //set the title
- this->SetCellValue(propertyKeys[ui][uj].renderPosition,
- 0,wxStr(propertyKeys[ui][uj].name));
-
- //Set the cell renderer
- wxGridCellAttr *attr = this->GetOrCreateCellAttr(
- propertyKeys[ui][uj].renderPosition, 1);
-
- //Attr will return 0 if the grid is not created.
- //you must create the grid before calling this function
- //(see wxGrd::CreateGrid(i,j)
- ASSERT(attr);
- //The datatype determines the appearance of the combo box
- switch (propertyKeys[ui][uj].type)
- {
- case PROPERTY_TYPE_BOOL:
- attr->SetRenderer(new wxGridCellBoolRenderer());
- //set the data
- this->SetCellValue(propertyKeys[ui][uj].renderPosition,
- 1,wxStr(propertyKeys[ui][uj].data));
- break;
- case PROPERTY_TYPE_INTEGER:
- attr->SetRenderer(new wxGridCellNumberRenderer());
- //set the data
- this->SetCellValue(propertyKeys[ui][uj].renderPosition,
- 1,wxStr(propertyKeys[ui][uj].data));
- break;
- case PROPERTY_TYPE_REAL:
- attr->SetRenderer(new wxGridCellFloatRenderer());
- //set the data
- this->SetCellValue(propertyKeys[ui][uj].renderPosition,
- 1,wxStr(propertyKeys[ui][uj].data));
- break;
- case PROPERTY_TYPE_COLOUR:
- //OK, this is totally inefficient, and hacky. but set the colour
- //based upon the colour string. Then when user edits, use a colour
- //dialog (handled elsewhere)
- unsigned char r,g,b,a;
- parseColString(propertyKeys[ui][uj].data,r,g,b,a);
- attr->SetBackgroundColour(wxColour(r,g,b,a));
-
- break;
- case PROPERTY_TYPE_CHOICE:
- {
- //set up the renderer
- std::string s;
- s=getActiveChoice(propertyKeys[ui][uj].data);
- attr->SetRenderer(new wxGridCellChoiceRenderer());
- this->SetCellValue(propertyKeys[ui][uj].renderPosition,
- 1,wxStr(s));
-
- //construct a wxStringArray of possible choices.
- s=choiceStringToCommaDelim(propertyKeys[ui][uj].data);
- vector<std::string> splitStrs;
- wxArrayString a;
- splitStrsRef(s.c_str(),',',splitStrs);
- for (unsigned int uk=0; uk<splitStrs.size(); uk++)
- a.Add(wxStr(splitStrs[uk]));
- //Set up the editor
- wxGridCellChoiceEditor *choiceEd=new wxFastComboEditor(a,false);
- this->SetCellEditor(propertyKeys[ui][uj].renderPosition,
- 1,choiceEd);
-
- //Required to prevent wx from asserting,
- // "GetEventHandler == this" failed in ~wxWindowBase(), any pushed event handlers must be removed".
- // I posted on the wxwidgets forum and got the reply that I should try this, but they were not sure.
- // seems to work
- attr->DecRef();
- break;
- }
- case PROPERTY_TYPE_STRING:
- case PROPERTY_TYPE_POINT3D:
- //set the data
- this->SetCellValue(propertyKeys[ui][uj].renderPosition,
- 1,wxStr(propertyKeys[ui][uj].data));
- break;
- }
-
-
- }
-
- //Add a blank, light grey, read only row, but not if it is the last
- //use to denote spacing between sets to user.
- if (ui+1 < propertyKeys.size())
- {
- //Optionally give it a description; if one has been provided
- if(sectionNames[ui+1].size())
- {
- this->SetCellValue(sepRows[ui],0,wxStr(sectionNames[ui+1]));
- wxFont f;
- f=*wxSMALL_FONT;
- f.SetStyle(wxFONTSTYLE_ITALIC);
- f.SetPointSize((int)(f.GetPointSize()*FONT_HEADING_SCALEFACTOR));
- this->SetCellFont(sepRows[ui],0,f);
- }
-
- wxGridCellAttr *readOnlyRowAttr=new wxGridCellAttr;
- readOnlyRowAttr->SetReadOnly(true);
- readOnlyRowAttr->SetBackgroundColour(wxColour(*wxLIGHT_GREY));
- this->SetRowAttr(sepRows[ui],readOnlyRowAttr);
-
- }
- }
-
- //First column is read only
- wxGridCellAttr *readOnlyGridAttr=new wxGridCellAttr;
- readOnlyGridAttr->SetReadOnly(true);
- SetColAttr(0,readOnlyGridAttr);
- //Remove labels for column lead-in
- SetRowLabelSize(0);
- SetMargins(0,0);
-
- AutoSizeColumn(0,true);
- EndBatch();
-
- //Expand the column contents to fit current size
- wxSize s;
- s=GetSize();
- fitCols(s);
-}
-
-unsigned int wxCustomPropGrid::getKeyFromRow(int row) const
-{
- for(unsigned int ui=0;ui<propertyKeys.size();ui++)
- {
-
- for(unsigned int uj=0;uj<propertyKeys[ui].size();uj++)
- {
- if(propertyKeys[ui][uj].renderPosition == row)
- return propertyKeys[ui][uj].key;
- }
- }
-
- ASSERT(false);
- return 0; // Shut gcc up
-}
-
-const GRID_PROPERTY *wxCustomPropGrid::getProperty(unsigned int key) const
-{
- for(unsigned int group=0;group<propertyKeys.size();group++)
- {
- for(unsigned int ui=0;ui<propertyKeys[group].size(); ui++)
- {
- if(propertyKeys[group][ui].key == key)
- return &(propertyKeys[group][ui]);
- }
- }
- return 0;
-}
-
-void wxFastComboEditor::BeginEdit(int row, int col, wxGrid* grid)
-{
- wxGridCellChoiceEditor::BeginEdit(row, col, grid);
- // unfortunately I don't know how to send a left button down message to a
- // control in GTK, if anyone can give me a hint it would be greatly appreciated :)
-#ifdef __WINDOWS__
- DWORD style = ::GetWindowLong((HWND)Combo()->GetHandle(), GWL_STYLE);
- style &= ~WS_TABSTOP;
- ::SetWindowLong((HWND)Combo()->GetHandle(), GWL_STYLE, style);
- if (m_pointActivate.x > -1 && m_pointActivate.y > -1)
- {
- m_pointActivate = Combo()->ScreenToClient(m_pointActivate);
- SendMessage((HWND)Combo()->GetHandle(), WM_LBUTTONDOWN, 0,
- MAKELPARAM(m_pointActivate.x, m_pointActivate.y));
- }
-#endif
-}
BEGIN_EVENT_TABLE(CopyGrid, wxGrid)
EVT_KEY_DOWN(CopyGrid::OnKey)
@@ -658,8 +184,8 @@ void CopyGrid::selectData()
void CopyGrid::saveData()
{
- wxFileDialog *wxF = new wxFileDialog(this,wxTRANS("Save Data..."), wxT(""),
- wxT(""),wxTRANS("Text File (*.txt)|*.txt|All Files (*)|*"),wxFD_SAVE);
+ wxFileDialog *wxF = new wxFileDialog(this,TRANS("Save Data..."), wxT(""),
+ wxT(""),TRANS("Text File (*.txt)|*.txt|All Files (*)|*"),wxFD_SAVE);
if( (wxF->ShowModal() == wxID_CANCEL))
return;
@@ -671,7 +197,7 @@ void CopyGrid::saveData()
if(!f)
{
wxMessageDialog *wxD =new wxMessageDialog(this,
- wxTRANS("Error saving file. Check output dir is writable."),wxTRANS("Save error"),wxOK|wxICON_ERROR);
+ TRANS("Error saving file. Check output dir is writable."),TRANS("Save error"),wxOK|wxICON_ERROR);
wxD->ShowModal();
wxD->Destroy();
@@ -681,13 +207,8 @@ void CopyGrid::saveData()
// Number of rows and cols
int rows,cols;
-#if wxCHECK_VERSION(2,9,0)
rows=GetNumberRows();
cols=GetNumberCols();
-#else
- rows=GetRows();
- cols=GetCols();
-#endif
// data variable contain text that must be set in the clipboard
// For each cell in selected range append the cell value in the data
//variable
@@ -883,7 +404,7 @@ void CopyGrid::copyData()
{
wxTextDataObject* clipData= new wxTextDataObject;
// Set data object value
- clipData->SetText(wxStr(data));
+ clipData->SetText((data));
wxTheClipboard->UsePrimarySelection(false);
wxTheClipboard->SetData(clipData);
wxTheClipboard->Close();
@@ -934,7 +455,7 @@ void TextTreeCtrl::OnTreePaint(wxPaintEvent &event)
if(font.IsOk())
dc->SetFont(font);
- wxSize textSize=dc->GetTextExtent(wxStr(messageStrs[idx]));
+ wxSize textSize=dc->GetTextExtent((messageStrs[idx]));
//Don't go ahead with the drawing if the text
// won't fit in the control
@@ -948,23 +469,26 @@ void TextTreeCtrl::OnTreePaint(wxPaintEvent &event)
}
//Draw each text in turn, advancing by spacing
-
+
+//FIXME dc->DrawText missing under windows?
+#ifndef __WIN32__
// start far enough back so that
float startY= 0.5*(h - blockHeight);
for(size_t ui=0;ui<messageStrs.size();ui++)
{
- textSize=dc->GetTextExtent(wxStr(messageStrs[ui]));
+ textSize=dc->GetTextExtent((messageStrs[ui]));
int startX;
startX=w/2 - textSize.GetWidth()/2;
- dc->DrawText(wxStr(messageStrs[ui]),
+ dc->DrawText((messageStrs[ui]),
startX,startY);
startY+=HEIGHT_SPACING*textSize.GetHeight();
}
delete dc;
+#endif
}
std::string TTFFinder::findFont(const char *fontFile)
@@ -999,14 +523,14 @@ std::string TTFFinder::macFindFont(const char *fontFile)
//Try a few standard locations
while(strlen(dirs[ui]))
{
- p->Add(wxCStr(dirs[ui]));
+ p->Add((dirs[ui]));
ui++;
};
wxString s;
//execute the search for the file
- s= p->FindValidPath(wxCStr(fontFile));
+ s= p->FindValidPath((fontFile));
std::string res;
@@ -1045,14 +569,14 @@ std::string TTFFinder::nxFindFont(const char *fontFile)
//Try a few standard locations
while(strlen(dirs[ui]))
{
- p->Add(wxCStr(dirs[ui]));
+ p->Add((dirs[ui]));
ui++;
};
wxString s;
//execute the search for the file
- s= p->FindValidPath(wxCStr(fontFile));
+ s= p->FindValidPath((fontFile));
std::string res;
@@ -1081,7 +605,7 @@ std::string TTFFinder::winFindFont(const char *fontFile)
//Try a few standard locations
while(strlen(dirs[ui]))
{
- p->Add(wxCStr(dirs[ui]));
+ p->Add((dirs[ui]));
ui++;
};
@@ -1090,7 +614,7 @@ std::string TTFFinder::winFindFont(const char *fontFile)
//execute the search for the file
- s= p->FindValidPath(wxCStr(fontFile));
+ s= p->FindValidPath((fontFile));
std::string res;
diff --git a/src/wx/wxcomponents.h b/src/wx/wxcomponents.h
index b10d790..0405ef3 100644
--- a/src/wx/wxcomponents.h
+++ b/src/wx/wxcomponents.h
@@ -30,22 +30,6 @@
#include "backend/filtertree.h"
-//Shut wxwidgets assertion errors up by defining a "safe" cb_sort wrapper macro
-#if defined(__WXMAC__) || defined(__WXGTK20__)
-
- #include <wx/version.h>
- #if wxCHECK_VERSION(2,9,0)
- //Sorted combos not supported under gtk in 2.8 series
- // http://trac.wxwidgets.org/ticket/4398
- //and not supported in mac.
- // http://trac.wxwidgets.org/ticket/12419
- #define SAFE_CB_SORT 0
- #else
- #define SAFE_CB_SORT wxCB_SORT
- #endif
-#else
- #define SAFE_CB_SORT wxCB_SORT
-#endif
//!3D combo grid renderer, from
@@ -122,88 +106,7 @@ class wxListUint : public wxClientData
unsigned int value;
};
-struct GRID_PROPERTY
-{
- unsigned int key;
- unsigned int type;
- int renderPosition;
- std::string name;
- std::string data; //String version of data stored
- std::string helpText; //Hover tool-tip help text
-};
-
-class wxCustomPropGrid;
-
-//!WxGrid derived class to hold and display property data
-//So it turns out that someone has MADE a property grid.
-//http://wxpropgrid.sourceforge.ne
-//This code is not from there. Maybe I should
-//use their code instead, its bound to be better.
-//Also, this appears up in the wxwidgets SVN,
-//so maybe there will be a name clash in future
-class wxCustomPropGrid : public wxGrid
-{
- protected:
- //First element is key number. Second element is key type
- std::vector<std::vector<GRID_PROPERTY> > propertyKeys;
- //Names of each of the grouped keys in propertyKeys
- std::vector<std::string> sectionNames;
-
- //Fit the columns to the specified size
- void fitCols(wxSize &size);
-
- //Rows used for separators
- std::vector<int> sepRows;
- //The last coordinates of mouse hovering
- size_t lastGridHoverCol,lastGridHoverRow;
-
- //Is the nth row a separator row?
- bool isSeparatorRow(int row) const;
- public:
- wxCustomPropGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS);
- ~wxCustomPropGrid();
-
- void OnSize(wxSizeEvent &size);
- void OnLabelDClick(wxGridEvent &size);
- void OnMouseMove(wxMouseEvent &mouse);
- void clearKeys();
-
- //!Set the number of separator groups to use
- void setNumGroups(unsigned int newGroupCount){propertyKeys.resize(newGroupCount); sectionNames.resize(newGroupCount);};
-
- //Set the names for each group. This will appear as a small text in the blank rows
- void setGroupName(unsigned int set, const std::string &name);
-
- //!This adds the item to the property key vector of a specified group
- //! key must be unique
- void addKey(const std::string &name, unsigned int group,
- unsigned int newKey, unsigned int type,
- const std::string &data,const std::string &helpText);
-
- //!Click event
- virtual void OnCellLeftClick(wxGridEvent &e);
- //!Cause grid to layout its elements
- void propertyLayout();
-
- //!Get the key from the row
- unsigned int getKeyFromRow(int row) const;
-
- //!Get the type from the row
- unsigned int getTypeFromRow(int row) const;
-
- //!Get the property from key and set
- const GRID_PROPERTY* getProperty(unsigned int key) const;
-
- //!Clear the grid
- void clear();
-
- //!Are we editing a combo box?
- bool isComboEditing() ;
-
- DECLARE_EVENT_TABLE()
-};
//A wx Grid with copy & paste support
class CopyGrid : public wxGrid
diff --git a/test/dogtail/test.py b/test/dogtail/test.py
index 039fc9d..6e66890 100755
--- a/test/dogtail/test.py
+++ b/test/dogtail/test.py
@@ -293,7 +293,7 @@ def prefTests(app3depict):
prefDialog=app3depict.findChild(element("Preferences","frame"));
#Get defaults tab
- tabFilterDefaults=prefDialog.findChild(element("Pref","page tab",));
+ tabFilterDefaults=prefDialog.findChild(element("Filt. Default","page tab",));
#Walk through all the filter entries in the list, clicking each one
listFilters=tabFilterDefaults.findChild(element("","table"))
listFilterEntries=tabFilterDefaults.findChildren(element("","table cell"))
diff --git a/translations/3Depict_base.pot b/translations/3Depict_base.pot
index 6ae63d3..2c9adb0 100644
--- a/translations/3Depict_base.pot
+++ b/translations/3Depict_base.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-04-12 18:12+0200\n"
+"POT-Creation-Date: 2014-08-23 15:32+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -17,25 +17,25 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../src/gl/cameras.cpp:598 ../src/gl/cameras.cpp:600
+#: ../src/gl/cameras.cpp:596
msgid "Lock"
msgstr ""
-#: ../src/gl/cameras.cpp:607 ../src/backend/filters/ionClip.cpp:526
-#: ../src/backend/filters/ionClip.cpp:548
-#: ../src/backend/filters/ionClip.cpp:570
-#: ../src/backend/filters/ionClip.cpp:610
-#: ../src/backend/filters/compositionProfile.cpp:1015
-#: ../src/backend/filters/compositionProfile.cpp:1056
-#: ../src/backend/filters/spatialAnalysis.cpp:599
-#: ../src/backend/filters/transform.cpp:1264
-#: ../src/backend/filters/transform.cpp:1291
-#: ../src/backend/filters/transform.cpp:1317
-#: ../src/backend/filters/annotation.cpp:569
+#: ../src/gl/cameras.cpp:603 ../src/backend/filters/ionClip.cpp:519
+#: ../src/backend/filters/ionClip.cpp:541
+#: ../src/backend/filters/ionClip.cpp:563
+#: ../src/backend/filters/ionClip.cpp:600
+#: ../src/backend/filters/compositionProfile.cpp:964
+#: ../src/backend/filters/compositionProfile.cpp:1002
+#: ../src/backend/filters/spatialAnalysis.cpp:774
+#: ../src/backend/filters/transform.cpp:1216
+#: ../src/backend/filters/transform.cpp:1243
+#: ../src/backend/filters/transform.cpp:1269
+#: ../src/backend/filters/annotation.cpp:563
msgid "Origin"
msgstr ""
-#: ../src/gl/cameras.cpp:612 ../src/backend/filters/spatialAnalysis.cpp:518
+#: ../src/gl/cameras.cpp:611 ../src/backend/filters/spatialAnalysis.cpp:697
msgid "Target"
msgstr ""
@@ -43,12 +43,12 @@ msgstr ""
msgid "Up Dir."
msgstr ""
-#: ../src/gl/cameras.cpp:625 ../src/gl/cameras.cpp:729
+#: ../src/gl/cameras.cpp:625 ../src/gl/cameras.cpp:728
msgid "Perspective"
msgstr ""
-#: ../src/gl/cameras.cpp:627 ../src/gl/cameras.cpp:731
-#: ../src/gui/mainFrame.cpp:5396
+#: ../src/gl/cameras.cpp:627 ../src/gl/cameras.cpp:730
+#: ../src/gui/mainFrame.cpp:5134
msgid "Orthogonal"
msgstr ""
@@ -56,167 +56,135 @@ msgstr ""
msgid "Projection"
msgstr ""
-#: ../src/gl/cameras.cpp:639
+#: ../src/gl/cameras.cpp:640
msgid "Field of View (deg)"
msgstr ""
-#: ../src/gl/cameras.cpp:645
+#: ../src/gl/cameras.cpp:646
msgid "View size"
msgstr ""
-#: ../src/wx/wxcomponents.cpp:441 ../src/gui/dialogs/ExportRngDialog.cpp:88
-#: ../src/gui/dialogs/prefDialog.cpp:110
-msgid "Param"
-msgstr ""
-
-#: ../src/wx/wxcomponents.cpp:442 ../src/gui/dialogs/ExportRngDialog.cpp:89
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:109
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:356
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1186
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1211
-#: ../src/gui/dialogs/prefDialog.cpp:111 ../src/gui/mainFrame.cpp:5849
-#: ../src/gui/mainFrame.cpp:5854 ../src/backend/filters/dataLoad.cpp:575
-msgid "Value"
-msgstr ""
-
-#: ../src/wx/wxcomponents.cpp:655
+#: ../src/wx/wxcomponents.cpp:187
msgid "Save Data..."
msgstr ""
-#: ../src/wx/wxcomponents.cpp:656
+#: ../src/wx/wxcomponents.cpp:188
msgid "Text File (*.txt)|*.txt|All Files (*)|*"
msgstr ""
-#: ../src/wx/wxcomponents.cpp:668
+#: ../src/wx/wxcomponents.cpp:200
msgid "Error saving file. Check output dir is writable."
msgstr ""
-#: ../src/wx/wxcomponents.cpp:668 ../src/gui/dialogs/ExportRngDialog.cpp:170
-#: ../src/gui/mainFrame.cpp:1422 ../src/gui/mainFrame.cpp:1548
-#: ../src/gui/mainFrame.cpp:1583 ../src/gui/mainFrame.cpp:1659
-#: ../src/gui/mainFrame.cpp:2213 ../src/gui/mainFrame.cpp:2279
-#: ../src/gui/mainFrame.cpp:2371 ../src/gui/mainFrame.cpp:2486
+#: ../src/wx/wxcomponents.cpp:200 ../src/gui/dialogs/ExportRngDialog.cpp:170
+#: ../src/gui/mainFrame.cpp:1446 ../src/gui/mainFrame.cpp:1572
+#: ../src/gui/mainFrame.cpp:1621 ../src/gui/mainFrame.cpp:1697
+#: ../src/gui/mainFrame.cpp:2253 ../src/gui/mainFrame.cpp:2319
+#: ../src/gui/mainFrame.cpp:2411 ../src/gui/mainFrame.cpp:2526
msgid "Save error"
msgstr ""
-#: ../src/common/basics.cpp:62 ../src/backend/APT/APTFileIO.cpp:65
-#: ../src/backend/APT/APTFileIO.cpp:89
-msgid "Error opening file"
-msgstr ""
-
-#: ../src/common/basics.cpp:63
-msgid "Error whilst reading file contents"
-msgstr ""
-
-#: ../src/common/basics.cpp:64 ../src/backend/APT/APTFileIO.cpp:69
-msgid "Error interpreting field in file"
-msgstr ""
-
-#: ../src/common/basics.cpp:65
-msgid "Inconsistent number of columns found"
-msgstr ""
-
-#: ../src/common/basics.cpp:197
+#: ../src/common/basics.cpp:183
msgid "in the future?"
msgstr ""
-#: ../src/common/basics.cpp:248
+#: ../src/common/basics.cpp:234
msgid "a decade ago"
msgstr ""
-#: ../src/common/basics.cpp:249
+#: ../src/common/basics.cpp:235
msgid "a year ago"
msgstr ""
-#: ../src/common/basics.cpp:250
+#: ../src/common/basics.cpp:236
msgid "a month ago"
msgstr ""
-#: ../src/common/basics.cpp:251
+#: ../src/common/basics.cpp:237
msgid "a week ago"
msgstr ""
-#: ../src/common/basics.cpp:252
+#: ../src/common/basics.cpp:238
msgid "a day ago"
msgstr ""
-#: ../src/common/basics.cpp:253
+#: ../src/common/basics.cpp:239
msgid "an hour ago"
msgstr ""
-#: ../src/common/basics.cpp:254
+#: ../src/common/basics.cpp:240
msgid "45 minutes ago"
msgstr ""
-#: ../src/common/basics.cpp:255
+#: ../src/common/basics.cpp:241
msgid "30 minutes ago"
msgstr ""
-#: ../src/common/basics.cpp:256
+#: ../src/common/basics.cpp:242
msgid "20 minutes ago"
msgstr ""
-#: ../src/common/basics.cpp:257
+#: ../src/common/basics.cpp:243
msgid "15 minutes ago"
msgstr ""
-#: ../src/common/basics.cpp:258
+#: ../src/common/basics.cpp:244
msgid "10 minutes ago"
msgstr ""
-#: ../src/common/basics.cpp:259
+#: ../src/common/basics.cpp:245
msgid "5 minutes ago"
msgstr ""
-#: ../src/common/basics.cpp:260
+#: ../src/common/basics.cpp:246
msgid "a minute ago"
msgstr ""
-#: ../src/common/basics.cpp:261
+#: ../src/common/basics.cpp:247
msgid "30 seconds ago"
msgstr ""
-#: ../src/common/basics.cpp:262
+#: ../src/common/basics.cpp:248
msgid "10 seconds ago"
msgstr ""
-#: ../src/common/basics.cpp:263
+#: ../src/common/basics.cpp:249
msgid "a second ago"
msgstr ""
-#: ../src/common/basics.cpp:268
+#: ../src/common/basics.cpp:254
msgid "a few decades ago"
msgstr ""
-#: ../src/common/basics.cpp:269
+#: ../src/common/basics.cpp:255
msgid "a few years ago"
msgstr ""
-#: ../src/common/basics.cpp:270
+#: ../src/common/basics.cpp:256
msgid "a few months ago"
msgstr ""
-#: ../src/common/basics.cpp:271
+#: ../src/common/basics.cpp:257
msgid "a few weeks ago"
msgstr ""
-#: ../src/common/basics.cpp:272
+#: ../src/common/basics.cpp:258
msgid "a few days ago"
msgstr ""
-#: ../src/common/basics.cpp:273
+#: ../src/common/basics.cpp:259
msgid "a few hours ago"
msgstr ""
-#: ../src/common/basics.cpp:280
+#: ../src/common/basics.cpp:266
msgid "a few minutes ago"
msgstr ""
-#: ../src/common/basics.cpp:283
+#: ../src/common/basics.cpp:269
msgid "a few seconds ago"
msgstr ""
-#: ../src/common/basics.cpp:310
+#: ../src/common/basics.cpp:296
msgid "moments ago"
msgstr ""
@@ -252,40 +220,43 @@ msgstr ""
msgid "Pseudo-Random"
msgstr ""
-#: ../src/gui/glPane.cpp:670
+#: ../src/common/constants.cpp:22
+msgid ""
+"Range Files (*.rng; *.env; *.rrng)|*.rng;*.env;*.rrng;*.RRNG;*.RNG;*.ENV|RNG "
+"File (*.rng)|*.rng;*.RNG|Environment File (*.env)|*.env;*.ENV|RRNG Files (*."
+"rrng)|*.rrng;*.RRNG|All Files (*)|*"
+msgstr ""
+
+#: ../src/gui/glPane.cpp:637
msgid "Use shift/ctrl-space or double tap to alter reset axis"
msgstr ""
-#: ../src/gui/glPane.cpp:934
+#: ../src/gui/glPane.cpp:910
msgid "Image progress"
msgstr ""
-#: ../src/gui/glPane.cpp:935
+#: ../src/gui/glPane.cpp:911
msgid "Rendering tiles..."
msgstr ""
-#: ../src/gui/glPane.cpp:969
-msgid "Tile "
-msgstr ""
-
-#: ../src/gui/glPane.cpp:969 ../src/gui/glPane.cpp:1080
-#: ../src/gui/mainFrame.cpp:4279 ../src/gui/mainFrame.cpp:4283
-#: ../src/gui/mainFrame.cpp:4296 ../src/backend/filters/dataLoad.cpp:311
-msgid " of "
-msgstr ""
-
-#: ../src/gui/glPane.cpp:1041
+#: ../src/gui/glPane.cpp:1097
msgid "Animation progress"
msgstr ""
-#: ../src/gui/glPane.cpp:1042
+#: ../src/gui/glPane.cpp:1098
msgid "Rendering sequence..."
msgstr ""
-#: ../src/gui/glPane.cpp:1080
+#: ../src/gui/glPane.cpp:1136
msgid "Saving Image "
msgstr ""
+#: ../src/gui/glPane.cpp:1136 ../src/gui/mainFrame.cpp:4309
+#: ../src/gui/mainFrame.cpp:4313 ../src/gui/mainFrame.cpp:4326
+#: ../src/backend/filters/dataLoad.cpp:307
+msgid " of "
+msgstr ""
+
#: ../src/gui/dialogs/ExportRngDialog.cpp:40
msgid "Range Sources"
msgstr ""
@@ -299,15 +270,29 @@ msgid "Source Filter"
msgstr ""
#: ../src/gui/dialogs/ExportRngDialog.cpp:54
+#: ../src/backend/filters/rangeFile.cpp:665
msgid "Ions"
msgstr ""
#: ../src/gui/dialogs/ExportRngDialog.cpp:55
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1606
-#: ../src/backend/filters/rangeFile.cpp:729
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1586
+#: ../src/backend/filters/voxelise.cpp:876
+#: ../src/backend/filters/rangeFile.cpp:732
msgid "Ranges"
msgstr ""
+#: ../src/gui/dialogs/ExportRngDialog.cpp:88
+msgid "Param"
+msgstr ""
+
+#: ../src/gui/dialogs/ExportRngDialog.cpp:89
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:105
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:352
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1173
+#: ../src/backend/filters/dataLoad.cpp:566
+msgid "Value"
+msgstr ""
+
#: ../src/gui/dialogs/ExportRngDialog.cpp:90
msgid "Value2"
msgstr ""
@@ -321,7 +306,7 @@ msgid "Num Ranges"
msgstr ""
#: ../src/gui/dialogs/ExportRngDialog.cpp:116
-#: ../src/gui/dialogs/rangeEditDialog.cpp:710 ../src/backend/filter.cpp:43
+#: ../src/gui/dialogs/rangeEditDialog.cpp:695 ../src/backend/filter.cpp:44
msgid "Ion"
msgstr ""
@@ -333,7 +318,7 @@ msgstr ""
msgid "Range end"
msgstr ""
-#: ../src/gui/dialogs/ExportRngDialog.cpp:151 ../src/gui/mainFrame.cpp:2315
+#: ../src/gui/dialogs/ExportRngDialog.cpp:151 ../src/gui/mainFrame.cpp:2355
msgid "Save pos..."
msgstr ""
@@ -341,10 +326,10 @@ msgstr ""
msgid "ORNL format RNG (*.rng)|*.rng|All Files (*)|*"
msgstr ""
-#: ../src/gui/dialogs/ExportRngDialog.cpp:167 ../src/gui/mainFrame.cpp:1422
-#: ../src/gui/mainFrame.cpp:1584 ../src/gui/mainFrame.cpp:1659
-#: ../src/gui/mainFrame.cpp:2214 ../src/gui/mainFrame.cpp:2372
-#: ../src/gui/mainFrame.cpp:2487
+#: ../src/gui/dialogs/ExportRngDialog.cpp:167 ../src/gui/mainFrame.cpp:1446
+#: ../src/gui/mainFrame.cpp:1622 ../src/gui/mainFrame.cpp:1697
+#: ../src/gui/mainFrame.cpp:2254 ../src/gui/mainFrame.cpp:2412
+#: ../src/gui/mainFrame.cpp:2527
msgid "Unable to save. Check output destination can be written to."
msgstr ""
@@ -368,86 +353,84 @@ msgstr ""
msgid "e.g. H2O"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:575
-#: ../src/gui/dialogs/rangeEditDialog.cpp:709 ../src/gui/mainFrame.cpp:6061
-#: ../src/backend/filter.cpp:44
+#: ../src/gui/dialogs/rangeEditDialog.cpp:560
+#: ../src/gui/dialogs/rangeEditDialog.cpp:694 ../src/gui/mainFrame.cpp:5800
+#: ../src/backend/filter.cpp:45
msgid "Plot"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:576
+#: ../src/gui/dialogs/rangeEditDialog.cpp:561
msgid "Short Name"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:577
+#: ../src/gui/dialogs/rangeEditDialog.cpp:562
msgid "Long Name"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:578
-#: ../src/backend/filters/voxelise.cpp:1022
-#: ../src/backend/filters/compositionProfile.cpp:1156
-#: ../src/backend/filters/annotation.cpp:903
-#: ../src/backend/filters/spectrumPlot.cpp:472
+#: ../src/gui/dialogs/rangeEditDialog.cpp:563
+#: ../src/backend/filters/voxelise.cpp:1020
+#: ../src/backend/filters/compositionProfile.cpp:1100
+#: ../src/backend/filters/annotation.cpp:896
+#: ../src/backend/filters/spectrumPlot.cpp:452
msgid "Colour"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:711
-#: ../src/backend/filters/annotation.cpp:606
-#: ../src/backend/filters/annotation.cpp:645
-#: ../src/backend/filters/annotation.cpp:812
+#: ../src/gui/dialogs/rangeEditDialog.cpp:696
+#: ../src/backend/filters/annotation.cpp:600
+#: ../src/backend/filters/annotation.cpp:641
+#: ../src/backend/filters/annotation.cpp:810
msgid "Start"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:712
-#: ../src/backend/filters/annotation.cpp:614
-#: ../src/backend/filters/annotation.cpp:654
-#: ../src/backend/filters/annotation.cpp:820
+#: ../src/gui/dialogs/rangeEditDialog.cpp:697
+#: ../src/backend/filters/annotation.cpp:608
+#: ../src/backend/filters/annotation.cpp:650
+#: ../src/backend/filters/annotation.cpp:818
msgid "End"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1275
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1278
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1259
msgid "Range or ion?"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1276
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1279
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1260
msgid "Select type to add"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1561
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1541
msgid "Range Editor"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1565
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1545
msgid "Enable or disable all overlays"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1566
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1546
msgid "Entered overlays, use delete to remove"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1567
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1547
msgid "Available plots for ranging"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1568
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1548
msgid "Enter species to display as overlay, e.g. SiO2"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1569
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1549
msgid "Editable ranges"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1570
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1550
msgid "Editable ions"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1605
-#: ../src/gui/dialogs/animateFilterDialog.cpp:172
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1585
+#: ../src/gui/dialogs/animateFilterDialog.cpp:173
msgid "Plots"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1607
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1587
msgid "Overlay"
msgstr ""
@@ -463,8 +446,8 @@ msgstr ""
msgid "Multiple autosave states were found; would you like to restore one?"
msgstr ""
-#: ../src/gui/dialogs/filterErrorDialog.cpp:37 ../src/backend/filter.cpp:388
-#: ../src/backend/filter.cpp:391
+#: ../src/gui/dialogs/filterErrorDialog.cpp:37 ../src/backend/filter.cpp:435
+#: ../src/backend/filter.cpp:438
msgid "Error"
msgstr ""
@@ -477,46 +460,46 @@ msgstr ""
msgid "Filter Errors"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:45
+#: ../src/gui/dialogs/StashDialog.cpp:46
msgid "Stashes"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:48
+#: ../src/gui/dialogs/StashDialog.cpp:49
msgid "Stashed Tree"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:50
+#: ../src/gui/dialogs/StashDialog.cpp:51
msgid "Properties"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:86
+#: ../src/gui/dialogs/StashDialog.cpp:57
+msgid "Stash Name"
+msgstr ""
+
+#: ../src/gui/dialogs/StashDialog.cpp:58
+msgid "Filter Count"
+msgstr ""
+
+#: ../src/gui/dialogs/StashDialog.cpp:91
msgid "Stashed Trees"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:89
+#: ../src/gui/dialogs/StashDialog.cpp:94
msgid "Erase stashed item"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:90
+#: ../src/gui/dialogs/StashDialog.cpp:95
msgid "Filter view for current stash"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:91
+#: ../src/gui/dialogs/StashDialog.cpp:96
msgid "Settings for selected filter in current stash"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:92
+#: ../src/gui/dialogs/StashDialog.cpp:97
msgid "Available stashes"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:153
-msgid "Stash Name"
-msgstr ""
-
-#: ../src/gui/dialogs/StashDialog.cpp:154
-msgid "Filter Count"
-msgstr ""
-
#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:45
msgid "Start Frame: "
msgstr ""
@@ -529,57 +512,57 @@ msgstr ""
msgid "From Table"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:108
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:354
-#: ../src/gui/dialogs/animateFilterDialog.cpp:191
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:104
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:350
+#: ../src/gui/dialogs/animateFilterDialog.cpp:192
msgid "Frame"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:244
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:240
msgid "Select text file..."
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:245
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:241
msgid "Text files (*.txt)|*.txt;|All Files (*)|*"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:346
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:342
msgid "String Keyframes"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:348
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:344
msgid "Frame at which to start string sequence"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:349
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:345
msgid "Frame offset for data start"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:350
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:346
msgid "File to use as string data source, one value per row"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:351
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:347
msgid "Select file to use as data source"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:352
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:348
msgid "Use table below for data source"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:358
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:354
msgid "Add new data rows to table, hold shift/cmd to insert multiple rows"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:359
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:355
msgid "Remove selected strings from table"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:360
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:356
msgid "Abort value selection and return to previous window"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:361
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:357
msgid "Accept data values"
msgstr ""
@@ -600,12 +583,12 @@ msgid "Ramp"
msgstr ""
#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:64
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1192
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1154
msgid "Start Frame"
msgstr ""
#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:66
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1193
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1155
msgid "End Frame"
msgstr ""
@@ -625,219 +608,221 @@ msgstr ""
msgid "endColour"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:237
+#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:235
msgid "Key Frame : Colour"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:239
+#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:237
msgid "Colour at the start of the transtition"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:240
+#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:238
msgid "Colour at end of transition"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:91
+#: ../src/gui/dialogs/animateFilterDialog.cpp:92
msgid "Oak-Ridge RNG"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:92
+#: ../src/gui/dialogs/animateFilterDialog.cpp:93
msgid "Cameca/Ametek RRNG"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:93
+#: ../src/gui/dialogs/animateFilterDialog.cpp:94
msgid "Cameca/Ametek ENV"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:151
+#: ../src/gui/dialogs/animateFilterDialog.cpp:152
msgid "Key frames"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:152
+#: ../src/gui/dialogs/animateFilterDialog.cpp:153
msgid "Output Data"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:153
+#: ../src/gui/dialogs/animateFilterDialog.cpp:154
msgid "Filters and properties"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:159
+#: ../src/gui/dialogs/animateFilterDialog.cpp:160
msgid "Dir : "
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:162
+#: ../src/gui/dialogs/animateFilterDialog.cpp:163
msgid "Output only when refresh required"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:164
+#: ../src/gui/dialogs/animateFilterDialog.cpp:165
msgid "Data Types:"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:165
+#: ../src/gui/dialogs/animateFilterDialog.cpp:166
msgid "3D Images"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:166
+#: ../src/gui/dialogs/animateFilterDialog.cpp:167
msgid "File Suffix: "
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:168
+#: ../src/gui/dialogs/animateFilterDialog.cpp:169
msgid "Size : "
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:170
+#: ../src/gui/dialogs/animateFilterDialog.cpp:171
msgid "..."
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:171
+#: ../src/gui/dialogs/animateFilterDialog.cpp:172
msgid "Point data"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:173
+#: ../src/gui/dialogs/animateFilterDialog.cpp:174
msgid "Voxel data"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:174
+#: ../src/gui/dialogs/animateFilterDialog.cpp:175
msgid "Range files"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:175
+#: ../src/gui/dialogs/animateFilterDialog.cpp:176
msgid "Format"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:672
+#: ../src/gui/dialogs/animateFilterDialog.cpp:677
msgid "transition frame"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:672
-#: ../src/gui/mainFrame.cpp:1636
+#: ../src/gui/dialogs/animateFilterDialog.cpp:677
+#: ../src/gui/mainFrame.cpp:1674
msgid "Frame count"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:744
+#: ../src/gui/dialogs/animateFilterDialog.cpp:749
msgid "Key frame : Colour"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:797
+#: ../src/gui/dialogs/animateFilterDialog.cpp:802
msgid "File existed, but was unable to read or interpret file contents."
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:798
+#: ../src/gui/dialogs/animateFilterDialog.cpp:803
msgid "String load failed"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:819
+#: ../src/gui/dialogs/animateFilterDialog.cpp:824
msgid "Keyframe : decimal"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:828
+#: ../src/gui/dialogs/animateFilterDialog.cpp:833
msgid "Keyframe : integer"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:837
+#: ../src/gui/dialogs/animateFilterDialog.cpp:842
msgid "Keyframe : 3D Point"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:962
+#: ../src/gui/dialogs/animateFilterDialog.cpp:967
msgid "Select or create new folder"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1182
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1147
msgid "Export Animation"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1183
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1148
msgid "Select filter"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1185
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1190
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1210
-#: ../src/gui/mainFrame.cpp:5848 ../src/gui/mainFrame.cpp:5853
-msgid "Property"
-msgstr ""
-
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1187
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1149
msgid "Select property"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1189
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1209
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1151
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1171
msgid "Filter"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1191
-#: ../src/backend/filters/transform.cpp:1182
-#: ../src/backend/filters/annotation.cpp:547
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1152
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1172
+msgid "Property"
+msgstr ""
+
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1153
+#: ../src/backend/filters/voxelise.cpp:903
+#: ../src/backend/filters/spatialAnalysis.cpp:906
+#: ../src/backend/filters/transform.cpp:1133
+#: ../src/backend/filters/annotation.cpp:540
+#: ../src/backend/filters/annotation.cpp:546
+#: ../src/backend/filters/ionDownsample.cpp:463
msgid "Mode"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1194
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1156
msgid "Keyframe table"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1195
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1157
msgid "Remove the selected keyframe from the table"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1196
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1158
msgid "Enter where the animation frames will be exported to"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1197
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1159
msgid "Browse to directory where the animation frames will be exported to"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1199
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1161
msgid ""
"Title for files, result will be saved as #-name.png, where # is image number."
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1200
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1162
msgid "Target resolution (image size)"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1202
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1164
msgid "Select frame for property display"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1203
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1165
msgid "Enter frame number to change frame (eg 1/20)"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1204
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1166
msgid "Save point data (POS files) in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1205
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1167
msgid "Save plots (as text files) in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1206
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1168
msgid "Save voxel data (raw files) in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1207
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1169
msgid "Save range files in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1212
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1174
msgid "Animation parameters for current frame"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1213
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1175
msgid "Abort animation"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1214
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1176
msgid "Run Animation"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1285
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1247
msgid "Filter view"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1286
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1248
msgid "Frame view"
msgstr ""
@@ -850,11 +835,11 @@ msgid "Height :"
msgstr ""
#: ../src/gui/dialogs/resolutionDialog.cpp:50
-#: ../src/gui/dialogs/prefDialog.cpp:83
+#: ../src/gui/dialogs/prefDialog.cpp:85
msgid "Reset"
msgstr ""
-#: ../src/gui/dialogs/resolutionDialog.cpp:350
+#: ../src/gui/dialogs/resolutionDialog.cpp:336
msgid "Resolution Selection"
msgstr ""
@@ -863,7 +848,7 @@ msgid "Export:"
msgstr ""
#: ../src/gui/dialogs/ExportPos.cpp:76
-#: ../src/backend/filters/boundingBox.cpp:520
+#: ../src/backend/filters/boundingBox.cpp:521
msgid "Visible"
msgstr ""
@@ -884,783 +869,787 @@ msgid "Index"
msgstr ""
#: ../src/gui/dialogs/ExportPos.cpp:111 ../src/gui/dialogs/ExportPos.cpp:114
-#: ../src/backend/filters/compositionProfile.cpp:549
-#: ../src/backend/filters/spatialAnalysis.cpp:1953
-#: ../src/backend/filters/spatialAnalysis.cpp:2022
-#: ../src/backend/filters/spatialAnalysis.cpp:3002
-#: ../src/backend/filters/spatialAnalysis.cpp:3221
-#: ../src/backend/filters/spatialAnalysis.cpp:3290
-#: ../src/backend/filters/spectrumPlot.cpp:240
+#: ../src/backend/filters/compositionProfile.cpp:581
+#: ../src/backend/filters/spatialAnalysis.cpp:2199
+#: ../src/backend/filters/spatialAnalysis.cpp:2259
+#: ../src/backend/filters/spatialAnalysis.cpp:3224
+#: ../src/backend/filters/spatialAnalysis.cpp:3436
+#: ../src/backend/filters/spatialAnalysis.cpp:3495
+#: ../src/backend/filters/spectrumPlot.cpp:237
msgid "Count"
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:450
+#: ../src/gui/dialogs/ExportPos.cpp:457
msgid "Export Pos Data"
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:453
+#: ../src/gui/dialogs/ExportPos.cpp:460
msgid "Tree of filters, select leaves to show ion data."
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:455
+#: ../src/gui/dialogs/ExportPos.cpp:462
msgid "Add all data from all filters"
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:456
+#: ../src/gui/dialogs/ExportPos.cpp:463
msgid "Add all data from currently selected filter"
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:457
+#: ../src/gui/dialogs/ExportPos.cpp:464
msgid "Add selected data from currently selected filter"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:72
+#: ../src/gui/dialogs/prefDialog.cpp:73
msgid "Panel Display"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:74
+#: ../src/gui/dialogs/prefDialog.cpp:75
msgid "Online Updates"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:76 ../src/gui/dialogs/prefDialog.cpp:654
+#: ../src/gui/dialogs/prefDialog.cpp:77 ../src/gui/dialogs/prefDialog.cpp:560
msgid "Startup"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:77
-msgid "Camera Speed"
-msgstr ""
-
#: ../src/gui/dialogs/prefDialog.cpp:78
-msgid "Filter Defaults"
+msgid "Camera Speed"
msgstr ""
#: ../src/gui/dialogs/prefDialog.cpp:79
msgid "Available Filters"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:82
+#: ../src/gui/dialogs/prefDialog.cpp:84
msgid "Reset All"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:85
+#: ../src/gui/dialogs/prefDialog.cpp:87
msgid "Show all panels"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:86
+#: ../src/gui/dialogs/prefDialog.cpp:88
msgid "Remember last"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:87
+#: ../src/gui/dialogs/prefDialog.cpp:89
msgid "Show Selected"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:90
+#: ../src/gui/dialogs/prefDialog.cpp:92
msgid "Control Pane"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:91
+#: ../src/gui/dialogs/prefDialog.cpp:93
msgid "Raw Data Panel"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:92 ../src/gui/mainFrame.cpp:652
+#: ../src/gui/dialogs/prefDialog.cpp:94 ../src/gui/mainFrame.cpp:663
msgid "Plot List"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:94
+#: ../src/gui/dialogs/prefDialog.cpp:96
msgid "Periodically notify about available updates"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:96
+#: ../src/gui/dialogs/prefDialog.cpp:98
msgid "Prefer orthographic at startup"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:97
+#: ../src/gui/dialogs/prefDialog.cpp:99
msgid "Move Rate"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:98 ../src/gui/dialogs/prefDialog.cpp:102
+#: ../src/gui/dialogs/prefDialog.cpp:100 ../src/gui/dialogs/prefDialog.cpp:104
msgid "(slow)"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:100 ../src/gui/dialogs/prefDialog.cpp:104
+#: ../src/gui/dialogs/prefDialog.cpp:102 ../src/gui/dialogs/prefDialog.cpp:106
msgid "(fast)"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:101
+#: ../src/gui/dialogs/prefDialog.cpp:103
msgid "Zoom Rate"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:456
-msgid "Notice"
-msgstr ""
-
-#: ../src/gui/dialogs/prefDialog.cpp:459
-msgid "For security reasons, defaults are not modifiable for this filter"
-msgstr ""
-
-#: ../src/gui/dialogs/prefDialog.cpp:496
+#: ../src/gui/dialogs/prefDialog.cpp:416
msgid "Show all panels when starting program"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:499
+#: ../src/gui/dialogs/prefDialog.cpp:419
msgid "Show panels visible at last shutdown when starting program"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:506
+#: ../src/gui/dialogs/prefDialog.cpp:426
msgid "Show selected panels when starting program"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:555
+#: ../src/gui/dialogs/prefDialog.cpp:475
msgid "Preferences"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:557
+#: ../src/gui/dialogs/prefDialog.cpp:477
msgid "Set the method of panel layout when starting the program"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:560
+#: ../src/gui/dialogs/prefDialog.cpp:480
msgid ""
"Lets the program check the internet to see if updates to the program version "
"are available, then notifies you about updates now and again."
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:562
+#: ../src/gui/dialogs/prefDialog.cpp:482
msgid ""
"By default, use an orthographic camera at startup. State files will override "
"this preference."
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:563
+#: ../src/gui/dialogs/prefDialog.cpp:483
msgid "Camera translation, orbit and swivel rates. "
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:564
+#: ../src/gui/dialogs/prefDialog.cpp:484
msgid "Camera zooming rate."
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:566
+#: ../src/gui/dialogs/prefDialog.cpp:486
msgid "Reset the filter initial values back to program defaults"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:567
+#: ../src/gui/dialogs/prefDialog.cpp:487
msgid "Reset all filter initial values back to program defaults"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:653
-msgid "Pref"
+#: ../src/gui/dialogs/prefDialog.cpp:559
+msgid "Filt. Default"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:655
+#: ../src/gui/dialogs/prefDialog.cpp:561
msgid "Camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:91
+#: ../src/gui/mainFrame.cpp:105
msgid "New camera name..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:92
-msgid "New stash name...."
+#: ../src/gui/mainFrame.cpp:106
+msgid "New stash name..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:108 ../src/backend/filters/annotation.cpp:561
-#: ../src/backend/filters/annotation.cpp:663
+#: ../src/gui/mainFrame.cpp:111
+msgid "New Filter..."
+msgstr ""
+
+#: ../src/gui/mainFrame.cpp:128 ../src/backend/filters/annotation.cpp:555
+#: ../src/backend/filters/annotation.cpp:659
#: ../src/backend/filters/annotation.h:96
msgid "Annotation"
msgstr ""
-#: ../src/gui/mainFrame.cpp:109
+#: ../src/gui/mainFrame.cpp:129
msgid "Bounding Box"
msgstr ""
-#: ../src/gui/mainFrame.cpp:110 ../src/backend/filters/ionClip.h:66
+#: ../src/gui/mainFrame.cpp:130 ../src/backend/filters/ionClip.cpp:619
+#: ../src/backend/filters/ionClip.h:66
msgid "Clipping"
msgstr ""
-#: ../src/gui/mainFrame.cpp:111 ../src/backend/filters/clusterAnalysis.h:140
+#: ../src/gui/mainFrame.cpp:131 ../src/backend/filters/clusterAnalysis.h:143
msgid "Cluster Analysis"
msgstr ""
-#: ../src/gui/mainFrame.cpp:112
+#: ../src/gui/mainFrame.cpp:132
msgid "Compos. Profiles"
msgstr ""
-#: ../src/gui/mainFrame.cpp:113
+#: ../src/gui/mainFrame.cpp:133
msgid "Downsampling"
msgstr ""
-#: ../src/gui/mainFrame.cpp:114
+#: ../src/gui/mainFrame.cpp:134
msgid "Extern. Prog."
msgstr ""
-#: ../src/gui/mainFrame.cpp:115
+#: ../src/gui/mainFrame.cpp:135
msgid "Ion Colour"
msgstr ""
-#: ../src/gui/mainFrame.cpp:116
+#: ../src/gui/mainFrame.cpp:136
msgid "Ion Info"
msgstr ""
-#: ../src/gui/mainFrame.cpp:117
+#: ../src/gui/mainFrame.cpp:137
msgid "Ion Transform"
msgstr ""
-#: ../src/gui/mainFrame.cpp:118 ../src/backend/filters/spectrumPlot.h:53
+#: ../src/gui/mainFrame.cpp:138 ../src/backend/filters/spectrumPlot.h:53
msgid "Spectrum"
msgstr ""
-#: ../src/gui/mainFrame.cpp:119
+#: ../src/gui/mainFrame.cpp:139
msgid "Range File"
msgstr ""
-#: ../src/gui/mainFrame.cpp:120 ../src/backend/filters/spatialAnalysis.h:172
+#: ../src/gui/mainFrame.cpp:140 ../src/backend/filters/spatialAnalysis.h:193
msgid "Spat. Analysis"
msgstr ""
-#: ../src/gui/mainFrame.cpp:121 ../src/backend/filters/voxelise.h:121
+#: ../src/gui/mainFrame.cpp:141 ../src/backend/filters/voxelise.h:121
msgid "Voxelisation"
msgstr ""
-#: ../src/gui/mainFrame.cpp:421
+#: ../src/gui/mainFrame.cpp:429
msgid "OpenGL Failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:422 ../src/gui/mainFrame.cpp:424
+#: ../src/gui/mainFrame.cpp:430 ../src/gui/mainFrame.cpp:432
msgid ""
"Unable to initialise the openGL (3D) panel. Program cannot start. Please "
"check your video drivers."
msgstr ""
-#: ../src/gui/mainFrame.cpp:444
+#: ../src/gui/mainFrame.cpp:452
msgid "&Open...\tCtrl+O"
msgstr ""
-#: ../src/gui/mainFrame.cpp:444
+#: ../src/gui/mainFrame.cpp:452
msgid "Open state file"
msgstr ""
-#: ../src/gui/mainFrame.cpp:445
+#: ../src/gui/mainFrame.cpp:453
msgid "&Merge...\tCtrl+Shift+O"
msgstr ""
-#: ../src/gui/mainFrame.cpp:445
+#: ../src/gui/mainFrame.cpp:453
msgid "Merge other file"
msgstr ""
-#: ../src/gui/mainFrame.cpp:449
+#: ../src/gui/mainFrame.cpp:457
msgid "&Recent"
msgstr ""
-#: ../src/gui/mainFrame.cpp:450
+#: ../src/gui/mainFrame.cpp:458
msgid "&Save\tCtrl+S"
msgstr ""
-#: ../src/gui/mainFrame.cpp:450
+#: ../src/gui/mainFrame.cpp:458
msgid "Save state to file"
msgstr ""
-#: ../src/gui/mainFrame.cpp:452
+#: ../src/gui/mainFrame.cpp:460
msgid "Save &As...\tCtrl+Shift+S"
msgstr ""
-#: ../src/gui/mainFrame.cpp:452
+#: ../src/gui/mainFrame.cpp:460
msgid "Save current state to new file"
msgstr ""
-#: ../src/gui/mainFrame.cpp:455
+#: ../src/gui/mainFrame.cpp:463
msgid "&Plot...\tCtrl+P"
msgstr ""
-#: ../src/gui/mainFrame.cpp:455
+#: ../src/gui/mainFrame.cpp:463
msgid "Export Current Plot"
msgstr ""
-#: ../src/gui/mainFrame.cpp:456
+#: ../src/gui/mainFrame.cpp:464
msgid "&Image...\tCtrl+I"
msgstr ""
-#: ../src/gui/mainFrame.cpp:456
+#: ../src/gui/mainFrame.cpp:464
msgid "Export Current 3D View"
msgstr ""
-#: ../src/gui/mainFrame.cpp:457
+#: ../src/gui/mainFrame.cpp:465
msgid "Ion&s...\tCtrl+N"
msgstr ""
-#: ../src/gui/mainFrame.cpp:457
+#: ../src/gui/mainFrame.cpp:465
msgid "Export Ion Data"
msgstr ""
-#: ../src/gui/mainFrame.cpp:458
+#: ../src/gui/mainFrame.cpp:466
msgid "Ran&ges...\tCtrl+G"
msgstr ""
-#: ../src/gui/mainFrame.cpp:458
+#: ../src/gui/mainFrame.cpp:466
msgid "Export Range Data"
msgstr ""
-#: ../src/gui/mainFrame.cpp:459
+#: ../src/gui/mainFrame.cpp:467
msgid "&Animate Filters...\tCtrl+A"
msgstr ""
-#: ../src/gui/mainFrame.cpp:459
+#: ../src/gui/mainFrame.cpp:467
msgid "Export Animated Filter"
msgstr ""
-#: ../src/gui/mainFrame.cpp:460
+#: ../src/gui/mainFrame.cpp:468
msgid "Ani&mate Camera...\tCtrl+M"
msgstr ""
-#: ../src/gui/mainFrame.cpp:460
+#: ../src/gui/mainFrame.cpp:468
msgid "Export Animated Camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:461
+#: ../src/gui/mainFrame.cpp:469
msgid "Pac&kage...\tCtrl+K"
msgstr ""
-#: ../src/gui/mainFrame.cpp:461
+#: ../src/gui/mainFrame.cpp:469
msgid "Export analysis package"
msgstr ""
-#: ../src/gui/mainFrame.cpp:463
+#: ../src/gui/mainFrame.cpp:471
msgid "&Export"
msgstr ""
-#: ../src/gui/mainFrame.cpp:466
+#: ../src/gui/mainFrame.cpp:474
msgid "&Quit\tCtrl+Q"
msgstr ""
-#: ../src/gui/mainFrame.cpp:466 ../src/gui/mainFrame.cpp:468
+#: ../src/gui/mainFrame.cpp:474 ../src/gui/mainFrame.cpp:476
msgid "Exit Program"
msgstr ""
-#: ../src/gui/mainFrame.cpp:468
+#: ../src/gui/mainFrame.cpp:476
msgid "E&xit"
msgstr ""
-#: ../src/gui/mainFrame.cpp:470
+#: ../src/gui/mainFrame.cpp:478
msgid "&File"
msgstr ""
-#: ../src/gui/mainFrame.cpp:474
+#: ../src/gui/mainFrame.cpp:482
msgid "&Background Colour...\tCtrl+B"
msgstr ""
-#: ../src/gui/mainFrame.cpp:474
+#: ../src/gui/mainFrame.cpp:482
msgid "Change background colour"
msgstr ""
-#: ../src/gui/mainFrame.cpp:478
+#: ../src/gui/mainFrame.cpp:486
msgid "&Control Pane\tF2"
msgstr ""
-#: ../src/gui/mainFrame.cpp:478 ../src/gui/mainFrame.cpp:481
+#: ../src/gui/mainFrame.cpp:486 ../src/gui/mainFrame.cpp:489
msgid "Toggle left control pane"
msgstr ""
-#: ../src/gui/mainFrame.cpp:481
+#: ../src/gui/mainFrame.cpp:489
msgid "&Control Pane\tAlt+C"
msgstr ""
-#: ../src/gui/mainFrame.cpp:487
+#: ../src/gui/mainFrame.cpp:495
msgid "&Raw Data Pane\tF3"
msgstr ""
-#: ../src/gui/mainFrame.cpp:487 ../src/gui/mainFrame.cpp:490
+#: ../src/gui/mainFrame.cpp:495 ../src/gui/mainFrame.cpp:498
msgid "Toggle raw data pane (bottom)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:490
+#: ../src/gui/mainFrame.cpp:498
msgid "&Raw Data Pane\tAlt+R"
msgstr ""
-#: ../src/gui/mainFrame.cpp:494
+#: ../src/gui/mainFrame.cpp:502
msgid "&Plot List\tF4"
msgstr ""
-#: ../src/gui/mainFrame.cpp:494 ../src/gui/mainFrame.cpp:496
+#: ../src/gui/mainFrame.cpp:502 ../src/gui/mainFrame.cpp:504
msgid "Toggle plot list"
msgstr ""
-#: ../src/gui/mainFrame.cpp:496
+#: ../src/gui/mainFrame.cpp:504
msgid "&Plot List\tAlt+P"
msgstr ""
-#: ../src/gui/mainFrame.cpp:502
+#: ../src/gui/mainFrame.cpp:510
msgid "&Legend\tCtrl+L"
msgstr ""
-#: ../src/gui/mainFrame.cpp:502
+#: ../src/gui/mainFrame.cpp:510
msgid "Toggle Legend display"
msgstr ""
-#: ../src/gui/mainFrame.cpp:504
+#: ../src/gui/mainFrame.cpp:512
msgid "P&lot..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:505
+#: ../src/gui/mainFrame.cpp:513
msgid "&Axis\tCtrl+Shift+I"
msgstr ""
-#: ../src/gui/mainFrame.cpp:505
+#: ../src/gui/mainFrame.cpp:513
msgid "Toggle World Axis display"
msgstr ""
-#: ../src/gui/mainFrame.cpp:510
+#: ../src/gui/mainFrame.cpp:518
msgid "&Fullscreen mode\tF11"
msgstr ""
-#: ../src/gui/mainFrame.cpp:510 ../src/gui/mainFrame.cpp:512
+#: ../src/gui/mainFrame.cpp:518 ../src/gui/mainFrame.cpp:520
msgid "Next fullscreen mode: with toolbars"
msgstr ""
-#: ../src/gui/mainFrame.cpp:512
+#: ../src/gui/mainFrame.cpp:520
msgid "&Fullscreen mode\tCtrl+Shift+F"
msgstr ""
-#: ../src/gui/mainFrame.cpp:517
+#: ../src/gui/mainFrame.cpp:525
msgid "&Undo\tCtrl+Z"
msgstr ""
-#: ../src/gui/mainFrame.cpp:519
+#: ../src/gui/mainFrame.cpp:527
msgid "&Redo\tCtrl+Y"
msgstr ""
-#: ../src/gui/mainFrame.cpp:522
+#: ../src/gui/mainFrame.cpp:530
msgid "&Range"
msgstr ""
-#: ../src/gui/mainFrame.cpp:525
+#: ../src/gui/mainFrame.cpp:533
msgid "&Preferences"
msgstr ""
-#: ../src/gui/mainFrame.cpp:527
+#: ../src/gui/mainFrame.cpp:535
msgid "&Edit"
msgstr ""
-#: ../src/gui/mainFrame.cpp:530
+#: ../src/gui/mainFrame.cpp:538
msgid "&View"
msgstr ""
-#: ../src/gui/mainFrame.cpp:532
+#: ../src/gui/mainFrame.cpp:540
msgid "&Help...\tCtrl+H"
msgstr ""
-#: ../src/gui/mainFrame.cpp:532
+#: ../src/gui/mainFrame.cpp:540
msgid "Show help files and documentation"
msgstr ""
-#: ../src/gui/mainFrame.cpp:533
+#: ../src/gui/mainFrame.cpp:541
msgid "&Contact..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:533
+#: ../src/gui/mainFrame.cpp:541
msgid "Open contact page"
msgstr ""
-#: ../src/gui/mainFrame.cpp:535
+#: ../src/gui/mainFrame.cpp:543
msgid "&About..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:535
+#: ../src/gui/mainFrame.cpp:543
msgid "Information about this program"
msgstr ""
-#: ../src/gui/mainFrame.cpp:536
+#: ../src/gui/mainFrame.cpp:544
msgid "&Help"
msgstr ""
-#: ../src/gui/mainFrame.cpp:538
+#: ../src/gui/mainFrame.cpp:546
msgid "Stashed Filters"
msgstr ""
-#: ../src/gui/mainFrame.cpp:543
+#: ../src/gui/mainFrame.cpp:551
msgid "New Filters"
msgstr ""
-#: ../src/gui/mainFrame.cpp:571
+#: ../src/gui/mainFrame.cpp:580
msgid "Last Outputs"
msgstr ""
-#: ../src/gui/mainFrame.cpp:573
+#: ../src/gui/mainFrame.cpp:582
msgid "Auto Refresh"
msgstr ""
-#: ../src/gui/mainFrame.cpp:579
+#: ../src/gui/mainFrame.cpp:588
msgid "Filter settings"
msgstr ""
-#: ../src/gui/mainFrame.cpp:581
+#: ../src/gui/mainFrame.cpp:591
msgid "Camera Name"
msgstr ""
-#: ../src/gui/mainFrame.cpp:587
+#: ../src/gui/mainFrame.cpp:598
msgid "3D Post-processing"
msgstr ""
-#: ../src/gui/mainFrame.cpp:589
+#: ../src/gui/mainFrame.cpp:600
msgid "Enable Cropping"
msgstr ""
-#: ../src/gui/mainFrame.cpp:591 ../src/gui/mainFrame.cpp:602
+#: ../src/gui/mainFrame.cpp:602 ../src/gui/mainFrame.cpp:613
msgid "x-y"
msgstr ""
-#: ../src/gui/mainFrame.cpp:592 ../src/gui/mainFrame.cpp:603
+#: ../src/gui/mainFrame.cpp:603 ../src/gui/mainFrame.cpp:614
msgid "x-z"
msgstr ""
-#: ../src/gui/mainFrame.cpp:593 ../src/gui/mainFrame.cpp:604
+#: ../src/gui/mainFrame.cpp:604 ../src/gui/mainFrame.cpp:615
msgid "y-x"
msgstr ""
-#: ../src/gui/mainFrame.cpp:594 ../src/gui/mainFrame.cpp:605
+#: ../src/gui/mainFrame.cpp:605 ../src/gui/mainFrame.cpp:616
msgid "y-z"
msgstr ""
-#: ../src/gui/mainFrame.cpp:595 ../src/gui/mainFrame.cpp:606
+#: ../src/gui/mainFrame.cpp:606 ../src/gui/mainFrame.cpp:617
msgid "z-x"
msgstr ""
-#: ../src/gui/mainFrame.cpp:596 ../src/gui/mainFrame.cpp:607
+#: ../src/gui/mainFrame.cpp:607 ../src/gui/mainFrame.cpp:618
msgid "z-y"
msgstr ""
-#: ../src/gui/mainFrame.cpp:611
+#: ../src/gui/mainFrame.cpp:622
msgid "Use camera coordinates"
msgstr ""
-#: ../src/gui/mainFrame.cpp:612
+#: ../src/gui/mainFrame.cpp:623
msgid "dX"
msgstr ""
-#: ../src/gui/mainFrame.cpp:614
+#: ../src/gui/mainFrame.cpp:625
msgid "dY"
msgstr ""
-#: ../src/gui/mainFrame.cpp:616
+#: ../src/gui/mainFrame.cpp:627
msgid "dZ"
msgstr ""
-#: ../src/gui/mainFrame.cpp:618
+#: ../src/gui/mainFrame.cpp:629
msgid "Enable Anaglyphic Stereo"
msgstr ""
-#: ../src/gui/mainFrame.cpp:619
+#: ../src/gui/mainFrame.cpp:630
msgid "Flip Channels"
msgstr ""
-#: ../src/gui/mainFrame.cpp:620
+#: ../src/gui/mainFrame.cpp:631
msgid "Anaglyph Mode"
msgstr ""
-#: ../src/gui/mainFrame.cpp:622
+#: ../src/gui/mainFrame.cpp:633
msgid "Red-Blue"
msgstr ""
-#: ../src/gui/mainFrame.cpp:623
+#: ../src/gui/mainFrame.cpp:634
msgid "Red-Green"
msgstr ""
-#: ../src/gui/mainFrame.cpp:624
+#: ../src/gui/mainFrame.cpp:635
msgid "Red-Cyan"
msgstr ""
-#: ../src/gui/mainFrame.cpp:625
+#: ../src/gui/mainFrame.cpp:636
msgid "Green-Magenta"
msgstr ""
-#: ../src/gui/mainFrame.cpp:629
+#: ../src/gui/mainFrame.cpp:640
msgid "Baseline Separation"
msgstr ""
-#: ../src/gui/mainFrame.cpp:631 ../src/backend/filters/voxelise.cpp:981
-#: ../src/backend/filters/voxelise.cpp:1037
-#: ../src/backend/filters/compositionProfile.cpp:1165
+#: ../src/gui/mainFrame.cpp:642 ../src/backend/filters/voxelise.cpp:982
+#: ../src/backend/filters/voxelise.cpp:1142
+#: ../src/backend/filters/compositionProfile.cpp:1109
#: ../src/backend/filters/boundingBox.cpp:648
-#: ../src/backend/filters/dataLoad.cpp:660
+#: ../src/backend/filters/annotation.cpp:901
+#: ../src/backend/filters/dataLoad.cpp:651
+#: ../src/backend/filters/spectrumPlot.cpp:459
msgid "Appearance"
msgstr ""
-#: ../src/gui/mainFrame.cpp:632
+#: ../src/gui/mainFrame.cpp:643
msgid "Smooth && translucent objects"
msgstr ""
-#: ../src/gui/mainFrame.cpp:634
+#: ../src/gui/mainFrame.cpp:645
msgid "3D lighting"
msgstr ""
-#: ../src/gui/mainFrame.cpp:637
+#: ../src/gui/mainFrame.cpp:648
msgid "Performance"
msgstr ""
-#: ../src/gui/mainFrame.cpp:638
+#: ../src/gui/mainFrame.cpp:649
msgid "Fast and weak randomisation."
msgstr ""
-#: ../src/gui/mainFrame.cpp:640
+#: ../src/gui/mainFrame.cpp:651
msgid "Limit Output Pts"
msgstr ""
-#: ../src/gui/mainFrame.cpp:646
+#: ../src/gui/mainFrame.cpp:657
msgid "Filter caching"
msgstr ""
-#: ../src/gui/mainFrame.cpp:648
+#: ../src/gui/mainFrame.cpp:659
msgid "Max. Ram usage (%)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:705
+#: ../src/gui/mainFrame.cpp:718
msgid "Type"
msgstr ""
-#: ../src/gui/mainFrame.cpp:706
+#: ../src/gui/mainFrame.cpp:719
msgid "Num"
msgstr ""
-#: ../src/gui/mainFrame.cpp:721
+#: ../src/gui/mainFrame.cpp:734
msgid "Warning: Your configuration file appears to be invalid:\n"
msgstr ""
-#: ../src/gui/mainFrame.cpp:722
+#: ../src/gui/mainFrame.cpp:735
msgid "\tConfig Load: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:974
+#: ../src/gui/mainFrame.cpp:984
msgid "Current state has not been saved, would you like to save it now?"
msgstr ""
-#: ../src/gui/mainFrame.cpp:975
+#: ../src/gui/mainFrame.cpp:985
msgid "State changed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:995
+#: ../src/gui/mainFrame.cpp:1005
msgid "Readable files (*.xml, *.pos, *.txt,*.csv, *.ato)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:997
+#: ../src/gui/mainFrame.cpp:1007
msgid "XML State File (*.xml)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:998
+#: ../src/gui/mainFrame.cpp:1008
msgid "POS File (*.pos)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:999
+#: ../src/gui/mainFrame.cpp:1009
msgid "LAWATAP ATO File (*.ato)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1000
+#: ../src/gui/mainFrame.cpp:1010
msgid "Text File (*.txt, *.csv)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1001
+#: ../src/gui/mainFrame.cpp:1011
msgid "All Files (*)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1014 ../src/gui/mainFrame.cpp:1068
+#: ../src/gui/mainFrame.cpp:1024 ../src/gui/mainFrame.cpp:1080
msgid "Select Data or State File..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1056 ../src/gui/mainFrame.cpp:1387
+#: ../src/gui/mainFrame.cpp:1068 ../src/gui/mainFrame.cpp:1407
msgid "Loaded file."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1069
+#: ../src/gui/mainFrame.cpp:1081
msgid ""
"3Depict file (*.xml, *.pos,*.txt)|*.xml;*.pos;*.txt|POS File (*.pos)|*.pos|"
"XML State File (*.xml)|*.xml|All Files (*)|*"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1080
+#: ../src/gui/mainFrame.cpp:1092
msgid "Merged file."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1182
+#: ../src/gui/mainFrame.cpp:1199
msgid "Tip: You can use ⌘ (command) to merge"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1184
+#: ../src/gui/mainFrame.cpp:1201
msgid "Tip: You can use ctrl to merge"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1221
+#: ../src/gui/mainFrame.cpp:1241
msgid "Load error"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1222
+#: ../src/gui/mainFrame.cpp:1242
msgid ""
"Error loading state file.\n"
"See console for more info."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1230
+#: ../src/gui/mainFrame.cpp:1250
msgid ""
"This state file contains filters that can be unsafe to run\n"
"Do you wish to remove these before continuing?."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1231
+#: ../src/gui/mainFrame.cpp:1251
msgid "Security warning"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1444 ../src/gui/mainFrame.cpp:1540
-#: ../src/gui/mainFrame.cpp:1957
+#: ../src/gui/mainFrame.cpp:1468 ../src/gui/mainFrame.cpp:1564
+#: ../src/gui/mainFrame.cpp:1997
msgid "Unable to save"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1445
+#: ../src/gui/mainFrame.cpp:1469
msgid "No plot available. Please create a plot before exporting."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1449
+#: ../src/gui/mainFrame.cpp:1473
msgid "Save plot..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1450
+#: ../src/gui/mainFrame.cpp:1474
msgid ""
"By Extension (svg,png)|*.svg;*.png|Scalable Vector Graphics File (*.svg)|*."
"svg|PNG File (*.png)|*.png|All Files (*)|*"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1504
+#: ../src/gui/mainFrame.cpp:1528
msgid "Select type for save"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1505
+#: ../src/gui/mainFrame.cpp:1529
msgid "Choose file type"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1525 ../src/gui/mainFrame.cpp:1568
-#: ../src/gui/mainFrame.cpp:1604
+#: ../src/gui/mainFrame.cpp:1549 ../src/gui/mainFrame.cpp:1606
+#: ../src/gui/mainFrame.cpp:1642
msgid "Choose resolution"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1541
+#: ../src/gui/mainFrame.cpp:1565
msgid "Unknown file extension. Please use \"svg\" or \"png\""
msgstr ""
-#: ../src/gui/mainFrame.cpp:1552
+#: ../src/gui/mainFrame.cpp:1576
msgid "Saved plot: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:1559 ../src/gui/mainFrame.cpp:1597
+#: ../src/gui/mainFrame.cpp:1583 ../src/gui/mainFrame.cpp:1635
msgid "Save Image..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1560 ../src/gui/mainFrame.cpp:1598
+#: ../src/gui/mainFrame.cpp:1584 ../src/gui/mainFrame.cpp:1636
msgid "PNG File (*.png)|*.png|All Files (*)|*"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1588 ../src/gui/mainFrame.cpp:1664
+#: ../src/gui/mainFrame.cpp:1598
+msgid "File already exists. Overwrite?"
+msgstr ""
+
+#: ../src/gui/mainFrame.cpp:1599 ../src/gui/mainFrame.cpp:2385
+#: ../src/gui/mainFrame.cpp:2483 ../src/gui/mainFrame.cpp:2507
+msgid "Overwrite?"
+msgstr ""
+
+#: ../src/gui/mainFrame.cpp:1626 ../src/gui/mainFrame.cpp:1702
msgid "Saved 3D View :"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1618
+#: ../src/gui/mainFrame.cpp:1656
msgid "Program limitation"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1619
+#: ../src/gui/mainFrame.cpp:1657
msgid ""
"Limitation on the screenshot dimension; please ensure that both width and "
"height exceed the initial values,\n"
@@ -1668,402 +1657,371 @@ msgid ""
" If this bothers, please submit a bug."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1636
+#: ../src/gui/mainFrame.cpp:1674
msgid "Number of frames"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1791
+#: ../src/gui/mainFrame.cpp:1829
msgid "Cannot animate with no filters."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1868
+#: ../src/gui/mainFrame.cpp:1908
msgid "Animating"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1869
+#: ../src/gui/mainFrame.cpp:1909
msgid "Performing refresh"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1898
+#: ../src/gui/mainFrame.cpp:1938
msgid "Filter property change failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1918
+#: ../src/gui/mainFrame.cpp:1958
msgid "Refresh failed on frame :"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1943
+#: ../src/gui/mainFrame.cpp:1983
msgid "Scene generation failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1944
+#: ../src/gui/mainFrame.cpp:1984
msgid "Unable to generate scene for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:1958
+#: ../src/gui/mainFrame.cpp:1998
msgid "Image save failed for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:1983
+#: ../src/gui/mainFrame.cpp:2023
msgid "Ion save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1984
+#: ../src/gui/mainFrame.cpp:2024
msgid "Unable to save ions for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2015
+#: ../src/gui/mainFrame.cpp:2055
msgid "Plot save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2016
+#: ../src/gui/mainFrame.cpp:2056
msgid "Unable to save plot or frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2057
+#: ../src/gui/mainFrame.cpp:2097
msgid "Range save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2058
+#: ../src/gui/mainFrame.cpp:2098
msgid "Unable to save range for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2087
+#: ../src/gui/mainFrame.cpp:2127
msgid "Voxel save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2088
+#: ../src/gui/mainFrame.cpp:2128
msgid "Unable to save voxels for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2118
+#: ../src/gui/mainFrame.cpp:2158
msgid "Animate failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2143 ../src/gui/mainFrame.cpp:2301
-#: ../src/gui/mainFrame.cpp:2397
+#: ../src/gui/mainFrame.cpp:2183 ../src/gui/mainFrame.cpp:2341
+#: ../src/gui/mainFrame.cpp:2437
msgid "No filters means no data to export"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2157
+#: ../src/gui/mainFrame.cpp:2197
msgid "Package name"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2158
+#: ../src/gui/mainFrame.cpp:2198
msgid "Package directory name"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2160
+#: ../src/gui/mainFrame.cpp:2200
msgid "AnalysisPackage"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2173
+#: ../src/gui/mainFrame.cpp:2213
msgid "Package folder already exists, won't overwrite."
msgstr ""
-#: ../src/gui/mainFrame.cpp:2174
+#: ../src/gui/mainFrame.cpp:2214
msgid "Not available"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2199
+#: ../src/gui/mainFrame.cpp:2239
msgid ""
"Package folder creation failed\n"
"check writing to this location is possible."
msgstr ""
-#: ../src/gui/mainFrame.cpp:2200
+#: ../src/gui/mainFrame.cpp:2240
msgid "Folder creation failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2219
+#: ../src/gui/mainFrame.cpp:2259
msgid "Copying"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2220
+#: ../src/gui/mainFrame.cpp:2260
msgid "Copying referenced files"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2279
+#: ../src/gui/mainFrame.cpp:2319
msgid "Error copying file"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2288
+#: ../src/gui/mainFrame.cpp:2328
msgid "Saved package: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2311
+#: ../src/gui/mainFrame.cpp:2351
msgid "Export"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2316
+#: ../src/gui/mainFrame.cpp:2356
msgid "POS Data (*.pos)|*.pos|All Files (*)|*"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2344 ../src/gui/mainFrame.cpp:2442
+#: ../src/gui/mainFrame.cpp:2384 ../src/gui/mainFrame.cpp:2482
msgid "File already exists, overwrite?"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2345 ../src/gui/mainFrame.cpp:2443
-#: ../src/gui/mainFrame.cpp:2467
-msgid "Overwrite?"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:2376
+#: ../src/gui/mainFrame.cpp:2416
msgid "Saved ions: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2401
+#: ../src/gui/mainFrame.cpp:2441
msgid "Export Ranges"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2424
+#: ../src/gui/mainFrame.cpp:2464
msgid "Save state..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:2425
+#: ../src/gui/mainFrame.cpp:2465
msgid "XML state file (*.xml)|*.xml|All Files (*)|*"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2466
+#: ../src/gui/mainFrame.cpp:2506
msgid "Files have been referred to using relative paths. Keep relative paths?"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2499
+#: ../src/gui/mainFrame.cpp:2539
msgid "Saved state: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2576
+#: ../src/gui/mainFrame.cpp:2616
msgid "Range editor"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2872
+#: ../src/gui/mainFrame.cpp:2871
msgid "Manual not found locally. Launching web browser"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2881
+#: ../src/gui/mainFrame.cpp:2880
msgid "Opening contact page in external web browser"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2893
+#: ../src/gui/mainFrame.cpp:2892
msgid "No filter stashes to edit."
msgstr ""
-#: ../src/gui/mainFrame.cpp:2897
+#: ../src/gui/mainFrame.cpp:2896
msgid "Filter Stashes"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2926
+#: ../src/gui/mainFrame.cpp:2925
msgid "Quick and dirty analysis for point data."
msgstr ""
-#: ../src/gui/mainFrame.cpp:2936
+#: ../src/gui/mainFrame.cpp:2935
msgid "Compiled with wx Version: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2957
+#: ../src/gui/mainFrame.cpp:2956
msgid "Press enter to store new stash"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2963
+#: ../src/gui/mainFrame.cpp:2962
msgid "Press enter to restore stash"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2998
+#: ../src/gui/mainFrame.cpp:2997
msgid "Unable to create stash, selection invalid"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3006
+#: ../src/gui/mainFrame.cpp:3005
msgid "Created new filter tree stash"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3128
+#: ../src/gui/mainFrame.cpp:3132
msgid "Filter type not a data source - can't be at tree base"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3302
+#: ../src/gui/mainFrame.cpp:3309
msgid "Moving - Hold ⌘ (command) to copy"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3304
+#: ../src/gui/mainFrame.cpp:3311
msgid "Moving - Hold control to copy"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3647
+#: ../src/gui/mainFrame.cpp:3630
msgid "Press enter to store new camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3649
+#: ../src/gui/mainFrame.cpp:3632
msgid "Press enter to restore camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3674 ../src/gui/mainFrame.cpp:3715
+#: ../src/gui/mainFrame.cpp:3657 ../src/gui/mainFrame.cpp:3698
msgid "Restored camera: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:3694
+#: ../src/gui/mainFrame.cpp:3677
msgid "Stored camera: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:3775
+#: ../src/gui/mainFrame.cpp:3759
msgid "Select an item from the filter tree before choosing a new filter"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3777
+#: ../src/gui/mainFrame.cpp:3761
msgid "Load data source (file->open) before choosing a new filter"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3798
+#: ../src/gui/mainFrame.cpp:3785
msgid "Select RNG File..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:3799
-msgid ""
-"Range Files (*rng; *env; *rrng)|*rng;*env;*rrng|RNG File (*.rng)|*.rng|"
-"Environment File (*.env)|*.env|RRNG Files (*.rrng)|*.rrng|All Files (*)|*"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:3819
+#: ../src/gui/mainFrame.cpp:3806
msgid "Failed reading range file."
msgstr ""
-#: ../src/gui/mainFrame.cpp:3823
+#: ../src/gui/mainFrame.cpp:3810
msgid "Error loading file"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3881 ../src/gui/mainFrame.cpp:3947
-#: ../src/gui/mainFrame.cpp:5508 ../src/gui/mainFrame.cpp:6063
+#: ../src/gui/mainFrame.cpp:3870 ../src/gui/mainFrame.cpp:3937
+#: ../src/gui/mainFrame.cpp:5268 ../src/gui/mainFrame.cpp:5802
msgid "Cons."
msgstr ""
-#: ../src/gui/mainFrame.cpp:3914
+#: ../src/gui/mainFrame.cpp:3904
msgid "Refresh Aborted."
msgstr ""
-#: ../src/gui/mainFrame.cpp:3951
+#: ../src/gui/mainFrame.cpp:3941
msgid "*Cons."
msgstr ""
-#: ../src/gui/mainFrame.cpp:3953
+#: ../src/gui/mainFrame.cpp:3943
msgid "§Cons."
msgstr ""
-#: ../src/gui/mainFrame.cpp:4076
+#: ../src/gui/mainFrame.cpp:4037
+msgid "msgs"
+msgstr ""
+
+#: ../src/gui/mainFrame.cpp:4077
msgid "Autosave complete."
msgstr ""
-#: ../src/gui/mainFrame.cpp:4243
+#: ../src/gui/mainFrame.cpp:4273
msgid "Aborted."
msgstr ""
-#: ../src/gui/mainFrame.cpp:4294
+#: ../src/gui/mainFrame.cpp:4324
msgid "Updated."
msgstr ""
-#: ../src/gui/mainFrame.cpp:4301
+#: ../src/gui/mainFrame.cpp:4331
msgid "\\% Done (Esc aborts)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:4303
+#: ../src/gui/mainFrame.cpp:4333
msgid "\\% Done"
msgstr ""
-#: ../src/gui/mainFrame.cpp:4562 ../src/gui/mainFrame.cpp:4569
-msgid "Next Fullscreen mode: none"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:4565
-msgid "Next Fullscreen mode: complete"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:4573
-msgid "Next Fullscreen mode: with toolbars"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:4589
-msgid "Next Mode: No fullscreen"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:4593
-msgid "Next Mode: fullscreen w/o toolbar"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:4597
-msgid "Next Mode: fullscreen with toolbar"
-msgstr ""
-
-#: ../src/gui/mainFrame.cpp:4638
+#: ../src/gui/mainFrame.cpp:4609
msgid "Tip: You can shift-click to force full refresh, if required"
msgstr ""
-#: ../src/gui/mainFrame.cpp:4910
+#: ../src/gui/mainFrame.cpp:4672
msgid "No data to save"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5082
+#: ../src/gui/mainFrame.cpp:4842
msgid "Aborting..."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5088
+#: ../src/gui/mainFrame.cpp:4848
msgid ""
"Waiting for refresh to abort. Exiting could lead to the program "
"backgrounding. Exit anyway? "
msgstr ""
-#: ../src/gui/mainFrame.cpp:5089 ../src/gui/mainFrame.cpp:5109
+#: ../src/gui/mainFrame.cpp:4849 ../src/gui/mainFrame.cpp:4869
msgid "Confirmation request"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5108
+#: ../src/gui/mainFrame.cpp:4868
msgid "Are you sure you wish to exit 3Depict?"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5536
+#: ../src/gui/mainFrame.cpp:5296
msgid "Update Notice: New version "
msgstr ""
-#: ../src/gui/mainFrame.cpp:5536
+#: ../src/gui/mainFrame.cpp:5296
msgid " found online."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5540
+#: ../src/gui/mainFrame.cpp:5300
msgid "Online Check: "
msgstr ""
-#: ../src/gui/mainFrame.cpp:5540
+#: ../src/gui/mainFrame.cpp:5300
msgid " is up-to-date."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5630
+#: ../src/gui/mainFrame.cpp:5395
msgid "An auto-save state was found, would you like to restore it?."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5631
+#: ../src/gui/mainFrame.cpp:5396
msgid "Autosave"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5638
+#: ../src/gui/mainFrame.cpp:5403
msgid "Unable to load autosave file.."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5830
+#: ../src/gui/mainFrame.cpp:5600
msgid "List of available filters"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5832
+#: ../src/gui/mainFrame.cpp:5602
msgid "Tree - drag to move items, hold ⌘ for copy. Tap delete to remove items"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5834
+#: ../src/gui/mainFrame.cpp:5604
msgid ""
"Tree - drag to move items, hold Ctrl for copy. Tap delete to remove items."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5836
+#: ../src/gui/mainFrame.cpp:5606
msgid ""
"Enable/Disable automatic updates of data when filter change takes effect"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5839
+#: ../src/gui/mainFrame.cpp:5609
msgid ""
"Enable/Disable \"Alpha blending\" (transparency) in rendering system. "
"Blending is used to smooth objects (avoids artefacts known as \"jaggies\") "
@@ -2071,14 +2029,14 @@ msgid ""
"but look more blocky"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5840
+#: ../src/gui/mainFrame.cpp:5610
msgid ""
"Enable/Disable lighting calculations in rendering, for objects that request "
"this. Lighting provides important depth cues for objects comprised of 3D "
"surfaces. Disabling may allow faster rendering in complex scenes"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5841
+#: ../src/gui/mainFrame.cpp:5611
msgid ""
"Enable/Disable weak randomisation (Galois linear feedback shift register). "
"Strong randomisation uses a much slower random selection method, but "
@@ -2086,14 +2044,14 @@ msgid ""
"recommended for final analyses"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5843
+#: ../src/gui/mainFrame.cpp:5613
msgid ""
"Limit the number of points that can be displayed in the 3D scene. Does not "
"affect filter tree calculations. Disabling this can severely reduce "
"performance, due to large numbers of points being visible at once."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5844
+#: ../src/gui/mainFrame.cpp:5614
msgid ""
"Enable/Disable caching of intermediate results during filter updates. "
"Disabling caching will use less system RAM, though changes to any filter "
@@ -2101,156 +2059,145 @@ msgid ""
"computations"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5855
+#: ../src/gui/mainFrame.cpp:5616
msgid "Camera data information"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5859
+#: ../src/gui/mainFrame.cpp:5620
msgid "Enable/disable visual effects on final 3D output"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5861
+#: ../src/gui/mainFrame.cpp:5622
msgid "Enable cropping post-process effect"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5864
+#: ../src/gui/mainFrame.cpp:5625
msgid ""
"Colour based 3D effect enable/disable - requires appropriate colour filter "
"3D glasses."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5865
+#: ../src/gui/mainFrame.cpp:5626
msgid "Glasses colour mode"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5867
+#: ../src/gui/mainFrame.cpp:5628
msgid ""
"Level of separation between left and right images, which sets 3D depth to "
"visual distortion tradeoff"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5871
+#: ../src/gui/mainFrame.cpp:5632
msgid "X"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5872
+#: ../src/gui/mainFrame.cpp:5633
msgid "Y"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5873
+#: ../src/gui/mainFrame.cpp:5634
msgid "Save raw data to file"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5874
+#: ../src/gui/mainFrame.cpp:5635
msgid "Copy raw data to clipboard"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5875
+#: ../src/gui/mainFrame.cpp:5636
msgid "Manage \"stashed\" data."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5876
+#: ../src/gui/mainFrame.cpp:5637
msgid "Program text output"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5877
+#: ../src/gui/mainFrame.cpp:5638
msgid "Select active camera, or type to create new named camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5878
+#: ../src/gui/mainFrame.cpp:5639
msgid "Remove the selected camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5879
+#: ../src/gui/mainFrame.cpp:5640
msgid "Perform cropping from coordinate frame of camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5880
+#: ../src/gui/mainFrame.cpp:5641
msgid ""
"Set the maximum amount of RAM to use in order to speed repeat computations"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5881
+#: ../src/gui/mainFrame.cpp:5642
msgid "Collapse the filter tree"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5882
+#: ../src/gui/mainFrame.cpp:5643
msgid "Expand the filter tree"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5883
+#: ../src/gui/mainFrame.cpp:5644
msgid "Process the filter tree, hold shift to purge cached filter data"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6023
+#: ../src/gui/mainFrame.cpp:5762
msgid "Crop"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6024
+#: ../src/gui/mainFrame.cpp:5763
msgid "Stereo"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6041
+#: ../src/gui/mainFrame.cpp:5780
+#: ../src/backend/filters/externalProgram.cpp:577
+#: ../src/backend/filters/ionColour.cpp:312
+#: ../src/backend/filters/spectrumPlot.cpp:418
msgid "Data"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6042
+#: ../src/gui/mainFrame.cpp:5781
msgid "Cam"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6043
+#: ../src/gui/mainFrame.cpp:5782
msgid "Post"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6044
+#: ../src/gui/mainFrame.cpp:5783
msgid "Tools"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6062
+#: ../src/gui/mainFrame.cpp:5801
msgid "Raw"
msgstr ""
-#: ../src/gui/mathglPane.cpp:230
+#: ../src/gui/mathglPane.cpp:241
msgid "No plots selected."
msgstr ""
-#: ../src/gui/mathglPane.cpp:1202
+#: ../src/gui/mathglPane.cpp:1165
msgid ""
"Unable to allocate requested memory.\n"
" Try a lower resolution, or save as vector (SVG)."
msgstr ""
-#: ../src/gui/mathglPane.cpp:1204
+#: ../src/gui/mathglPane.cpp:1167
msgid "Plotting functions returned an error:\n"
msgstr ""
-#: ../src/gui/mathglPane.cpp:1206
+#: ../src/gui/mathglPane.cpp:1169
msgid "File readback check failed"
msgstr ""
-#: ../src/gui/mathglPane.cpp:1208
+#: ../src/gui/mathglPane.cpp:1171
msgid "Filesize during readback appears to be zero."
msgstr ""
-#: ../src/3Depict.cpp:78
-msgid "displays this message"
-msgstr ""
-
-#: ../src/3Depict.cpp:80
-msgid "inputfile"
-msgstr ""
-
-#: ../src/3Depict.cpp:89
-msgid ""
-"Run debug unit tests, returns nonzero on test failure, zero on success.\n"
-"\t\tXML files may be passed to run, instead of default tests"
-msgstr ""
-
-#: ../src/3Depict.cpp:383
+#: ../src/3Depict.cpp:381
msgid "File : "
msgstr ""
-#: ../src/3Depict.cpp:383
+#: ../src/3Depict.cpp:381
msgid " does not exist. Skipping"
msgstr ""
@@ -2266,1497 +2213,1472 @@ msgstr ""
msgid "Unable to determine filter type in defaults listing."
msgstr ""
-#: ../src/backend/configFile.cpp:610
+#: ../src/backend/configFile.cpp:604
msgid "Online access for non win32/apple platforms is intentionally disabled, "
msgstr ""
-#: ../src/backend/configFile.cpp:611
+#: ../src/backend/configFile.cpp:605
msgid ""
"regardless of the settings you use here. Use your package manager to keep up-"
"to-date"
msgstr ""
-#: ../src/backend/plot.cpp:30 ../src/backend/filters/voxelise.cpp:122
-#: ../src/backend/filters/voxelise.cpp:132
+#: ../src/backend/plot.cpp:28 ../src/backend/filters/voxelise.cpp:123
+#: ../src/backend/filters/voxelise.cpp:133
msgid "None"
msgstr ""
-#: ../src/backend/plot.cpp:31
+#: ../src/backend/plot.cpp:29
msgid "Moving avg."
msgstr ""
-#: ../src/backend/plot.cpp:35
+#: ../src/backend/plot.cpp:33
msgid "Lines"
msgstr ""
-#: ../src/backend/plot.cpp:36
+#: ../src/backend/plot.cpp:34
msgid "Bars"
msgstr ""
-#: ../src/backend/plot.cpp:37
+#: ../src/backend/plot.cpp:35
msgid "Steps"
msgstr ""
-#: ../src/backend/plot.cpp:38
+#: ../src/backend/plot.cpp:36
msgid "Stem"
msgstr ""
-#: ../src/backend/plot.cpp:39
+#: ../src/backend/plot.cpp:37
msgid "Points"
msgstr ""
-#: ../src/backend/plot.cpp:841 ../src/backend/plot.cpp:849
+#: ../src/backend/plot.cpp:39
+msgid "Density"
+msgstr ""
+
+#: ../src/backend/plot.cpp:40
+msgid "Scatter"
+msgstr ""
+
+#: ../src/backend/plot.cpp:787 ../src/backend/plot.cpp:795
msgid "Multiple data types"
msgstr ""
-#: ../src/backend/plot.cpp:1550
+#: ../src/backend/plot.cpp:1559
msgid "error"
msgstr ""
-#: ../src/backend/filtertree.cpp:1051
+#: ../src/backend/plot.cpp:1772
+msgid "Amplitude"
+msgstr ""
+
+#: ../src/backend/filtertree.cpp:1060
msgid "WARNING: Skipping node "
msgstr ""
-#: ../src/backend/filtertree.cpp:1051
+#: ../src/backend/filtertree.cpp:1060
msgid " as it was not recognised"
msgstr ""
-#: ../src/backend/filtertree.cpp:1089
+#: ../src/backend/filtertree.cpp:1098
msgid "Error processing node: "
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:543
+#: ../src/backend/filters/externalProgram.cpp:545
+#: ../src/backend/filters/externalProgram.cpp:559
msgid "Command"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:546
+#: ../src/backend/filters/externalProgram.cpp:548
msgid ""
"Full command to send to operating system. See manual for escape sequence "
"meanings"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:550
+#: ../src/backend/filters/externalProgram.cpp:552
msgid "Work Dir"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:553
+#: ../src/backend/filters/externalProgram.cpp:555
msgid "Directory to run the command in"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:563
+#: ../src/backend/filters/externalProgram.cpp:562
msgid "Cleanup input"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:566
+#: ../src/backend/filters/externalProgram.cpp:565
msgid "Erase input files when command completed"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:575
+#: ../src/backend/filters/externalProgram.cpp:570
msgid "Cache"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:578
+#: ../src/backend/filters/externalProgram.cpp:573
msgid ""
"Assume program does not alter its output, unless inputs from 3Depict are "
"altered"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:660
-msgid "Error processing command line"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:662
-msgid "Unable to set working directory"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:664
-msgid "Error saving posfile result for external program"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:666
-msgid "Error saving plot result for externalprogram"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:668
-msgid "Error creating temporary directory"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:670
-msgid "Detected unusable number of columns in plot"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:672
-msgid "Unable to parse plot result from external program"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:674
-msgid "Unable to load ions from external program"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:676
-msgid "Unable to perform commandline substitution"
-msgstr ""
-
-#: ../src/backend/filters/externalProgram.cpp:678
-msgid "Error executing external program"
-msgstr ""
-
-#: ../src/backend/filters/ionClip.cpp:59
-#: ../src/backend/filters/compositionProfile.cpp:43
+#: ../src/backend/filters/ionClip.cpp:60
+#: ../src/backend/filters/compositionProfile.cpp:44
msgid "Sphere"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:60
+#: ../src/backend/filters/ionClip.cpp:61
msgid "Plane"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:61
-#: ../src/backend/filters/compositionProfile.cpp:42
+#: ../src/backend/filters/ionClip.cpp:62
+#: ../src/backend/filters/compositionProfile.cpp:43
msgid "Cylinder"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:62
+#: ../src/backend/filters/ionClip.cpp:63
msgid "Aligned box"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:495
+#: ../src/backend/filters/ionClip.cpp:488
+#: ../src/backend/filters/compositionProfile.cpp:943
msgid "Primitive"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:498
+#: ../src/backend/filters/ionClip.cpp:491
msgid "Shape of clipping object"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:504
-#: ../src/backend/filters/compositionProfile.cpp:1000
+#: ../src/backend/filters/ionClip.cpp:497
+#: ../src/backend/filters/compositionProfile.cpp:949
msgid "Show Primitive"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:507
+#: ../src/backend/filters/ionClip.cpp:500
msgid "Display the 3D interaction object"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:512
+#: ../src/backend/filters/ionClip.cpp:505
msgid "Invert Clip"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:515
+#: ../src/backend/filters/ionClip.cpp:508
msgid ""
"Switch between retaining points inside (false) and outside (true) of "
"primitive"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:529
-#: ../src/backend/filters/compositionProfile.cpp:1059
+#: ../src/backend/filters/ionClip.cpp:522
+#: ../src/backend/filters/compositionProfile.cpp:1005
msgid "Position for centre of sphere"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:534
-#: ../src/backend/filters/ionClip.cpp:597
-#: ../src/backend/filters/compositionProfile.cpp:1042
-#: ../src/backend/filters/compositionProfile.cpp:1064
-#: ../src/backend/filters/spatialAnalysis.cpp:93
-#: ../src/backend/filters/spatialAnalysis.cpp:616
+#: ../src/backend/filters/ionClip.cpp:527
+#: ../src/backend/filters/ionClip.cpp:587
+#: ../src/backend/filters/compositionProfile.cpp:988
+#: ../src/backend/filters/compositionProfile.cpp:1010
+#: ../src/backend/filters/spatialAnalysis.cpp:111
+#: ../src/backend/filters/spatialAnalysis.cpp:791
msgid "Radius"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:537
-#: ../src/backend/filters/compositionProfile.cpp:1067
+#: ../src/backend/filters/ionClip.cpp:530
+#: ../src/backend/filters/compositionProfile.cpp:1013
msgid "Radius of sphere"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:551
+#: ../src/backend/filters/ionClip.cpp:544
msgid "Position that plane passes through"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:556
+#: ../src/backend/filters/ionClip.cpp:549
msgid "Plane Normal"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:559
+#: ../src/backend/filters/ionClip.cpp:552
msgid "Perpendicular direction for plane"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:573
+#: ../src/backend/filters/ionClip.cpp:566
msgid "Centre of cylinder"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:578
-#: ../src/backend/filters/compositionProfile.cpp:1023
-#: ../src/backend/filters/spatialAnalysis.cpp:607
-#: ../src/backend/filters/transform.cpp:1325
+#: ../src/backend/filters/ionClip.cpp:571
+#: ../src/backend/filters/compositionProfile.cpp:972
+#: ../src/backend/filters/spatialAnalysis.cpp:782
+#: ../src/backend/filters/transform.cpp:1277
msgid "Axis"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:581
+#: ../src/backend/filters/ionClip.cpp:574
msgid "Positive vector for cylinder"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:589
-#: ../src/backend/filters/compositionProfile.cpp:1034
+#: ../src/backend/filters/ionClip.cpp:579
+#: ../src/backend/filters/compositionProfile.cpp:980
msgid "Lock Axis Mag."
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:592
+#: ../src/backend/filters/ionClip.cpp:582
msgid "Prevent changing length of cylinder during 3D interaction"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:600
-#: ../src/backend/filters/compositionProfile.cpp:1045
-#: ../src/backend/filters/spatialAnalysis.cpp:619
+#: ../src/backend/filters/ionClip.cpp:590
+#: ../src/backend/filters/compositionProfile.cpp:991
+#: ../src/backend/filters/spatialAnalysis.cpp:794
msgid "Radius of cylinder"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:613
+#: ../src/backend/filters/ionClip.cpp:603
msgid "Centre of axis aligned box"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:618
+#: ../src/backend/filters/ionClip.cpp:608
msgid "Corner offset"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:621
+#: ../src/backend/filters/ionClip.cpp:611
msgid "Vector to corner of box"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:77
-#: ../src/backend/filters/clusterAnalysis.cpp:1017
+#: ../src/backend/filters/clusterAnalysis.cpp:80
+#: ../src/backend/filters/clusterAnalysis.cpp:1045
msgid "Size Distribution"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:78
+#: ../src/backend/filters/clusterAnalysis.cpp:81
msgid "Chemistry Distribution"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:491
+#: ../src/backend/filters/clusterAnalysis.cpp:499
msgid "No range data. Can't cluster."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:502
+#: ../src/backend/filters/clusterAnalysis.cpp:510
msgid ""
"No ranges selected for cluster \"core\". Cannot continue with clustering."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:511
+#: ../src/backend/filters/clusterAnalysis.cpp:519
msgid ""
"No ranges selected for cluster \"bulk\". Cannot continue with clustering."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:684
-msgid "Morphology Plot"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:685
-msgid "\\lambda_1:\\lambda_2 ratio"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:686
-msgid "\\lambda_2:\\lambda_3 ratio"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:723
-msgid "No clusters had sufficient dimensionality to compute singular values"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:780
+#: ../src/backend/filters/clusterAnalysis.cpp:789
msgid "Found :"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:782
+#: ../src/backend/filters/clusterAnalysis.cpp:791
msgid " clusters"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:850
+#: ../src/backend/filters/clusterAnalysis.cpp:873
msgid "Compositions (fractional, core+bulk)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:852
+#: ../src/backend/filters/clusterAnalysis.cpp:875
msgid "Compositions (fractional, core only)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:870
+#: ../src/backend/filters/clusterAnalysis.cpp:893
msgid "Frequencies (core+bulk)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:898
+#: ../src/backend/filters/clusterAnalysis.cpp:924
msgid "Core Link + Erode"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:902
-#: ../src/backend/filters/spatialAnalysis.cpp:373
-#: ../src/backend/filters/ionInfo.cpp:440
+#: ../src/backend/filters/clusterAnalysis.cpp:928
+#: ../src/backend/filters/clusterAnalysis.cpp:936
+#: ../src/backend/filters/spatialAnalysis.cpp:541
+#: ../src/backend/filters/spatialAnalysis.cpp:549
+#: ../src/backend/filters/transform.cpp:1140
+#: ../src/backend/filters/ionInfo.cpp:441
msgid "Algorithm"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:906
+#: ../src/backend/filters/clusterAnalysis.cpp:932
msgid "Cluster algorithm mode"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:915
+#: ../src/backend/filters/clusterAnalysis.cpp:943
msgid "Core Classify"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:918
+#: ../src/backend/filters/clusterAnalysis.cpp:946
msgid ""
"Enable core-classifcation pre-step in clustering (Stephenson et al, 2007)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:924
+#: ../src/backend/filters/clusterAnalysis.cpp:952
msgid "Core Classify Dist"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:927
+#: ../src/backend/filters/clusterAnalysis.cpp:955
msgid "Restrict only atoms by distance to be cluster sources"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:932
+#: ../src/backend/filters/clusterAnalysis.cpp:960
msgid "Classify Knn Max"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:935
+#: ../src/backend/filters/clusterAnalysis.cpp:963
msgid ""
"Require that the kth NN (this number) is within the classify distance, to be "
"a cluster source"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:941
+#: ../src/backend/filters/clusterAnalysis.cpp:969
msgid "Core Link Dist"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:944
+#: ../src/backend/filters/clusterAnalysis.cpp:972
msgid "Distance between clusters to allow linking"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:949
+#: ../src/backend/filters/clusterAnalysis.cpp:977
msgid "Bulk Link"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:952
-#: ../src/backend/filters/clusterAnalysis.cpp:970
+#: ../src/backend/filters/clusterAnalysis.cpp:980
+#: ../src/backend/filters/clusterAnalysis.cpp:998
msgid "Enable linking of non-cluster species - eg for composition analysis "
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:959
+#: ../src/backend/filters/clusterAnalysis.cpp:987
msgid "Bulk Link (Envelope) Dist"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:962
+#: ../src/backend/filters/clusterAnalysis.cpp:990
msgid ""
"Distance from core points that form cluster that is used to grab surrounding "
"bulk points"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:967
+#: ../src/backend/filters/clusterAnalysis.cpp:995
msgid "Erosion"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:976
+#: ../src/backend/filters/clusterAnalysis.cpp:1004
msgid "Erode Dist"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:979
+#: ../src/backend/filters/clusterAnalysis.cpp:1007
msgid ""
"Distance from unclustered material in which bulk points are eroded from "
"cluster"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:985
+#: ../src/backend/filters/clusterAnalysis.cpp:1013
msgid "Clustering Params"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:990
+#: ../src/backend/filters/clusterAnalysis.cpp:1018
msgid "Size Cropping"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:993
+#: ../src/backend/filters/clusterAnalysis.cpp:1021
msgid "Remove clusters based upon size distribution"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1000
+#: ../src/backend/filters/clusterAnalysis.cpp:1028
msgid "Min Size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1003
+#: ../src/backend/filters/clusterAnalysis.cpp:1031
msgid "Remove clusters below this size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1008
+#: ../src/backend/filters/clusterAnalysis.cpp:1036
msgid "Max Size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1011
+#: ../src/backend/filters/clusterAnalysis.cpp:1039
msgid "Remove clusters above this size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1020
+#: ../src/backend/filters/clusterAnalysis.cpp:1048
msgid "Show number of clusters as a function of cluster size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1026
+#: ../src/backend/filters/clusterAnalysis.cpp:1054
msgid "Log Scale"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1029
+#: ../src/backend/filters/clusterAnalysis.cpp:1057
msgid "Use logarithmic scale for size distribution"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1045
+#: ../src/backend/filters/clusterAnalysis.cpp:1075
+msgid "Cluster Id"
+msgstr ""
+
+#: ../src/backend/filters/clusterAnalysis.cpp:1078
+msgid "Assign cluster output a unique per-cluster value (id)."
+msgstr ""
+
+#: ../src/backend/filters/clusterAnalysis.cpp:1085
msgid "Chemistry Dist."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1048
+#: ../src/backend/filters/clusterAnalysis.cpp:1088
msgid "Create a plot showing chemistry for each cluster size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1055
-#: ../src/backend/filters/compositionProfile.cpp:1107
-#: ../src/backend/filters/spatialAnalysis.cpp:674
+#: ../src/backend/filters/clusterAnalysis.cpp:1095
+#: ../src/backend/filters/compositionProfile.cpp:1053
+#: ../src/backend/filters/spatialAnalysis.cpp:849
#: ../src/backend/filters/ionInfo.cpp:412
msgid "Normalise"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1058
+#: ../src/backend/filters/clusterAnalysis.cpp:1098
msgid "Convert cluster counts to composition"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1064
+#: ../src/backend/filters/clusterAnalysis.cpp:1104
msgid "Postprocess"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1083
+#: ../src/backend/filters/clusterAnalysis.cpp:1123
msgid "If selected, use as \"core\" ion type (can make clusters)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1088
+#: ../src/backend/filters/clusterAnalysis.cpp:1128
msgid "Core Ranges"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1102
+#: ../src/backend/filters/clusterAnalysis.cpp:1142
msgid ""
"If selected, use as \"bulk\" ion type (can be included in existing clusters)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1107
+#: ../src/backend/filters/clusterAnalysis.cpp:1147
msgid "Bulk Ranges"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1123
+#: ../src/backend/filters/clusterAnalysis.cpp:1163
msgid "Max. Sep + Erode"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1803
-msgid "Clustering aborted"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:1805
-msgid "No core ions for cluster"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:1807
-msgid "No bulk ions for cluster"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:1885
+#: ../src/backend/filters/clusterAnalysis.cpp:1891
msgid " --------------------------- Parameter selection notice ------------- "
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1886
+#: ../src/backend/filters/clusterAnalysis.cpp:1892
msgid "You have specified a bulk distance larger than half your link distance."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1887
+#: ../src/backend/filters/clusterAnalysis.cpp:1893
msgid ""
"You can do this; thats OK, but the output is no longer independent of the "
"computational process;"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1888
+#: ../src/backend/filters/clusterAnalysis.cpp:1894
msgid ""
"This will be a problem in the case where two or more clusters can equally "
"lay claim to a \"bulk\" ion. "
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1889
+#: ../src/backend/filters/clusterAnalysis.cpp:1895
msgid ""
" If your inter-cluster distance is sufficiently large (larger than your bulk "
"linking distance), then you can get away with this."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1890
+#: ../src/backend/filters/clusterAnalysis.cpp:1896
msgid ""
" In theory it is possible to \"join\" the clusters, but this has not been "
"implemented for speed reasons."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1891
+#: ../src/backend/filters/clusterAnalysis.cpp:1897
msgid ""
"If you want this, please contact the author, or just use the source to add "
"this in yourself."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1892
+#: ../src/backend/filters/clusterAnalysis.cpp:1898
msgid "---------------------------------------------------------------------- "
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1902
-#: ../src/backend/filters/spatialAnalysis.cpp:1757
-#: ../src/backend/filters/spatialAnalysis.cpp:2084
-#: ../src/backend/filters/spatialAnalysis.cpp:2382
-#: ../src/backend/filters/spatialAnalysis.cpp:3078
-#: ../src/backend/filters/transform.cpp:1033
+#: ../src/backend/filters/clusterAnalysis.cpp:1908
+#: ../src/backend/filters/spatialAnalysis.cpp:1971
+#: ../src/backend/filters/spatialAnalysis.cpp:2314
+#: ../src/backend/filters/spatialAnalysis.cpp:2605
+#: ../src/backend/filters/spatialAnalysis.cpp:3293
+#: ../src/backend/filters/transform.cpp:991
msgid "Collate"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1921
+#: ../src/backend/filters/clusterAnalysis.cpp:1927
msgid "Build Core"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1939
+#: ../src/backend/filters/clusterAnalysis.cpp:1945
msgid "Classify Core"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2032
+#: ../src/backend/filters/clusterAnalysis.cpp:2038
msgid "Build Bulk"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2052
+#: ../src/backend/filters/clusterAnalysis.cpp:2058
msgid "Core"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2197
+#: ../src/backend/filters/clusterAnalysis.cpp:2203
msgid "Bulk"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2327
+#: ../src/backend/filters/clusterAnalysis.cpp:2333
msgid "Erode"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2401
+#: ../src/backend/filters/clusterAnalysis.cpp:2407
msgid "Re-Collate"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2669
-#: ../src/backend/filters/clusterAnalysis.cpp:2873
+#: ../src/backend/filters/clusterAnalysis.cpp:2675
+#: ../src/backend/filters/clusterAnalysis.cpp:2879
msgid "Cluster Size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2670
-#: ../src/backend/filters/clusterAnalysis.cpp:2877
+#: ../src/backend/filters/clusterAnalysis.cpp:2676
+#: ../src/backend/filters/clusterAnalysis.cpp:2883
msgid "Frequency"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2875
+#: ../src/backend/filters/clusterAnalysis.cpp:2881
msgid "Composition"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:109
+#: ../src/backend/filters/voxelise.cpp:110
msgid "None (Raw count)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:110
+#: ../src/backend/filters/voxelise.cpp:111
msgid "Volume (Density)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:111
+#: ../src/backend/filters/voxelise.cpp:112
msgid "All Ions (conc)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:112
+#: ../src/backend/filters/voxelise.cpp:113
msgid "Ratio (Num/Denom)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:116
+#: ../src/backend/filters/voxelise.cpp:117
msgid "Point Cloud"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:117
+#: ../src/backend/filters/voxelise.cpp:118
msgid "Isosurface"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:118
+#: ../src/backend/filters/voxelise.cpp:119
msgid "Axial slice"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:123
+#: ../src/backend/filters/voxelise.cpp:124
msgid "Gaussian (2𝜎)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:127
+#: ../src/backend/filters/voxelise.cpp:128
msgid "Zero"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:128
+#: ../src/backend/filters/voxelise.cpp:129
msgid "Bounce"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:133
+#: ../src/backend/filters/voxelise.cpp:134
msgid "Linear"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:604
+#: ../src/backend/filters/voxelise.cpp:601
msgid "Voxel Limits (min,max): ("
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:754
+#: ../src/backend/filters/voxelise.cpp:751
msgid "Fixed width"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:758
+#: ../src/backend/filters/voxelise.cpp:755
msgid "If true, use fixed size voxels, otherwise use fixed count"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:764
+#: ../src/backend/filters/voxelise.cpp:761
msgid "Bin width x"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:768
+#: ../src/backend/filters/voxelise.cpp:765
msgid "Voxel size in X direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:772
+#: ../src/backend/filters/voxelise.cpp:769
msgid "Bin width y"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:775
+#: ../src/backend/filters/voxelise.cpp:772
msgid "Voxel size in Y direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:781
+#: ../src/backend/filters/voxelise.cpp:778
msgid "Bin width z"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:784
+#: ../src/backend/filters/voxelise.cpp:781
msgid "Voxel size in Z direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:791
+#: ../src/backend/filters/voxelise.cpp:788
msgid "Num bins x"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:795
+#: ../src/backend/filters/voxelise.cpp:792
msgid "Number of voxels to use in X direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:800
+#: ../src/backend/filters/voxelise.cpp:797
msgid "Num bins y"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:803
+#: ../src/backend/filters/voxelise.cpp:800
msgid "Number of voxels to use in Y direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:809
+#: ../src/backend/filters/voxelise.cpp:806
msgid "Num bins z"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:811
+#: ../src/backend/filters/voxelise.cpp:808
msgid "Number of voxels to use in Z direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:832
+#: ../src/backend/filters/voxelise.cpp:838
msgid "Normalise by"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:835
+#: ../src/backend/filters/voxelise.cpp:841
msgid "Method to use to normalise scalar value in each voxel"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:838
+#: ../src/backend/filters/voxelise.cpp:844
msgid "Computation"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:845
+#: ../src/backend/filters/voxelise.cpp:851
msgid "Numerator"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:848
+#: ../src/backend/filters/voxelise.cpp:854
msgid "Parmeter \"a\" used in fraction (a/b) to get voxel value"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:868
+#: ../src/backend/filters/voxelise.cpp:871
msgid "Enable this ion for numerator"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:879
+#: ../src/backend/filters/voxelise.cpp:883
msgid "Denominator"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:882
+#: ../src/backend/filters/voxelise.cpp:886
msgid "Parameter \"b\" used in fraction (a/b) to get voxel value"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:898
+#: ../src/backend/filters/voxelise.cpp:899
msgid "Enable this ion for denominator contribution"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:919
-#: ../src/backend/filters/voxelise.cpp:954
+#: ../src/backend/filters/voxelise.cpp:920
+#: ../src/backend/filters/voxelise.cpp:955
msgid "Filtering"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:923
+#: ../src/backend/filters/voxelise.cpp:924
msgid "Smoothing method to use on voxels"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:926
+#: ../src/backend/filters/voxelise.cpp:927
msgid "Processing"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:932
+#: ../src/backend/filters/voxelise.cpp:933
msgid "Kernel Bins"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:936
+#: ../src/backend/filters/voxelise.cpp:937
msgid "Number of bins in convolution kernel"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:947
+#: ../src/backend/filters/voxelise.cpp:948
msgid "Exterior values"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:950
+#: ../src/backend/filters/voxelise.cpp:951
msgid "Method to use to treat boundaries of voxel data for convolution"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:970
+#: ../src/backend/filters/voxelise.cpp:971
msgid "Representation"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:973
+#: ../src/backend/filters/voxelise.cpp:974
msgid "3D display method"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:984
+#: ../src/backend/filters/voxelise.cpp:985
msgid "Spot size"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:987
+#: ../src/backend/filters/voxelise.cpp:988
msgid "Size of the spots to use for display"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:992
-#: ../src/backend/filters/voxelise.cpp:1030
+#: ../src/backend/filters/voxelise.cpp:993
+#: ../src/backend/filters/voxelise.cpp:1028
msgid "Transparency"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:995
+#: ../src/backend/filters/voxelise.cpp:996
msgid "How \"see through\" each point is (0 - opaque, 1 - invisible)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1004
+#: ../src/backend/filters/voxelise.cpp:1005
msgid "Surf. param."
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1007
+#: ../src/backend/filters/voxelise.cpp:1008
msgid "Isovalue"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1010
+#: ../src/backend/filters/voxelise.cpp:1011
msgid "Scalar value to show as isosurface"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1025
+#: ../src/backend/filters/voxelise.cpp:1016
+#: ../src/backend/filters/voxelise.cpp:1081
+#: ../src/backend/filters/spatialAnalysis.cpp:2019
+#: ../src/backend/filters/spatialAnalysis.cpp:2073
+msgid "Surface"
+msgstr ""
+
+#: ../src/backend/filters/voxelise.cpp:1023
msgid "Colour of isosurface"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1033
+#: ../src/backend/filters/voxelise.cpp:1031
msgid "How \"see through\" each facet is (0 - opaque, 1 - invisible)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1045
+#: ../src/backend/filters/voxelise.cpp:1042
msgid "Slice param."
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1053
+#: ../src/backend/filters/voxelise.cpp:1050
msgid "Slice Axis"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1056
+#: ../src/backend/filters/voxelise.cpp:1053
msgid "Normal for the planar slice"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1063
+#: ../src/backend/filters/voxelise.cpp:1060
msgid "Slice Coord"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1066
+#: ../src/backend/filters/voxelise.cpp:1063
msgid "Fractional coordinate that slice plane passes through"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1071
+#: ../src/backend/filters/voxelise.cpp:1068
msgid "Interp. Mode"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1079
+#: ../src/backend/filters/voxelise.cpp:1076
msgid "Interpolation mode for direction normal to slice"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1094
+#: ../src/backend/filters/voxelise.cpp:1092
msgid "Colour mode"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1097
-#: ../src/backend/filters/ionColour.cpp:262
+#: ../src/backend/filters/voxelise.cpp:1095
+#: ../src/backend/filters/ionColour.cpp:265
msgid "Colour scheme used to assign points colours by value"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1106
-#: ../src/backend/filters/ionColour.cpp:274
+#: ../src/backend/filters/voxelise.cpp:1100
+#: ../src/backend/filters/ionColour.cpp:277
msgid "Show Bar"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1116
+#: ../src/backend/filters/voxelise.cpp:1107
msgid "Auto Bounds"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1117
+#: ../src/backend/filters/voxelise.cpp:1108
msgid "Auto-compute min/max values in map"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1127
-#: ../src/backend/filters/ionColour.cpp:289
+#: ../src/backend/filters/voxelise.cpp:1118
+#: ../src/backend/filters/ionColour.cpp:298
msgid "Map start"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1128
-#: ../src/backend/filters/ionColour.cpp:290
+#: ../src/backend/filters/voxelise.cpp:1119
+#: ../src/backend/filters/ionColour.cpp:299
msgid "Assign points with this value to the first colour in map"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1135
-#: ../src/backend/filters/ionColour.cpp:297
+#: ../src/backend/filters/voxelise.cpp:1126
+#: ../src/backend/filters/ionColour.cpp:306
msgid "Map end"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1136
-#: ../src/backend/filters/ionColour.cpp:298
+#: ../src/backend/filters/voxelise.cpp:1127
+#: ../src/backend/filters/ionColour.cpp:307
msgid "Assign points with this value to the last colour in map"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1707
-msgid "Voxelisation aborted"
-msgstr ""
-
-#: ../src/backend/filters/voxelise.cpp:1709
-msgid "Out of memory"
-msgstr ""
-
-#: ../src/backend/filters/voxelise.cpp:1711
-msgid "Unable to perform filter convolution"
-msgstr ""
-
-#: ../src/backend/filters/voxelise.cpp:1713
-msgid "Voxelisation bounds are invalid"
-msgstr ""
-
-#: ../src/backend/filters/ionColour.cpp:258
+#: ../src/backend/filters/ionColour.cpp:261
msgid "Colour Map"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:266
+#: ../src/backend/filters/ionColour.cpp:269
msgid "Reverse map"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:267
+#: ../src/backend/filters/ionColour.cpp:270
msgid "Reverse the colour scale"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:281
+#: ../src/backend/filters/ionColour.cpp:283
+msgid "Opacity"
+msgstr ""
+
+#: ../src/backend/filters/ionColour.cpp:290
msgid "Num Colours"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:283
+#: ../src/backend/filters/ionColour.cpp:292
msgid "Number of unique colours to use in colour map"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:416
-#: ../src/backend/filters/transform.cpp:1579
-#: ../src/backend/filters/ionInfo.cpp:541
+#: ../src/backend/filters/ionColour.cpp:413
msgid "Aborted"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:536
+#: ../src/backend/filters/compositionProfile.cpp:568
msgid "Distance"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:544
+#: ../src/backend/filters/compositionProfile.cpp:576
msgid "Fraction"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:546
+#: ../src/backend/filters/compositionProfile.cpp:578
msgid "Density (\\frac{\\#}{len^3})"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:573
+#: ../src/backend/filters/compositionProfile.cpp:605
msgid "Freq. Profile"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:641
-msgid "Too many bins in comp. profile."
+#: ../src/backend/filters/compositionProfile.cpp:657
+msgid "No data remained in profile - cannot display result"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:643
-msgid "Not enough memory for comp. profile."
-msgstr ""
-
-#: ../src/backend/filters/compositionProfile.cpp:645
-msgid "Aborted composition prof."
-msgstr ""
-
-#: ../src/backend/filters/compositionProfile.cpp:989
+#: ../src/backend/filters/compositionProfile.cpp:937
msgid "Primitive type"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:993
+#: ../src/backend/filters/compositionProfile.cpp:941
msgid "Basic shape to use for profile"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1004
+#: ../src/backend/filters/compositionProfile.cpp:953
msgid "Display the 3D composition profile interaction object"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1018
-#: ../src/backend/filters/spatialAnalysis.cpp:602
+#: ../src/backend/filters/compositionProfile.cpp:967
+#: ../src/backend/filters/spatialAnalysis.cpp:777
msgid "Position for centre of cylinder"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1026
+#: ../src/backend/filters/compositionProfile.cpp:975
msgid "Vector between ends of cylinder"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1037
+#: ../src/backend/filters/compositionProfile.cpp:983
msgid "Prevent length of cylinder changing during interaction"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1077
+#: ../src/backend/filters/compositionProfile.cpp:1023
msgid "Fixed Bin Num"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1080
+#: ../src/backend/filters/compositionProfile.cpp:1026
msgid ""
"If true, use a fixed number of bins for profile, otherwise use fixed step "
"size"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1086
-#: ../src/backend/filters/spatialAnalysis.cpp:433
-#: ../src/backend/filters/spatialAnalysis.cpp:575
+#: ../src/backend/filters/compositionProfile.cpp:1032
+#: ../src/backend/filters/spatialAnalysis.cpp:612
+#: ../src/backend/filters/spatialAnalysis.cpp:754
msgid "Num Bins"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1091
+#: ../src/backend/filters/compositionProfile.cpp:1037
msgid "Number of bins to use for profile"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1096
-#: ../src/backend/filters/spectrumPlot.cpp:396
+#: ../src/backend/filters/compositionProfile.cpp:1042
+#: ../src/backend/filters/spectrumPlot.cpp:386
msgid "Bin width"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1102
+#: ../src/backend/filters/compositionProfile.cpp:1048
msgid "Size of each bin in profile"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1111
+#: ../src/backend/filters/compositionProfile.cpp:1057
msgid "Convert bin counts into relative frequencies in each bin"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1115
+#: ../src/backend/filters/compositionProfile.cpp:1061
msgid "Min. events"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1119
+#: ../src/backend/filters/compositionProfile.cpp:1065
msgid "Drop data that does not have this many events"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1143
-#: ../src/backend/filters/spectrumPlot.cpp:459
+#: ../src/backend/filters/compositionProfile.cpp:1068
+msgid "Settings"
+msgstr ""
+
+#: ../src/backend/filters/compositionProfile.cpp:1090
+#: ../src/backend/filters/spectrumPlot.cpp:445
msgid "Plot Type"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1146
+#: ../src/backend/filters/compositionProfile.cpp:1093
msgid "Visual style for plot"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1159
+#: ../src/backend/filters/compositionProfile.cpp:1103
msgid "Colour of plot"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1175
+#: ../src/backend/filters/compositionProfile.cpp:1119
msgid "Err. Estimator"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1178
+#: ../src/backend/filters/compositionProfile.cpp:1122
msgid "Method of estimating error associated with each bin"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1185
+#: ../src/backend/filters/compositionProfile.cpp:1129
msgid "Avg. Window"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1188
+#: ../src/backend/filters/compositionProfile.cpp:1132
msgid "Number of bins to include in moving average filter"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1192
+#: ../src/backend/filters/compositionProfile.cpp:1136
msgid "Error analysis"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:84
+#: ../src/backend/filters/spatialAnalysis.cpp:101
msgid "Local Density"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:85
+#: ../src/backend/filters/spatialAnalysis.cpp:102
msgid "Density Filtering"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:86
+#: ../src/backend/filters/spatialAnalysis.cpp:103
msgid "Radial Distribution"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:87
+#: ../src/backend/filters/spatialAnalysis.cpp:104
msgid "Axial Distribution"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:88
+#: ../src/backend/filters/spatialAnalysis.cpp:105
msgid "Binomial Distribution"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:92
+#: ../src/backend/filters/spatialAnalysis.cpp:106
+msgid "Point Em/Replacement"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:110
msgid "Neighbour Count"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:376
+#: ../src/backend/filters/spatialAnalysis.cpp:544
msgid "Spatial analysis algorithm to use"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:398
+#: ../src/backend/filters/spatialAnalysis.cpp:567
msgid "Stop Mode"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:401
+#: ../src/backend/filters/spatialAnalysis.cpp:570
msgid "Method to use to terminate algorithm when examining each point"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:408
+#: ../src/backend/filters/spatialAnalysis.cpp:577
msgid "NN Max"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:411
+#: ../src/backend/filters/spatialAnalysis.cpp:580
msgid "Maximum number of neighbours to examine"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:417
+#: ../src/backend/filters/spatialAnalysis.cpp:586
+msgid "Normalise bins"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:589
+msgid ""
+"Normalise counts by binwidth. Needed when comparing NN histograms against "
+"one another"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:596
msgid "Dist Max"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:420
+#: ../src/backend/filters/spatialAnalysis.cpp:599
msgid "Maximum distance from each point for search"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:436
-#: ../src/backend/filters/spatialAnalysis.cpp:578
+#: ../src/backend/filters/spatialAnalysis.cpp:615
+#: ../src/backend/filters/spatialAnalysis.cpp:757
msgid "Number of bins for output 1D RDF plot"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:442
+#: ../src/backend/filters/spatialAnalysis.cpp:621
msgid "Surface Remove"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:445
+#: ../src/backend/filters/spatialAnalysis.cpp:624
msgid ""
"Exclude surface as part of source to minimise bias in RDF (at cost of "
"increased noise)"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:452
+#: ../src/backend/filters/spatialAnalysis.cpp:631
msgid "Remove Dist"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:455
+#: ../src/backend/filters/spatialAnalysis.cpp:634
msgid "Minimum distance to remove from surface"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:466
-#: ../src/backend/filters/spatialAnalysis.cpp:587
+#: ../src/backend/filters/spatialAnalysis.cpp:642
+#: ../src/backend/filters/spatialAnalysis.cpp:762
msgid "Plot colour "
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:469
-#: ../src/backend/filters/spatialAnalysis.cpp:590
+#: ../src/backend/filters/spatialAnalysis.cpp:645
+#: ../src/backend/filters/spatialAnalysis.cpp:765
msgid "Colour of output plot"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:488
+#: ../src/backend/filters/spatialAnalysis.cpp:649
+#: ../src/backend/filters/spatialAnalysis.cpp:743
+#: ../src/backend/filters/spatialAnalysis.cpp:748
+#: ../src/backend/filters/spatialAnalysis.cpp:797
+#: ../src/backend/filters/spatialAnalysis.cpp:836
+msgid "Alg. Params."
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:665
msgid "Source"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:491
+#: ../src/backend/filters/spatialAnalysis.cpp:668
msgid "Ions to use for initiating RDF search"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:504
+#: ../src/backend/filters/spatialAnalysis.cpp:681
msgid "Enable/disable ion as source"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:521
+#: ../src/backend/filters/spatialAnalysis.cpp:687
+msgid "Source Ion"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:700
msgid "Enable/disable all ions as target"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:533
+#: ../src/backend/filters/spatialAnalysis.cpp:712
msgid "Enable/disable this ion as target"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:541
-#: ../src/backend/filters/spatialAnalysis.cpp:564
-#: ../src/backend/filters/spatialAnalysis.cpp:569
-#: ../src/backend/filters/spatialAnalysis.cpp:622
-#: ../src/backend/filters/spatialAnalysis.cpp:661
-msgid "Alg. Params."
+#: ../src/backend/filters/spatialAnalysis.cpp:717
+msgid "Target Ion"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:548
+#: ../src/backend/filters/spatialAnalysis.cpp:727
msgid "Cutoff"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:551
+#: ../src/backend/filters/spatialAnalysis.cpp:730
msgid "Remove points with local density above/below this value"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:557
+#: ../src/backend/filters/spatialAnalysis.cpp:736
msgid "Retain Upper"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:560
+#: ../src/backend/filters/spatialAnalysis.cpp:739
msgid "Retain either points with density above (enabled) or below cutoff"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:610
+#: ../src/backend/filters/spatialAnalysis.cpp:785
msgid "Vector between centre and end of cylinder"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:629
-#: ../src/backend/filters/spatialAnalysis.cpp:3217
-#: ../src/backend/filters/spatialAnalysis.cpp:3286
+#: ../src/backend/filters/spatialAnalysis.cpp:804
+#: ../src/backend/filters/spatialAnalysis.cpp:3432
+#: ../src/backend/filters/spatialAnalysis.cpp:3491
msgid "Block size"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:632
+#: ../src/backend/filters/spatialAnalysis.cpp:807
msgid "Number of ions to use per block"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:639
+#: ../src/backend/filters/spatialAnalysis.cpp:814
msgid "Max Block Aspect"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:642
+#: ../src/backend/filters/spatialAnalysis.cpp:817
msgid ""
"Maximum allowable block aspect ratio. Blocks above this aspect are "
"discarded. Setting too high decreases correlation strength. Too low causes "
"loss of statistical power."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:653
+#: ../src/backend/filters/spatialAnalysis.cpp:828
msgid "Extrusion Direction"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:656
+#: ../src/backend/filters/spatialAnalysis.cpp:831
msgid "Direction in which blocks are extended during construction."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:665
+#: ../src/backend/filters/spatialAnalysis.cpp:840
msgid "Plot Counts"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:668
+#: ../src/backend/filters/spatialAnalysis.cpp:843
msgid "Show the counts in the binomial histogram"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:677
+#: ../src/backend/filters/spatialAnalysis.cpp:852
msgid ""
"Normalise the counts in the binomial histogram to a probability density "
"function"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:691
+#: ../src/backend/filters/spatialAnalysis.cpp:866
msgid "Display Grid"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:700
+#: ../src/backend/filters/spatialAnalysis.cpp:875
msgid "View Options"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1227
-msgid "Spatial analysis aborted by user"
+#: ../src/backend/filters/spatialAnalysis.cpp:881
+msgid "Data File"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1229
-msgid "Insufficient data to complete analysis."
+#: ../src/backend/filters/spatialAnalysis.cpp:885
+msgid "Pos file of points to subtract/replace/etc"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1231
-msgid "Insufficient bins in histogram for analysis."
+#: ../src/backend/filters/spatialAnalysis.cpp:890
+msgid "Match Tol."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1233
-msgid "Insufficient memory for binomial. Reduce input size?"
+#: ../src/backend/filters/spatialAnalysis.cpp:893
+msgid "Tolerance to allow for matching"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1235
-msgid "Binomial requires a parent range file"
+#: ../src/backend/filters/spatialAnalysis.cpp:909
+msgid "Replacment condition"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1791
-#: ../src/backend/filters/spatialAnalysis.cpp:1843
-#: ../src/backend/filters/spatialAnalysis.cpp:2090
-#: ../src/backend/filters/spatialAnalysis.cpp:2388
-#: ../src/backend/filters/spatialAnalysis.cpp:2920
-msgid "Build"
+#: ../src/backend/filters/spatialAnalysis.cpp:915
+msgid "Replace value"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1803
-#: ../src/backend/filters/spatialAnalysis.cpp:1855
-msgid "Surface"
+#: ../src/backend/filters/spatialAnalysis.cpp:918
+msgid "Use value data from file when replacing ions"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:923
+msgid "Replacement"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:2005
+#: ../src/backend/filters/spatialAnalysis.cpp:2059
+#: ../src/backend/filters/spatialAnalysis.cpp:2320
+#: ../src/backend/filters/spatialAnalysis.cpp:2611
+#: ../src/backend/filters/spatialAnalysis.cpp:3136
+msgid "Build"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1895
-#: ../src/backend/filters/spatialAnalysis.cpp:2117
-#: ../src/backend/filters/spatialAnalysis.cpp:2415
+#: ../src/backend/filters/spatialAnalysis.cpp:2113
+#: ../src/backend/filters/spatialAnalysis.cpp:2347
+#: ../src/backend/filters/spatialAnalysis.cpp:2638
msgid "Analyse"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1952
-#: ../src/backend/filters/spatialAnalysis.cpp:2021
+#: ../src/backend/filters/spatialAnalysis.cpp:2195
+#: ../src/backend/filters/spatialAnalysis.cpp:2258
msgid "Radial Distance"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1956
+#: ../src/backend/filters/spatialAnalysis.cpp:2197
+msgid "Count/Distance"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:2202
msgid "NN Freq."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2012
+#: ../src/backend/filters/spatialAnalysis.cpp:2249
msgid "Warning, "
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2013
+#: ../src/backend/filters/spatialAnalysis.cpp:2250
msgid ""
" points were unable to find neighbour points that exceeded the search "
"radius, and thus terminated prematurely"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2023
+#: ../src/backend/filters/spatialAnalysis.cpp:2260
msgid " RDF"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2313
-#: ../src/backend/filters/spatialAnalysis.cpp:2621
+#: ../src/backend/filters/spatialAnalysis.cpp:2543
+#: ../src/backend/filters/spatialAnalysis.cpp:2844
msgid "Number Density (\\#/Vol^3)"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2342
-#: ../src/backend/filters/spatialAnalysis.cpp:2648
+#: ../src/backend/filters/spatialAnalysis.cpp:2565
+#: ../src/backend/filters/spatialAnalysis.cpp:2864
msgid "Warning,"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2343
-#: ../src/backend/filters/spatialAnalysis.cpp:2649
+#: ../src/backend/filters/spatialAnalysis.cpp:2566
+#: ../src/backend/filters/spatialAnalysis.cpp:2865
msgid " points were un-analysable. These have been dropped"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2365
-#: ../src/backend/filters/spatialAnalysis.cpp:2671
+#: ../src/backend/filters/spatialAnalysis.cpp:2588
+#: ../src/backend/filters/spatialAnalysis.cpp:2887
msgid "And so on..."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2754
+#: ../src/backend/filters/spatialAnalysis.cpp:2970
msgid "Extract"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2829
+#: ../src/backend/filters/spatialAnalysis.cpp:3045
msgid "Reduce"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2937
+#: ../src/backend/filters/spatialAnalysis.cpp:3155
msgid "Compute"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2965
+#: ../src/backend/filters/spatialAnalysis.cpp:3200
msgid "Insufficient points to complete analysis"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3001
+#: ../src/backend/filters/spatialAnalysis.cpp:3223
msgid "Axial Distance"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3003
+#: ../src/backend/filters/spatialAnalysis.cpp:3225
msgid " 1D Dist. Func."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3087
+#: ../src/backend/filters/spatialAnalysis.cpp:3302
msgid "Binomial"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3219
-#: ../src/backend/filters/spatialAnalysis.cpp:3288
+#: ../src/backend/filters/spatialAnalysis.cpp:3434
+#: ../src/backend/filters/spatialAnalysis.cpp:3493
msgid "Rel. Frequency"
msgstr ""
-#: ../src/backend/filters/transform.cpp:77
+#: ../src/backend/filters/transform.cpp:78
msgid "Translate"
msgstr ""
-#: ../src/backend/filters/transform.cpp:78
+#: ../src/backend/filters/transform.cpp:79
msgid "Scale (isotropic)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:79
+#: ../src/backend/filters/transform.cpp:80
msgid "Scale (anisotropic)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:80
+#: ../src/backend/filters/transform.cpp:81
msgid "Rotate"
msgstr ""
-#: ../src/backend/filters/transform.cpp:81
+#: ../src/backend/filters/transform.cpp:82
msgid "Value Shuffle"
msgstr ""
-#: ../src/backend/filters/transform.cpp:82
+#: ../src/backend/filters/transform.cpp:83
msgid "Spatial Noise"
msgstr ""
-#: ../src/backend/filters/transform.cpp:83
+#: ../src/backend/filters/transform.cpp:84
msgid "Translate Value"
msgstr ""
-#: ../src/backend/filters/transform.cpp:87
+#: ../src/backend/filters/transform.cpp:88
msgid "Specify"
msgstr ""
-#: ../src/backend/filters/transform.cpp:88
+#: ../src/backend/filters/transform.cpp:89
msgid "Boundbox Centre"
msgstr ""
-#: ../src/backend/filters/transform.cpp:89
+#: ../src/backend/filters/transform.cpp:90
msgid "Mass Centre"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1052
+#: ../src/backend/filters/transform.cpp:1010
msgid "Mass-to-Charge (amu/e)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1106
+#: ../src/backend/filters/transform.cpp:1064
msgid "Shuffle"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1130
+#: ../src/backend/filters/transform.cpp:1088
msgid "Splice"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1185
+#: ../src/backend/filters/transform.cpp:1136
msgid "Algorithm to use to transform point data"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1201
+#: ../src/backend/filters/transform.cpp:1153
msgid "Origin mode"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1204
+#: ../src/backend/filters/transform.cpp:1156
msgid "Select how transform origin is computed"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1209
+#: ../src/backend/filters/transform.cpp:1161
msgid "Show marker"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1213
+#: ../src/backend/filters/transform.cpp:1165
msgid "Display an interactive object to set transform origin"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1215
+#: ../src/backend/filters/transform.cpp:1167
msgid "Display a small marker to denote transform origin"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1231
+#: ../src/backend/filters/transform.cpp:1183
msgid "Translation"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1234
+#: ../src/backend/filters/transform.cpp:1186
msgid "Translation vector for transform"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1246
+#: ../src/backend/filters/transform.cpp:1198
msgid "Offset"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1250
+#: ../src/backend/filters/transform.cpp:1202
msgid "Scalar to use to offset each point's associated value"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1267
-#: ../src/backend/filters/transform.cpp:1294
+#: ../src/backend/filters/transform.cpp:1219
+#: ../src/backend/filters/transform.cpp:1246
msgid "Origin of scale trasnform"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1274
-#: ../src/backend/filters/transform.cpp:1301
+#: ../src/backend/filters/transform.cpp:1226
+#: ../src/backend/filters/transform.cpp:1253
msgid "Scale Fact."
msgstr ""
-#: ../src/backend/filters/transform.cpp:1277
-#: ../src/backend/filters/transform.cpp:1304
+#: ../src/backend/filters/transform.cpp:1229
+#: ../src/backend/filters/transform.cpp:1256
msgid "Enlargement factor for scaling around origin"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1320
+#: ../src/backend/filters/transform.cpp:1272
msgid "Origin of rotation"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1328
+#: ../src/backend/filters/transform.cpp:1280
msgid "Axis around which to revolve"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1333
+#: ../src/backend/filters/transform.cpp:1285
msgid "Angle (deg)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1336
+#: ../src/backend/filters/transform.cpp:1288
msgid "Angle to perform rotation (ACW, as viewed from axis towards origin)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1353
+#: ../src/backend/filters/transform.cpp:1305
msgid "Noise Type"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1356
+#: ../src/backend/filters/transform.cpp:1308
msgid "Method to use to degrade point data"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1363
+#: ../src/backend/filters/transform.cpp:1315
msgid "Noise level"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1365
+#: ../src/backend/filters/transform.cpp:1317
msgid "Standard dev."
msgstr ""
-#: ../src/backend/filters/transform.cpp:1373
+#: ../src/backend/filters/transform.cpp:1325
msgid "Amplitude of noise"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1385
+#: ../src/backend/filters/transform.cpp:1337
msgid "Transform Params"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1582
-msgid "Unable to allocate memory"
-msgstr ""
-
-#: ../src/backend/filters/transform.cpp:1761
+#: ../src/backend/filters/transform.cpp:1675
msgid "White"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1763
+#: ../src/backend/filters/transform.cpp:1677
msgid "Gaussian"
msgstr ""
@@ -3772,102 +3694,106 @@ msgstr ""
msgid "Dimension"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:524
+#: ../src/backend/filters/boundingBox.cpp:525
msgid "If true, show box, otherwise hide box"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:537
+#: ../src/backend/filters/boundingBox.cpp:538
msgid "Style"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:540
+#: ../src/backend/filters/boundingBox.cpp:541
msgid "Box display mode"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:551
+#: ../src/backend/filters/boundingBox.cpp:544
+msgid "Display mode"
+msgstr ""
+
+#: ../src/backend/filters/boundingBox.cpp:553
msgid "Fixed Tick Num"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:555
+#: ../src/backend/filters/boundingBox.cpp:557
msgid ""
"If true, evenly use specified number of ticks. Otherwise, use distance to "
"determine tick count"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:563
+#: ../src/backend/filters/boundingBox.cpp:565
msgid "Num X"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:566
+#: ../src/backend/filters/boundingBox.cpp:568
msgid "Tick count in X direction"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:571
+#: ../src/backend/filters/boundingBox.cpp:573
msgid "Num Y"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:574
+#: ../src/backend/filters/boundingBox.cpp:576
msgid "Tick count in Y direction"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:579
+#: ../src/backend/filters/boundingBox.cpp:581
msgid "Num Z"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:582
+#: ../src/backend/filters/boundingBox.cpp:584
msgid "Tick count in Z direction"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:588
+#: ../src/backend/filters/boundingBox.cpp:590
msgid "Spacing X"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:592
+#: ../src/backend/filters/boundingBox.cpp:594
msgid "Distance between ticks on X axis"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:596
+#: ../src/backend/filters/boundingBox.cpp:598
msgid "Spacing Y"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:600
+#: ../src/backend/filters/boundingBox.cpp:602
msgid "Distance between ticks on Y axis"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:604
+#: ../src/backend/filters/boundingBox.cpp:606
msgid "Spacing Z"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:608
+#: ../src/backend/filters/boundingBox.cpp:610
msgid "Distance between ticks on Z axis"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:611
+#: ../src/backend/filters/boundingBox.cpp:613
msgid "Tick marks"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:621
+#: ../src/backend/filters/boundingBox.cpp:620
msgid "Box Colour"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:625
+#: ../src/backend/filters/boundingBox.cpp:624
msgid "Colour of the bounding box"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:630
+#: ../src/backend/filters/boundingBox.cpp:629
msgid "Line thickness"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:634
+#: ../src/backend/filters/boundingBox.cpp:633
msgid "Thickness of the lines used to draw the box"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:642
-#: ../src/backend/filters/annotation.cpp:845
+#: ../src/backend/filters/boundingBox.cpp:641
+#: ../src/backend/filters/annotation.cpp:843
msgid "Font Size"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:645
+#: ../src/backend/filters/boundingBox.cpp:644
msgid "Relative size for text"
msgstr ""
@@ -3891,248 +3817,250 @@ msgstr ""
msgid "Ruler"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:526
+#: ../src/backend/filters/annotation.cpp:519
msgid "Enable"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:529
+#: ../src/backend/filters/annotation.cpp:522
msgid "Enable/disable annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:550
+#: ../src/backend/filters/annotation.cpp:543
msgid "Type or style of annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:565
-#: ../src/backend/filters/annotation.cpp:667
+#: ../src/backend/filters/annotation.cpp:559
+#: ../src/backend/filters/annotation.cpp:663
msgid "Text of annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:573
+#: ../src/backend/filters/annotation.cpp:567
msgid "Position of annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:577
-#: ../src/backend/filters/annotation.cpp:681
-#: ../src/backend/filters/annotation.cpp:739
-#: ../src/backend/filters/annotation.cpp:828
+#: ../src/backend/filters/annotation.cpp:571
+#: ../src/backend/filters/annotation.cpp:678
+#: ../src/backend/filters/annotation.cpp:737
+#: ../src/backend/filters/annotation.cpp:826
msgid "Up dir"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:581
-#: ../src/backend/filters/annotation.cpp:832
+#: ../src/backend/filters/annotation.cpp:575
+#: ../src/backend/filters/annotation.cpp:830
msgid "Vector for up direction of annotation text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:585
-#: ../src/backend/filters/annotation.cpp:688
-#: ../src/backend/filters/annotation.cpp:731
-#: ../src/backend/filters/annotation.cpp:836
+#: ../src/backend/filters/annotation.cpp:579
+#: ../src/backend/filters/annotation.cpp:685
+#: ../src/backend/filters/annotation.cpp:729
+#: ../src/backend/filters/annotation.cpp:834
msgid "Across dir"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:589
-#: ../src/backend/filters/annotation.cpp:840
+#: ../src/backend/filters/annotation.cpp:583
+#: ../src/backend/filters/annotation.cpp:838
msgid "Reading direction for annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:594
-#: ../src/backend/filters/annotation.cpp:673
-#: ../src/backend/filters/annotation.cpp:766
+#: ../src/backend/filters/annotation.cpp:588
+#: ../src/backend/filters/annotation.cpp:670
+#: ../src/backend/filters/annotation.cpp:764
msgid "Text size"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:598
-#: ../src/backend/filters/annotation.cpp:677
-#: ../src/backend/filters/annotation.cpp:848
+#: ../src/backend/filters/annotation.cpp:592
+#: ../src/backend/filters/annotation.cpp:674
+#: ../src/backend/filters/annotation.cpp:846
msgid "Relative size of annotation text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:610
-#: ../src/backend/filters/annotation.cpp:649
+#: ../src/backend/filters/annotation.cpp:604
+#: ../src/backend/filters/annotation.cpp:645
msgid "3D position for tail of arrow"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:618
-#: ../src/backend/filters/annotation.cpp:658
+#: ../src/backend/filters/annotation.cpp:612
+#: ../src/backend/filters/annotation.cpp:654
msgid "3D Position to which arrow points"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:624
-#: ../src/backend/filters/annotation.cpp:695
+#: ../src/backend/filters/annotation.cpp:615
+#: ../src/backend/filters/annotation.cpp:725
+msgid "Positioning"
+msgstr ""
+
+#: ../src/backend/filters/annotation.cpp:620
+#: ../src/backend/filters/annotation.cpp:692
msgid "Tip radius"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:628
+#: ../src/backend/filters/annotation.cpp:624
msgid "Size of the arrow head"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:632
+#: ../src/backend/filters/annotation.cpp:628
msgid "Line size"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:636
+#: ../src/backend/filters/annotation.cpp:632
msgid "Thickness of line used to draw arrow stem"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:705
+#: ../src/backend/filters/annotation.cpp:666
+msgid "Options"
+msgstr ""
+
+#: ../src/backend/filters/annotation.cpp:702
msgid "Position A"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:709
+#: ../src/backend/filters/annotation.cpp:706
msgid "Location of first non-central vertex"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:713
+#: ../src/backend/filters/annotation.cpp:710
msgid "Origin "
msgstr ""
-#: ../src/backend/filters/annotation.cpp:717
+#: ../src/backend/filters/annotation.cpp:714
msgid "Location of central vertex"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:721
+#: ../src/backend/filters/annotation.cpp:718
msgid "Position B"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:725
+#: ../src/backend/filters/annotation.cpp:722
msgid "Location of second non-central vertex"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:735
+#: ../src/backend/filters/annotation.cpp:733
msgid "Reading direction for angle text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:740
+#: ../src/backend/filters/annotation.cpp:738
msgid "Vector for up direction of angle text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:748
+#: ../src/backend/filters/annotation.cpp:746
msgid "Reflexive"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:751
+#: ../src/backend/filters/annotation.cpp:749
msgid "Measure interor (enabled) or exterior angle (disabled)"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:756
+#: ../src/backend/filters/annotation.cpp:754
msgid "Show Angle"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:760
+#: ../src/backend/filters/annotation.cpp:758
msgid "Display angle text (when enabled)"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:770
+#: ../src/backend/filters/annotation.cpp:768
msgid "Size of angle text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:788
+#: ../src/backend/filters/annotation.cpp:786
msgid "Digit format"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:792
+#: ../src/backend/filters/annotation.cpp:790
msgid ""
"Format of angle text; # for numeral position, '.' for separator, eg ##.## "
"gives 12.34"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:798
-#: ../src/backend/filters/annotation.cpp:886
+#: ../src/backend/filters/annotation.cpp:796
+#: ../src/backend/filters/annotation.cpp:881
msgid "Sphere size"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:802
-#: ../src/backend/filters/annotation.cpp:890
+#: ../src/backend/filters/annotation.cpp:800
+#: ../src/backend/filters/annotation.cpp:885
msgid "Marker sphere size for manipulating tool"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:816
+#: ../src/backend/filters/annotation.cpp:814
msgid "Ruler beginning 3D location"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:824
+#: ../src/backend/filters/annotation.cpp:822
msgid "Ruler finish 3D location"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:857
+#: ../src/backend/filters/annotation.cpp:852
msgid "Fixed ticks"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:860
+#: ../src/backend/filters/annotation.cpp:855
msgid ""
"Use fixed (enabled) number of text markers, or one every fixed distance "
"(disabled)"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:867
+#: ../src/backend/filters/annotation.cpp:862
msgid "Num Ticks"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:870
+#: ../src/backend/filters/annotation.cpp:865
msgid "Number of tick marks along ruler"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:877
+#: ../src/backend/filters/annotation.cpp:872
msgid "Tick Spacing"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:880
+#: ../src/backend/filters/annotation.cpp:875
msgid "Distance between tick marks along ruler"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:906
+#: ../src/backend/filters/annotation.cpp:899
msgid "Colour for ruler and ticks"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:460
+#: ../src/backend/filters/ionDownsample.cpp:445
msgid "By Count"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:463
+#: ../src/backend/filters/ionDownsample.cpp:448
msgid "Sample up to a fixed number of ions"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:469
+#: ../src/backend/filters/ionDownsample.cpp:454
msgid "Per Species"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:473
+#: ../src/backend/filters/ionDownsample.cpp:458
msgid "Use species specific (from ranging) sampling values"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:478
-msgid "Sampling rates"
+#: ../src/backend/filters/ionDownsample.cpp:487
+msgid "Sampling value for species"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:501
-msgid "Sampling value for species"
+#: ../src/backend/filters/ionDownsample.cpp:495
+#: ../src/backend/filters/ionDownsample.cpp:519
+msgid "Sampling rates"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:513
+#: ../src/backend/filters/ionDownsample.cpp:503
msgid "Output Count"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:516
+#: ../src/backend/filters/ionDownsample.cpp:506
msgid "Sample up to this value of points"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:521
+#: ../src/backend/filters/ionDownsample.cpp:511
msgid "Out Fraction"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:525
+#: ../src/backend/filters/ionDownsample.cpp:515
msgid "Sample this fraction of points"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:669
-msgid "Downsample Aborted"
-msgstr ""
-
-#: ../src/backend/filters/ionDownsample.cpp:671
-msgid "Insuffient memory for downsample"
-msgstr ""
-
#: ../src/backend/filters/ionInfo.cpp:30
msgid "Rectilinear"
msgstr ""
@@ -4213,24 +4141,24 @@ msgstr ""
msgid "Normalise count data"
msgstr ""
-#: ../src/backend/filters/ionInfo.cpp:425
+#: ../src/backend/filters/ionInfo.cpp:421
+msgid "Ion data"
+msgstr ""
+
+#: ../src/backend/filters/ionInfo.cpp:426
msgid "Volume"
msgstr ""
-#: ../src/backend/filters/ionInfo.cpp:428
+#: ../src/backend/filters/ionInfo.cpp:429
msgid "Compute volume for point data"
msgstr ""
-#: ../src/backend/filters/ionInfo.cpp:443
+#: ../src/backend/filters/ionInfo.cpp:444
msgid "Select volume counting technique"
msgstr ""
-#: ../src/backend/filters/ionInfo.cpp:539
-msgid "Insufficient memory for operation"
-msgstr ""
-
-#: ../src/backend/filters/ionInfo.cpp:543
-msgid "Bug? Problem with qhull library, cannot run convex hull."
+#: ../src/backend/filters/ionInfo.cpp:457
+msgid "Volume data"
msgstr ""
#: ../src/backend/filters/dataLoad.cpp:56
@@ -4257,336 +4185,340 @@ msgstr ""
msgid "ATO Data"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:242
+#: ../src/backend/filters/dataLoad.cpp:238
msgid " does not exist"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:280
-#: ../src/backend/filters/dataLoad.cpp:293
-#: ../src/backend/filters/dataLoad.cpp:336
-#: ../src/backend/filters/dataLoad.cpp:347
-#: ../src/backend/filters/dataLoad.cpp:408
+#: ../src/backend/filters/dataLoad.cpp:276
+#: ../src/backend/filters/dataLoad.cpp:289
+#: ../src/backend/filters/dataLoad.cpp:332
+#: ../src/backend/filters/dataLoad.cpp:343
+#: ../src/backend/filters/dataLoad.cpp:404
msgid "Error loading file: "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:310
+#: ../src/backend/filters/dataLoad.cpp:306
msgid "Sampling is active, loaded "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:311
+#: ../src/backend/filters/dataLoad.cpp:307
msgid " available."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:319
+#: ../src/backend/filters/dataLoad.cpp:315
msgid "Loaded entire dataset, "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:319
-#: ../src/backend/filters/dataLoad.cpp:418
+#: ../src/backend/filters/dataLoad.cpp:315
+#: ../src/backend/filters/dataLoad.cpp:414
msgid " points."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:362
+#: ../src/backend/filters/dataLoad.cpp:358
msgid ""
"Data file contained incorrect number of columns -- should be 3 or 4, was "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:417
+#: ../src/backend/filters/dataLoad.cpp:413
msgid "Loaded dataset, "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:449
+#: ../src/backend/filters/dataLoad.cpp:445
msgid ""
"Warning:One or more bounds of the loaded data approaches the limits of "
"numerical stability for the internal data type(magnitude too large). "
"Consider rescaling data before loading"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:481
-#: ../src/backend/filters/rangeFile.cpp:567
+#: ../src/backend/filters/dataLoad.cpp:469
+#: ../src/backend/filters/dataLoad.cpp:490
+#: ../src/backend/filters/rangeFile.cpp:569
+#: ../src/backend/filters/rangeFile.cpp:589
msgid "File"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:482
+#: ../src/backend/filters/dataLoad.cpp:470
msgid "File from which to load data"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:493
+#: ../src/backend/filters/dataLoad.cpp:473
+msgid ""
+"Readable files (*.xml, *.pos, *.txt,*.csv, *.ato)|*.xml;*.pos;*.txt;*.csv;*."
+"ato|All Files|*"
+msgstr ""
+
+#: ../src/backend/filters/dataLoad.cpp:483
msgid "File type"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:495
+#: ../src/backend/filters/dataLoad.cpp:485
msgid "Type of file to be loaded"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:509
+#: ../src/backend/filters/dataLoad.cpp:500
msgid "Entries per point"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:510
+#: ../src/backend/filters/dataLoad.cpp:501
msgid "Number of decimal values in file per 3D point (normally 4)"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:529
+#: ../src/backend/filters/dataLoad.cpp:520
msgid "File \"Endianness\""
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:530
+#: ../src/backend/filters/dataLoad.cpp:521
msgid "On-disk data storage format. If file won't load, just try each"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:555
+#: ../src/backend/filters/dataLoad.cpp:546
msgid "Relative offset of each entry in file for point's X position"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:563
+#: ../src/backend/filters/dataLoad.cpp:554
msgid "Relative offset of each entry in file for point's Y position"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:571
+#: ../src/backend/filters/dataLoad.cpp:562
msgid "Relative offset of each entry in file for point's Z position"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:579
+#: ../src/backend/filters/dataLoad.cpp:570
msgid ""
"Relative offset of each entry in file to use for scalar value of 3D point"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:582
+#: ../src/backend/filters/dataLoad.cpp:573
msgid "Value Label"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:586
+#: ../src/backend/filters/dataLoad.cpp:577
msgid "Name for the scalar value associated with each point"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:589
+#: ../src/backend/filters/dataLoad.cpp:580
msgid "Format params."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:595
+#: ../src/backend/filters/dataLoad.cpp:586
msgid "Enabled"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:599
+#: ../src/backend/filters/dataLoad.cpp:590
msgid "Load this file?"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:610
+#: ../src/backend/filters/dataLoad.cpp:601
msgid "Sample data"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:613
+#: ../src/backend/filters/dataLoad.cpp:604
msgid ""
"Perform random selection on file contents, instead of loading entire file"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:620
+#: ../src/backend/filters/dataLoad.cpp:611
msgid "Load Limit (MB)"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:623
+#: ../src/backend/filters/dataLoad.cpp:614
msgid "Limit for size of data to load"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:630
+#: ../src/backend/filters/dataLoad.cpp:621
msgid "Monitor"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:634
+#: ../src/backend/filters/dataLoad.cpp:625
msgid ""
"Watch file timestamp to track changes to file contents from other programs"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:636
+#: ../src/backend/filters/dataLoad.cpp:629
msgid "Load params."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:646
+#: ../src/backend/filters/dataLoad.cpp:636
msgid "Default colour "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:649
+#: ../src/backend/filters/dataLoad.cpp:639
msgid "Default colour for points, if not overridden by other filters"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:654
+#: ../src/backend/filters/dataLoad.cpp:644
msgid "Draw Size"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:657
+#: ../src/backend/filters/dataLoad.cpp:647
msgid "Default size for points, if not overridden by other filters"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:125
+#: ../src/backend/filters/spectrumPlot.cpp:122
msgid "Extrema"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:174
+#: ../src/backend/filters/spectrumPlot.cpp:171
msgid "count"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:259
+#: ../src/backend/filters/spectrumPlot.cpp:256
msgid "Mixed data"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:400
+#: ../src/backend/filters/spectrumPlot.cpp:390
msgid "Step size for spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:409
+#: ../src/backend/filters/spectrumPlot.cpp:395
msgid "Auto Min/max"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:413
+#: ../src/backend/filters/spectrumPlot.cpp:399
msgid "Automatically compute spectrum upper and lower bound"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:418
+#: ../src/backend/filters/spectrumPlot.cpp:404
msgid "Min"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:421
+#: ../src/backend/filters/spectrumPlot.cpp:407
msgid "Starting position for spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:426
+#: ../src/backend/filters/spectrumPlot.cpp:412
msgid "Max"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:429
+#: ../src/backend/filters/spectrumPlot.cpp:415
msgid "Ending position for spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:437
+#: ../src/backend/filters/spectrumPlot.cpp:423
msgid "Logarithmic"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:440
+#: ../src/backend/filters/spectrumPlot.cpp:426
msgid "Convert the plot to logarithmic mode"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:462
+#: ../src/backend/filters/spectrumPlot.cpp:448
msgid "Visual style of plot"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:475
+#: ../src/backend/filters/spectrumPlot.cpp:455
msgid "Colour of plotted spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:709
-msgid "Insufficient memory for spectrum filter."
-msgstr ""
-
-#: ../src/backend/filters/spectrumPlot.cpp:711
-msgid "Bad bincount value in spectrum filter."
-msgstr ""
-
-#: ../src/backend/filters/rangeFile.cpp:149
+#: ../src/backend/filters/rangeFile.cpp:151
msgid "Pre-Allocate"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:280 ../src/backend/filter.cpp:46
+#: ../src/backend/filters/rangeFile.cpp:282 ../src/backend/filter.cpp:48
msgid "Range"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:569
+#: ../src/backend/filters/rangeFile.cpp:572
msgid "File to use for range data"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:581
+#: ../src/backend/filters/rangeFile.cpp:582
msgid "Drop unranged"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:583
+#: ../src/backend/filters/rangeFile.cpp:584
msgid "Remove unranged points when generating output"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:603
+#: ../src/backend/filters/rangeFile.cpp:594
+msgid "Legend"
+msgstr ""
+
+#: ../src/backend/filters/rangeFile.cpp:596
+msgid "Display colour legend for enabled ions"
+msgstr ""
+
+#: ../src/backend/filters/rangeFile.cpp:600
+msgid "View"
+msgstr ""
+
+#: ../src/backend/filters/rangeFile.cpp:616
msgid "All Ions"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:604
+#: ../src/backend/filters/rangeFile.cpp:617
msgid "Enable/disable all ions at once"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:612
+#: ../src/backend/filters/rangeFile.cpp:625
msgid "Species"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:619
+#: ../src/backend/filters/rangeFile.cpp:632
msgid "IonID "
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:620
+#: ../src/backend/filters/rangeFile.cpp:633
msgid "Enable/disable specified ion"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:633
+#: ../src/backend/filters/rangeFile.cpp:643
msgid "Active Ion "
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:635
+#: ../src/backend/filters/rangeFile.cpp:645
msgid "If true, ion is used in output"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:649
+#: ../src/backend/filters/rangeFile.cpp:655
msgid "Colour "
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:652
+#: ../src/backend/filters/rangeFile.cpp:659
msgid "Colour used to represent ion"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:676
+#: ../src/backend/filters/rangeFile.cpp:682
msgid "All Ranges"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:677
+#: ../src/backend/filters/rangeFile.cpp:683
msgid "Enable/disable all ranges"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:695
+#: ../src/backend/filters/rangeFile.cpp:698
msgid "Active Rng "
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:698
+#: ../src/backend/filters/rangeFile.cpp:701
msgid ""
"Enable/disable specified range (ion must also be enabled to activiate range)"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:702
+#: ../src/backend/filters/rangeFile.cpp:705
msgid "Ion "
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:705
+#: ../src/backend/filters/rangeFile.cpp:708
msgid "Name of ion associate to this range"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:714
+#: ../src/backend/filters/rangeFile.cpp:717
msgid "Start rng "
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:717
+#: ../src/backend/filters/rangeFile.cpp:720
msgid "Start value for range"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:722
+#: ../src/backend/filters/rangeFile.cpp:725
msgid "End rng "
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:725
+#: ../src/backend/filters/rangeFile.cpp:728
msgid "Stopping value for range`"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:1029
-msgid "Ranging aborted by user"
-msgstr ""
-
-#: ../src/backend/filters/rangeFile.cpp:1031
-msgid "Insufficient memory for range"
-msgstr ""
-
#: ../src/backend/state.cpp:137
msgid ""
"This file is a \"state\" file for the 3Depict program, and stores "
@@ -4598,136 +4530,130 @@ msgstr ""
msgid "Failed to allocate parser"
msgstr ""
-#: ../src/backend/state.cpp:326
+#: ../src/backend/state.cpp:325
msgid ""
"Unable to retrieve root node in input state file... Is this really a non-"
"empty XML file?"
msgstr ""
-#: ../src/backend/state.cpp:333
+#: ../src/backend/state.cpp:332
msgid "Base state node missing. Is this really a state XML file??"
msgstr ""
-#: ../src/backend/state.cpp:362
+#: ../src/backend/state.cpp:361
msgid "State was created by a newer version of this program.. "
msgstr ""
-#: ../src/backend/state.cpp:363
+#: ../src/backend/state.cpp:362
msgid "file reading will continue, but may fail."
msgstr ""
-#: ../src/backend/state.cpp:368
+#: ../src/backend/state.cpp:367
msgid ""
"Warning, unparseable version number in state file. File reading will "
"continue, but may fail"
msgstr ""
-#: ../src/backend/state.cpp:375
+#: ../src/backend/state.cpp:374
msgid "Unable to find the \"writer\" node"
msgstr ""
-#: ../src/backend/state.cpp:385
+#: ../src/backend/state.cpp:384
msgid "Unable to find the \"backcolour\" node."
msgstr ""
-#: ../src/backend/state.cpp:392
+#: ../src/backend/state.cpp:391
msgid "\"backcolour\" node missing \"r\" value."
msgstr ""
-#: ../src/backend/state.cpp:397
+#: ../src/backend/state.cpp:396
msgid "Unable to interpret \"backColour\" node's \"r\" value."
msgstr ""
-#: ../src/backend/state.cpp:405
+#: ../src/backend/state.cpp:404
msgid "\"backcolour\" node missing \"g\" value."
msgstr ""
-#: ../src/backend/state.cpp:411
+#: ../src/backend/state.cpp:410
msgid "Unable to interpret \"backColour\" node's \"g\" value."
msgstr ""
-#: ../src/backend/state.cpp:419
+#: ../src/backend/state.cpp:418
msgid "\"backcolour\" node missing \"b\" value."
msgstr ""
-#: ../src/backend/state.cpp:425
+#: ../src/backend/state.cpp:424
msgid "Unable to interpret \"backColour\" node's \"b\" value."
msgstr ""
-#: ../src/backend/state.cpp:432
+#: ../src/backend/state.cpp:431
msgid "\"backcolour\"s rgb values must be in range [0,1]"
msgstr ""
-#: ../src/backend/state.cpp:460
+#: ../src/backend/state.cpp:459
msgid "Unable to find or interpret \"showaxis\" node"
msgstr ""
-#: ../src/backend/state.cpp:504
+#: ../src/backend/state.cpp:503
msgid "Unable to locate \"filtertree\" node."
msgstr ""
-#: ../src/backend/state.cpp:520
+#: ../src/backend/state.cpp:519
msgid "Cameras section missing \"active\" node."
msgstr ""
-#: ../src/backend/state.cpp:528
+#: ../src/backend/state.cpp:527
msgid "Unable to find property \"value\" for \"cameras->active\" node."
msgstr ""
-#: ../src/backend/state.cpp:534
+#: ../src/backend/state.cpp:533
msgid "Unable to interpret property \"value\" for \"cameras->active\" node."
msgstr ""
-#: ../src/backend/state.cpp:553
+#: ../src/backend/state.cpp:552
msgid "Failed to interpret camera state for camera : "
msgstr ""
-#: ../src/backend/state.cpp:561
+#: ../src/backend/state.cpp:560
msgid "Unable to interpret the camera type for camera : "
msgstr ""
-#: ../src/backend/state.cpp:597
+#: ../src/backend/state.cpp:596
msgid "Unable to locate stash name for stash "
msgstr ""
-#: ../src/backend/state.cpp:604
+#: ../src/backend/state.cpp:603
msgid "Empty stash name for stash "
msgstr ""
-#: ../src/backend/state.cpp:613
+#: ../src/backend/state.cpp:612
msgid "No filter tree for stash:"
msgstr ""
-#: ../src/backend/state.cpp:619
+#: ../src/backend/state.cpp:618
msgid "For stash "
msgstr ""
-#: ../src/backend/state.cpp:651
+#: ../src/backend/state.cpp:650
msgid "Unrecognised effect :"
msgstr ""
-#: ../src/backend/state.cpp:661
+#: ../src/backend/state.cpp:660
msgid "Duplicate effect found"
msgstr ""
-#: ../src/backend/state.cpp:661
+#: ../src/backend/state.cpp:660
msgid " cannot use."
msgstr ""
-#: ../src/backend/state.cpp:671
+#: ../src/backend/state.cpp:670
msgid "Error reading effect : "
msgstr ""
-#: ../src/backend/state.cpp:789
+#: ../src/backend/state.cpp:866
msgid "-merge"
msgstr ""
-#: ../src/backend/state.cpp:794
-msgid ""
-" Unable to merge stashes correctly. This is improbable, so please report "
-"this."
-msgstr ""
-
#: ../src/backend/filtertreeAnalyse.cpp:199
msgid ""
"Parent filter has no output, but filter requires input -- there is no point "
@@ -4780,174 +4706,211 @@ msgstr ""
msgid "Filter missing needed parent"
msgstr ""
-#: ../src/backend/filtertreeAnalyse.cpp:554
+#: ../src/backend/filtertreeAnalyse.cpp:555
msgid "Composition results possibly altered"
msgstr ""
-#: ../src/backend/filtertreeAnalyse.cpp:555
+#: ../src/backend/filtertreeAnalyse.cpp:556
msgid ""
"Filters and settings selected that could bias reported composition. Check to "
"see if species biasing may occcur in the filter tree - this warning is "
"provisional only."
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:40
+#: ../src/backend/APT/APTFileIO.cpp:43 ../src/backend/APT/APTFileIO.cpp:78
+#: ../src/backend/APT/APTFileIO.cpp:102
+msgid "Error opening file"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:44
+msgid "Only found header, no data"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:45
+msgid "Unable to reopen file after first scan"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:46
+msgid "Error whilst reading file contents"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:47 ../src/backend/APT/APTFileIO.cpp:48
+msgid "Unexpected file format"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:49
+msgid "Insufficient memory to continue"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:53
msgid "Memory allocation failure on POS load"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:41
+#: ../src/backend/APT/APTFileIO.cpp:54
msgid "Error opening pos file"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:42
+#: ../src/backend/APT/APTFileIO.cpp:55
msgid "Pos file empty"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:43
+#: ../src/backend/APT/APTFileIO.cpp:56
msgid "Pos file size appears to have non-integer number of entries"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:44
+#: ../src/backend/APT/APTFileIO.cpp:57
msgid "Error reading from pos file (after open)"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:45
+#: ../src/backend/APT/APTFileIO.cpp:58
msgid "Error - Found NaN in pos file"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:46
+#: ../src/backend/APT/APTFileIO.cpp:59
+msgid "Error - Found Inf in pos file"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:60
msgid "Pos load aborted by interrupt."
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:66
+#: ../src/backend/APT/APTFileIO.cpp:79
msgid "No numerical data found"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:67
+#: ../src/backend/APT/APTFileIO.cpp:80
msgid "Error re-opening file, after first scan"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:68
+#: ../src/backend/APT/APTFileIO.cpp:81
msgid "Unable to read file contents after open"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:70
+#: ../src/backend/APT/APTFileIO.cpp:82
+msgid "Error interpreting field in file"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:83
msgid "Incorrect number of fields in file"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:71 ../src/backend/APT/APTFileIO.cpp:93
+#: ../src/backend/APT/APTFileIO.cpp:84 ../src/backend/APT/APTFileIO.cpp:106
msgid "Unable to allocate memory to store data"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:90
+#: ../src/backend/APT/APTFileIO.cpp:103
msgid "File is empty"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:91
+#: ../src/backend/APT/APTFileIO.cpp:104
msgid "Filesize does not match expected format"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:92
+#: ../src/backend/APT/APTFileIO.cpp:105
msgid "File version number not <4, as expected"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:94
+#: ../src/backend/APT/APTFileIO.cpp:107
msgid "Unable to detect endian-ness in file"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:47
+#: ../src/backend/APT/APTRanges.cpp:48
msgid "Error opening file, check name and permissions."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:48
+#: ../src/backend/APT/APTRanges.cpp:49
msgid ""
"Error interpreting range file header, expecting ion count and range count, "
"respectively."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:49
+#: ../src/backend/APT/APTRanges.cpp:50
msgid ""
"Range file appears to be empty, check file is a proper range file and is not "
"empty."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:50
+#: ../src/backend/APT/APTRanges.cpp:51
msgid "Error reading the long name for ion."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:51
+#: ../src/backend/APT/APTRanges.cpp:52
msgid "Error reading the short name for ion."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:52
+#: ../src/backend/APT/APTRanges.cpp:53
msgid ""
"Error reading colour data in the file, expecting 3 decimal values, space "
"separated."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:53
+#: ../src/backend/APT/APTRanges.cpp:54
msgid ""
"Tried skipping to table separator line (line with dashes), but did not find "
"it."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:54
+#: ../src/backend/APT/APTRanges.cpp:55
msgid ""
"Number of ions in the table header did not match the number specified at the "
"start of the file"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:55
+#: ../src/backend/APT/APTRanges.cpp:56
msgid ""
"Unexpected failure whilst trying to skip over range lead-in data (bit before "
"range start value)"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:56
+#: ../src/backend/APT/APTRanges.cpp:57
msgid ""
"Range table had an incorrect number of entries, should be 2 or 3 + number of "
"ranges"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:57
+#: ../src/backend/APT/APTRanges.cpp:58
msgid "Unable to read range start and end values"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:58
+#: ../src/backend/APT/APTRanges.cpp:59
msgid "Unable to read range table entry"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:59
+#: ../src/backend/APT/APTRanges.cpp:60
msgid ""
"Error reading file, unexpected format, are you sure it is a proper range "
"file?"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:60
+#: ../src/backend/APT/APTRanges.cpp:61
msgid ""
"Too many ranges appeared to have range entries with no usable data (eg, all "
"blank)"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:61
+#: ../src/backend/APT/APTRanges.cpp:62
msgid ""
"Range file appears to contain malformed data, check things like start and "
"ends of m/c are not equal or flipped."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:62
+#: ../src/backend/APT/APTRanges.cpp:63
msgid "Range file appears to be inconsistent (eg, overlapping ranges)"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:63
+#: ../src/backend/APT/APTRanges.cpp:64
msgid "No ion name mapping found for multiple ion."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:64
+#: ../src/backend/APT/APTRanges.cpp:65
msgid "Polyatomic extension range matches multiple masses in first section"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:1387
+#: ../src/backend/APT/APTRanges.cpp:66
+msgid "Range file is exceedingly large. Refusing to open"
+msgstr ""
+
+#: ../src/backend/APT/APTRanges.cpp:1403
msgid ""
"Range headings do not match order of the ions listed in the name "
"specifications. The name specification ordering will be used when reading "
@@ -4956,15 +4919,19 @@ msgid ""
"Check range-species associations actually match what you expect."
msgstr ""
-#: ../src/backend/filter.cpp:45
-msgid "Draw"
+#: ../src/backend/filter.cpp:46
+msgid "2D Plot"
msgstr ""
#: ../src/backend/filter.cpp:47
+msgid "Draw"
+msgstr ""
+
+#: ../src/backend/filter.cpp:49
msgid "Voxel"
msgstr ""
-#: ../src/wx/wxcomponents.h:98
+#: ../src/wx/wxcomponents.h:82
msgid "treeCtrl"
msgstr ""
@@ -4972,7 +4939,7 @@ msgstr ""
msgid "Ion. Transform"
msgstr ""
-#: ../src/backend/filters/ionColour.h:61
+#: ../src/backend/filters/ionColour.h:63
msgid "Spectral Colour"
msgstr ""
@@ -4988,7 +4955,7 @@ msgstr ""
msgid "Ion info"
msgstr ""
-#: ../src/backend/filters/dataLoad.h:136
+#: ../src/backend/filters/dataLoad.h:135
msgid "Pos Data"
msgstr ""
@@ -4996,7 +4963,7 @@ msgstr ""
msgid "Ext. Program"
msgstr ""
-#: ../src/backend/filters/rangeFile.h:89
+#: ../src/backend/filters/rangeFile.h:93
msgid "Ranging"
msgstr ""
diff --git a/translations/3Depict_de_DE.mo b/translations/3Depict_de_DE.mo
index cf1c383..36291f1 100644
Binary files a/translations/3Depict_de_DE.mo and b/translations/3Depict_de_DE.mo differ
diff --git a/translations/3Depict_de_DE.po b/translations/3Depict_de_DE.po
index 888bc71..8cee9e4 100644
--- a/translations/3Depict_de_DE.po
+++ b/translations/3Depict_de_DE.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 3Depict\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-04-12 18:12+0200\n"
+"POT-Creation-Date: 2014-08-23 15:32+0100\n"
"PO-Revision-Date: 2012-07-09 08:21+0000\n"
"Last-Translator: epix1234 <erich_s at gmx.de>\n"
"Language-Team: German (Germany) (http://www.transifex.com/projects/p/3depict/"
@@ -21,25 +21,25 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: ../src/gl/cameras.cpp:598 ../src/gl/cameras.cpp:600
+#: ../src/gl/cameras.cpp:596
msgid "Lock"
msgstr "Sperren"
-#: ../src/gl/cameras.cpp:607 ../src/backend/filters/ionClip.cpp:526
-#: ../src/backend/filters/ionClip.cpp:548
-#: ../src/backend/filters/ionClip.cpp:570
-#: ../src/backend/filters/ionClip.cpp:610
-#: ../src/backend/filters/compositionProfile.cpp:1015
-#: ../src/backend/filters/compositionProfile.cpp:1056
-#: ../src/backend/filters/spatialAnalysis.cpp:599
-#: ../src/backend/filters/transform.cpp:1264
-#: ../src/backend/filters/transform.cpp:1291
-#: ../src/backend/filters/transform.cpp:1317
-#: ../src/backend/filters/annotation.cpp:569
+#: ../src/gl/cameras.cpp:603 ../src/backend/filters/ionClip.cpp:519
+#: ../src/backend/filters/ionClip.cpp:541
+#: ../src/backend/filters/ionClip.cpp:563
+#: ../src/backend/filters/ionClip.cpp:600
+#: ../src/backend/filters/compositionProfile.cpp:964
+#: ../src/backend/filters/compositionProfile.cpp:1002
+#: ../src/backend/filters/spatialAnalysis.cpp:774
+#: ../src/backend/filters/transform.cpp:1216
+#: ../src/backend/filters/transform.cpp:1243
+#: ../src/backend/filters/transform.cpp:1269
+#: ../src/backend/filters/annotation.cpp:563
msgid "Origin"
msgstr "Ursprung"
-#: ../src/gl/cameras.cpp:612 ../src/backend/filters/spatialAnalysis.cpp:518
+#: ../src/gl/cameras.cpp:611 ../src/backend/filters/spatialAnalysis.cpp:697
msgid "Target"
msgstr "Ziel"
@@ -47,12 +47,12 @@ msgstr "Ziel"
msgid "Up Dir."
msgstr "Up Dir."
-#: ../src/gl/cameras.cpp:625 ../src/gl/cameras.cpp:729
+#: ../src/gl/cameras.cpp:625 ../src/gl/cameras.cpp:728
msgid "Perspective"
msgstr "Perspektivisch"
-#: ../src/gl/cameras.cpp:627 ../src/gl/cameras.cpp:731
-#: ../src/gui/mainFrame.cpp:5396
+#: ../src/gl/cameras.cpp:627 ../src/gl/cameras.cpp:730
+#: ../src/gui/mainFrame.cpp:5134
msgid "Orthogonal"
msgstr "Orthogonal"
@@ -60,169 +60,137 @@ msgstr "Orthogonal"
msgid "Projection"
msgstr "Projektion"
-#: ../src/gl/cameras.cpp:639
+#: ../src/gl/cameras.cpp:640
msgid "Field of View (deg)"
msgstr "Bildausschnitt"
-#: ../src/gl/cameras.cpp:645
+#: ../src/gl/cameras.cpp:646
msgid "View size"
msgstr "Anzeigegröße"
-#: ../src/wx/wxcomponents.cpp:441 ../src/gui/dialogs/ExportRngDialog.cpp:88
-#: ../src/gui/dialogs/prefDialog.cpp:110
-msgid "Param"
-msgstr "Param."
-
-#: ../src/wx/wxcomponents.cpp:442 ../src/gui/dialogs/ExportRngDialog.cpp:89
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:109
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:356
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1186
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1211
-#: ../src/gui/dialogs/prefDialog.cpp:111 ../src/gui/mainFrame.cpp:5849
-#: ../src/gui/mainFrame.cpp:5854 ../src/backend/filters/dataLoad.cpp:575
-msgid "Value"
-msgstr "Wert"
-
-#: ../src/wx/wxcomponents.cpp:655
+#: ../src/wx/wxcomponents.cpp:187
msgid "Save Data..."
msgstr "Datei speichern..."
-#: ../src/wx/wxcomponents.cpp:656
+#: ../src/wx/wxcomponents.cpp:188
msgid "Text File (*.txt)|*.txt|All Files (*)|*"
msgstr "Text Datei (*.txt)|*.txt|Alle Dateien (*)|*"
-#: ../src/wx/wxcomponents.cpp:668
+#: ../src/wx/wxcomponents.cpp:200
msgid "Error saving file. Check output dir is writable."
msgstr ""
"Fehler beim Schreiben der Datei. Stellen Sie sicher, dass das "
"Zielverzeichnis nicht schreibgeschüzt ist."
-#: ../src/wx/wxcomponents.cpp:668 ../src/gui/dialogs/ExportRngDialog.cpp:170
-#: ../src/gui/mainFrame.cpp:1422 ../src/gui/mainFrame.cpp:1548
-#: ../src/gui/mainFrame.cpp:1583 ../src/gui/mainFrame.cpp:1659
-#: ../src/gui/mainFrame.cpp:2213 ../src/gui/mainFrame.cpp:2279
-#: ../src/gui/mainFrame.cpp:2371 ../src/gui/mainFrame.cpp:2486
+#: ../src/wx/wxcomponents.cpp:200 ../src/gui/dialogs/ExportRngDialog.cpp:170
+#: ../src/gui/mainFrame.cpp:1446 ../src/gui/mainFrame.cpp:1572
+#: ../src/gui/mainFrame.cpp:1621 ../src/gui/mainFrame.cpp:1697
+#: ../src/gui/mainFrame.cpp:2253 ../src/gui/mainFrame.cpp:2319
+#: ../src/gui/mainFrame.cpp:2411 ../src/gui/mainFrame.cpp:2526
msgid "Save error"
msgstr "Fehler speichern"
-#: ../src/common/basics.cpp:62 ../src/backend/APT/APTFileIO.cpp:65
-#: ../src/backend/APT/APTFileIO.cpp:89
-msgid "Error opening file"
-msgstr "Fehler beim Öffnen der Datei"
-
-#: ../src/common/basics.cpp:63
-msgid "Error whilst reading file contents"
-msgstr "Fehler beim Lesen des Dateiinhaltes"
-
-#: ../src/common/basics.cpp:64 ../src/backend/APT/APTFileIO.cpp:69
-msgid "Error interpreting field in file"
-msgstr "Fehler beim Interpretieren eine Feldes in der Datei"
-
-#: ../src/common/basics.cpp:65
-msgid "Inconsistent number of columns found"
-msgstr "Inkonsistente Anzahl an Spalten gefunden"
-
-#: ../src/common/basics.cpp:197
+#: ../src/common/basics.cpp:183
msgid "in the future?"
msgstr "in Zukunft?"
-#: ../src/common/basics.cpp:248
+#: ../src/common/basics.cpp:234
msgid "a decade ago"
msgstr "vor zehn Jahren"
-#: ../src/common/basics.cpp:249
+#: ../src/common/basics.cpp:235
msgid "a year ago"
msgstr "vor einem Jahr"
-#: ../src/common/basics.cpp:250
+#: ../src/common/basics.cpp:236
msgid "a month ago"
msgstr "vor einem Monat"
-#: ../src/common/basics.cpp:251
+#: ../src/common/basics.cpp:237
msgid "a week ago"
msgstr "vor einer Woche"
-#: ../src/common/basics.cpp:252
+#: ../src/common/basics.cpp:238
msgid "a day ago"
msgstr "gestern"
-#: ../src/common/basics.cpp:253
+#: ../src/common/basics.cpp:239
msgid "an hour ago"
msgstr "vor einer Stunde"
-#: ../src/common/basics.cpp:254
+#: ../src/common/basics.cpp:240
msgid "45 minutes ago"
msgstr "vor 45 Minuten"
-#: ../src/common/basics.cpp:255
+#: ../src/common/basics.cpp:241
msgid "30 minutes ago"
msgstr "vor 30 Minuten"
-#: ../src/common/basics.cpp:256
+#: ../src/common/basics.cpp:242
msgid "20 minutes ago"
msgstr "vor 20 Minuten"
-#: ../src/common/basics.cpp:257
+#: ../src/common/basics.cpp:243
msgid "15 minutes ago"
msgstr "vor 15 Minuten"
-#: ../src/common/basics.cpp:258
+#: ../src/common/basics.cpp:244
msgid "10 minutes ago"
msgstr "vor 10 Minuten"
-#: ../src/common/basics.cpp:259
+#: ../src/common/basics.cpp:245
msgid "5 minutes ago"
msgstr "vor 5 Minuten"
-#: ../src/common/basics.cpp:260
+#: ../src/common/basics.cpp:246
msgid "a minute ago"
msgstr "vor einer Minute"
-#: ../src/common/basics.cpp:261
+#: ../src/common/basics.cpp:247
msgid "30 seconds ago"
msgstr "vor 30 Sekunden"
-#: ../src/common/basics.cpp:262
+#: ../src/common/basics.cpp:248
msgid "10 seconds ago"
msgstr "vor 10 Sekunden"
-#: ../src/common/basics.cpp:263
+#: ../src/common/basics.cpp:249
msgid "a second ago"
msgstr "vor einer Sekunde"
-#: ../src/common/basics.cpp:268
+#: ../src/common/basics.cpp:254
msgid "a few decades ago"
msgstr "vor einigen Dekaden"
-#: ../src/common/basics.cpp:269
+#: ../src/common/basics.cpp:255
msgid "a few years ago"
msgstr "vor einigen Jahren"
-#: ../src/common/basics.cpp:270
+#: ../src/common/basics.cpp:256
msgid "a few months ago"
msgstr "vor einigen Monaten"
-#: ../src/common/basics.cpp:271
+#: ../src/common/basics.cpp:257
msgid "a few weeks ago"
msgstr "vor einigen Wochen"
-#: ../src/common/basics.cpp:272
+#: ../src/common/basics.cpp:258
msgid "a few days ago"
msgstr "vor einigen Tagen"
-#: ../src/common/basics.cpp:273
+#: ../src/common/basics.cpp:259
msgid "a few hours ago"
msgstr "vor einigen Stunden"
-#: ../src/common/basics.cpp:280
+#: ../src/common/basics.cpp:266
msgid "a few minutes ago"
msgstr "vor einigen Minuten"
-#: ../src/common/basics.cpp:283
+#: ../src/common/basics.cpp:269
msgid "a few seconds ago"
msgstr "vor einigen Sekunden"
-#: ../src/common/basics.cpp:310
+#: ../src/common/basics.cpp:296
msgid "moments ago"
msgstr "kürzlich"
@@ -258,42 +226,45 @@ msgstr "Blau"
msgid "Pseudo-Random"
msgstr "Pseudo-Random"
-#: ../src/gui/glPane.cpp:670
+#: ../src/common/constants.cpp:22
+msgid ""
+"Range Files (*.rng; *.env; *.rrng)|*.rng;*.env;*.rrng;*.RRNG;*.RNG;*.ENV|RNG "
+"File (*.rng)|*.rng;*.RNG|Environment File (*.env)|*.env;*.ENV|RRNG Files (*."
+"rrng)|*.rrng;*.RRNG|All Files (*)|*"
+msgstr ""
+
+#: ../src/gui/glPane.cpp:637
msgid "Use shift/ctrl-space or double tap to alter reset axis"
msgstr ""
"Verwenden Sie Shift / ⌘-Leertaste oder doppeltippen, um Achsen "
"zurückzusetzen oder zu verändern"
-#: ../src/gui/glPane.cpp:934
+#: ../src/gui/glPane.cpp:910
msgid "Image progress"
msgstr "Bild Fortschritt"
-#: ../src/gui/glPane.cpp:935
+#: ../src/gui/glPane.cpp:911
msgid "Rendering tiles..."
msgstr "Rendering tiles..."
-#: ../src/gui/glPane.cpp:969
-msgid "Tile "
-msgstr "Tile "
-
-#: ../src/gui/glPane.cpp:969 ../src/gui/glPane.cpp:1080
-#: ../src/gui/mainFrame.cpp:4279 ../src/gui/mainFrame.cpp:4283
-#: ../src/gui/mainFrame.cpp:4296 ../src/backend/filters/dataLoad.cpp:311
-msgid " of "
-msgstr " von "
-
-#: ../src/gui/glPane.cpp:1041
+#: ../src/gui/glPane.cpp:1097
msgid "Animation progress"
msgstr "Animation-Fortschritt"
-#: ../src/gui/glPane.cpp:1042
+#: ../src/gui/glPane.cpp:1098
msgid "Rendering sequence..."
msgstr "Renderreihenfolge..."
-#: ../src/gui/glPane.cpp:1080
+#: ../src/gui/glPane.cpp:1136
msgid "Saving Image "
msgstr "Speichere Bild "
+#: ../src/gui/glPane.cpp:1136 ../src/gui/mainFrame.cpp:4309
+#: ../src/gui/mainFrame.cpp:4313 ../src/gui/mainFrame.cpp:4326
+#: ../src/backend/filters/dataLoad.cpp:307
+msgid " of "
+msgstr " von "
+
#: ../src/gui/dialogs/ExportRngDialog.cpp:40
msgid "Range Sources"
msgstr "Range Sources"
@@ -307,15 +278,29 @@ msgid "Source Filter"
msgstr "Source Filter"
#: ../src/gui/dialogs/ExportRngDialog.cpp:54
+#: ../src/backend/filters/rangeFile.cpp:665
msgid "Ions"
msgstr "Ionen"
#: ../src/gui/dialogs/ExportRngDialog.cpp:55
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1606
-#: ../src/backend/filters/rangeFile.cpp:729
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1586
+#: ../src/backend/filters/voxelise.cpp:876
+#: ../src/backend/filters/rangeFile.cpp:732
msgid "Ranges"
msgstr "Ranges"
+#: ../src/gui/dialogs/ExportRngDialog.cpp:88
+msgid "Param"
+msgstr "Param."
+
+#: ../src/gui/dialogs/ExportRngDialog.cpp:89
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:105
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:352
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1173
+#: ../src/backend/filters/dataLoad.cpp:566
+msgid "Value"
+msgstr "Wert"
+
#: ../src/gui/dialogs/ExportRngDialog.cpp:90
msgid "Value2"
msgstr "Wert2"
@@ -329,7 +314,7 @@ msgid "Num Ranges"
msgstr "Num Ranges"
#: ../src/gui/dialogs/ExportRngDialog.cpp:116
-#: ../src/gui/dialogs/rangeEditDialog.cpp:710 ../src/backend/filter.cpp:43
+#: ../src/gui/dialogs/rangeEditDialog.cpp:695 ../src/backend/filter.cpp:44
msgid "Ion"
msgstr "Ion"
@@ -341,7 +326,7 @@ msgstr "Range Anfang"
msgid "Range end"
msgstr "Range Ende"
-#: ../src/gui/dialogs/ExportRngDialog.cpp:151 ../src/gui/mainFrame.cpp:2315
+#: ../src/gui/dialogs/ExportRngDialog.cpp:151 ../src/gui/mainFrame.cpp:2355
msgid "Save pos..."
msgstr "pos speichern..."
@@ -349,10 +334,10 @@ msgstr "pos speichern..."
msgid "ORNL format RNG (*.rng)|*.rng|All Files (*)|*"
msgstr "ORNL Format RNG (*.rng)|*.rng|Alle Dateien (*)|*"
-#: ../src/gui/dialogs/ExportRngDialog.cpp:167 ../src/gui/mainFrame.cpp:1422
-#: ../src/gui/mainFrame.cpp:1584 ../src/gui/mainFrame.cpp:1659
-#: ../src/gui/mainFrame.cpp:2214 ../src/gui/mainFrame.cpp:2372
-#: ../src/gui/mainFrame.cpp:2487
+#: ../src/gui/dialogs/ExportRngDialog.cpp:167 ../src/gui/mainFrame.cpp:1446
+#: ../src/gui/mainFrame.cpp:1622 ../src/gui/mainFrame.cpp:1697
+#: ../src/gui/mainFrame.cpp:2254 ../src/gui/mainFrame.cpp:2412
+#: ../src/gui/mainFrame.cpp:2527
msgid "Unable to save. Check output destination can be written to."
msgstr ""
"Speichern nicht möglich. Bitte überprüfen Sie ob der Ausgabepfad "
@@ -378,86 +363,84 @@ msgstr ""
msgid "e.g. H2O"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:575
-#: ../src/gui/dialogs/rangeEditDialog.cpp:709 ../src/gui/mainFrame.cpp:6061
-#: ../src/backend/filter.cpp:44
+#: ../src/gui/dialogs/rangeEditDialog.cpp:560
+#: ../src/gui/dialogs/rangeEditDialog.cpp:694 ../src/gui/mainFrame.cpp:5800
+#: ../src/backend/filter.cpp:45
msgid "Plot"
msgstr "Plot"
-#: ../src/gui/dialogs/rangeEditDialog.cpp:576
+#: ../src/gui/dialogs/rangeEditDialog.cpp:561
msgid "Short Name"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:577
+#: ../src/gui/dialogs/rangeEditDialog.cpp:562
msgid "Long Name"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:578
-#: ../src/backend/filters/voxelise.cpp:1022
-#: ../src/backend/filters/compositionProfile.cpp:1156
-#: ../src/backend/filters/annotation.cpp:903
-#: ../src/backend/filters/spectrumPlot.cpp:472
+#: ../src/gui/dialogs/rangeEditDialog.cpp:563
+#: ../src/backend/filters/voxelise.cpp:1020
+#: ../src/backend/filters/compositionProfile.cpp:1100
+#: ../src/backend/filters/annotation.cpp:896
+#: ../src/backend/filters/spectrumPlot.cpp:452
msgid "Colour"
msgstr "Farbe"
-#: ../src/gui/dialogs/rangeEditDialog.cpp:711
-#: ../src/backend/filters/annotation.cpp:606
-#: ../src/backend/filters/annotation.cpp:645
-#: ../src/backend/filters/annotation.cpp:812
+#: ../src/gui/dialogs/rangeEditDialog.cpp:696
+#: ../src/backend/filters/annotation.cpp:600
+#: ../src/backend/filters/annotation.cpp:641
+#: ../src/backend/filters/annotation.cpp:810
msgid "Start"
msgstr "Anfang"
-#: ../src/gui/dialogs/rangeEditDialog.cpp:712
-#: ../src/backend/filters/annotation.cpp:614
-#: ../src/backend/filters/annotation.cpp:654
-#: ../src/backend/filters/annotation.cpp:820
+#: ../src/gui/dialogs/rangeEditDialog.cpp:697
+#: ../src/backend/filters/annotation.cpp:608
+#: ../src/backend/filters/annotation.cpp:650
+#: ../src/backend/filters/annotation.cpp:818
msgid "End"
msgstr "Ende"
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1275
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1278
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1259
msgid "Range or ion?"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1276
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1279
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1260
msgid "Select type to add"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1561
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1541
msgid "Range Editor"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1565
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1545
msgid "Enable or disable all overlays"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1566
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1546
msgid "Entered overlays, use delete to remove"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1567
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1547
msgid "Available plots for ranging"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1568
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1548
msgid "Enter species to display as overlay, e.g. SiO2"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1569
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1549
msgid "Editable ranges"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1570
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1550
msgid "Editable ions"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1605
-#: ../src/gui/dialogs/animateFilterDialog.cpp:172
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1585
+#: ../src/gui/dialogs/animateFilterDialog.cpp:173
msgid "Plots"
msgstr ""
-#: ../src/gui/dialogs/rangeEditDialog.cpp:1607
+#: ../src/gui/dialogs/rangeEditDialog.cpp:1587
msgid "Overlay"
msgstr ""
@@ -473,8 +456,8 @@ msgstr ""
msgid "Multiple autosave states were found; would you like to restore one?"
msgstr ""
-#: ../src/gui/dialogs/filterErrorDialog.cpp:37 ../src/backend/filter.cpp:388
-#: ../src/backend/filter.cpp:391
+#: ../src/gui/dialogs/filterErrorDialog.cpp:37 ../src/backend/filter.cpp:435
+#: ../src/backend/filter.cpp:438
msgid "Error"
msgstr ""
@@ -487,46 +470,46 @@ msgstr ""
msgid "Filter Errors"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:45
+#: ../src/gui/dialogs/StashDialog.cpp:46
msgid "Stashes"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:48
+#: ../src/gui/dialogs/StashDialog.cpp:49
msgid "Stashed Tree"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:50
+#: ../src/gui/dialogs/StashDialog.cpp:51
msgid "Properties"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:86
+#: ../src/gui/dialogs/StashDialog.cpp:57
+msgid "Stash Name"
+msgstr "Stash Name"
+
+#: ../src/gui/dialogs/StashDialog.cpp:58
+msgid "Filter Count"
+msgstr "Filter Count"
+
+#: ../src/gui/dialogs/StashDialog.cpp:91
msgid "Stashed Trees"
msgstr "Stashed Trees"
-#: ../src/gui/dialogs/StashDialog.cpp:89
+#: ../src/gui/dialogs/StashDialog.cpp:94
msgid "Erase stashed item"
msgstr ""
-#: ../src/gui/dialogs/StashDialog.cpp:90
+#: ../src/gui/dialogs/StashDialog.cpp:95
msgid "Filter view for current stash"
msgstr "Filteransicht für den aktuellen Stash"
-#: ../src/gui/dialogs/StashDialog.cpp:91
+#: ../src/gui/dialogs/StashDialog.cpp:96
msgid "Settings for selected filter in current stash"
msgstr "Einstellungen für den ausgewählten Stash"
-#: ../src/gui/dialogs/StashDialog.cpp:92
+#: ../src/gui/dialogs/StashDialog.cpp:97
msgid "Available stashes"
msgstr "Verfügbare Stash"
-#: ../src/gui/dialogs/StashDialog.cpp:153
-msgid "Stash Name"
-msgstr "Stash Name"
-
-#: ../src/gui/dialogs/StashDialog.cpp:154
-msgid "Filter Count"
-msgstr "Filter Count"
-
#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:45
msgid "Start Frame: "
msgstr ""
@@ -539,57 +522,57 @@ msgstr ""
msgid "From Table"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:108
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:354
-#: ../src/gui/dialogs/animateFilterDialog.cpp:191
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:104
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:350
+#: ../src/gui/dialogs/animateFilterDialog.cpp:192
msgid "Frame"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:244
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:240
msgid "Select text file..."
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:245
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:241
msgid "Text files (*.txt)|*.txt;|All Files (*)|*"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:346
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:342
msgid "String Keyframes"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:348
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:344
msgid "Frame at which to start string sequence"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:349
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:345
msgid "Frame offset for data start"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:350
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:346
msgid "File to use as string data source, one value per row"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:351
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:347
msgid "Select file to use as data source"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:352
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:348
msgid "Use table below for data source"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:358
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:354
msgid "Add new data rows to table, hold shift/cmd to insert multiple rows"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:359
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:355
msgid "Remove selected strings from table"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:360
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:356
msgid "Abort value selection and return to previous window"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:361
+#: ../src/gui/dialogs/animateSubDialogs/stringKeyFrameDialog.cpp:357
msgid "Accept data values"
msgstr ""
@@ -610,12 +593,12 @@ msgid "Ramp"
msgstr ""
#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:64
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1192
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1154
msgid "Start Frame"
msgstr ""
#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:66
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1193
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1155
msgid "End Frame"
msgstr ""
@@ -635,219 +618,221 @@ msgstr ""
msgid "endColour"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:237
+#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:235
msgid "Key Frame : Colour"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:239
+#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:237
msgid "Colour at the start of the transtition"
msgstr ""
-#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:240
+#: ../src/gui/dialogs/animateSubDialogs/colourKeyFrameDialog.cpp:238
msgid "Colour at end of transition"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:91
+#: ../src/gui/dialogs/animateFilterDialog.cpp:92
msgid "Oak-Ridge RNG"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:92
+#: ../src/gui/dialogs/animateFilterDialog.cpp:93
msgid "Cameca/Ametek RRNG"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:93
+#: ../src/gui/dialogs/animateFilterDialog.cpp:94
msgid "Cameca/Ametek ENV"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:151
+#: ../src/gui/dialogs/animateFilterDialog.cpp:152
msgid "Key frames"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:152
+#: ../src/gui/dialogs/animateFilterDialog.cpp:153
msgid "Output Data"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:153
+#: ../src/gui/dialogs/animateFilterDialog.cpp:154
msgid "Filters and properties"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:159
+#: ../src/gui/dialogs/animateFilterDialog.cpp:160
msgid "Dir : "
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:162
+#: ../src/gui/dialogs/animateFilterDialog.cpp:163
msgid "Output only when refresh required"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:164
+#: ../src/gui/dialogs/animateFilterDialog.cpp:165
msgid "Data Types:"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:165
+#: ../src/gui/dialogs/animateFilterDialog.cpp:166
msgid "3D Images"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:166
+#: ../src/gui/dialogs/animateFilterDialog.cpp:167
msgid "File Suffix: "
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:168
+#: ../src/gui/dialogs/animateFilterDialog.cpp:169
msgid "Size : "
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:170
+#: ../src/gui/dialogs/animateFilterDialog.cpp:171
msgid "..."
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:171
+#: ../src/gui/dialogs/animateFilterDialog.cpp:172
msgid "Point data"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:173
+#: ../src/gui/dialogs/animateFilterDialog.cpp:174
msgid "Voxel data"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:174
+#: ../src/gui/dialogs/animateFilterDialog.cpp:175
msgid "Range files"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:175
+#: ../src/gui/dialogs/animateFilterDialog.cpp:176
msgid "Format"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:672
+#: ../src/gui/dialogs/animateFilterDialog.cpp:677
msgid "transition frame"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:672
-#: ../src/gui/mainFrame.cpp:1636
+#: ../src/gui/dialogs/animateFilterDialog.cpp:677
+#: ../src/gui/mainFrame.cpp:1674
msgid "Frame count"
msgstr "Bildanzahl"
-#: ../src/gui/dialogs/animateFilterDialog.cpp:744
+#: ../src/gui/dialogs/animateFilterDialog.cpp:749
msgid "Key frame : Colour"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:797
+#: ../src/gui/dialogs/animateFilterDialog.cpp:802
msgid "File existed, but was unable to read or interpret file contents."
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:798
+#: ../src/gui/dialogs/animateFilterDialog.cpp:803
msgid "String load failed"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:819
+#: ../src/gui/dialogs/animateFilterDialog.cpp:824
msgid "Keyframe : decimal"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:828
+#: ../src/gui/dialogs/animateFilterDialog.cpp:833
msgid "Keyframe : integer"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:837
+#: ../src/gui/dialogs/animateFilterDialog.cpp:842
msgid "Keyframe : 3D Point"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:962
+#: ../src/gui/dialogs/animateFilterDialog.cpp:967
msgid "Select or create new folder"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1182
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1147
msgid "Export Animation"
msgstr "Animation exportieren"
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1183
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1148
msgid "Select filter"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1185
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1190
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1210
-#: ../src/gui/mainFrame.cpp:5848 ../src/gui/mainFrame.cpp:5853
-msgid "Property"
-msgstr "Eigenschaft"
-
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1187
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1149
msgid "Select property"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1189
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1209
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1151
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1171
msgid "Filter"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1191
-#: ../src/backend/filters/transform.cpp:1182
-#: ../src/backend/filters/annotation.cpp:547
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1152
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1172
+msgid "Property"
+msgstr "Eigenschaft"
+
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1153
+#: ../src/backend/filters/voxelise.cpp:903
+#: ../src/backend/filters/spatialAnalysis.cpp:906
+#: ../src/backend/filters/transform.cpp:1133
+#: ../src/backend/filters/annotation.cpp:540
+#: ../src/backend/filters/annotation.cpp:546
+#: ../src/backend/filters/ionDownsample.cpp:463
msgid "Mode"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1194
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1156
msgid "Keyframe table"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1195
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1157
msgid "Remove the selected keyframe from the table"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1196
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1158
msgid "Enter where the animation frames will be exported to"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1197
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1159
msgid "Browse to directory where the animation frames will be exported to"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1199
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1161
msgid ""
"Title for files, result will be saved as #-name.png, where # is image number."
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1200
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1162
msgid "Target resolution (image size)"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1202
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1164
msgid "Select frame for property display"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1203
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1165
msgid "Enter frame number to change frame (eg 1/20)"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1204
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1166
msgid "Save point data (POS files) in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1205
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1167
msgid "Save plots (as text files) in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1206
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1168
msgid "Save voxel data (raw files) in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1207
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1169
msgid "Save range files in output folder?"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1212
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1174
msgid "Animation parameters for current frame"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1213
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1175
msgid "Abort animation"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1214
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1176
msgid "Run Animation"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1285
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1247
msgid "Filter view"
msgstr ""
-#: ../src/gui/dialogs/animateFilterDialog.cpp:1286
+#: ../src/gui/dialogs/animateFilterDialog.cpp:1248
msgid "Frame view"
msgstr ""
@@ -860,11 +845,11 @@ msgid "Height :"
msgstr ""
#: ../src/gui/dialogs/resolutionDialog.cpp:50
-#: ../src/gui/dialogs/prefDialog.cpp:83
+#: ../src/gui/dialogs/prefDialog.cpp:85
msgid "Reset"
msgstr "Zurücksetzen"
-#: ../src/gui/dialogs/resolutionDialog.cpp:350
+#: ../src/gui/dialogs/resolutionDialog.cpp:336
msgid "Resolution Selection"
msgstr ""
@@ -873,7 +858,7 @@ msgid "Export:"
msgstr "Exportieren:"
#: ../src/gui/dialogs/ExportPos.cpp:76
-#: ../src/backend/filters/boundingBox.cpp:520
+#: ../src/backend/filters/boundingBox.cpp:521
msgid "Visible"
msgstr "Sichtbar"
@@ -894,143 +879,129 @@ msgid "Index"
msgstr "Index"
#: ../src/gui/dialogs/ExportPos.cpp:111 ../src/gui/dialogs/ExportPos.cpp:114
-#: ../src/backend/filters/compositionProfile.cpp:549
-#: ../src/backend/filters/spatialAnalysis.cpp:1953
-#: ../src/backend/filters/spatialAnalysis.cpp:2022
-#: ../src/backend/filters/spatialAnalysis.cpp:3002
-#: ../src/backend/filters/spatialAnalysis.cpp:3221
-#: ../src/backend/filters/spatialAnalysis.cpp:3290
-#: ../src/backend/filters/spectrumPlot.cpp:240
+#: ../src/backend/filters/compositionProfile.cpp:581
+#: ../src/backend/filters/spatialAnalysis.cpp:2199
+#: ../src/backend/filters/spatialAnalysis.cpp:2259
+#: ../src/backend/filters/spatialAnalysis.cpp:3224
+#: ../src/backend/filters/spatialAnalysis.cpp:3436
+#: ../src/backend/filters/spatialAnalysis.cpp:3495
+#: ../src/backend/filters/spectrumPlot.cpp:237
msgid "Count"
msgstr "Anzahl"
-#: ../src/gui/dialogs/ExportPos.cpp:450
+#: ../src/gui/dialogs/ExportPos.cpp:457
msgid "Export Pos Data"
msgstr "POS Daten exportieren"
-#: ../src/gui/dialogs/ExportPos.cpp:453
+#: ../src/gui/dialogs/ExportPos.cpp:460
msgid "Tree of filters, select leaves to show ion data."
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:455
+#: ../src/gui/dialogs/ExportPos.cpp:462
msgid "Add all data from all filters"
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:456
+#: ../src/gui/dialogs/ExportPos.cpp:463
msgid "Add all data from currently selected filter"
msgstr ""
-#: ../src/gui/dialogs/ExportPos.cpp:457
+#: ../src/gui/dialogs/ExportPos.cpp:464
msgid "Add selected data from currently selected filter"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:72
+#: ../src/gui/dialogs/prefDialog.cpp:73
msgid "Panel Display"
msgstr "Panel Display"
-#: ../src/gui/dialogs/prefDialog.cpp:74
+#: ../src/gui/dialogs/prefDialog.cpp:75
msgid "Online Updates"
msgstr "Online Updates"
-#: ../src/gui/dialogs/prefDialog.cpp:76 ../src/gui/dialogs/prefDialog.cpp:654
+#: ../src/gui/dialogs/prefDialog.cpp:77 ../src/gui/dialogs/prefDialog.cpp:560
msgid "Startup"
msgstr "Startup"
-#: ../src/gui/dialogs/prefDialog.cpp:77
+#: ../src/gui/dialogs/prefDialog.cpp:78
msgid "Camera Speed"
msgstr "Kamerageschwindigkeit"
-#: ../src/gui/dialogs/prefDialog.cpp:78
-msgid "Filter Defaults"
-msgstr "Filtervoreinstellungen"
-
#: ../src/gui/dialogs/prefDialog.cpp:79
msgid "Available Filters"
msgstr "Verfügbare Filter"
-#: ../src/gui/dialogs/prefDialog.cpp:82
+#: ../src/gui/dialogs/prefDialog.cpp:84
msgid "Reset All"
msgstr "Alle zurücksetzen"
-#: ../src/gui/dialogs/prefDialog.cpp:85
+#: ../src/gui/dialogs/prefDialog.cpp:87
msgid "Show all panels"
msgstr "Zeige alle Fenster"
-#: ../src/gui/dialogs/prefDialog.cpp:86
+#: ../src/gui/dialogs/prefDialog.cpp:88
msgid "Remember last"
msgstr "Zuletzt verwendet"
-#: ../src/gui/dialogs/prefDialog.cpp:87
+#: ../src/gui/dialogs/prefDialog.cpp:89
msgid "Show Selected"
msgstr "Zeige Auswahl"
-#: ../src/gui/dialogs/prefDialog.cpp:90
+#: ../src/gui/dialogs/prefDialog.cpp:92
msgid "Control Pane"
msgstr "Kontrollfenster"
-#: ../src/gui/dialogs/prefDialog.cpp:91
+#: ../src/gui/dialogs/prefDialog.cpp:93
msgid "Raw Data Panel"
msgstr "Rohdatenfenster"
-#: ../src/gui/dialogs/prefDialog.cpp:92 ../src/gui/mainFrame.cpp:652
+#: ../src/gui/dialogs/prefDialog.cpp:94 ../src/gui/mainFrame.cpp:663
msgid "Plot List"
msgstr "Plotliste"
-#: ../src/gui/dialogs/prefDialog.cpp:94
+#: ../src/gui/dialogs/prefDialog.cpp:96
msgid "Periodically notify about available updates"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:96
+#: ../src/gui/dialogs/prefDialog.cpp:98
msgid "Prefer orthographic at startup"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:97
+#: ../src/gui/dialogs/prefDialog.cpp:99
msgid "Move Rate"
msgstr "Bewegungsgeschwindigkeit"
-#: ../src/gui/dialogs/prefDialog.cpp:98 ../src/gui/dialogs/prefDialog.cpp:102
+#: ../src/gui/dialogs/prefDialog.cpp:100 ../src/gui/dialogs/prefDialog.cpp:104
msgid "(slow)"
msgstr "(langsam)"
-#: ../src/gui/dialogs/prefDialog.cpp:100 ../src/gui/dialogs/prefDialog.cpp:104
+#: ../src/gui/dialogs/prefDialog.cpp:102 ../src/gui/dialogs/prefDialog.cpp:106
msgid "(fast)"
msgstr "(schnell)"
-#: ../src/gui/dialogs/prefDialog.cpp:101
+#: ../src/gui/dialogs/prefDialog.cpp:103
msgid "Zoom Rate"
msgstr "Zoomgeschwindigkeit"
-#: ../src/gui/dialogs/prefDialog.cpp:456
-msgid "Notice"
-msgstr "Notiz"
-
-#: ../src/gui/dialogs/prefDialog.cpp:459
-msgid "For security reasons, defaults are not modifiable for this filter"
-msgstr ""
-"Aus Sicherheitsgründen können die Voreinstellungen für diesen Filter nicht "
-"geändert werden."
-
-#: ../src/gui/dialogs/prefDialog.cpp:496
+#: ../src/gui/dialogs/prefDialog.cpp:416
msgid "Show all panels when starting program"
msgstr "Zeige alle Fenster beim Programmstart"
-#: ../src/gui/dialogs/prefDialog.cpp:499
+#: ../src/gui/dialogs/prefDialog.cpp:419
msgid "Show panels visible at last shutdown when starting program"
msgstr "Beim Programmstart zuletzt eingeschaltete Fenster anzeigen."
-#: ../src/gui/dialogs/prefDialog.cpp:506
+#: ../src/gui/dialogs/prefDialog.cpp:426
msgid "Show selected panels when starting program"
msgstr "Zeige ausgewählte Fenster beim Programmstart"
-#: ../src/gui/dialogs/prefDialog.cpp:555
+#: ../src/gui/dialogs/prefDialog.cpp:475
msgid "Preferences"
msgstr "Voreinstellungen"
-#: ../src/gui/dialogs/prefDialog.cpp:557
+#: ../src/gui/dialogs/prefDialog.cpp:477
msgid "Set the method of panel layout when starting the program"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:560
+#: ../src/gui/dialogs/prefDialog.cpp:480
msgid ""
"Lets the program check the internet to see if updates to the program version "
"are available, then notifies you about updates now and again."
@@ -1038,107 +1009,112 @@ msgstr ""
"Lässt das Programm via Internet überprüfen ob Updates für diese "
"Programmversion verfügbar sind. Danach informiert es über die neuen Updates."
-#: ../src/gui/dialogs/prefDialog.cpp:562
+#: ../src/gui/dialogs/prefDialog.cpp:482
msgid ""
"By default, use an orthographic camera at startup. State files will override "
"this preference."
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:563
+#: ../src/gui/dialogs/prefDialog.cpp:483
msgid "Camera translation, orbit and swivel rates. "
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:564
+#: ../src/gui/dialogs/prefDialog.cpp:484
msgid "Camera zooming rate."
msgstr "Zoomgeschwindigkeit der Kamera"
-#: ../src/gui/dialogs/prefDialog.cpp:566
+#: ../src/gui/dialogs/prefDialog.cpp:486
msgid "Reset the filter initial values back to program defaults"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:567
+#: ../src/gui/dialogs/prefDialog.cpp:487
msgid "Reset all filter initial values back to program defaults"
msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:653
-msgid "Pref"
-msgstr "Pref"
+#: ../src/gui/dialogs/prefDialog.cpp:559
+msgid "Filt. Default"
+msgstr ""
-#: ../src/gui/dialogs/prefDialog.cpp:655
+#: ../src/gui/dialogs/prefDialog.cpp:561
msgid "Camera"
msgstr "Kamera"
-#: ../src/gui/mainFrame.cpp:91
+#: ../src/gui/mainFrame.cpp:105
msgid "New camera name..."
msgstr "Neuer Kameraname..."
-#: ../src/gui/mainFrame.cpp:92
-msgid "New stash name...."
-msgstr "Neuer Stashname..."
+#: ../src/gui/mainFrame.cpp:106
+msgid "New stash name..."
+msgstr ""
+
+#: ../src/gui/mainFrame.cpp:111
+msgid "New Filter..."
+msgstr ""
-#: ../src/gui/mainFrame.cpp:108 ../src/backend/filters/annotation.cpp:561
-#: ../src/backend/filters/annotation.cpp:663
+#: ../src/gui/mainFrame.cpp:128 ../src/backend/filters/annotation.cpp:555
+#: ../src/backend/filters/annotation.cpp:659
#: ../src/backend/filters/annotation.h:96
msgid "Annotation"
msgstr "Kommentar"
-#: ../src/gui/mainFrame.cpp:109
+#: ../src/gui/mainFrame.cpp:129
msgid "Bounding Box"
msgstr "Begrenzungs-Box"
-#: ../src/gui/mainFrame.cpp:110 ../src/backend/filters/ionClip.h:66
+#: ../src/gui/mainFrame.cpp:130 ../src/backend/filters/ionClip.cpp:619
+#: ../src/backend/filters/ionClip.h:66
msgid "Clipping"
msgstr "Zuschneiden"
-#: ../src/gui/mainFrame.cpp:111 ../src/backend/filters/clusterAnalysis.h:140
+#: ../src/gui/mainFrame.cpp:131 ../src/backend/filters/clusterAnalysis.h:143
msgid "Cluster Analysis"
msgstr "Clusteranalyse"
-#: ../src/gui/mainFrame.cpp:112
+#: ../src/gui/mainFrame.cpp:132
msgid "Compos. Profiles"
msgstr "Konz.Profil"
-#: ../src/gui/mainFrame.cpp:113
+#: ../src/gui/mainFrame.cpp:133
msgid "Downsampling"
msgstr "Datenreduktion"
-#: ../src/gui/mainFrame.cpp:114
+#: ../src/gui/mainFrame.cpp:134
msgid "Extern. Prog."
msgstr "Ext. Progr."
-#: ../src/gui/mainFrame.cpp:115
+#: ../src/gui/mainFrame.cpp:135
msgid "Ion Colour"
msgstr "Ionenfarbe"
-#: ../src/gui/mainFrame.cpp:116
+#: ../src/gui/mainFrame.cpp:136
msgid "Ion Info"
msgstr "Ion Info"
-#: ../src/gui/mainFrame.cpp:117
+#: ../src/gui/mainFrame.cpp:137
msgid "Ion Transform"
msgstr "Ionentransform."
-#: ../src/gui/mainFrame.cpp:118 ../src/backend/filters/spectrumPlot.h:53
+#: ../src/gui/mainFrame.cpp:138 ../src/backend/filters/spectrumPlot.h:53
msgid "Spectrum"
msgstr "Spektrum"
-#: ../src/gui/mainFrame.cpp:119
+#: ../src/gui/mainFrame.cpp:139
msgid "Range File"
msgstr "Rangedatei"
-#: ../src/gui/mainFrame.cpp:120 ../src/backend/filters/spatialAnalysis.h:172
+#: ../src/gui/mainFrame.cpp:140 ../src/backend/filters/spatialAnalysis.h:193
msgid "Spat. Analysis"
msgstr "Räumliche Analyse"
-#: ../src/gui/mainFrame.cpp:121 ../src/backend/filters/voxelise.h:121
+#: ../src/gui/mainFrame.cpp:141 ../src/backend/filters/voxelise.h:121
msgid "Voxelisation"
msgstr "Voxelisation"
-#: ../src/gui/mainFrame.cpp:421
+#: ../src/gui/mainFrame.cpp:429
msgid "OpenGL Failed"
msgstr "OpenGL fehlgeschlagen"
-#: ../src/gui/mainFrame.cpp:422 ../src/gui/mainFrame.cpp:424
+#: ../src/gui/mainFrame.cpp:430 ../src/gui/mainFrame.cpp:432
msgid ""
"Unable to initialise the openGL (3D) panel. Program cannot start. Please "
"check your video drivers."
@@ -1146,445 +1122,447 @@ msgstr ""
"Kann das OpenGL (3D)-Panel nicht initialisieren. Das Programm kann nicht "
"gestartet werden. Bitte überprüfen Sie Ihren Video-Treiber."
-#: ../src/gui/mainFrame.cpp:444
+#: ../src/gui/mainFrame.cpp:452
msgid "&Open...\tCtrl+O"
msgstr "&Öffnen...\tCtrl+O"
-#: ../src/gui/mainFrame.cpp:444
+#: ../src/gui/mainFrame.cpp:452
msgid "Open state file"
msgstr "Statusdatei öffnen"
-#: ../src/gui/mainFrame.cpp:445
+#: ../src/gui/mainFrame.cpp:453
msgid "&Merge...\tCtrl+Shift+O"
msgstr "&Zusammenführen...\tCtrl+Shift+O"
-#: ../src/gui/mainFrame.cpp:445
+#: ../src/gui/mainFrame.cpp:453
msgid "Merge other file"
msgstr "Merge other file"
-#: ../src/gui/mainFrame.cpp:449
+#: ../src/gui/mainFrame.cpp:457
msgid "&Recent"
msgstr "&Letzte"
-#: ../src/gui/mainFrame.cpp:450
+#: ../src/gui/mainFrame.cpp:458
msgid "&Save\tCtrl+S"
msgstr "&Speichern\tCtrl+S"
-#: ../src/gui/mainFrame.cpp:450
+#: ../src/gui/mainFrame.cpp:458
msgid "Save state to file"
msgstr "Status in Datei speichern"
-#: ../src/gui/mainFrame.cpp:452
+#: ../src/gui/mainFrame.cpp:460
msgid "Save &As...\tCtrl+Shift+S"
msgstr "Speichern &als...\tCtrl+Shift+S"
-#: ../src/gui/mainFrame.cpp:452
+#: ../src/gui/mainFrame.cpp:460
msgid "Save current state to new file"
msgstr "Aktuellen Status als neue Datei speichern"
-#: ../src/gui/mainFrame.cpp:455
+#: ../src/gui/mainFrame.cpp:463
msgid "&Plot...\tCtrl+P"
msgstr "&Plot...\tCtrl+P"
-#: ../src/gui/mainFrame.cpp:455
+#: ../src/gui/mainFrame.cpp:463
msgid "Export Current Plot"
msgstr "Aktuellen Plot exportieren"
-#: ../src/gui/mainFrame.cpp:456
+#: ../src/gui/mainFrame.cpp:464
msgid "&Image...\tCtrl+I"
msgstr "&Bild...\tCtrl+I"
-#: ../src/gui/mainFrame.cpp:456
+#: ../src/gui/mainFrame.cpp:464
msgid "Export Current 3D View"
msgstr "Aktuelle 3D Ansicht exportieren"
-#: ../src/gui/mainFrame.cpp:457
+#: ../src/gui/mainFrame.cpp:465
msgid "Ion&s...\tCtrl+N"
msgstr "Ion&en...\tCtrl+N"
-#: ../src/gui/mainFrame.cpp:457
+#: ../src/gui/mainFrame.cpp:465
msgid "Export Ion Data"
msgstr "Ionendaten exportieren"
-#: ../src/gui/mainFrame.cpp:458
+#: ../src/gui/mainFrame.cpp:466
msgid "Ran&ges...\tCtrl+G"
msgstr "Ran&ges...\tCtrl+G"
-#: ../src/gui/mainFrame.cpp:458
+#: ../src/gui/mainFrame.cpp:466
msgid "Export Range Data"
msgstr "Rangedaten exportieren"
-#: ../src/gui/mainFrame.cpp:459
+#: ../src/gui/mainFrame.cpp:467
msgid "&Animate Filters...\tCtrl+A"
msgstr ""
-#: ../src/gui/mainFrame.cpp:459
+#: ../src/gui/mainFrame.cpp:467
msgid "Export Animated Filter"
msgstr ""
-#: ../src/gui/mainFrame.cpp:460
+#: ../src/gui/mainFrame.cpp:468
msgid "Ani&mate Camera...\tCtrl+M"
msgstr ""
-#: ../src/gui/mainFrame.cpp:460
+#: ../src/gui/mainFrame.cpp:468
msgid "Export Animated Camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:461
+#: ../src/gui/mainFrame.cpp:469
msgid "Pac&kage...\tCtrl+K"
msgstr "Pa&ket...\tCtrl+K"
-#: ../src/gui/mainFrame.cpp:461
+#: ../src/gui/mainFrame.cpp:469
msgid "Export analysis package"
msgstr "Analysepaket exportieren"
-#: ../src/gui/mainFrame.cpp:463
+#: ../src/gui/mainFrame.cpp:471
msgid "&Export"
msgstr "&Exportieren"
-#: ../src/gui/mainFrame.cpp:466
+#: ../src/gui/mainFrame.cpp:474
msgid "&Quit\tCtrl+Q"
msgstr "&Beenden\tCtrl+Q"
-#: ../src/gui/mainFrame.cpp:466 ../src/gui/mainFrame.cpp:468
+#: ../src/gui/mainFrame.cpp:474 ../src/gui/mainFrame.cpp:476
msgid "Exit Program"
msgstr "Programm beenden"
-#: ../src/gui/mainFrame.cpp:468
+#: ../src/gui/mainFrame.cpp:476
msgid "E&xit"
msgstr "E&xit"
-#: ../src/gui/mainFrame.cpp:470
+#: ../src/gui/mainFrame.cpp:478
msgid "&File"
msgstr "&Datei"
-#: ../src/gui/mainFrame.cpp:474
+#: ../src/gui/mainFrame.cpp:482
msgid "&Background Colour...\tCtrl+B"
msgstr "&Hintergrundfarbe...\tCtrl+B"
-#: ../src/gui/mainFrame.cpp:474
+#: ../src/gui/mainFrame.cpp:482
msgid "Change background colour"
msgstr "Hintergrundfarbe ändern"
-#: ../src/gui/mainFrame.cpp:478
+#: ../src/gui/mainFrame.cpp:486
msgid "&Control Pane\tF2"
msgstr "&Kontrollfenster\tF2"
-#: ../src/gui/mainFrame.cpp:478 ../src/gui/mainFrame.cpp:481
+#: ../src/gui/mainFrame.cpp:486 ../src/gui/mainFrame.cpp:489
msgid "Toggle left control pane"
msgstr "Linkes Kontrollfenster ein/aus schalten"
-#: ../src/gui/mainFrame.cpp:481
+#: ../src/gui/mainFrame.cpp:489
msgid "&Control Pane\tAlt+C"
msgstr "&Kontrollfenster\tAlt+C"
-#: ../src/gui/mainFrame.cpp:487
+#: ../src/gui/mainFrame.cpp:495
msgid "&Raw Data Pane\tF3"
msgstr "&Rohdatenfenster\tF3"
-#: ../src/gui/mainFrame.cpp:487 ../src/gui/mainFrame.cpp:490
+#: ../src/gui/mainFrame.cpp:495 ../src/gui/mainFrame.cpp:498
msgid "Toggle raw data pane (bottom)"
msgstr "Rohdatenfenster (unten)"
-#: ../src/gui/mainFrame.cpp:490
+#: ../src/gui/mainFrame.cpp:498
msgid "&Raw Data Pane\tAlt+R"
msgstr "&Rohdatenfenster\tAlt+R"
-#: ../src/gui/mainFrame.cpp:494
+#: ../src/gui/mainFrame.cpp:502
msgid "&Plot List\tF4"
msgstr "&Plot Liste\tF4"
-#: ../src/gui/mainFrame.cpp:494 ../src/gui/mainFrame.cpp:496
+#: ../src/gui/mainFrame.cpp:502 ../src/gui/mainFrame.cpp:504
msgid "Toggle plot list"
msgstr "Plotliste ein/aus schalten"
-#: ../src/gui/mainFrame.cpp:496
+#: ../src/gui/mainFrame.cpp:504
msgid "&Plot List\tAlt+P"
msgstr "&Plot Liste\tAlt+P"
-#: ../src/gui/mainFrame.cpp:502
+#: ../src/gui/mainFrame.cpp:510
msgid "&Legend\tCtrl+L"
msgstr "&Legende\tCtrl+L"
-#: ../src/gui/mainFrame.cpp:502
+#: ../src/gui/mainFrame.cpp:510
msgid "Toggle Legend display"
msgstr "Legende anzeigen ein/aus"
-#: ../src/gui/mainFrame.cpp:504
+#: ../src/gui/mainFrame.cpp:512
msgid "P&lot..."
msgstr "P&lot..."
-#: ../src/gui/mainFrame.cpp:505
+#: ../src/gui/mainFrame.cpp:513
msgid "&Axis\tCtrl+Shift+I"
msgstr "&Achsen\tCtrl+Shift+I"
-#: ../src/gui/mainFrame.cpp:505
+#: ../src/gui/mainFrame.cpp:513
msgid "Toggle World Axis display"
msgstr "Hauptachsen ein/aus schalten"
-#: ../src/gui/mainFrame.cpp:510
+#: ../src/gui/mainFrame.cpp:518
msgid "&Fullscreen mode\tF11"
msgstr "&Vollbildmodus\tF11"
-#: ../src/gui/mainFrame.cpp:510 ../src/gui/mainFrame.cpp:512
+#: ../src/gui/mainFrame.cpp:518 ../src/gui/mainFrame.cpp:520
msgid "Next fullscreen mode: with toolbars"
msgstr "Nächster Vollbildmodus: ohne Werkzeugleisten"
-#: ../src/gui/mainFrame.cpp:512
+#: ../src/gui/mainFrame.cpp:520
msgid "&Fullscreen mode\tCtrl+Shift+F"
msgstr "&Vollbildmodus\tCtrl+Shift+F"
-#: ../src/gui/mainFrame.cpp:517
+#: ../src/gui/mainFrame.cpp:525
msgid "&Undo\tCtrl+Z"
msgstr "&Zurück\tCtrl+Z"
-#: ../src/gui/mainFrame.cpp:519
+#: ../src/gui/mainFrame.cpp:527
msgid "&Redo\tCtrl+Y"
msgstr "&Wiederholen\tCtrl+Y"
-#: ../src/gui/mainFrame.cpp:522
+#: ../src/gui/mainFrame.cpp:530
msgid "&Range"
msgstr ""
-#: ../src/gui/mainFrame.cpp:525
+#: ../src/gui/mainFrame.cpp:533
msgid "&Preferences"
msgstr "&Voreinstellungen"
-#: ../src/gui/mainFrame.cpp:527
+#: ../src/gui/mainFrame.cpp:535
msgid "&Edit"
msgstr "&Bearbeiten"
-#: ../src/gui/mainFrame.cpp:530
+#: ../src/gui/mainFrame.cpp:538
msgid "&View"
msgstr "&Ansicht"
-#: ../src/gui/mainFrame.cpp:532
+#: ../src/gui/mainFrame.cpp:540
msgid "&Help...\tCtrl+H"
msgstr "&Hilfe...\tCtrl+H"
-#: ../src/gui/mainFrame.cpp:532
+#: ../src/gui/mainFrame.cpp:540
msgid "Show help files and documentation"
msgstr "Hilfedateien und Dokumentation anzeigen"
-#: ../src/gui/mainFrame.cpp:533
+#: ../src/gui/mainFrame.cpp:541
msgid "&Contact..."
msgstr "&Kontakt..."
-#: ../src/gui/mainFrame.cpp:533
+#: ../src/gui/mainFrame.cpp:541
msgid "Open contact page"
msgstr "Kontaktseite öffnen"
-#: ../src/gui/mainFrame.cpp:535
+#: ../src/gui/mainFrame.cpp:543
msgid "&About..."
msgstr "Über 3Depict..."
-#: ../src/gui/mainFrame.cpp:535
+#: ../src/gui/mainFrame.cpp:543
msgid "Information about this program"
msgstr "Informationen zu diesem Programm"
-#: ../src/gui/mainFrame.cpp:536
+#: ../src/gui/mainFrame.cpp:544
msgid "&Help"
msgstr "&Hilfe"
-#: ../src/gui/mainFrame.cpp:538
+#: ../src/gui/mainFrame.cpp:546
msgid "Stashed Filters"
msgstr "Zwischengelagerte Filter"
-#: ../src/gui/mainFrame.cpp:543
+#: ../src/gui/mainFrame.cpp:551
msgid "New Filters"
msgstr ""
-#: ../src/gui/mainFrame.cpp:571
+#: ../src/gui/mainFrame.cpp:580
msgid "Last Outputs"
msgstr "Letzte Ausgabe"
-#: ../src/gui/mainFrame.cpp:573
+#: ../src/gui/mainFrame.cpp:582
msgid "Auto Refresh"
msgstr ""
"Autom.\n"
"aktualisieren"
-#: ../src/gui/mainFrame.cpp:579
+#: ../src/gui/mainFrame.cpp:588
msgid "Filter settings"
msgstr "Filtereinstellungen"
-#: ../src/gui/mainFrame.cpp:581
+#: ../src/gui/mainFrame.cpp:591
msgid "Camera Name"
msgstr "Kameraname"
-#: ../src/gui/mainFrame.cpp:587
+#: ../src/gui/mainFrame.cpp:598
msgid "3D Post-processing"
msgstr "3D Nachbearbeitung"
-#: ../src/gui/mainFrame.cpp:589
+#: ../src/gui/mainFrame.cpp:600
msgid "Enable Cropping"
msgstr "Zuschneiden aktivieren"
-#: ../src/gui/mainFrame.cpp:591 ../src/gui/mainFrame.cpp:602
+#: ../src/gui/mainFrame.cpp:602 ../src/gui/mainFrame.cpp:613
msgid "x-y"
msgstr "x-y"
-#: ../src/gui/mainFrame.cpp:592 ../src/gui/mainFrame.cpp:603
+#: ../src/gui/mainFrame.cpp:603 ../src/gui/mainFrame.cpp:614
msgid "x-z"
msgstr "x-z"
-#: ../src/gui/mainFrame.cpp:593 ../src/gui/mainFrame.cpp:604
+#: ../src/gui/mainFrame.cpp:604 ../src/gui/mainFrame.cpp:615
msgid "y-x"
msgstr "y-x"
-#: ../src/gui/mainFrame.cpp:594 ../src/gui/mainFrame.cpp:605
+#: ../src/gui/mainFrame.cpp:605 ../src/gui/mainFrame.cpp:616
msgid "y-z"
msgstr "y-z"
-#: ../src/gui/mainFrame.cpp:595 ../src/gui/mainFrame.cpp:606
+#: ../src/gui/mainFrame.cpp:606 ../src/gui/mainFrame.cpp:617
msgid "z-x"
msgstr "z-x"
-#: ../src/gui/mainFrame.cpp:596 ../src/gui/mainFrame.cpp:607
+#: ../src/gui/mainFrame.cpp:607 ../src/gui/mainFrame.cpp:618
msgid "z-y"
msgstr "z-y"
-#: ../src/gui/mainFrame.cpp:611
+#: ../src/gui/mainFrame.cpp:622
msgid "Use camera coordinates"
msgstr "Verwende Kamerakoordinaten"
-#: ../src/gui/mainFrame.cpp:612
+#: ../src/gui/mainFrame.cpp:623
msgid "dX"
msgstr "dX"
-#: ../src/gui/mainFrame.cpp:614
+#: ../src/gui/mainFrame.cpp:625
msgid "dY"
msgstr "dY"
-#: ../src/gui/mainFrame.cpp:616
+#: ../src/gui/mainFrame.cpp:627
msgid "dZ"
msgstr "dZ"
-#: ../src/gui/mainFrame.cpp:618
+#: ../src/gui/mainFrame.cpp:629
msgid "Enable Anaglyphic Stereo"
msgstr "Anaglyphic Stereo aktivieren"
-#: ../src/gui/mainFrame.cpp:619
+#: ../src/gui/mainFrame.cpp:630
msgid "Flip Channels"
msgstr "Kanäle tauschen"
-#: ../src/gui/mainFrame.cpp:620
+#: ../src/gui/mainFrame.cpp:631
msgid "Anaglyph Mode"
msgstr "Anaglyphmodus"
-#: ../src/gui/mainFrame.cpp:622
+#: ../src/gui/mainFrame.cpp:633
msgid "Red-Blue"
msgstr "Rot-Blau"
-#: ../src/gui/mainFrame.cpp:623
+#: ../src/gui/mainFrame.cpp:634
msgid "Red-Green"
msgstr "Rot-Grün"
-#: ../src/gui/mainFrame.cpp:624
+#: ../src/gui/mainFrame.cpp:635
msgid "Red-Cyan"
msgstr "Rot-Zyan"
-#: ../src/gui/mainFrame.cpp:625
+#: ../src/gui/mainFrame.cpp:636
msgid "Green-Magenta"
msgstr "Grün-Magenta"
-#: ../src/gui/mainFrame.cpp:629
+#: ../src/gui/mainFrame.cpp:640
msgid "Baseline Separation"
msgstr "Basislinienabstand"
-#: ../src/gui/mainFrame.cpp:631 ../src/backend/filters/voxelise.cpp:981
-#: ../src/backend/filters/voxelise.cpp:1037
-#: ../src/backend/filters/compositionProfile.cpp:1165
+#: ../src/gui/mainFrame.cpp:642 ../src/backend/filters/voxelise.cpp:982
+#: ../src/backend/filters/voxelise.cpp:1142
+#: ../src/backend/filters/compositionProfile.cpp:1109
#: ../src/backend/filters/boundingBox.cpp:648
-#: ../src/backend/filters/dataLoad.cpp:660
+#: ../src/backend/filters/annotation.cpp:901
+#: ../src/backend/filters/dataLoad.cpp:651
+#: ../src/backend/filters/spectrumPlot.cpp:459
msgid "Appearance"
msgstr ""
-#: ../src/gui/mainFrame.cpp:632
+#: ../src/gui/mainFrame.cpp:643
msgid "Smooth && translucent objects"
msgstr "Glatte && durchsichtige Objekte"
-#: ../src/gui/mainFrame.cpp:634
+#: ../src/gui/mainFrame.cpp:645
msgid "3D lighting"
msgstr "3D Beleuchtung"
-#: ../src/gui/mainFrame.cpp:637
+#: ../src/gui/mainFrame.cpp:648
msgid "Performance"
msgstr ""
-#: ../src/gui/mainFrame.cpp:638
+#: ../src/gui/mainFrame.cpp:649
msgid "Fast and weak randomisation."
msgstr "Schnelle aber schwache Randomisierung"
-#: ../src/gui/mainFrame.cpp:640
+#: ../src/gui/mainFrame.cpp:651
msgid "Limit Output Pts"
msgstr ""
-#: ../src/gui/mainFrame.cpp:646
+#: ../src/gui/mainFrame.cpp:657
msgid "Filter caching"
msgstr "Filter zwischenspeichern"
-#: ../src/gui/mainFrame.cpp:648
+#: ../src/gui/mainFrame.cpp:659
msgid "Max. Ram usage (%)"
msgstr "Max. RAM-Nutzung (%)"
-#: ../src/gui/mainFrame.cpp:705
+#: ../src/gui/mainFrame.cpp:718
msgid "Type"
msgstr "Type"
-#: ../src/gui/mainFrame.cpp:706
+#: ../src/gui/mainFrame.cpp:719
msgid "Num"
msgstr "Num"
-#: ../src/gui/mainFrame.cpp:721
+#: ../src/gui/mainFrame.cpp:734
msgid "Warning: Your configuration file appears to be invalid:\n"
msgstr "Warnung: Ihre Konfigurationsdatei scheint ungültig zu sein.\n"
-#: ../src/gui/mainFrame.cpp:722
+#: ../src/gui/mainFrame.cpp:735
msgid "\tConfig Load: "
msgstr "\tConfig Load: "
-#: ../src/gui/mainFrame.cpp:974
+#: ../src/gui/mainFrame.cpp:984
msgid "Current state has not been saved, would you like to save it now?"
msgstr ""
-#: ../src/gui/mainFrame.cpp:975
+#: ../src/gui/mainFrame.cpp:985
msgid "State changed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:995
+#: ../src/gui/mainFrame.cpp:1005
msgid "Readable files (*.xml, *.pos, *.txt,*.csv, *.ato)"
msgstr "Lesbare Dateien (*.xml, *.pos, *.txt,*.csv,*.ato)"
-#: ../src/gui/mainFrame.cpp:997
+#: ../src/gui/mainFrame.cpp:1007
msgid "XML State File (*.xml)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:998
+#: ../src/gui/mainFrame.cpp:1008
msgid "POS File (*.pos)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:999
+#: ../src/gui/mainFrame.cpp:1009
msgid "LAWATAP ATO File (*.ato)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1000
+#: ../src/gui/mainFrame.cpp:1010
msgid "Text File (*.txt, *.csv)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1001
+#: ../src/gui/mainFrame.cpp:1011
msgid "All Files (*)"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1014 ../src/gui/mainFrame.cpp:1068
+#: ../src/gui/mainFrame.cpp:1024 ../src/gui/mainFrame.cpp:1080
msgid "Select Data or State File..."
msgstr "Daten oder Statusdatei auswählen..."
-#: ../src/gui/mainFrame.cpp:1056 ../src/gui/mainFrame.cpp:1387
+#: ../src/gui/mainFrame.cpp:1068 ../src/gui/mainFrame.cpp:1407
msgid "Loaded file."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1069
+#: ../src/gui/mainFrame.cpp:1081
msgid ""
"3Depict file (*.xml, *.pos,*.txt)|*.xml;*.pos;*.txt|POS File (*.pos)|*.pos|"
"XML State File (*.xml)|*.xml|All Files (*)|*"
@@ -1592,23 +1570,23 @@ msgstr ""
"3Depictdateien (*.xml, *.pos,*.txt)|*.xml;*.pos;*.txt|POS Datei (*.pos)|*."
"pos|XML Status Datei (*.xml)|*.xml|All Files (*)|*"
-#: ../src/gui/mainFrame.cpp:1080
+#: ../src/gui/mainFrame.cpp:1092
msgid "Merged file."
msgstr "Datei zusammengeführt."
-#: ../src/gui/mainFrame.cpp:1182
+#: ../src/gui/mainFrame.cpp:1199
msgid "Tip: You can use ⌘ (command) to merge"
msgstr "Tip: Sie können ⌘ (command) zum Zusammenführen verwenden"
-#: ../src/gui/mainFrame.cpp:1184
+#: ../src/gui/mainFrame.cpp:1201
msgid "Tip: You can use ctrl to merge"
msgstr "Tip: Sie können strg zum Zusammen führen verwenden"
-#: ../src/gui/mainFrame.cpp:1221
+#: ../src/gui/mainFrame.cpp:1241
msgid "Load error"
msgstr "Fehler beim Laden"
-#: ../src/gui/mainFrame.cpp:1222
+#: ../src/gui/mainFrame.cpp:1242
msgid ""
"Error loading state file.\n"
"See console for more info."
@@ -1616,7 +1594,7 @@ msgstr ""
"Fehler beim Laden der Statusdatei.\n"
"Konsole für mehr Informationen."
-#: ../src/gui/mainFrame.cpp:1230
+#: ../src/gui/mainFrame.cpp:1250
msgid ""
"This state file contains filters that can be unsafe to run\n"
"Do you wish to remove these before continuing?."
@@ -1624,24 +1602,24 @@ msgstr ""
"Diese Statusdatei enthält Filter deren Anwendung möglicherweise unsicher "
"ist. Wollen Sie diese entfernen."
-#: ../src/gui/mainFrame.cpp:1231
+#: ../src/gui/mainFrame.cpp:1251
msgid "Security warning"
msgstr "Sicherheitswarnung"
-#: ../src/gui/mainFrame.cpp:1444 ../src/gui/mainFrame.cpp:1540
-#: ../src/gui/mainFrame.cpp:1957
+#: ../src/gui/mainFrame.cpp:1468 ../src/gui/mainFrame.cpp:1564
+#: ../src/gui/mainFrame.cpp:1997
msgid "Unable to save"
msgstr "Speichern nicht möglich"
-#: ../src/gui/mainFrame.cpp:1445
+#: ../src/gui/mainFrame.cpp:1469
msgid "No plot available. Please create a plot before exporting."
msgstr "Kein Plot vefügbar. Plot muss vor dem Exportieren erzeugt werden."
-#: ../src/gui/mainFrame.cpp:1449
+#: ../src/gui/mainFrame.cpp:1473
msgid "Save plot..."
msgstr "Plot speichern..."
-#: ../src/gui/mainFrame.cpp:1450
+#: ../src/gui/mainFrame.cpp:1474
msgid ""
"By Extension (svg,png)|*.svg;*.png|Scalable Vector Graphics File (*.svg)|*."
"svg|PNG File (*.png)|*.png|All Files (*)|*"
@@ -1649,44 +1627,53 @@ msgstr ""
"Dateierweiterung (svg,png)|*.svg;*.png|Skalierbare Vektorgrafik (*.svg)|*."
"svg|PNG Datei (*.png)|*.png|Alle Dateien (*)|*"
-#: ../src/gui/mainFrame.cpp:1504
+#: ../src/gui/mainFrame.cpp:1528
msgid "Select type for save"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1505
+#: ../src/gui/mainFrame.cpp:1529
msgid "Choose file type"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1525 ../src/gui/mainFrame.cpp:1568
-#: ../src/gui/mainFrame.cpp:1604
+#: ../src/gui/mainFrame.cpp:1549 ../src/gui/mainFrame.cpp:1606
+#: ../src/gui/mainFrame.cpp:1642
msgid "Choose resolution"
msgstr "Auflösung auswählen"
-#: ../src/gui/mainFrame.cpp:1541
+#: ../src/gui/mainFrame.cpp:1565
msgid "Unknown file extension. Please use \"svg\" or \"png\""
msgstr "Unbekannte Dateierweiterung. Bitte verwenden Sie \"svg\" oder \"png\""
-#: ../src/gui/mainFrame.cpp:1552
+#: ../src/gui/mainFrame.cpp:1576
msgid "Saved plot: "
msgstr "Gespeicherter Plot:"
-#: ../src/gui/mainFrame.cpp:1559 ../src/gui/mainFrame.cpp:1597
+#: ../src/gui/mainFrame.cpp:1583 ../src/gui/mainFrame.cpp:1635
msgid "Save Image..."
msgstr "Speichere Bild..."
-#: ../src/gui/mainFrame.cpp:1560 ../src/gui/mainFrame.cpp:1598
+#: ../src/gui/mainFrame.cpp:1584 ../src/gui/mainFrame.cpp:1636
msgid "PNG File (*.png)|*.png|All Files (*)|*"
msgstr "PNG Datei (*.png)|*.png|Alle Dateien (*)|*"
-#: ../src/gui/mainFrame.cpp:1588 ../src/gui/mainFrame.cpp:1664
+#: ../src/gui/mainFrame.cpp:1598
+msgid "File already exists. Overwrite?"
+msgstr ""
+
+#: ../src/gui/mainFrame.cpp:1599 ../src/gui/mainFrame.cpp:2385
+#: ../src/gui/mainFrame.cpp:2483 ../src/gui/mainFrame.cpp:2507
+msgid "Overwrite?"
+msgstr "Überschreiben?"
+
+#: ../src/gui/mainFrame.cpp:1626 ../src/gui/mainFrame.cpp:1702
msgid "Saved 3D View :"
msgstr "Gespeicherte 3D Ansicht"
-#: ../src/gui/mainFrame.cpp:1618
+#: ../src/gui/mainFrame.cpp:1656
msgid "Program limitation"
msgstr "Programmeinschränkung"
-#: ../src/gui/mainFrame.cpp:1619
+#: ../src/gui/mainFrame.cpp:1657
msgid ""
"Limitation on the screenshot dimension; please ensure that both width and "
"height exceed the initial values,\n"
@@ -1698,104 +1685,104 @@ msgstr ""
"kleiner als die ursprünglichen Werte sind. Sollte Sie dies stören, melden "
"Sie bitte einen Bug."
-#: ../src/gui/mainFrame.cpp:1636
+#: ../src/gui/mainFrame.cpp:1674
msgid "Number of frames"
msgstr "Bilderanzahl"
-#: ../src/gui/mainFrame.cpp:1791
+#: ../src/gui/mainFrame.cpp:1829
msgid "Cannot animate with no filters."
msgstr ""
-#: ../src/gui/mainFrame.cpp:1868
+#: ../src/gui/mainFrame.cpp:1908
msgid "Animating"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1869
+#: ../src/gui/mainFrame.cpp:1909
msgid "Performing refresh"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1898
+#: ../src/gui/mainFrame.cpp:1938
msgid "Filter property change failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1918
+#: ../src/gui/mainFrame.cpp:1958
msgid "Refresh failed on frame :"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1943
+#: ../src/gui/mainFrame.cpp:1983
msgid "Scene generation failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1944
+#: ../src/gui/mainFrame.cpp:1984
msgid "Unable to generate scene for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:1958
+#: ../src/gui/mainFrame.cpp:1998
msgid "Image save failed for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:1983
+#: ../src/gui/mainFrame.cpp:2023
msgid "Ion save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:1984
+#: ../src/gui/mainFrame.cpp:2024
msgid "Unable to save ions for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2015
+#: ../src/gui/mainFrame.cpp:2055
msgid "Plot save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2016
+#: ../src/gui/mainFrame.cpp:2056
msgid "Unable to save plot or frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2057
+#: ../src/gui/mainFrame.cpp:2097
msgid "Range save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2058
+#: ../src/gui/mainFrame.cpp:2098
msgid "Unable to save range for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2087
+#: ../src/gui/mainFrame.cpp:2127
msgid "Voxel save failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2088
+#: ../src/gui/mainFrame.cpp:2128
msgid "Unable to save voxels for frame "
msgstr ""
-#: ../src/gui/mainFrame.cpp:2118
+#: ../src/gui/mainFrame.cpp:2158
msgid "Animate failed"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2143 ../src/gui/mainFrame.cpp:2301
-#: ../src/gui/mainFrame.cpp:2397
+#: ../src/gui/mainFrame.cpp:2183 ../src/gui/mainFrame.cpp:2341
+#: ../src/gui/mainFrame.cpp:2437
msgid "No filters means no data to export"
msgstr "Keine Filter bedeutet keine Daten zum Exportieren"
-#: ../src/gui/mainFrame.cpp:2157
+#: ../src/gui/mainFrame.cpp:2197
msgid "Package name"
msgstr "Paketname"
-#: ../src/gui/mainFrame.cpp:2158
+#: ../src/gui/mainFrame.cpp:2198
msgid "Package directory name"
msgstr "Paketverzeichnis"
-#: ../src/gui/mainFrame.cpp:2160
+#: ../src/gui/mainFrame.cpp:2200
msgid "AnalysisPackage"
msgstr "Analysepaket"
-#: ../src/gui/mainFrame.cpp:2173
+#: ../src/gui/mainFrame.cpp:2213
msgid "Package folder already exists, won't overwrite."
msgstr "Paketverzeichnis existiert bereits. Werde es nicht überschreiben."
-#: ../src/gui/mainFrame.cpp:2174
+#: ../src/gui/mainFrame.cpp:2214
msgid "Not available"
msgstr "Nicht verfügbar"
-#: ../src/gui/mainFrame.cpp:2199
+#: ../src/gui/mainFrame.cpp:2239
msgid ""
"Package folder creation failed\n"
"check writing to this location is possible."
@@ -1803,244 +1790,211 @@ msgstr ""
"Anlegen des Paketverzeichnisses fehlgeschlagen\n"
"Überprüfen Sie ob der angegenbene Ort schreibgeschützt ist."
-#: ../src/gui/mainFrame.cpp:2200
+#: ../src/gui/mainFrame.cpp:2240
msgid "Folder creation failed"
msgstr "Anlegen des Ordners ist fehlgeschlagen"
-#: ../src/gui/mainFrame.cpp:2219
+#: ../src/gui/mainFrame.cpp:2259
msgid "Copying"
msgstr "kopiere"
-#: ../src/gui/mainFrame.cpp:2220
+#: ../src/gui/mainFrame.cpp:2260
msgid "Copying referenced files"
msgstr "Copying referenced files"
-#: ../src/gui/mainFrame.cpp:2279
+#: ../src/gui/mainFrame.cpp:2319
msgid "Error copying file"
msgstr "Fehler beim Kopieren der Datei"
-#: ../src/gui/mainFrame.cpp:2288
+#: ../src/gui/mainFrame.cpp:2328
msgid "Saved package: "
msgstr "Gespeicherte Pakete: "
-#: ../src/gui/mainFrame.cpp:2311
+#: ../src/gui/mainFrame.cpp:2351
msgid "Export"
msgstr "Exportieren"
-#: ../src/gui/mainFrame.cpp:2316
+#: ../src/gui/mainFrame.cpp:2356
msgid "POS Data (*.pos)|*.pos|All Files (*)|*"
msgstr "POS-Daten (*.pos)|*.pos|All Files (*)|*"
-#: ../src/gui/mainFrame.cpp:2344 ../src/gui/mainFrame.cpp:2442
+#: ../src/gui/mainFrame.cpp:2384 ../src/gui/mainFrame.cpp:2482
msgid "File already exists, overwrite?"
msgstr "Datei existiert bereits. Überschreiben?"
-#: ../src/gui/mainFrame.cpp:2345 ../src/gui/mainFrame.cpp:2443
-#: ../src/gui/mainFrame.cpp:2467
-msgid "Overwrite?"
-msgstr "Überschreiben?"
-
-#: ../src/gui/mainFrame.cpp:2376
+#: ../src/gui/mainFrame.cpp:2416
msgid "Saved ions: "
msgstr "Gespeicherte Ionen:"
-#: ../src/gui/mainFrame.cpp:2401
+#: ../src/gui/mainFrame.cpp:2441
msgid "Export Ranges"
msgstr "Range exportieren"
-#: ../src/gui/mainFrame.cpp:2424
+#: ../src/gui/mainFrame.cpp:2464
msgid "Save state..."
msgstr "Speichere Status..."
-#: ../src/gui/mainFrame.cpp:2425
+#: ../src/gui/mainFrame.cpp:2465
msgid "XML state file (*.xml)|*.xml|All Files (*)|*"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2466
+#: ../src/gui/mainFrame.cpp:2506
msgid "Files have been referred to using relative paths. Keep relative paths?"
msgstr ""
"Auf Dateien wurde mit relativen Pfaden verwiesen. Relative Pfade beibehalten?"
-#: ../src/gui/mainFrame.cpp:2499
+#: ../src/gui/mainFrame.cpp:2539
msgid "Saved state: "
msgstr "Gespeicherter Status: "
-#: ../src/gui/mainFrame.cpp:2576
+#: ../src/gui/mainFrame.cpp:2616
msgid "Range editor"
msgstr ""
-#: ../src/gui/mainFrame.cpp:2872
+#: ../src/gui/mainFrame.cpp:2871
msgid "Manual not found locally. Launching web browser"
msgstr "Anleitung konnte lokal nicht gefunden werden. Starte Webbrowser"
-#: ../src/gui/mainFrame.cpp:2881
+#: ../src/gui/mainFrame.cpp:2880
msgid "Opening contact page in external web browser"
msgstr "Öffne Kontaktseite in externem Browser"
-#: ../src/gui/mainFrame.cpp:2893
+#: ../src/gui/mainFrame.cpp:2892
msgid "No filter stashes to edit."
msgstr "Keine Filterstashes zum Bearbeiten."
-#: ../src/gui/mainFrame.cpp:2897
+#: ../src/gui/mainFrame.cpp:2896
msgid "Filter Stashes"
msgstr "Filter Stashes"
-#: ../src/gui/mainFrame.cpp:2926
+#: ../src/gui/mainFrame.cpp:2925
msgid "Quick and dirty analysis for point data."
msgstr "\"Quick and dirty\" Analyse von Punktdaten."
-#: ../src/gui/mainFrame.cpp:2936
+#: ../src/gui/mainFrame.cpp:2935
msgid "Compiled with wx Version: "
msgstr "Kompiliert mit wx Version: "
-#: ../src/gui/mainFrame.cpp:2957
+#: ../src/gui/mainFrame.cpp:2956
msgid "Press enter to store new stash"
msgstr "Eingabe drücken um neuen Filterstash zu speichern"
-#: ../src/gui/mainFrame.cpp:2963
+#: ../src/gui/mainFrame.cpp:2962
msgid "Press enter to restore stash"
msgstr "Eingabe drücken um Stash wiederherzustellen"
-#: ../src/gui/mainFrame.cpp:2998
+#: ../src/gui/mainFrame.cpp:2997
msgid "Unable to create stash, selection invalid"
msgstr "Stash kann nicht erstellt werden, Auswahl ungültig"
-#: ../src/gui/mainFrame.cpp:3006
+#: ../src/gui/mainFrame.cpp:3005
msgid "Created new filter tree stash"
msgstr "Neuer Filterstash wurde erzeugt"
-#: ../src/gui/mainFrame.cpp:3128
+#: ../src/gui/mainFrame.cpp:3132
msgid "Filter type not a data source - can't be at tree base"
msgstr ""
-#: ../src/gui/mainFrame.cpp:3302
+#: ../src/gui/mainFrame.cpp:3309
msgid "Moving - Hold ⌘ (command) to copy"
msgstr "Verschieben - Halte ⌘ (command) um zu kopieren"
-#: ../src/gui/mainFrame.cpp:3304
+#: ../src/gui/mainFrame.cpp:3311
msgid "Moving - Hold control to copy"
msgstr "Verschieben - Halte Strg zum kopieren"
-#: ../src/gui/mainFrame.cpp:3647
+#: ../src/gui/mainFrame.cpp:3630
msgid "Press enter to store new camera"
msgstr "Eingabe drücken um neue Kamera zu speichern"
-#: ../src/gui/mainFrame.cpp:3649
+#: ../src/gui/mainFrame.cpp:3632
msgid "Press enter to restore camera"
msgstr "Eingabe drücken um Kamera wiederherzustellen"
-#: ../src/gui/mainFrame.cpp:3674 ../src/gui/mainFrame.cpp:3715
+#: ../src/gui/mainFrame.cpp:3657 ../src/gui/mainFrame.cpp:3698
msgid "Restored camera: "
msgstr "Wiederhergestellte Kamera: "
-#: ../src/gui/mainFrame.cpp:3694
+#: ../src/gui/mainFrame.cpp:3677
msgid "Stored camera: "
msgstr "Gespeicherte Kamera: "
-#: ../src/gui/mainFrame.cpp:3775
+#: ../src/gui/mainFrame.cpp:3759
msgid "Select an item from the filter tree before choosing a new filter"
msgstr ""
"Aktivieren Sie zuerst ein Punkt aus dem Filterverlauf bevor Sie einen neuen "
"Filter auswählen"
-#: ../src/gui/mainFrame.cpp:3777
+#: ../src/gui/mainFrame.cpp:3761
msgid "Load data source (file->open) before choosing a new filter"
msgstr "Lade Datenquelle (Datei->öffnen) vor dem Auswählen eines neuen Filters"
-#: ../src/gui/mainFrame.cpp:3798
+#: ../src/gui/mainFrame.cpp:3785
msgid "Select RNG File..."
msgstr "RNG Datei auswählen..."
-#: ../src/gui/mainFrame.cpp:3799
-msgid ""
-"Range Files (*rng; *env; *rrng)|*rng;*env;*rrng|RNG File (*.rng)|*.rng|"
-"Environment File (*.env)|*.env|RRNG Files (*.rrng)|*.rrng|All Files (*)|*"
-msgstr ""
-"Rangedatei (*rng; *env; *rrng)|*rng;*env;*rrng|RNG File (*.rng)|*.rng|"
-"Environment Datei (*.env)|*.env|RRNG Files (*.rrng)|*.rrng|Alle Dateien (*)|*"
-
-#: ../src/gui/mainFrame.cpp:3819
+#: ../src/gui/mainFrame.cpp:3806
msgid "Failed reading range file."
msgstr "Fehler beim Lesen der Rangedatei."
-#: ../src/gui/mainFrame.cpp:3823
+#: ../src/gui/mainFrame.cpp:3810
msgid "Error loading file"
msgstr "Fehler beim Laden der Datei"
-#: ../src/gui/mainFrame.cpp:3881 ../src/gui/mainFrame.cpp:3947
-#: ../src/gui/mainFrame.cpp:5508 ../src/gui/mainFrame.cpp:6063
+#: ../src/gui/mainFrame.cpp:3870 ../src/gui/mainFrame.cpp:3937
+#: ../src/gui/mainFrame.cpp:5268 ../src/gui/mainFrame.cpp:5802
msgid "Cons."
msgstr "Kons."
-#: ../src/gui/mainFrame.cpp:3914
+#: ../src/gui/mainFrame.cpp:3904
msgid "Refresh Aborted."
msgstr "Aktualisieren abgebrochen"
-#: ../src/gui/mainFrame.cpp:3951
+#: ../src/gui/mainFrame.cpp:3941
msgid "*Cons."
msgstr ""
-#: ../src/gui/mainFrame.cpp:3953
+#: ../src/gui/mainFrame.cpp:3943
msgid "§Cons."
msgstr "§Kons."
-#: ../src/gui/mainFrame.cpp:4076
+#: ../src/gui/mainFrame.cpp:4037
+msgid "msgs"
+msgstr ""
+
+#: ../src/gui/mainFrame.cpp:4077
msgid "Autosave complete."
msgstr "Autosave beendet."
-#: ../src/gui/mainFrame.cpp:4243
+#: ../src/gui/mainFrame.cpp:4273
msgid "Aborted."
msgstr "Abgebrochen"
-#: ../src/gui/mainFrame.cpp:4294
+#: ../src/gui/mainFrame.cpp:4324
msgid "Updated."
msgstr "Updated."
-#: ../src/gui/mainFrame.cpp:4301
+#: ../src/gui/mainFrame.cpp:4331
msgid "\\% Done (Esc aborts)"
msgstr "\\% fertig (Esc abbrechen)"
-#: ../src/gui/mainFrame.cpp:4303
+#: ../src/gui/mainFrame.cpp:4333
msgid "\\% Done"
msgstr "\\% fertig"
-#: ../src/gui/mainFrame.cpp:4562 ../src/gui/mainFrame.cpp:4569
-msgid "Next Fullscreen mode: none"
-msgstr "Nächster Vollbildmodus: keiner"
-
-#: ../src/gui/mainFrame.cpp:4565
-msgid "Next Fullscreen mode: complete"
-msgstr "Nächster Vollbildmodus: vollständig"
-
-#: ../src/gui/mainFrame.cpp:4573
-msgid "Next Fullscreen mode: with toolbars"
-msgstr "Nächster Vollbildmodus: mit Werkzeugleisten"
-
-#: ../src/gui/mainFrame.cpp:4589
-msgid "Next Mode: No fullscreen"
-msgstr "Nächster Modus: Kein Vollbild"
-
-#: ../src/gui/mainFrame.cpp:4593
-msgid "Next Mode: fullscreen w/o toolbar"
-msgstr "Nächster Modus: Vollbild ohne Werkzeugleiste"
-
-#: ../src/gui/mainFrame.cpp:4597
-msgid "Next Mode: fullscreen with toolbar"
-msgstr "Nächster Modus: Vollbild mit Werkzeugleiste"
-
-#: ../src/gui/mainFrame.cpp:4638
+#: ../src/gui/mainFrame.cpp:4609
msgid "Tip: You can shift-click to force full refresh, if required"
msgstr "Tipp: Verwende shift-click um komplettes Aktualisieren zu erzwingen"
-#: ../src/gui/mainFrame.cpp:4910
+#: ../src/gui/mainFrame.cpp:4672
msgid "No data to save"
msgstr "Keine Daten zum Sichern"
-#: ../src/gui/mainFrame.cpp:5082
+#: ../src/gui/mainFrame.cpp:4842
msgid "Aborting..."
msgstr "Abbrechen..."
-#: ../src/gui/mainFrame.cpp:5088
+#: ../src/gui/mainFrame.cpp:4848
msgid ""
"Waiting for refresh to abort. Exiting could lead to the program "
"backgrounding. Exit anyway? "
@@ -2048,63 +2002,63 @@ msgstr ""
"Waiting for refresh to abort. Exiting could lead to the program "
"backgrounding. Exit anyway? "
-#: ../src/gui/mainFrame.cpp:5089 ../src/gui/mainFrame.cpp:5109
+#: ../src/gui/mainFrame.cpp:4849 ../src/gui/mainFrame.cpp:4869
msgid "Confirmation request"
msgstr "Bestätigungsabfrage"
-#: ../src/gui/mainFrame.cpp:5108
+#: ../src/gui/mainFrame.cpp:4868
msgid "Are you sure you wish to exit 3Depict?"
msgstr "Sind Sie sicher, dass Sie 3Depict beenden wollen?"
-#: ../src/gui/mainFrame.cpp:5536
+#: ../src/gui/mainFrame.cpp:5296
msgid "Update Notice: New version "
msgstr "Updatenotiz: Neue Version "
-#: ../src/gui/mainFrame.cpp:5536
+#: ../src/gui/mainFrame.cpp:5296
msgid " found online."
msgstr " online gefunden."
-#: ../src/gui/mainFrame.cpp:5540
+#: ../src/gui/mainFrame.cpp:5300
msgid "Online Check: "
msgstr "Überprüfe online:"
-#: ../src/gui/mainFrame.cpp:5540
+#: ../src/gui/mainFrame.cpp:5300
msgid " is up-to-date."
msgstr "ist up-to-date."
-#: ../src/gui/mainFrame.cpp:5630
+#: ../src/gui/mainFrame.cpp:5395
msgid "An auto-save state was found, would you like to restore it?."
msgstr "Ein auto-save Status wurde gefunden. Wollen Sie ihn wiederherstellen?"
-#: ../src/gui/mainFrame.cpp:5631
+#: ../src/gui/mainFrame.cpp:5396
msgid "Autosave"
msgstr "Automatisch speichern"
-#: ../src/gui/mainFrame.cpp:5638
+#: ../src/gui/mainFrame.cpp:5403
msgid "Unable to load autosave file.."
msgstr "Kann Autosavedatei nicht laden.."
-#: ../src/gui/mainFrame.cpp:5830
+#: ../src/gui/mainFrame.cpp:5600
msgid "List of available filters"
msgstr "Liste der verfügbaren Filter"
-#: ../src/gui/mainFrame.cpp:5832
+#: ../src/gui/mainFrame.cpp:5602
msgid "Tree - drag to move items, hold ⌘ for copy. Tap delete to remove items"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5834
+#: ../src/gui/mainFrame.cpp:5604
msgid ""
"Tree - drag to move items, hold Ctrl for copy. Tap delete to remove items."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5836
+#: ../src/gui/mainFrame.cpp:5606
msgid ""
"Enable/Disable automatic updates of data when filter change takes effect"
msgstr ""
"Ein/Ausschalten vom automatischen Aktualisieren der Daten wenn Änderungen am "
"Filter wirksam werden"
-#: ../src/gui/mainFrame.cpp:5839
+#: ../src/gui/mainFrame.cpp:5609
msgid ""
"Enable/Disable \"Alpha blending\" (transparency) in rendering system. "
"Blending is used to smooth objects (avoids artefacts known as \"jaggies\") "
@@ -2116,7 +2070,7 @@ msgstr ""
"und transparente Oberflächen zu generieren. Ausschalten erlaubt schnelleres "
"Renden führt jedoch zu blockigerer Darstellung."
-#: ../src/gui/mainFrame.cpp:5840
+#: ../src/gui/mainFrame.cpp:5610
msgid ""
"Enable/Disable lighting calculations in rendering, for objects that request "
"this. Lighting provides important depth cues for objects comprised of 3D "
@@ -2127,7 +2081,7 @@ msgstr ""
"umrandete Objekte. Deaktivieren erlaubt u.U. schnelleres Rendern bei "
"komplizierten Szenen."
-#: ../src/gui/mainFrame.cpp:5841
+#: ../src/gui/mainFrame.cpp:5611
msgid ""
"Enable/Disable weak randomisation (Galois linear feedback shift register). "
"Strong randomisation uses a much slower random selection method, but "
@@ -2139,14 +2093,14 @@ msgstr ""
"Auswahlmethode bietet dafür aber einen besseren Schutz gegen unbeabsichtigte "
"Korrelationen und wird für die endgültige Analyse empfohlen."
-#: ../src/gui/mainFrame.cpp:5843
+#: ../src/gui/mainFrame.cpp:5613
msgid ""
"Limit the number of points that can be displayed in the 3D scene. Does not "
"affect filter tree calculations. Disabling this can severely reduce "
"performance, due to large numbers of points being visible at once."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5844
+#: ../src/gui/mainFrame.cpp:5614
msgid ""
"Enable/Disable caching of intermediate results during filter updates. "
"Disabling caching will use less system RAM, though changes to any filter "
@@ -2158,30 +2112,30 @@ msgstr ""
"bei Änderungen der Filterparameter der ganze Filterbaum neu berechnet wird. "
"Dies erhöht den Rechenaufwand deutlich."
-#: ../src/gui/mainFrame.cpp:5855
+#: ../src/gui/mainFrame.cpp:5616
msgid "Camera data information"
msgstr "Kamerainformation"
-#: ../src/gui/mainFrame.cpp:5859
+#: ../src/gui/mainFrame.cpp:5620
msgid "Enable/disable visual effects on final 3D output"
msgstr "Ein/Ausschalten von visuellen Effekten in der finalen 3D Ausgabe."
-#: ../src/gui/mainFrame.cpp:5861
+#: ../src/gui/mainFrame.cpp:5622
msgid "Enable cropping post-process effect"
msgstr "Cropping post-Prozess Effect einschalten"
-#: ../src/gui/mainFrame.cpp:5864
+#: ../src/gui/mainFrame.cpp:5625
msgid ""
"Colour based 3D effect enable/disable - requires appropriate colour filter "
"3D glasses."
msgstr ""
"Farbbasierte 3D-Effekte ein/ausschalten - erfordert geeignete 3D-Brillen"
-#: ../src/gui/mainFrame.cpp:5865
+#: ../src/gui/mainFrame.cpp:5626
msgid "Glasses colour mode"
msgstr "Brillenfarbmodus"
-#: ../src/gui/mainFrame.cpp:5867
+#: ../src/gui/mainFrame.cpp:5628
msgid ""
"Level of separation between left and right images, which sets 3D depth to "
"visual distortion tradeoff"
@@ -2189,92 +2143,95 @@ msgstr ""
"Level of separation between left and right images, which sets 3D depth to "
"visual distortion tradeoff"
-#: ../src/gui/mainFrame.cpp:5871
+#: ../src/gui/mainFrame.cpp:5632
msgid "X"
msgstr "X"
-#: ../src/gui/mainFrame.cpp:5872
+#: ../src/gui/mainFrame.cpp:5633
msgid "Y"
msgstr "Y"
-#: ../src/gui/mainFrame.cpp:5873
+#: ../src/gui/mainFrame.cpp:5634
msgid "Save raw data to file"
msgstr "Speichere Rohdaten in Datei"
-#: ../src/gui/mainFrame.cpp:5874
+#: ../src/gui/mainFrame.cpp:5635
msgid "Copy raw data to clipboard"
msgstr "Kopiere Rohdaten in die Zwischenablage"
-#: ../src/gui/mainFrame.cpp:5875
+#: ../src/gui/mainFrame.cpp:5636
msgid "Manage \"stashed\" data."
msgstr ""
-#: ../src/gui/mainFrame.cpp:5876
+#: ../src/gui/mainFrame.cpp:5637
msgid "Program text output"
msgstr "Programm Textausgabe"
-#: ../src/gui/mainFrame.cpp:5877
+#: ../src/gui/mainFrame.cpp:5638
msgid "Select active camera, or type to create new named camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5878
+#: ../src/gui/mainFrame.cpp:5639
msgid "Remove the selected camera"
msgstr "Ausgewählte Kamera entfernen"
-#: ../src/gui/mainFrame.cpp:5879
+#: ../src/gui/mainFrame.cpp:5640
msgid "Perform cropping from coordinate frame of camera"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5880
+#: ../src/gui/mainFrame.cpp:5641
msgid ""
"Set the maximum amount of RAM to use in order to speed repeat computations"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5881
+#: ../src/gui/mainFrame.cpp:5642
msgid "Collapse the filter tree"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5882
+#: ../src/gui/mainFrame.cpp:5643
msgid "Expand the filter tree"
msgstr ""
-#: ../src/gui/mainFrame.cpp:5883
+#: ../src/gui/mainFrame.cpp:5644
msgid "Process the filter tree, hold shift to purge cached filter data"
msgstr ""
-#: ../src/gui/mainFrame.cpp:6023
+#: ../src/gui/mainFrame.cpp:5762
msgid "Crop"
msgstr "Zuschneiden"
-#: ../src/gui/mainFrame.cpp:6024
+#: ../src/gui/mainFrame.cpp:5763
msgid "Stereo"
msgstr "Stereo"
-#: ../src/gui/mainFrame.cpp:6041
+#: ../src/gui/mainFrame.cpp:5780
+#: ../src/backend/filters/externalProgram.cpp:577
+#: ../src/backend/filters/ionColour.cpp:312
+#: ../src/backend/filters/spectrumPlot.cpp:418
msgid "Data"
msgstr "Daten"
-#: ../src/gui/mainFrame.cpp:6042
+#: ../src/gui/mainFrame.cpp:5781
msgid "Cam"
msgstr "Cam"
-#: ../src/gui/mainFrame.cpp:6043
+#: ../src/gui/mainFrame.cpp:5782
msgid "Post"
msgstr "Post"
-#: ../src/gui/mainFrame.cpp:6044
+#: ../src/gui/mainFrame.cpp:5783
msgid "Tools"
msgstr "Werkz."
-#: ../src/gui/mainFrame.cpp:6062
+#: ../src/gui/mainFrame.cpp:5801
msgid "Raw"
msgstr "Roh"
-#: ../src/gui/mathglPane.cpp:230
+#: ../src/gui/mathglPane.cpp:241
msgid "No plots selected."
msgstr "Kein Plot ausgewählt."
-#: ../src/gui/mathglPane.cpp:1202
+#: ../src/gui/mathglPane.cpp:1165
msgid ""
"Unable to allocate requested memory.\n"
" Try a lower resolution, or save as vector (SVG)."
@@ -2282,37 +2239,23 @@ msgstr ""
"Kann den notwendigen Speicher nicht zuordnen. Versuche eine geringer "
"Auflösung oder speichere als Vektografik (svg)."
-#: ../src/gui/mathglPane.cpp:1204
+#: ../src/gui/mathglPane.cpp:1167
msgid "Plotting functions returned an error:\n"
msgstr "Plot-Funktion meldete einen Fehler:\n"
-#: ../src/gui/mathglPane.cpp:1206
+#: ../src/gui/mathglPane.cpp:1169
msgid "File readback check failed"
msgstr "File readback check failed"
-#: ../src/gui/mathglPane.cpp:1208
+#: ../src/gui/mathglPane.cpp:1171
msgid "Filesize during readback appears to be zero."
msgstr "Filesize during readback appears to be zero."
-#: ../src/3Depict.cpp:78
-msgid "displays this message"
-msgstr "zeigt diese Nachricht"
-
-#: ../src/3Depict.cpp:80
-msgid "inputfile"
-msgstr "Eingabedatei"
-
-#: ../src/3Depict.cpp:89
-msgid ""
-"Run debug unit tests, returns nonzero on test failure, zero on success.\n"
-"\t\tXML files may be passed to run, instead of default tests"
-msgstr ""
-
-#: ../src/3Depict.cpp:383
+#: ../src/3Depict.cpp:381
msgid "File : "
msgstr "Datei : "
-#: ../src/3Depict.cpp:383
+#: ../src/3Depict.cpp:381
msgid " does not exist. Skipping"
msgstr " existiert nicht. Überspringe"
@@ -2328,12 +2271,12 @@ msgstr "Kann den letzten Dateieintrag nicht interpretieren"
msgid "Unable to determine filter type in defaults listing."
msgstr "Kann den Filtertyp im Defaultslisting nicht bestimmen."
-#: ../src/backend/configFile.cpp:610
+#: ../src/backend/configFile.cpp:604
msgid "Online access for non win32/apple platforms is intentionally disabled, "
msgstr ""
"Onlinezugang für nicht Win32/apple systeme wurde absichtlich deaktiviert."
-#: ../src/backend/configFile.cpp:611
+#: ../src/backend/configFile.cpp:605
msgid ""
"regardless of the settings you use here. Use your package manager to keep up-"
"to-date"
@@ -2341,499 +2284,456 @@ msgstr ""
"Nutzen Sie Ihren Paketmanager um up-to-date zu sein unabhängig von den "
"Einstellungen die Sie hier verwenden"
-#: ../src/backend/plot.cpp:30 ../src/backend/filters/voxelise.cpp:122
-#: ../src/backend/filters/voxelise.cpp:132
+#: ../src/backend/plot.cpp:28 ../src/backend/filters/voxelise.cpp:123
+#: ../src/backend/filters/voxelise.cpp:133
msgid "None"
msgstr "Keiner"
-#: ../src/backend/plot.cpp:31
+#: ../src/backend/plot.cpp:29
msgid "Moving avg."
msgstr "Gleit.Durchschn."
-#: ../src/backend/plot.cpp:35
+#: ../src/backend/plot.cpp:33
msgid "Lines"
msgstr "Linien"
-#: ../src/backend/plot.cpp:36
+#: ../src/backend/plot.cpp:34
msgid "Bars"
msgstr "Block"
-#: ../src/backend/plot.cpp:37
+#: ../src/backend/plot.cpp:35
msgid "Steps"
msgstr "Stufen"
-#: ../src/backend/plot.cpp:38
+#: ../src/backend/plot.cpp:36
msgid "Stem"
msgstr "Stem"
-#: ../src/backend/plot.cpp:39
+#: ../src/backend/plot.cpp:37
msgid "Points"
msgstr "Punkte"
-#: ../src/backend/plot.cpp:841 ../src/backend/plot.cpp:849
-msgid "Multiple data types"
+#: ../src/backend/plot.cpp:39
+msgid "Density"
msgstr ""
-#: ../src/backend/plot.cpp:1550
-msgid "error"
-msgstr "Fehler"
+#: ../src/backend/plot.cpp:40
+msgid "Scatter"
+msgstr ""
+
+#: ../src/backend/plot.cpp:787 ../src/backend/plot.cpp:795
+msgid "Multiple data types"
+msgstr ""
+
+#: ../src/backend/plot.cpp:1559
+msgid "error"
+msgstr "Fehler"
+
+#: ../src/backend/plot.cpp:1772
+msgid "Amplitude"
+msgstr ""
-#: ../src/backend/filtertree.cpp:1051
+#: ../src/backend/filtertree.cpp:1060
msgid "WARNING: Skipping node "
msgstr "WARNUNG: Skipping node "
-#: ../src/backend/filtertree.cpp:1051
+#: ../src/backend/filtertree.cpp:1060
msgid " as it was not recognised"
msgstr " wurde nicht erkannt."
-#: ../src/backend/filtertree.cpp:1089
+#: ../src/backend/filtertree.cpp:1098
msgid "Error processing node: "
msgstr "Fehler beim Verarbeiten von Node: "
-#: ../src/backend/filters/externalProgram.cpp:543
+#: ../src/backend/filters/externalProgram.cpp:545
+#: ../src/backend/filters/externalProgram.cpp:559
msgid "Command"
msgstr "Befehl"
-#: ../src/backend/filters/externalProgram.cpp:546
+#: ../src/backend/filters/externalProgram.cpp:548
msgid ""
"Full command to send to operating system. See manual for escape sequence "
"meanings"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:550
+#: ../src/backend/filters/externalProgram.cpp:552
msgid "Work Dir"
msgstr "Arbeitsverzeichnis"
-#: ../src/backend/filters/externalProgram.cpp:553
+#: ../src/backend/filters/externalProgram.cpp:555
msgid "Directory to run the command in"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:563
+#: ../src/backend/filters/externalProgram.cpp:562
msgid "Cleanup input"
msgstr "Bereinige Eingabe"
-#: ../src/backend/filters/externalProgram.cpp:566
+#: ../src/backend/filters/externalProgram.cpp:565
msgid "Erase input files when command completed"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:575
+#: ../src/backend/filters/externalProgram.cpp:570
msgid "Cache"
msgstr "Zwischenspeicher"
-#: ../src/backend/filters/externalProgram.cpp:578
+#: ../src/backend/filters/externalProgram.cpp:573
msgid ""
"Assume program does not alter its output, unless inputs from 3Depict are "
"altered"
msgstr ""
-#: ../src/backend/filters/externalProgram.cpp:660
-msgid "Error processing command line"
-msgstr "Fehler beim Ausführen der Kommandozeile"
-
-#: ../src/backend/filters/externalProgram.cpp:662
-msgid "Unable to set working directory"
-msgstr "Kann Arbeitsverzeichnis nicht festlegen"
-
-#: ../src/backend/filters/externalProgram.cpp:664
-msgid "Error saving posfile result for external program"
-msgstr "Fehler beim Speichern von Posdateiergebnis für externes Programm"
-
-#: ../src/backend/filters/externalProgram.cpp:666
-msgid "Error saving plot result for externalprogram"
-msgstr "Fehler beim Speichern von Posdateiergebnis für externes Programm"
-
-#: ../src/backend/filters/externalProgram.cpp:668
-msgid "Error creating temporary directory"
-msgstr "Fehler beim Anlegen des temporären Verzeichnisses"
-
-#: ../src/backend/filters/externalProgram.cpp:670
-msgid "Detected unusable number of columns in plot"
-msgstr "Detected unusable number of columns in plot"
-
-#: ../src/backend/filters/externalProgram.cpp:672
-msgid "Unable to parse plot result from external program"
-msgstr "Unable to parse plot result from external program"
-
-#: ../src/backend/filters/externalProgram.cpp:674
-msgid "Unable to load ions from external program"
-msgstr "Kann Ionen von externem Programm nicht laden"
-
-#: ../src/backend/filters/externalProgram.cpp:676
-msgid "Unable to perform commandline substitution"
-msgstr "Unable to perform commandline substitution"
-
-#: ../src/backend/filters/externalProgram.cpp:678
-msgid "Error executing external program"
-msgstr "Fehler beim Ausführen von externem Programm"
-
-#: ../src/backend/filters/ionClip.cpp:59
-#: ../src/backend/filters/compositionProfile.cpp:43
+#: ../src/backend/filters/ionClip.cpp:60
+#: ../src/backend/filters/compositionProfile.cpp:44
msgid "Sphere"
msgstr "Kugel"
-#: ../src/backend/filters/ionClip.cpp:60
+#: ../src/backend/filters/ionClip.cpp:61
msgid "Plane"
msgstr "Ebene"
-#: ../src/backend/filters/ionClip.cpp:61
-#: ../src/backend/filters/compositionProfile.cpp:42
+#: ../src/backend/filters/ionClip.cpp:62
+#: ../src/backend/filters/compositionProfile.cpp:43
msgid "Cylinder"
msgstr "Zylinder"
-#: ../src/backend/filters/ionClip.cpp:62
+#: ../src/backend/filters/ionClip.cpp:63
msgid "Aligned box"
msgstr "Ausgerichtete Box"
-#: ../src/backend/filters/ionClip.cpp:495
+#: ../src/backend/filters/ionClip.cpp:488
+#: ../src/backend/filters/compositionProfile.cpp:943
msgid "Primitive"
msgstr "Primitiv"
-#: ../src/backend/filters/ionClip.cpp:498
+#: ../src/backend/filters/ionClip.cpp:491
msgid "Shape of clipping object"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:504
-#: ../src/backend/filters/compositionProfile.cpp:1000
+#: ../src/backend/filters/ionClip.cpp:497
+#: ../src/backend/filters/compositionProfile.cpp:949
msgid "Show Primitive"
msgstr "Zeige Primitiv"
-#: ../src/backend/filters/ionClip.cpp:507
+#: ../src/backend/filters/ionClip.cpp:500
msgid "Display the 3D interaction object"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:512
+#: ../src/backend/filters/ionClip.cpp:505
msgid "Invert Clip"
msgstr "Invertiere Clip"
-#: ../src/backend/filters/ionClip.cpp:515
+#: ../src/backend/filters/ionClip.cpp:508
msgid ""
"Switch between retaining points inside (false) and outside (true) of "
"primitive"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:529
-#: ../src/backend/filters/compositionProfile.cpp:1059
+#: ../src/backend/filters/ionClip.cpp:522
+#: ../src/backend/filters/compositionProfile.cpp:1005
msgid "Position for centre of sphere"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:534
-#: ../src/backend/filters/ionClip.cpp:597
-#: ../src/backend/filters/compositionProfile.cpp:1042
-#: ../src/backend/filters/compositionProfile.cpp:1064
-#: ../src/backend/filters/spatialAnalysis.cpp:93
-#: ../src/backend/filters/spatialAnalysis.cpp:616
+#: ../src/backend/filters/ionClip.cpp:527
+#: ../src/backend/filters/ionClip.cpp:587
+#: ../src/backend/filters/compositionProfile.cpp:988
+#: ../src/backend/filters/compositionProfile.cpp:1010
+#: ../src/backend/filters/spatialAnalysis.cpp:111
+#: ../src/backend/filters/spatialAnalysis.cpp:791
msgid "Radius"
msgstr "Radius"
-#: ../src/backend/filters/ionClip.cpp:537
-#: ../src/backend/filters/compositionProfile.cpp:1067
+#: ../src/backend/filters/ionClip.cpp:530
+#: ../src/backend/filters/compositionProfile.cpp:1013
msgid "Radius of sphere"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:551
+#: ../src/backend/filters/ionClip.cpp:544
msgid "Position that plane passes through"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:556
+#: ../src/backend/filters/ionClip.cpp:549
msgid "Plane Normal"
msgstr "Plane Normal"
-#: ../src/backend/filters/ionClip.cpp:559
+#: ../src/backend/filters/ionClip.cpp:552
msgid "Perpendicular direction for plane"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:573
+#: ../src/backend/filters/ionClip.cpp:566
msgid "Centre of cylinder"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:578
-#: ../src/backend/filters/compositionProfile.cpp:1023
-#: ../src/backend/filters/spatialAnalysis.cpp:607
-#: ../src/backend/filters/transform.cpp:1325
+#: ../src/backend/filters/ionClip.cpp:571
+#: ../src/backend/filters/compositionProfile.cpp:972
+#: ../src/backend/filters/spatialAnalysis.cpp:782
+#: ../src/backend/filters/transform.cpp:1277
msgid "Axis"
msgstr "Achse"
-#: ../src/backend/filters/ionClip.cpp:581
+#: ../src/backend/filters/ionClip.cpp:574
msgid "Positive vector for cylinder"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:589
-#: ../src/backend/filters/compositionProfile.cpp:1034
+#: ../src/backend/filters/ionClip.cpp:579
+#: ../src/backend/filters/compositionProfile.cpp:980
msgid "Lock Axis Mag."
msgstr "Achsen Vergr. sperren"
-#: ../src/backend/filters/ionClip.cpp:592
+#: ../src/backend/filters/ionClip.cpp:582
msgid "Prevent changing length of cylinder during 3D interaction"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:600
-#: ../src/backend/filters/compositionProfile.cpp:1045
-#: ../src/backend/filters/spatialAnalysis.cpp:619
+#: ../src/backend/filters/ionClip.cpp:590
+#: ../src/backend/filters/compositionProfile.cpp:991
+#: ../src/backend/filters/spatialAnalysis.cpp:794
msgid "Radius of cylinder"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:613
+#: ../src/backend/filters/ionClip.cpp:603
msgid "Centre of axis aligned box"
msgstr ""
-#: ../src/backend/filters/ionClip.cpp:618
+#: ../src/backend/filters/ionClip.cpp:608
msgid "Corner offset"
msgstr "Corner offset"
-#: ../src/backend/filters/ionClip.cpp:621
+#: ../src/backend/filters/ionClip.cpp:611
msgid "Vector to corner of box"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:77
-#: ../src/backend/filters/clusterAnalysis.cpp:1017
+#: ../src/backend/filters/clusterAnalysis.cpp:80
+#: ../src/backend/filters/clusterAnalysis.cpp:1045
msgid "Size Distribution"
msgstr "Größenverteilung"
-#: ../src/backend/filters/clusterAnalysis.cpp:78
+#: ../src/backend/filters/clusterAnalysis.cpp:81
msgid "Chemistry Distribution"
msgstr "Chemische Verteilung"
-#: ../src/backend/filters/clusterAnalysis.cpp:491
+#: ../src/backend/filters/clusterAnalysis.cpp:499
msgid "No range data. Can't cluster."
msgstr "Keine Rangedaten. Clusteranalyse nicht möglich."
-#: ../src/backend/filters/clusterAnalysis.cpp:502
+#: ../src/backend/filters/clusterAnalysis.cpp:510
msgid ""
"No ranges selected for cluster \"core\". Cannot continue with clustering."
msgstr ""
"Kein Range für cluster \"core\" ausgewählt. Kann mit Clusteranalyse nicht "
"weitermachen."
-#: ../src/backend/filters/clusterAnalysis.cpp:511
+#: ../src/backend/filters/clusterAnalysis.cpp:519
msgid ""
"No ranges selected for cluster \"bulk\". Cannot continue with clustering."
msgstr ""
"Kein Range für \"bulk\" ausgewählt. Kann mit Clusteranalyse nicht "
"weitermachen."
-#: ../src/backend/filters/clusterAnalysis.cpp:684
-msgid "Morphology Plot"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:685
-msgid "\\lambda_1:\\lambda_2 ratio"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:686
-msgid "\\lambda_2:\\lambda_3 ratio"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:723
-msgid "No clusters had sufficient dimensionality to compute singular values"
-msgstr ""
-
-#: ../src/backend/filters/clusterAnalysis.cpp:780
+#: ../src/backend/filters/clusterAnalysis.cpp:789
msgid "Found :"
msgstr "Gefunden:"
-#: ../src/backend/filters/clusterAnalysis.cpp:782
+#: ../src/backend/filters/clusterAnalysis.cpp:791
msgid " clusters"
msgstr " Cluster"
-#: ../src/backend/filters/clusterAnalysis.cpp:850
+#: ../src/backend/filters/clusterAnalysis.cpp:873
msgid "Compositions (fractional, core+bulk)"
msgstr "Zusammensetzungen (fractional, core+bulk)"
-#: ../src/backend/filters/clusterAnalysis.cpp:852
+#: ../src/backend/filters/clusterAnalysis.cpp:875
msgid "Compositions (fractional, core only)"
msgstr "Zusammensetzungen (fractional, core only)"
-#: ../src/backend/filters/clusterAnalysis.cpp:870
+#: ../src/backend/filters/clusterAnalysis.cpp:893
msgid "Frequencies (core+bulk)"
msgstr "Häufigkeiten (core+bulk)"
-#: ../src/backend/filters/clusterAnalysis.cpp:898
+#: ../src/backend/filters/clusterAnalysis.cpp:924
msgid "Core Link + Erode"
msgstr "Core Link + Erode"
-#: ../src/backend/filters/clusterAnalysis.cpp:902
-#: ../src/backend/filters/spatialAnalysis.cpp:373
-#: ../src/backend/filters/ionInfo.cpp:440
+#: ../src/backend/filters/clusterAnalysis.cpp:928
+#: ../src/backend/filters/clusterAnalysis.cpp:936
+#: ../src/backend/filters/spatialAnalysis.cpp:541
+#: ../src/backend/filters/spatialAnalysis.cpp:549
+#: ../src/backend/filters/transform.cpp:1140
+#: ../src/backend/filters/ionInfo.cpp:441
msgid "Algorithm"
msgstr "Algorithmus"
-#: ../src/backend/filters/clusterAnalysis.cpp:906
+#: ../src/backend/filters/clusterAnalysis.cpp:932
msgid "Cluster algorithm mode"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:915
+#: ../src/backend/filters/clusterAnalysis.cpp:943
msgid "Core Classify"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:918
+#: ../src/backend/filters/clusterAnalysis.cpp:946
msgid ""
"Enable core-classifcation pre-step in clustering (Stephenson et al, 2007)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:924
+#: ../src/backend/filters/clusterAnalysis.cpp:952
msgid "Core Classify Dist"
msgstr "Core Classify Dist"
-#: ../src/backend/filters/clusterAnalysis.cpp:927
+#: ../src/backend/filters/clusterAnalysis.cpp:955
msgid "Restrict only atoms by distance to be cluster sources"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:932
+#: ../src/backend/filters/clusterAnalysis.cpp:960
msgid "Classify Knn Max"
msgstr "Classify Knn Max"
-#: ../src/backend/filters/clusterAnalysis.cpp:935
+#: ../src/backend/filters/clusterAnalysis.cpp:963
msgid ""
"Require that the kth NN (this number) is within the classify distance, to be "
"a cluster source"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:941
+#: ../src/backend/filters/clusterAnalysis.cpp:969
msgid "Core Link Dist"
msgstr "Core Link Dist"
-#: ../src/backend/filters/clusterAnalysis.cpp:944
+#: ../src/backend/filters/clusterAnalysis.cpp:972
msgid "Distance between clusters to allow linking"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:949
+#: ../src/backend/filters/clusterAnalysis.cpp:977
msgid "Bulk Link"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:952
-#: ../src/backend/filters/clusterAnalysis.cpp:970
+#: ../src/backend/filters/clusterAnalysis.cpp:980
+#: ../src/backend/filters/clusterAnalysis.cpp:998
msgid "Enable linking of non-cluster species - eg for composition analysis "
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:959
+#: ../src/backend/filters/clusterAnalysis.cpp:987
msgid "Bulk Link (Envelope) Dist"
msgstr "Bulk Link (Envelope) Dist"
-#: ../src/backend/filters/clusterAnalysis.cpp:962
+#: ../src/backend/filters/clusterAnalysis.cpp:990
msgid ""
"Distance from core points that form cluster that is used to grab surrounding "
"bulk points"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:967
+#: ../src/backend/filters/clusterAnalysis.cpp:995
msgid "Erosion"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:976
+#: ../src/backend/filters/clusterAnalysis.cpp:1004
msgid "Erode Dist"
msgstr "Erode Dist"
-#: ../src/backend/filters/clusterAnalysis.cpp:979
+#: ../src/backend/filters/clusterAnalysis.cpp:1007
msgid ""
"Distance from unclustered material in which bulk points are eroded from "
"cluster"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:985
+#: ../src/backend/filters/clusterAnalysis.cpp:1013
msgid "Clustering Params"
msgstr "Cluster Parameter"
-#: ../src/backend/filters/clusterAnalysis.cpp:990
+#: ../src/backend/filters/clusterAnalysis.cpp:1018
msgid "Size Cropping"
msgstr "Größeneinschrankungen"
-#: ../src/backend/filters/clusterAnalysis.cpp:993
+#: ../src/backend/filters/clusterAnalysis.cpp:1021
msgid "Remove clusters based upon size distribution"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1000
+#: ../src/backend/filters/clusterAnalysis.cpp:1028
msgid "Min Size"
msgstr "Min Größe"
-#: ../src/backend/filters/clusterAnalysis.cpp:1003
+#: ../src/backend/filters/clusterAnalysis.cpp:1031
msgid "Remove clusters below this size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1008
+#: ../src/backend/filters/clusterAnalysis.cpp:1036
msgid "Max Size"
msgstr "Max Größe"
-#: ../src/backend/filters/clusterAnalysis.cpp:1011
+#: ../src/backend/filters/clusterAnalysis.cpp:1039
msgid "Remove clusters above this size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1020
+#: ../src/backend/filters/clusterAnalysis.cpp:1048
msgid "Show number of clusters as a function of cluster size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1026
+#: ../src/backend/filters/clusterAnalysis.cpp:1054
msgid "Log Scale"
msgstr "Log. Skala"
-#: ../src/backend/filters/clusterAnalysis.cpp:1029
+#: ../src/backend/filters/clusterAnalysis.cpp:1057
msgid "Use logarithmic scale for size distribution"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1045
+#: ../src/backend/filters/clusterAnalysis.cpp:1075
+msgid "Cluster Id"
+msgstr ""
+
+#: ../src/backend/filters/clusterAnalysis.cpp:1078
+msgid "Assign cluster output a unique per-cluster value (id)."
+msgstr ""
+
+#: ../src/backend/filters/clusterAnalysis.cpp:1085
msgid "Chemistry Dist."
msgstr "Chemistry Dist."
-#: ../src/backend/filters/clusterAnalysis.cpp:1048
+#: ../src/backend/filters/clusterAnalysis.cpp:1088
msgid "Create a plot showing chemistry for each cluster size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1055
-#: ../src/backend/filters/compositionProfile.cpp:1107
-#: ../src/backend/filters/spatialAnalysis.cpp:674
+#: ../src/backend/filters/clusterAnalysis.cpp:1095
+#: ../src/backend/filters/compositionProfile.cpp:1053
+#: ../src/backend/filters/spatialAnalysis.cpp:849
#: ../src/backend/filters/ionInfo.cpp:412
msgid "Normalise"
msgstr "Normalisieren"
-#: ../src/backend/filters/clusterAnalysis.cpp:1058
+#: ../src/backend/filters/clusterAnalysis.cpp:1098
msgid "Convert cluster counts to composition"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1064
+#: ../src/backend/filters/clusterAnalysis.cpp:1104
msgid "Postprocess"
msgstr "Postprozess"
-#: ../src/backend/filters/clusterAnalysis.cpp:1083
+#: ../src/backend/filters/clusterAnalysis.cpp:1123
msgid "If selected, use as \"core\" ion type (can make clusters)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1088
+#: ../src/backend/filters/clusterAnalysis.cpp:1128
msgid "Core Ranges"
msgstr "Core Ranges"
-#: ../src/backend/filters/clusterAnalysis.cpp:1102
+#: ../src/backend/filters/clusterAnalysis.cpp:1142
msgid ""
"If selected, use as \"bulk\" ion type (can be included in existing clusters)"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1107
+#: ../src/backend/filters/clusterAnalysis.cpp:1147
msgid "Bulk Ranges"
msgstr "Bulk Ranges"
-#: ../src/backend/filters/clusterAnalysis.cpp:1123
+#: ../src/backend/filters/clusterAnalysis.cpp:1163
msgid "Max. Sep + Erode"
msgstr "Max. Sep + Erode"
-#: ../src/backend/filters/clusterAnalysis.cpp:1803
-msgid "Clustering aborted"
-msgstr "Clustering abgebrochen"
-
-#: ../src/backend/filters/clusterAnalysis.cpp:1805
-msgid "No core ions for cluster"
-msgstr "Keine Kernionen für Cluster"
-
-#: ../src/backend/filters/clusterAnalysis.cpp:1807
-msgid "No bulk ions for cluster"
-msgstr "Keine Bulkionen für Cluster"
-
-#: ../src/backend/filters/clusterAnalysis.cpp:1885
+#: ../src/backend/filters/clusterAnalysis.cpp:1891
msgid " --------------------------- Parameter selection notice ------------- "
msgstr " --------------------------- Parameterauswahl Notiz ------------- "
-#: ../src/backend/filters/clusterAnalysis.cpp:1886
+#: ../src/backend/filters/clusterAnalysis.cpp:1892
msgid "You have specified a bulk distance larger than half your link distance."
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1887
+#: ../src/backend/filters/clusterAnalysis.cpp:1893
msgid ""
"You can do this; thats OK, but the output is no longer independent of the "
"computational process;"
@@ -2841,7 +2741,7 @@ msgstr ""
"Sie könne das machen, das ist in Ordnung, aber die Ausgabe ist nicht länger "
"unabhängig vom Berechnungsprozess"
-#: ../src/backend/filters/clusterAnalysis.cpp:1888
+#: ../src/backend/filters/clusterAnalysis.cpp:1894
msgid ""
"This will be a problem in the case where two or more clusters can equally "
"lay claim to a \"bulk\" ion. "
@@ -2849,7 +2749,7 @@ msgstr ""
"Dies ist ein Problem wenn zwei oder mehrere Cluster auf dasselbe \"bulk\" "
"Ion Anspruch erheben. "
-#: ../src/backend/filters/clusterAnalysis.cpp:1889
+#: ../src/backend/filters/clusterAnalysis.cpp:1895
msgid ""
" If your inter-cluster distance is sufficiently large (larger than your bulk "
"linking distance), then you can get away with this."
@@ -2857,7 +2757,7 @@ msgstr ""
" If your inter-cluster distance is sufficiently large (larger than your bulk "
"linking distance), then you can get away with this."
-#: ../src/backend/filters/clusterAnalysis.cpp:1890
+#: ../src/backend/filters/clusterAnalysis.cpp:1896
msgid ""
" In theory it is possible to \"join\" the clusters, but this has not been "
"implemented for speed reasons."
@@ -2865,7 +2765,7 @@ msgstr ""
"Theoretisch ist es möglich die Cluster zu 'verbinden', dies wurde jedoch aus "
"Gescheindigkeitsgründen nicht implementiert."
-#: ../src/backend/filters/clusterAnalysis.cpp:1891
+#: ../src/backend/filters/clusterAnalysis.cpp:1897
msgid ""
"If you want this, please contact the author, or just use the source to add "
"this in yourself."
@@ -2873,752 +2773,773 @@ msgstr ""
"Sollten Sie dies wollen, kontaktieren Sie den Autor oder verwenden Sie den "
"Sourcecode um es selbst hinzuzufügen."
-#: ../src/backend/filters/clusterAnalysis.cpp:1892
+#: ../src/backend/filters/clusterAnalysis.cpp:1898
msgid "---------------------------------------------------------------------- "
msgstr "---------------------------------------------------------------------- "
-#: ../src/backend/filters/clusterAnalysis.cpp:1902
-#: ../src/backend/filters/spatialAnalysis.cpp:1757
-#: ../src/backend/filters/spatialAnalysis.cpp:2084
-#: ../src/backend/filters/spatialAnalysis.cpp:2382
-#: ../src/backend/filters/spatialAnalysis.cpp:3078
-#: ../src/backend/filters/transform.cpp:1033
+#: ../src/backend/filters/clusterAnalysis.cpp:1908
+#: ../src/backend/filters/spatialAnalysis.cpp:1971
+#: ../src/backend/filters/spatialAnalysis.cpp:2314
+#: ../src/backend/filters/spatialAnalysis.cpp:2605
+#: ../src/backend/filters/spatialAnalysis.cpp:3293
+#: ../src/backend/filters/transform.cpp:991
msgid "Collate"
msgstr "Abgleichen"
-#: ../src/backend/filters/clusterAnalysis.cpp:1921
+#: ../src/backend/filters/clusterAnalysis.cpp:1927
msgid "Build Core"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:1939
+#: ../src/backend/filters/clusterAnalysis.cpp:1945
msgid "Classify Core"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2032
+#: ../src/backend/filters/clusterAnalysis.cpp:2038
msgid "Build Bulk"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2052
+#: ../src/backend/filters/clusterAnalysis.cpp:2058
msgid "Core"
msgstr "Kern"
-#: ../src/backend/filters/clusterAnalysis.cpp:2197
+#: ../src/backend/filters/clusterAnalysis.cpp:2203
msgid "Bulk"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2327
+#: ../src/backend/filters/clusterAnalysis.cpp:2333
msgid "Erode"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2401
+#: ../src/backend/filters/clusterAnalysis.cpp:2407
msgid "Re-Collate"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2669
-#: ../src/backend/filters/clusterAnalysis.cpp:2873
+#: ../src/backend/filters/clusterAnalysis.cpp:2675
+#: ../src/backend/filters/clusterAnalysis.cpp:2879
msgid "Cluster Size"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2670
-#: ../src/backend/filters/clusterAnalysis.cpp:2877
+#: ../src/backend/filters/clusterAnalysis.cpp:2676
+#: ../src/backend/filters/clusterAnalysis.cpp:2883
msgid "Frequency"
msgstr ""
-#: ../src/backend/filters/clusterAnalysis.cpp:2875
+#: ../src/backend/filters/clusterAnalysis.cpp:2881
msgid "Composition"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:109
+#: ../src/backend/filters/voxelise.cpp:110
msgid "None (Raw count)"
msgstr "Keine (Roh count)"
-#: ../src/backend/filters/voxelise.cpp:110
+#: ../src/backend/filters/voxelise.cpp:111
msgid "Volume (Density)"
msgstr "Volumen (Dichte)"
-#: ../src/backend/filters/voxelise.cpp:111
+#: ../src/backend/filters/voxelise.cpp:112
msgid "All Ions (conc)"
msgstr "Alle Ionen (Konz)"
-#: ../src/backend/filters/voxelise.cpp:112
+#: ../src/backend/filters/voxelise.cpp:113
msgid "Ratio (Num/Denom)"
msgstr "Verhältnis (Zähler/Nenner)"
-#: ../src/backend/filters/voxelise.cpp:116
+#: ../src/backend/filters/voxelise.cpp:117
msgid "Point Cloud"
msgstr "Punktwolke"
-#: ../src/backend/filters/voxelise.cpp:117
+#: ../src/backend/filters/voxelise.cpp:118
msgid "Isosurface"
msgstr "Isosurface"
-#: ../src/backend/filters/voxelise.cpp:118
+#: ../src/backend/filters/voxelise.cpp:119
msgid "Axial slice"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:123
+#: ../src/backend/filters/voxelise.cpp:124
msgid "Gaussian (2𝜎)"
msgstr "Gauss (2𝜎)"
-#: ../src/backend/filters/voxelise.cpp:127
+#: ../src/backend/filters/voxelise.cpp:128
msgid "Zero"
msgstr "Null"
-#: ../src/backend/filters/voxelise.cpp:128
+#: ../src/backend/filters/voxelise.cpp:129
msgid "Bounce"
msgstr "Bounce"
-#: ../src/backend/filters/voxelise.cpp:133
+#: ../src/backend/filters/voxelise.cpp:134
msgid "Linear"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:604
+#: ../src/backend/filters/voxelise.cpp:601
msgid "Voxel Limits (min,max): ("
msgstr "Voxel Grenzen (min,max): ("
-#: ../src/backend/filters/voxelise.cpp:754
+#: ../src/backend/filters/voxelise.cpp:751
msgid "Fixed width"
msgstr "Fixe Breite"
-#: ../src/backend/filters/voxelise.cpp:758
+#: ../src/backend/filters/voxelise.cpp:755
msgid "If true, use fixed size voxels, otherwise use fixed count"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:764
+#: ../src/backend/filters/voxelise.cpp:761
msgid "Bin width x"
msgstr "Bin-Breite x"
-#: ../src/backend/filters/voxelise.cpp:768
+#: ../src/backend/filters/voxelise.cpp:765
msgid "Voxel size in X direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:772
+#: ../src/backend/filters/voxelise.cpp:769
msgid "Bin width y"
msgstr "Bin-Breite y"
-#: ../src/backend/filters/voxelise.cpp:775
+#: ../src/backend/filters/voxelise.cpp:772
msgid "Voxel size in Y direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:781
+#: ../src/backend/filters/voxelise.cpp:778
msgid "Bin width z"
msgstr "Bin-Breite Z"
-#: ../src/backend/filters/voxelise.cpp:784
+#: ../src/backend/filters/voxelise.cpp:781
msgid "Voxel size in Z direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:791
+#: ../src/backend/filters/voxelise.cpp:788
msgid "Num bins x"
msgstr "Anzahl Bins x"
-#: ../src/backend/filters/voxelise.cpp:795
+#: ../src/backend/filters/voxelise.cpp:792
msgid "Number of voxels to use in X direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:800
+#: ../src/backend/filters/voxelise.cpp:797
msgid "Num bins y"
msgstr "Anzahl Bins y"
-#: ../src/backend/filters/voxelise.cpp:803
+#: ../src/backend/filters/voxelise.cpp:800
msgid "Number of voxels to use in Y direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:809
+#: ../src/backend/filters/voxelise.cpp:806
msgid "Num bins z"
msgstr "Anzahl Bins z"
-#: ../src/backend/filters/voxelise.cpp:811
+#: ../src/backend/filters/voxelise.cpp:808
msgid "Number of voxels to use in Z direction"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:832
+#: ../src/backend/filters/voxelise.cpp:838
msgid "Normalise by"
msgstr "Normalisieren mit"
-#: ../src/backend/filters/voxelise.cpp:835
+#: ../src/backend/filters/voxelise.cpp:841
msgid "Method to use to normalise scalar value in each voxel"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:838
+#: ../src/backend/filters/voxelise.cpp:844
msgid "Computation"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:845
+#: ../src/backend/filters/voxelise.cpp:851
msgid "Numerator"
msgstr "Zähler"
-#: ../src/backend/filters/voxelise.cpp:848
+#: ../src/backend/filters/voxelise.cpp:854
msgid "Parmeter \"a\" used in fraction (a/b) to get voxel value"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:868
+#: ../src/backend/filters/voxelise.cpp:871
msgid "Enable this ion for numerator"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:879
+#: ../src/backend/filters/voxelise.cpp:883
msgid "Denominator"
msgstr "Nenner"
-#: ../src/backend/filters/voxelise.cpp:882
+#: ../src/backend/filters/voxelise.cpp:886
msgid "Parameter \"b\" used in fraction (a/b) to get voxel value"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:898
+#: ../src/backend/filters/voxelise.cpp:899
msgid "Enable this ion for denominator contribution"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:919
-#: ../src/backend/filters/voxelise.cpp:954
+#: ../src/backend/filters/voxelise.cpp:920
+#: ../src/backend/filters/voxelise.cpp:955
msgid "Filtering"
msgstr "Filtern"
-#: ../src/backend/filters/voxelise.cpp:923
+#: ../src/backend/filters/voxelise.cpp:924
msgid "Smoothing method to use on voxels"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:926
+#: ../src/backend/filters/voxelise.cpp:927
msgid "Processing"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:932
+#: ../src/backend/filters/voxelise.cpp:933
msgid "Kernel Bins"
msgstr "Kernel Bins"
-#: ../src/backend/filters/voxelise.cpp:936
+#: ../src/backend/filters/voxelise.cpp:937
msgid "Number of bins in convolution kernel"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:947
+#: ../src/backend/filters/voxelise.cpp:948
msgid "Exterior values"
msgstr "Exterior values"
-#: ../src/backend/filters/voxelise.cpp:950
+#: ../src/backend/filters/voxelise.cpp:951
msgid "Method to use to treat boundaries of voxel data for convolution"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:970
+#: ../src/backend/filters/voxelise.cpp:971
msgid "Representation"
msgstr "Representation"
-#: ../src/backend/filters/voxelise.cpp:973
+#: ../src/backend/filters/voxelise.cpp:974
msgid "3D display method"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:984
+#: ../src/backend/filters/voxelise.cpp:985
msgid "Spot size"
msgstr "Spot size"
-#: ../src/backend/filters/voxelise.cpp:987
+#: ../src/backend/filters/voxelise.cpp:988
msgid "Size of the spots to use for display"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:992
-#: ../src/backend/filters/voxelise.cpp:1030
+#: ../src/backend/filters/voxelise.cpp:993
+#: ../src/backend/filters/voxelise.cpp:1028
msgid "Transparency"
msgstr "Transparenz"
-#: ../src/backend/filters/voxelise.cpp:995
+#: ../src/backend/filters/voxelise.cpp:996
msgid "How \"see through\" each point is (0 - opaque, 1 - invisible)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1004
+#: ../src/backend/filters/voxelise.cpp:1005
msgid "Surf. param."
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1007
+#: ../src/backend/filters/voxelise.cpp:1008
msgid "Isovalue"
msgstr "Isovalue"
-#: ../src/backend/filters/voxelise.cpp:1010
+#: ../src/backend/filters/voxelise.cpp:1011
msgid "Scalar value to show as isosurface"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1025
+#: ../src/backend/filters/voxelise.cpp:1016
+#: ../src/backend/filters/voxelise.cpp:1081
+#: ../src/backend/filters/spatialAnalysis.cpp:2019
+#: ../src/backend/filters/spatialAnalysis.cpp:2073
+msgid "Surface"
+msgstr "Oberfläche"
+
+#: ../src/backend/filters/voxelise.cpp:1023
msgid "Colour of isosurface"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1033
+#: ../src/backend/filters/voxelise.cpp:1031
msgid "How \"see through\" each facet is (0 - opaque, 1 - invisible)"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1045
+#: ../src/backend/filters/voxelise.cpp:1042
msgid "Slice param."
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1053
+#: ../src/backend/filters/voxelise.cpp:1050
msgid "Slice Axis"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1056
+#: ../src/backend/filters/voxelise.cpp:1053
msgid "Normal for the planar slice"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1063
+#: ../src/backend/filters/voxelise.cpp:1060
msgid "Slice Coord"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1066
+#: ../src/backend/filters/voxelise.cpp:1063
msgid "Fractional coordinate that slice plane passes through"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1071
+#: ../src/backend/filters/voxelise.cpp:1068
msgid "Interp. Mode"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1079
+#: ../src/backend/filters/voxelise.cpp:1076
msgid "Interpolation mode for direction normal to slice"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1094
+#: ../src/backend/filters/voxelise.cpp:1092
msgid "Colour mode"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1097
-#: ../src/backend/filters/ionColour.cpp:262
+#: ../src/backend/filters/voxelise.cpp:1095
+#: ../src/backend/filters/ionColour.cpp:265
msgid "Colour scheme used to assign points colours by value"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1106
-#: ../src/backend/filters/ionColour.cpp:274
+#: ../src/backend/filters/voxelise.cpp:1100
+#: ../src/backend/filters/ionColour.cpp:277
msgid "Show Bar"
msgstr "Zeige Balken"
-#: ../src/backend/filters/voxelise.cpp:1116
+#: ../src/backend/filters/voxelise.cpp:1107
msgid "Auto Bounds"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1117
+#: ../src/backend/filters/voxelise.cpp:1108
msgid "Auto-compute min/max values in map"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1127
-#: ../src/backend/filters/ionColour.cpp:289
+#: ../src/backend/filters/voxelise.cpp:1118
+#: ../src/backend/filters/ionColour.cpp:298
msgid "Map start"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1128
-#: ../src/backend/filters/ionColour.cpp:290
+#: ../src/backend/filters/voxelise.cpp:1119
+#: ../src/backend/filters/ionColour.cpp:299
msgid "Assign points with this value to the first colour in map"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1135
-#: ../src/backend/filters/ionColour.cpp:297
+#: ../src/backend/filters/voxelise.cpp:1126
+#: ../src/backend/filters/ionColour.cpp:306
msgid "Map end"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1136
-#: ../src/backend/filters/ionColour.cpp:298
+#: ../src/backend/filters/voxelise.cpp:1127
+#: ../src/backend/filters/ionColour.cpp:307
msgid "Assign points with this value to the last colour in map"
msgstr ""
-#: ../src/backend/filters/voxelise.cpp:1707
-msgid "Voxelisation aborted"
-msgstr "Voxelisation abgebrochen"
-
-#: ../src/backend/filters/voxelise.cpp:1709
-msgid "Out of memory"
-msgstr "Zu wenig Speicher"
-
-#: ../src/backend/filters/voxelise.cpp:1711
-msgid "Unable to perform filter convolution"
-msgstr "Kann Filter convolution nicht durchführen"
-
-#: ../src/backend/filters/voxelise.cpp:1713
-msgid "Voxelisation bounds are invalid"
-msgstr "Voxelisation Grenzen sin ungültig"
-
-#: ../src/backend/filters/ionColour.cpp:258
+#: ../src/backend/filters/ionColour.cpp:261
msgid "Colour Map"
msgstr "Farbtabelle"
-#: ../src/backend/filters/ionColour.cpp:266
+#: ../src/backend/filters/ionColour.cpp:269
msgid "Reverse map"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:267
+#: ../src/backend/filters/ionColour.cpp:270
msgid "Reverse the colour scale"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:281
+#: ../src/backend/filters/ionColour.cpp:283
+msgid "Opacity"
+msgstr ""
+
+#: ../src/backend/filters/ionColour.cpp:290
msgid "Num Colours"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:283
+#: ../src/backend/filters/ionColour.cpp:292
msgid "Number of unique colours to use in colour map"
msgstr ""
-#: ../src/backend/filters/ionColour.cpp:416
-#: ../src/backend/filters/transform.cpp:1579
-#: ../src/backend/filters/ionInfo.cpp:541
+#: ../src/backend/filters/ionColour.cpp:413
msgid "Aborted"
msgstr "Abgebrochen"
-#: ../src/backend/filters/compositionProfile.cpp:536
+#: ../src/backend/filters/compositionProfile.cpp:568
msgid "Distance"
msgstr "Abstand"
-#: ../src/backend/filters/compositionProfile.cpp:544
+#: ../src/backend/filters/compositionProfile.cpp:576
msgid "Fraction"
msgstr "Anteil"
-#: ../src/backend/filters/compositionProfile.cpp:546
+#: ../src/backend/filters/compositionProfile.cpp:578
msgid "Density (\\frac{\\#}{len^3})"
msgstr "Dichte (\\frac{\\#}{len^3})"
-
-#: ../src/backend/filters/compositionProfile.cpp:573
+#: ../src/backend/filters/compositionProfile.cpp:605
msgid "Freq. Profile"
msgstr "Häufigkeitsprofil"
-#: ../src/backend/filters/compositionProfile.cpp:641
-msgid "Too many bins in comp. profile."
-msgstr "Zu viele Bins im Konzentrationsprofil."
-
-#: ../src/backend/filters/compositionProfile.cpp:643
-msgid "Not enough memory for comp. profile."
-msgstr "Nicht genug Speicher für Konz.-Profil."
-
-#: ../src/backend/filters/compositionProfile.cpp:645
-msgid "Aborted composition prof."
-msgstr "Konzentrationspr. abgebr."
+#: ../src/backend/filters/compositionProfile.cpp:657
+msgid "No data remained in profile - cannot display result"
+msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:989
+#: ../src/backend/filters/compositionProfile.cpp:937
msgid "Primitive type"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:993
+#: ../src/backend/filters/compositionProfile.cpp:941
msgid "Basic shape to use for profile"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1004
+#: ../src/backend/filters/compositionProfile.cpp:953
msgid "Display the 3D composition profile interaction object"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1018
-#: ../src/backend/filters/spatialAnalysis.cpp:602
+#: ../src/backend/filters/compositionProfile.cpp:967
+#: ../src/backend/filters/spatialAnalysis.cpp:777
msgid "Position for centre of cylinder"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1026
+#: ../src/backend/filters/compositionProfile.cpp:975
msgid "Vector between ends of cylinder"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1037
+#: ../src/backend/filters/compositionProfile.cpp:983
msgid "Prevent length of cylinder changing during interaction"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1077
+#: ../src/backend/filters/compositionProfile.cpp:1023
msgid "Fixed Bin Num"
msgstr "Fix. Bin-Anz."
-#: ../src/backend/filters/compositionProfile.cpp:1080
+#: ../src/backend/filters/compositionProfile.cpp:1026
msgid ""
"If true, use a fixed number of bins for profile, otherwise use fixed step "
"size"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1086
-#: ../src/backend/filters/spatialAnalysis.cpp:433
-#: ../src/backend/filters/spatialAnalysis.cpp:575
+#: ../src/backend/filters/compositionProfile.cpp:1032
+#: ../src/backend/filters/spatialAnalysis.cpp:612
+#: ../src/backend/filters/spatialAnalysis.cpp:754
msgid "Num Bins"
msgstr "Bin-Anz."
-#: ../src/backend/filters/compositionProfile.cpp:1091
+#: ../src/backend/filters/compositionProfile.cpp:1037
msgid "Number of bins to use for profile"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1096
-#: ../src/backend/filters/spectrumPlot.cpp:396
+#: ../src/backend/filters/compositionProfile.cpp:1042
+#: ../src/backend/filters/spectrumPlot.cpp:386
msgid "Bin width"
msgstr "Bin-Breite"
-#: ../src/backend/filters/compositionProfile.cpp:1102
+#: ../src/backend/filters/compositionProfile.cpp:1048
msgid "Size of each bin in profile"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1111
+#: ../src/backend/filters/compositionProfile.cpp:1057
msgid "Convert bin counts into relative frequencies in each bin"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1115
+#: ../src/backend/filters/compositionProfile.cpp:1061
msgid "Min. events"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1119
+#: ../src/backend/filters/compositionProfile.cpp:1065
msgid "Drop data that does not have this many events"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1143
-#: ../src/backend/filters/spectrumPlot.cpp:459
+#: ../src/backend/filters/compositionProfile.cpp:1068
+msgid "Settings"
+msgstr ""
+
+#: ../src/backend/filters/compositionProfile.cpp:1090
+#: ../src/backend/filters/spectrumPlot.cpp:445
msgid "Plot Type"
msgstr "Plot Type"
-#: ../src/backend/filters/compositionProfile.cpp:1146
+#: ../src/backend/filters/compositionProfile.cpp:1093
msgid "Visual style for plot"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1159
+#: ../src/backend/filters/compositionProfile.cpp:1103
msgid "Colour of plot"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1175
+#: ../src/backend/filters/compositionProfile.cpp:1119
msgid "Err. Estimator"
msgstr "Fehlerschätzer"
-#: ../src/backend/filters/compositionProfile.cpp:1178
+#: ../src/backend/filters/compositionProfile.cpp:1122
msgid "Method of estimating error associated with each bin"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1185
+#: ../src/backend/filters/compositionProfile.cpp:1129
msgid "Avg. Window"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1188
+#: ../src/backend/filters/compositionProfile.cpp:1132
msgid "Number of bins to include in moving average filter"
msgstr ""
-#: ../src/backend/filters/compositionProfile.cpp:1192
+#: ../src/backend/filters/compositionProfile.cpp:1136
msgid "Error analysis"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:84
+#: ../src/backend/filters/spatialAnalysis.cpp:101
msgid "Local Density"
msgstr "Lokale Dichte"
-#: ../src/backend/filters/spatialAnalysis.cpp:85
+#: ../src/backend/filters/spatialAnalysis.cpp:102
msgid "Density Filtering"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:86
+#: ../src/backend/filters/spatialAnalysis.cpp:103
msgid "Radial Distribution"
msgstr "Radial Distribution"
-#: ../src/backend/filters/spatialAnalysis.cpp:87
+#: ../src/backend/filters/spatialAnalysis.cpp:104
msgid "Axial Distribution"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:88
+#: ../src/backend/filters/spatialAnalysis.cpp:105
msgid "Binomial Distribution"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:92
+#: ../src/backend/filters/spatialAnalysis.cpp:106
+msgid "Point Em/Replacement"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:110
msgid "Neighbour Count"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:376
+#: ../src/backend/filters/spatialAnalysis.cpp:544
msgid "Spatial analysis algorithm to use"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:398
+#: ../src/backend/filters/spatialAnalysis.cpp:567
msgid "Stop Mode"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:401
+#: ../src/backend/filters/spatialAnalysis.cpp:570
msgid "Method to use to terminate algorithm when examining each point"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:408
+#: ../src/backend/filters/spatialAnalysis.cpp:577
msgid "NN Max"
msgstr "NN Max"
-#: ../src/backend/filters/spatialAnalysis.cpp:411
+#: ../src/backend/filters/spatialAnalysis.cpp:580
msgid "Maximum number of neighbours to examine"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:417
+#: ../src/backend/filters/spatialAnalysis.cpp:586
+msgid "Normalise bins"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:589
+msgid ""
+"Normalise counts by binwidth. Needed when comparing NN histograms against "
+"one another"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:596
msgid "Dist Max"
msgstr "Abst. Max."
-#: ../src/backend/filters/spatialAnalysis.cpp:420
+#: ../src/backend/filters/spatialAnalysis.cpp:599
msgid "Maximum distance from each point for search"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:436
-#: ../src/backend/filters/spatialAnalysis.cpp:578
+#: ../src/backend/filters/spatialAnalysis.cpp:615
+#: ../src/backend/filters/spatialAnalysis.cpp:757
msgid "Number of bins for output 1D RDF plot"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:442
+#: ../src/backend/filters/spatialAnalysis.cpp:621
msgid "Surface Remove"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:445
+#: ../src/backend/filters/spatialAnalysis.cpp:624
msgid ""
"Exclude surface as part of source to minimise bias in RDF (at cost of "
"increased noise)"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:452
+#: ../src/backend/filters/spatialAnalysis.cpp:631
msgid "Remove Dist"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:455
+#: ../src/backend/filters/spatialAnalysis.cpp:634
msgid "Minimum distance to remove from surface"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:466
-#: ../src/backend/filters/spatialAnalysis.cpp:587
+#: ../src/backend/filters/spatialAnalysis.cpp:642
+#: ../src/backend/filters/spatialAnalysis.cpp:762
msgid "Plot colour "
msgstr "Plotfarbe "
-#: ../src/backend/filters/spatialAnalysis.cpp:469
-#: ../src/backend/filters/spatialAnalysis.cpp:590
+#: ../src/backend/filters/spatialAnalysis.cpp:645
+#: ../src/backend/filters/spatialAnalysis.cpp:765
msgid "Colour of output plot"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:488
+#: ../src/backend/filters/spatialAnalysis.cpp:649
+#: ../src/backend/filters/spatialAnalysis.cpp:743
+#: ../src/backend/filters/spatialAnalysis.cpp:748
+#: ../src/backend/filters/spatialAnalysis.cpp:797
+#: ../src/backend/filters/spatialAnalysis.cpp:836
+msgid "Alg. Params."
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:665
msgid "Source"
msgstr "Quelle"
-#: ../src/backend/filters/spatialAnalysis.cpp:491
+#: ../src/backend/filters/spatialAnalysis.cpp:668
msgid "Ions to use for initiating RDF search"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:504
+#: ../src/backend/filters/spatialAnalysis.cpp:681
msgid "Enable/disable ion as source"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:521
+#: ../src/backend/filters/spatialAnalysis.cpp:687
+msgid "Source Ion"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:700
msgid "Enable/disable all ions as target"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:533
+#: ../src/backend/filters/spatialAnalysis.cpp:712
msgid "Enable/disable this ion as target"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:541
-#: ../src/backend/filters/spatialAnalysis.cpp:564
-#: ../src/backend/filters/spatialAnalysis.cpp:569
-#: ../src/backend/filters/spatialAnalysis.cpp:622
-#: ../src/backend/filters/spatialAnalysis.cpp:661
-msgid "Alg. Params."
+#: ../src/backend/filters/spatialAnalysis.cpp:717
+msgid "Target Ion"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:548
+#: ../src/backend/filters/spatialAnalysis.cpp:727
msgid "Cutoff"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:551
+#: ../src/backend/filters/spatialAnalysis.cpp:730
msgid "Remove points with local density above/below this value"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:557
+#: ../src/backend/filters/spatialAnalysis.cpp:736
msgid "Retain Upper"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:560
+#: ../src/backend/filters/spatialAnalysis.cpp:739
msgid "Retain either points with density above (enabled) or below cutoff"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:610
+#: ../src/backend/filters/spatialAnalysis.cpp:785
msgid "Vector between centre and end of cylinder"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:629
-#: ../src/backend/filters/spatialAnalysis.cpp:3217
-#: ../src/backend/filters/spatialAnalysis.cpp:3286
+#: ../src/backend/filters/spatialAnalysis.cpp:804
+#: ../src/backend/filters/spatialAnalysis.cpp:3432
+#: ../src/backend/filters/spatialAnalysis.cpp:3491
msgid "Block size"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:632
+#: ../src/backend/filters/spatialAnalysis.cpp:807
msgid "Number of ions to use per block"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:639
+#: ../src/backend/filters/spatialAnalysis.cpp:814
msgid "Max Block Aspect"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:642
+#: ../src/backend/filters/spatialAnalysis.cpp:817
msgid ""
"Maximum allowable block aspect ratio. Blocks above this aspect are "
"discarded. Setting too high decreases correlation strength. Too low causes "
"loss of statistical power."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:653
+#: ../src/backend/filters/spatialAnalysis.cpp:828
msgid "Extrusion Direction"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:656
+#: ../src/backend/filters/spatialAnalysis.cpp:831
msgid "Direction in which blocks are extended during construction."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:665
+#: ../src/backend/filters/spatialAnalysis.cpp:840
msgid "Plot Counts"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:668
+#: ../src/backend/filters/spatialAnalysis.cpp:843
msgid "Show the counts in the binomial histogram"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:677
+#: ../src/backend/filters/spatialAnalysis.cpp:852
msgid ""
"Normalise the counts in the binomial histogram to a probability density "
"function"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:691
+#: ../src/backend/filters/spatialAnalysis.cpp:866
msgid "Display Grid"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:700
+#: ../src/backend/filters/spatialAnalysis.cpp:875
msgid "View Options"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1227
-msgid "Spatial analysis aborted by user"
-msgstr "Spatial analysis aborted by user"
+#: ../src/backend/filters/spatialAnalysis.cpp:881
+msgid "Data File"
+msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1229
-msgid "Insufficient data to complete analysis."
-msgstr "Ungenügend Daten zum Fertigstellen der Analyse."
+#: ../src/backend/filters/spatialAnalysis.cpp:885
+msgid "Pos file of points to subtract/replace/etc"
+msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1231
-msgid "Insufficient bins in histogram for analysis."
+#: ../src/backend/filters/spatialAnalysis.cpp:890
+msgid "Match Tol."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1233
-msgid "Insufficient memory for binomial. Reduce input size?"
+#: ../src/backend/filters/spatialAnalysis.cpp:893
+msgid "Tolerance to allow for matching"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1235
-msgid "Binomial requires a parent range file"
+#: ../src/backend/filters/spatialAnalysis.cpp:909
+msgid "Replacment condition"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1791
-#: ../src/backend/filters/spatialAnalysis.cpp:1843
-#: ../src/backend/filters/spatialAnalysis.cpp:2090
-#: ../src/backend/filters/spatialAnalysis.cpp:2388
-#: ../src/backend/filters/spatialAnalysis.cpp:2920
-msgid "Build"
+#: ../src/backend/filters/spatialAnalysis.cpp:915
+msgid "Replace value"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1803
-#: ../src/backend/filters/spatialAnalysis.cpp:1855
-msgid "Surface"
-msgstr "Oberfläche"
+#: ../src/backend/filters/spatialAnalysis.cpp:918
+msgid "Use value data from file when replacing ions"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:923
+msgid "Replacement"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:2005
+#: ../src/backend/filters/spatialAnalysis.cpp:2059
+#: ../src/backend/filters/spatialAnalysis.cpp:2320
+#: ../src/backend/filters/spatialAnalysis.cpp:2611
+#: ../src/backend/filters/spatialAnalysis.cpp:3136
+msgid "Build"
+msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:1895
-#: ../src/backend/filters/spatialAnalysis.cpp:2117
-#: ../src/backend/filters/spatialAnalysis.cpp:2415
+#: ../src/backend/filters/spatialAnalysis.cpp:2113
+#: ../src/backend/filters/spatialAnalysis.cpp:2347
+#: ../src/backend/filters/spatialAnalysis.cpp:2638
msgid "Analyse"
msgstr "Analyse"
-#: ../src/backend/filters/spatialAnalysis.cpp:1952
-#: ../src/backend/filters/spatialAnalysis.cpp:2021
+#: ../src/backend/filters/spatialAnalysis.cpp:2195
+#: ../src/backend/filters/spatialAnalysis.cpp:2258
msgid "Radial Distance"
msgstr "Radialer Abstand"
-#: ../src/backend/filters/spatialAnalysis.cpp:1956
+#: ../src/backend/filters/spatialAnalysis.cpp:2197
+msgid "Count/Distance"
+msgstr ""
+
+#: ../src/backend/filters/spatialAnalysis.cpp:2202
msgid "NN Freq."
msgstr "NN Freq."
-#: ../src/backend/filters/spatialAnalysis.cpp:2012
+#: ../src/backend/filters/spatialAnalysis.cpp:2249
msgid "Warning, "
msgstr "Warnung, "
-#: ../src/backend/filters/spatialAnalysis.cpp:2013
+#: ../src/backend/filters/spatialAnalysis.cpp:2250
msgid ""
" points were unable to find neighbour points that exceeded the search "
"radius, and thus terminated prematurely"
@@ -3626,219 +3547,215 @@ msgstr ""
" Punkte konnten keine Nachbapunkte die den Suchradius überschritten finden "
"und beendeten vorzeitig."
-#: ../src/backend/filters/spatialAnalysis.cpp:2023
+#: ../src/backend/filters/spatialAnalysis.cpp:2260
msgid " RDF"
msgstr " RDF"
-#: ../src/backend/filters/spatialAnalysis.cpp:2313
-#: ../src/backend/filters/spatialAnalysis.cpp:2621
+#: ../src/backend/filters/spatialAnalysis.cpp:2543
+#: ../src/backend/filters/spatialAnalysis.cpp:2844
msgid "Number Density (\\#/Vol^3)"
msgstr "Number Density (\\#/Vol^3)"
-#: ../src/backend/filters/spatialAnalysis.cpp:2342
-#: ../src/backend/filters/spatialAnalysis.cpp:2648
+#: ../src/backend/filters/spatialAnalysis.cpp:2565
+#: ../src/backend/filters/spatialAnalysis.cpp:2864
msgid "Warning,"
msgstr "Warnung,"
-#: ../src/backend/filters/spatialAnalysis.cpp:2343
-#: ../src/backend/filters/spatialAnalysis.cpp:2649
+#: ../src/backend/filters/spatialAnalysis.cpp:2566
+#: ../src/backend/filters/spatialAnalysis.cpp:2865
msgid " points were un-analysable. These have been dropped"
msgstr " points were un-analysable. These have been dropped"
-#: ../src/backend/filters/spatialAnalysis.cpp:2365
-#: ../src/backend/filters/spatialAnalysis.cpp:2671
+#: ../src/backend/filters/spatialAnalysis.cpp:2588
+#: ../src/backend/filters/spatialAnalysis.cpp:2887
msgid "And so on..."
msgstr "Und so weiter..."
-#: ../src/backend/filters/spatialAnalysis.cpp:2754
+#: ../src/backend/filters/spatialAnalysis.cpp:2970
msgid "Extract"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2829
+#: ../src/backend/filters/spatialAnalysis.cpp:3045
msgid "Reduce"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2937
+#: ../src/backend/filters/spatialAnalysis.cpp:3155
msgid "Compute"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:2965
+#: ../src/backend/filters/spatialAnalysis.cpp:3200
msgid "Insufficient points to complete analysis"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3001
+#: ../src/backend/filters/spatialAnalysis.cpp:3223
msgid "Axial Distance"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3003
+#: ../src/backend/filters/spatialAnalysis.cpp:3225
msgid " 1D Dist. Func."
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3087
+#: ../src/backend/filters/spatialAnalysis.cpp:3302
msgid "Binomial"
msgstr ""
-#: ../src/backend/filters/spatialAnalysis.cpp:3219
-#: ../src/backend/filters/spatialAnalysis.cpp:3288
+#: ../src/backend/filters/spatialAnalysis.cpp:3434
+#: ../src/backend/filters/spatialAnalysis.cpp:3493
msgid "Rel. Frequency"
msgstr ""
-#: ../src/backend/filters/transform.cpp:77
+#: ../src/backend/filters/transform.cpp:78
msgid "Translate"
msgstr "Translate"
-#: ../src/backend/filters/transform.cpp:78
+#: ../src/backend/filters/transform.cpp:79
msgid "Scale (isotropic)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:79
+#: ../src/backend/filters/transform.cpp:80
msgid "Scale (anisotropic)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:80
+#: ../src/backend/filters/transform.cpp:81
msgid "Rotate"
msgstr "Rotieren"
-#: ../src/backend/filters/transform.cpp:81
+#: ../src/backend/filters/transform.cpp:82
msgid "Value Shuffle"
msgstr ""
-#: ../src/backend/filters/transform.cpp:82
+#: ../src/backend/filters/transform.cpp:83
msgid "Spatial Noise"
msgstr ""
-#: ../src/backend/filters/transform.cpp:83
+#: ../src/backend/filters/transform.cpp:84
msgid "Translate Value"
msgstr "Translate Wert"
-#: ../src/backend/filters/transform.cpp:87
+#: ../src/backend/filters/transform.cpp:88
msgid "Specify"
msgstr "Angeben"
-#: ../src/backend/filters/transform.cpp:88
+#: ../src/backend/filters/transform.cpp:89
msgid "Boundbox Centre"
msgstr "Boundbox Zentrum"
-#: ../src/backend/filters/transform.cpp:89
+#: ../src/backend/filters/transform.cpp:90
msgid "Mass Centre"
msgstr "Massen-Zentrum"
-#: ../src/backend/filters/transform.cpp:1052
+#: ../src/backend/filters/transform.cpp:1010
msgid "Mass-to-Charge (amu/e)"
msgstr "Masse-zu-Ladung (amu/e)"
-#: ../src/backend/filters/transform.cpp:1106
+#: ../src/backend/filters/transform.cpp:1064
msgid "Shuffle"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1130
+#: ../src/backend/filters/transform.cpp:1088
msgid "Splice"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1185
+#: ../src/backend/filters/transform.cpp:1136
msgid "Algorithm to use to transform point data"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1201
+#: ../src/backend/filters/transform.cpp:1153
msgid "Origin mode"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1204
+#: ../src/backend/filters/transform.cpp:1156
msgid "Select how transform origin is computed"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1209
+#: ../src/backend/filters/transform.cpp:1161
msgid "Show marker"
msgstr "Zeige Markierung"
-#: ../src/backend/filters/transform.cpp:1213
+#: ../src/backend/filters/transform.cpp:1165
msgid "Display an interactive object to set transform origin"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1215
+#: ../src/backend/filters/transform.cpp:1167
msgid "Display a small marker to denote transform origin"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1231
+#: ../src/backend/filters/transform.cpp:1183
msgid "Translation"
msgstr "Translation"
-#: ../src/backend/filters/transform.cpp:1234
+#: ../src/backend/filters/transform.cpp:1186
msgid "Translation vector for transform"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1246
+#: ../src/backend/filters/transform.cpp:1198
msgid "Offset"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1250
+#: ../src/backend/filters/transform.cpp:1202
msgid "Scalar to use to offset each point's associated value"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1267
-#: ../src/backend/filters/transform.cpp:1294
+#: ../src/backend/filters/transform.cpp:1219
+#: ../src/backend/filters/transform.cpp:1246
msgid "Origin of scale trasnform"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1274
-#: ../src/backend/filters/transform.cpp:1301
+#: ../src/backend/filters/transform.cpp:1226
+#: ../src/backend/filters/transform.cpp:1253
msgid "Scale Fact."
msgstr "Skalierungsfaktor"
-#: ../src/backend/filters/transform.cpp:1277
-#: ../src/backend/filters/transform.cpp:1304
+#: ../src/backend/filters/transform.cpp:1229
+#: ../src/backend/filters/transform.cpp:1256
msgid "Enlargement factor for scaling around origin"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1320
+#: ../src/backend/filters/transform.cpp:1272
msgid "Origin of rotation"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1328
+#: ../src/backend/filters/transform.cpp:1280
msgid "Axis around which to revolve"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1333
+#: ../src/backend/filters/transform.cpp:1285
msgid "Angle (deg)"
msgstr "Winkel (deg)"
-#: ../src/backend/filters/transform.cpp:1336
+#: ../src/backend/filters/transform.cpp:1288
msgid "Angle to perform rotation (ACW, as viewed from axis towards origin)"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1353
+#: ../src/backend/filters/transform.cpp:1305
msgid "Noise Type"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1356
+#: ../src/backend/filters/transform.cpp:1308
msgid "Method to use to degrade point data"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1363
+#: ../src/backend/filters/transform.cpp:1315
msgid "Noise level"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1365
+#: ../src/backend/filters/transform.cpp:1317
msgid "Standard dev."
msgstr "Standardabweichung"
-#: ../src/backend/filters/transform.cpp:1373
+#: ../src/backend/filters/transform.cpp:1325
msgid "Amplitude of noise"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1385
+#: ../src/backend/filters/transform.cpp:1337
msgid "Transform Params"
msgstr "Transformationsparameter"
-#: ../src/backend/filters/transform.cpp:1582
-msgid "Unable to allocate memory"
-msgstr "Kann Speicher nicht zuweisen"
-
-#: ../src/backend/filters/transform.cpp:1761
+#: ../src/backend/filters/transform.cpp:1675
msgid "White"
msgstr ""
-#: ../src/backend/filters/transform.cpp:1763
+#: ../src/backend/filters/transform.cpp:1677
msgid "Gaussian"
msgstr ""
@@ -3854,102 +3771,106 @@ msgstr ""
msgid "Dimension"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:524
+#: ../src/backend/filters/boundingBox.cpp:525
msgid "If true, show box, otherwise hide box"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:537
+#: ../src/backend/filters/boundingBox.cpp:538
msgid "Style"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:540
+#: ../src/backend/filters/boundingBox.cpp:541
msgid "Box display mode"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:551
+#: ../src/backend/filters/boundingBox.cpp:544
+msgid "Display mode"
+msgstr ""
+
+#: ../src/backend/filters/boundingBox.cpp:553
msgid "Fixed Tick Num"
msgstr "Fixed Tick Num"
-#: ../src/backend/filters/boundingBox.cpp:555
+#: ../src/backend/filters/boundingBox.cpp:557
msgid ""
"If true, evenly use specified number of ticks. Otherwise, use distance to "
"determine tick count"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:563
+#: ../src/backend/filters/boundingBox.cpp:565
msgid "Num X"
msgstr "Num X"
-#: ../src/backend/filters/boundingBox.cpp:566
+#: ../src/backend/filters/boundingBox.cpp:568
msgid "Tick count in X direction"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:571
+#: ../src/backend/filters/boundingBox.cpp:573
msgid "Num Y"
msgstr "Num Y"
-#: ../src/backend/filters/boundingBox.cpp:574
+#: ../src/backend/filters/boundingBox.cpp:576
msgid "Tick count in Y direction"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:579
+#: ../src/backend/filters/boundingBox.cpp:581
msgid "Num Z"
msgstr "Num Z"
-#: ../src/backend/filters/boundingBox.cpp:582
+#: ../src/backend/filters/boundingBox.cpp:584
msgid "Tick count in Z direction"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:588
+#: ../src/backend/filters/boundingBox.cpp:590
msgid "Spacing X"
msgstr "X-Abstand"
-#: ../src/backend/filters/boundingBox.cpp:592
+#: ../src/backend/filters/boundingBox.cpp:594
msgid "Distance between ticks on X axis"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:596
+#: ../src/backend/filters/boundingBox.cpp:598
msgid "Spacing Y"
msgstr "Y-Abstand"
-#: ../src/backend/filters/boundingBox.cpp:600
+#: ../src/backend/filters/boundingBox.cpp:602
msgid "Distance between ticks on Y axis"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:604
+#: ../src/backend/filters/boundingBox.cpp:606
msgid "Spacing Z"
msgstr "Z-Abstand"
-#: ../src/backend/filters/boundingBox.cpp:608
+#: ../src/backend/filters/boundingBox.cpp:610
msgid "Distance between ticks on Z axis"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:611
+#: ../src/backend/filters/boundingBox.cpp:613
msgid "Tick marks"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:621
+#: ../src/backend/filters/boundingBox.cpp:620
msgid "Box Colour"
msgstr "Box Farbe"
-#: ../src/backend/filters/boundingBox.cpp:625
+#: ../src/backend/filters/boundingBox.cpp:624
msgid "Colour of the bounding box"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:630
+#: ../src/backend/filters/boundingBox.cpp:629
msgid "Line thickness"
msgstr "Linienbreite"
-#: ../src/backend/filters/boundingBox.cpp:634
+#: ../src/backend/filters/boundingBox.cpp:633
msgid "Thickness of the lines used to draw the box"
msgstr ""
-#: ../src/backend/filters/boundingBox.cpp:642
-#: ../src/backend/filters/annotation.cpp:845
+#: ../src/backend/filters/boundingBox.cpp:641
+#: ../src/backend/filters/annotation.cpp:843
msgid "Font Size"
msgstr "Schriftgröße"
-#: ../src/backend/filters/boundingBox.cpp:645
+#: ../src/backend/filters/boundingBox.cpp:644
msgid "Relative size for text"
msgstr ""
@@ -3973,248 +3894,250 @@ msgstr "Winkel"
msgid "Ruler"
msgstr "Lineal"
-#: ../src/backend/filters/annotation.cpp:526
+#: ../src/backend/filters/annotation.cpp:519
msgid "Enable"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:529
+#: ../src/backend/filters/annotation.cpp:522
msgid "Enable/disable annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:550
+#: ../src/backend/filters/annotation.cpp:543
msgid "Type or style of annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:565
-#: ../src/backend/filters/annotation.cpp:667
+#: ../src/backend/filters/annotation.cpp:559
+#: ../src/backend/filters/annotation.cpp:663
msgid "Text of annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:573
+#: ../src/backend/filters/annotation.cpp:567
msgid "Position of annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:577
-#: ../src/backend/filters/annotation.cpp:681
-#: ../src/backend/filters/annotation.cpp:739
-#: ../src/backend/filters/annotation.cpp:828
+#: ../src/backend/filters/annotation.cpp:571
+#: ../src/backend/filters/annotation.cpp:678
+#: ../src/backend/filters/annotation.cpp:737
+#: ../src/backend/filters/annotation.cpp:826
msgid "Up dir"
msgstr "Up dir"
-#: ../src/backend/filters/annotation.cpp:581
-#: ../src/backend/filters/annotation.cpp:832
+#: ../src/backend/filters/annotation.cpp:575
+#: ../src/backend/filters/annotation.cpp:830
msgid "Vector for up direction of annotation text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:585
-#: ../src/backend/filters/annotation.cpp:688
-#: ../src/backend/filters/annotation.cpp:731
-#: ../src/backend/filters/annotation.cpp:836
+#: ../src/backend/filters/annotation.cpp:579
+#: ../src/backend/filters/annotation.cpp:685
+#: ../src/backend/filters/annotation.cpp:729
+#: ../src/backend/filters/annotation.cpp:834
msgid "Across dir"
msgstr "Across dir"
-#: ../src/backend/filters/annotation.cpp:589
-#: ../src/backend/filters/annotation.cpp:840
+#: ../src/backend/filters/annotation.cpp:583
+#: ../src/backend/filters/annotation.cpp:838
msgid "Reading direction for annotation"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:594
-#: ../src/backend/filters/annotation.cpp:673
-#: ../src/backend/filters/annotation.cpp:766
+#: ../src/backend/filters/annotation.cpp:588
+#: ../src/backend/filters/annotation.cpp:670
+#: ../src/backend/filters/annotation.cpp:764
msgid "Text size"
msgstr "Textgröße"
-#: ../src/backend/filters/annotation.cpp:598
-#: ../src/backend/filters/annotation.cpp:677
-#: ../src/backend/filters/annotation.cpp:848
+#: ../src/backend/filters/annotation.cpp:592
+#: ../src/backend/filters/annotation.cpp:674
+#: ../src/backend/filters/annotation.cpp:846
msgid "Relative size of annotation text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:610
-#: ../src/backend/filters/annotation.cpp:649
+#: ../src/backend/filters/annotation.cpp:604
+#: ../src/backend/filters/annotation.cpp:645
msgid "3D position for tail of arrow"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:618
-#: ../src/backend/filters/annotation.cpp:658
+#: ../src/backend/filters/annotation.cpp:612
+#: ../src/backend/filters/annotation.cpp:654
msgid "3D Position to which arrow points"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:624
-#: ../src/backend/filters/annotation.cpp:695
+#: ../src/backend/filters/annotation.cpp:615
+#: ../src/backend/filters/annotation.cpp:725
+msgid "Positioning"
+msgstr ""
+
+#: ../src/backend/filters/annotation.cpp:620
+#: ../src/backend/filters/annotation.cpp:692
msgid "Tip radius"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:628
+#: ../src/backend/filters/annotation.cpp:624
msgid "Size of the arrow head"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:632
+#: ../src/backend/filters/annotation.cpp:628
msgid "Line size"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:636
+#: ../src/backend/filters/annotation.cpp:632
msgid "Thickness of line used to draw arrow stem"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:705
+#: ../src/backend/filters/annotation.cpp:666
+msgid "Options"
+msgstr ""
+
+#: ../src/backend/filters/annotation.cpp:702
msgid "Position A"
msgstr "Position A"
-#: ../src/backend/filters/annotation.cpp:709
+#: ../src/backend/filters/annotation.cpp:706
msgid "Location of first non-central vertex"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:713
+#: ../src/backend/filters/annotation.cpp:710
msgid "Origin "
msgstr "Ursprung "
-#: ../src/backend/filters/annotation.cpp:717
+#: ../src/backend/filters/annotation.cpp:714
msgid "Location of central vertex"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:721
+#: ../src/backend/filters/annotation.cpp:718
msgid "Position B"
msgstr "Position B"
-#: ../src/backend/filters/annotation.cpp:725
+#: ../src/backend/filters/annotation.cpp:722
msgid "Location of second non-central vertex"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:735
+#: ../src/backend/filters/annotation.cpp:733
msgid "Reading direction for angle text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:740
+#: ../src/backend/filters/annotation.cpp:738
msgid "Vector for up direction of angle text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:748
+#: ../src/backend/filters/annotation.cpp:746
msgid "Reflexive"
msgstr "Reflexive"
-#: ../src/backend/filters/annotation.cpp:751
+#: ../src/backend/filters/annotation.cpp:749
msgid "Measure interor (enabled) or exterior angle (disabled)"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:756
+#: ../src/backend/filters/annotation.cpp:754
msgid "Show Angle"
msgstr "Zeige Winkel"
-#: ../src/backend/filters/annotation.cpp:760
+#: ../src/backend/filters/annotation.cpp:758
msgid "Display angle text (when enabled)"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:770
+#: ../src/backend/filters/annotation.cpp:768
msgid "Size of angle text"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:788
+#: ../src/backend/filters/annotation.cpp:786
msgid "Digit format"
msgstr "Zahlenformat"
-#: ../src/backend/filters/annotation.cpp:792
+#: ../src/backend/filters/annotation.cpp:790
msgid ""
"Format of angle text; # for numeral position, '.' for separator, eg ##.## "
"gives 12.34"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:798
-#: ../src/backend/filters/annotation.cpp:886
+#: ../src/backend/filters/annotation.cpp:796
+#: ../src/backend/filters/annotation.cpp:881
msgid "Sphere size"
msgstr "Kugelgröße"
-#: ../src/backend/filters/annotation.cpp:802
-#: ../src/backend/filters/annotation.cpp:890
+#: ../src/backend/filters/annotation.cpp:800
+#: ../src/backend/filters/annotation.cpp:885
msgid "Marker sphere size for manipulating tool"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:816
+#: ../src/backend/filters/annotation.cpp:814
msgid "Ruler beginning 3D location"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:824
+#: ../src/backend/filters/annotation.cpp:822
msgid "Ruler finish 3D location"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:857
+#: ../src/backend/filters/annotation.cpp:852
msgid "Fixed ticks"
msgstr "Fixe Marker"
-#: ../src/backend/filters/annotation.cpp:860
+#: ../src/backend/filters/annotation.cpp:855
msgid ""
"Use fixed (enabled) number of text markers, or one every fixed distance "
"(disabled)"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:867
+#: ../src/backend/filters/annotation.cpp:862
msgid "Num Ticks"
msgstr "Anzahl Marker"
-#: ../src/backend/filters/annotation.cpp:870
+#: ../src/backend/filters/annotation.cpp:865
msgid "Number of tick marks along ruler"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:877
+#: ../src/backend/filters/annotation.cpp:872
msgid "Tick Spacing"
msgstr "Markerabstand"
-#: ../src/backend/filters/annotation.cpp:880
+#: ../src/backend/filters/annotation.cpp:875
msgid "Distance between tick marks along ruler"
msgstr ""
-#: ../src/backend/filters/annotation.cpp:906
+#: ../src/backend/filters/annotation.cpp:899
msgid "Colour for ruler and ticks"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:460
+#: ../src/backend/filters/ionDownsample.cpp:445
msgid "By Count"
msgstr "Nach Anzahl"
-#: ../src/backend/filters/ionDownsample.cpp:463
+#: ../src/backend/filters/ionDownsample.cpp:448
msgid "Sample up to a fixed number of ions"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:469
+#: ../src/backend/filters/ionDownsample.cpp:454
msgid "Per Species"
msgstr "Nach Spezies"
-#: ../src/backend/filters/ionDownsample.cpp:473
+#: ../src/backend/filters/ionDownsample.cpp:458
msgid "Use species specific (from ranging) sampling values"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:478
-msgid "Sampling rates"
+#: ../src/backend/filters/ionDownsample.cpp:487
+msgid "Sampling value for species"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:501
-msgid "Sampling value for species"
+#: ../src/backend/filters/ionDownsample.cpp:495
+#: ../src/backend/filters/ionDownsample.cpp:519
+msgid "Sampling rates"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:513
+#: ../src/backend/filters/ionDownsample.cpp:503
msgid "Output Count"
msgstr "Ausgabe Anzahl"
-#: ../src/backend/filters/ionDownsample.cpp:516
+#: ../src/backend/filters/ionDownsample.cpp:506
msgid "Sample up to this value of points"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:521
+#: ../src/backend/filters/ionDownsample.cpp:511
msgid "Out Fraction"
msgstr "Ausgabe Anteil"
-#: ../src/backend/filters/ionDownsample.cpp:525
+#: ../src/backend/filters/ionDownsample.cpp:515
msgid "Sample this fraction of points"
msgstr ""
-#: ../src/backend/filters/ionDownsample.cpp:669
-msgid "Downsample Aborted"
-msgstr "Datenreduktion abgebrochen"
-
-#: ../src/backend/filters/ionDownsample.cpp:671
-msgid "Insuffient memory for downsample"
-msgstr "Nicht genug Speicher zur Datenreduktion"
-
#: ../src/backend/filters/ionInfo.cpp:30
msgid "Rectilinear"
msgstr "Geradlinig"
@@ -4295,25 +4218,25 @@ msgstr ""
msgid "Normalise count data"
msgstr ""
-#: ../src/backend/filters/ionInfo.cpp:425
+#: ../src/backend/filters/ionInfo.cpp:421
+msgid "Ion data"
+msgstr ""
+
+#: ../src/backend/filters/ionInfo.cpp:426
msgid "Volume"
msgstr "Volumen"
-#: ../src/backend/filters/ionInfo.cpp:428
+#: ../src/backend/filters/ionInfo.cpp:429
msgid "Compute volume for point data"
msgstr ""
-#: ../src/backend/filters/ionInfo.cpp:443
+#: ../src/backend/filters/ionInfo.cpp:444
msgid "Select volume counting technique"
msgstr ""
-#: ../src/backend/filters/ionInfo.cpp:539
-msgid "Insufficient memory for operation"
-msgstr "Nicht genügend Speicher für Operation"
-
-#: ../src/backend/filters/ionInfo.cpp:543
-msgid "Bug? Problem with qhull library, cannot run convex hull."
-msgstr "Bug? Problem mit qhull Bibliothek. Kann convex hull nicht ausführen."
+#: ../src/backend/filters/ionInfo.cpp:457
+msgid "Volume data"
+msgstr ""
#: ../src/backend/filters/dataLoad.cpp:56
msgid "Auto"
@@ -4339,45 +4262,45 @@ msgstr "Text-Daten"
msgid "ATO Data"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:242
+#: ../src/backend/filters/dataLoad.cpp:238
msgid " does not exist"
msgstr " existiert nicht"
-#: ../src/backend/filters/dataLoad.cpp:280
-#: ../src/backend/filters/dataLoad.cpp:293
-#: ../src/backend/filters/dataLoad.cpp:336
-#: ../src/backend/filters/dataLoad.cpp:347
-#: ../src/backend/filters/dataLoad.cpp:408
+#: ../src/backend/filters/dataLoad.cpp:276
+#: ../src/backend/filters/dataLoad.cpp:289
+#: ../src/backend/filters/dataLoad.cpp:332
+#: ../src/backend/filters/dataLoad.cpp:343
+#: ../src/backend/filters/dataLoad.cpp:404
msgid "Error loading file: "
msgstr "Fehler beim Laden der Datei: "
-#: ../src/backend/filters/dataLoad.cpp:310
+#: ../src/backend/filters/dataLoad.cpp:306
msgid "Sampling is active, loaded "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:311
+#: ../src/backend/filters/dataLoad.cpp:307
msgid " available."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:319
+#: ../src/backend/filters/dataLoad.cpp:315
msgid "Loaded entire dataset, "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:319
-#: ../src/backend/filters/dataLoad.cpp:418
+#: ../src/backend/filters/dataLoad.cpp:315
+#: ../src/backend/filters/dataLoad.cpp:414
msgid " points."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:362
+#: ../src/backend/filters/dataLoad.cpp:358
msgid ""
"Data file contained incorrect number of columns -- should be 3 or 4, was "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:417
+#: ../src/backend/filters/dataLoad.cpp:413
msgid "Loaded dataset, "
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:449
+#: ../src/backend/filters/dataLoad.cpp:445
msgid ""
"Warning:One or more bounds of the loaded data approaches the limits of "
"numerical stability for the internal data type(magnitude too large). "
@@ -4387,291 +4310,295 @@ msgstr ""
"der numerischen Stabilität des internen Datentyps (Größenordnung zu groß). "
"Erwägen Sie die Daten vor dem Laden zu skalieren. "
-#: ../src/backend/filters/dataLoad.cpp:481
-#: ../src/backend/filters/rangeFile.cpp:567
+#: ../src/backend/filters/dataLoad.cpp:469
+#: ../src/backend/filters/dataLoad.cpp:490
+#: ../src/backend/filters/rangeFile.cpp:569
+#: ../src/backend/filters/rangeFile.cpp:589
msgid "File"
msgstr "Datei"
-#: ../src/backend/filters/dataLoad.cpp:482
+#: ../src/backend/filters/dataLoad.cpp:470
msgid "File from which to load data"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:493
+#: ../src/backend/filters/dataLoad.cpp:473
+msgid ""
+"Readable files (*.xml, *.pos, *.txt,*.csv, *.ato)|*.xml;*.pos;*.txt;*.csv;*."
+"ato|All Files|*"
+msgstr ""
+
+#: ../src/backend/filters/dataLoad.cpp:483
msgid "File type"
msgstr "Dateityp"
-#: ../src/backend/filters/dataLoad.cpp:495
+#: ../src/backend/filters/dataLoad.cpp:485
msgid "Type of file to be loaded"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:509
+#: ../src/backend/filters/dataLoad.cpp:500
msgid "Entries per point"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:510
+#: ../src/backend/filters/dataLoad.cpp:501
msgid "Number of decimal values in file per 3D point (normally 4)"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:529
+#: ../src/backend/filters/dataLoad.cpp:520
msgid "File \"Endianness\""
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:530
+#: ../src/backend/filters/dataLoad.cpp:521
msgid "On-disk data storage format. If file won't load, just try each"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:555
+#: ../src/backend/filters/dataLoad.cpp:546
msgid "Relative offset of each entry in file for point's X position"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:563
+#: ../src/backend/filters/dataLoad.cpp:554
msgid "Relative offset of each entry in file for point's Y position"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:571
+#: ../src/backend/filters/dataLoad.cpp:562
msgid "Relative offset of each entry in file for point's Z position"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:579
+#: ../src/backend/filters/dataLoad.cpp:570
msgid ""
"Relative offset of each entry in file to use for scalar value of 3D point"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:582
+#: ../src/backend/filters/dataLoad.cpp:573
msgid "Value Label"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:586
+#: ../src/backend/filters/dataLoad.cpp:577
msgid "Name for the scalar value associated with each point"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:589
+#: ../src/backend/filters/dataLoad.cpp:580
msgid "Format params."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:595
+#: ../src/backend/filters/dataLoad.cpp:586
msgid "Enabled"
msgstr "Aktiviert"
-#: ../src/backend/filters/dataLoad.cpp:599
+#: ../src/backend/filters/dataLoad.cpp:590
msgid "Load this file?"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:610
+#: ../src/backend/filters/dataLoad.cpp:601
msgid "Sample data"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:613
+#: ../src/backend/filters/dataLoad.cpp:604
msgid ""
"Perform random selection on file contents, instead of loading entire file"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:620
+#: ../src/backend/filters/dataLoad.cpp:611
msgid "Load Limit (MB)"
msgstr "Ladelimit (MB)"
-#: ../src/backend/filters/dataLoad.cpp:623
+#: ../src/backend/filters/dataLoad.cpp:614
msgid "Limit for size of data to load"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:630
+#: ../src/backend/filters/dataLoad.cpp:621
msgid "Monitor"
msgstr "Monitor"
-#: ../src/backend/filters/dataLoad.cpp:634
+#: ../src/backend/filters/dataLoad.cpp:625
msgid ""
"Watch file timestamp to track changes to file contents from other programs"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:636
+#: ../src/backend/filters/dataLoad.cpp:629
msgid "Load params."
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:646
+#: ../src/backend/filters/dataLoad.cpp:636
msgid "Default colour "
msgstr "Bevorzugte Farbe "
-#: ../src/backend/filters/dataLoad.cpp:649
+#: ../src/backend/filters/dataLoad.cpp:639
msgid "Default colour for points, if not overridden by other filters"
msgstr ""
-#: ../src/backend/filters/dataLoad.cpp:654
+#: ../src/backend/filters/dataLoad.cpp:644
msgid "Draw Size"
msgstr "Draw Size"
-#: ../src/backend/filters/dataLoad.cpp:657
+#: ../src/backend/filters/dataLoad.cpp:647
msgid "Default size for points, if not overridden by other filters"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:125
+#: ../src/backend/filters/spectrumPlot.cpp:122
msgid "Extrema"
msgstr "Extrema"
-#: ../src/backend/filters/spectrumPlot.cpp:174
+#: ../src/backend/filters/spectrumPlot.cpp:171
msgid "count"
msgstr "Anzahl"
-#: ../src/backend/filters/spectrumPlot.cpp:259
+#: ../src/backend/filters/spectrumPlot.cpp:256
msgid "Mixed data"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:400
+#: ../src/backend/filters/spectrumPlot.cpp:390
msgid "Step size for spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:409
+#: ../src/backend/filters/spectrumPlot.cpp:395
msgid "Auto Min/max"
msgstr "Auto Min/max"
-#: ../src/backend/filters/spectrumPlot.cpp:413
+#: ../src/backend/filters/spectrumPlot.cpp:399
msgid "Automatically compute spectrum upper and lower bound"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:418
+#: ../src/backend/filters/spectrumPlot.cpp:404
msgid "Min"
msgstr "Min"
-#: ../src/backend/filters/spectrumPlot.cpp:421
+#: ../src/backend/filters/spectrumPlot.cpp:407
msgid "Starting position for spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:426
+#: ../src/backend/filters/spectrumPlot.cpp:412
msgid "Max"
msgstr "Max"
-#: ../src/backend/filters/spectrumPlot.cpp:429
+#: ../src/backend/filters/spectrumPlot.cpp:415
msgid "Ending position for spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:437
+#: ../src/backend/filters/spectrumPlot.cpp:423
msgid "Logarithmic"
msgstr "Logarithmisch"
-#: ../src/backend/filters/spectrumPlot.cpp:440
+#: ../src/backend/filters/spectrumPlot.cpp:426
msgid "Convert the plot to logarithmic mode"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:462
+#: ../src/backend/filters/spectrumPlot.cpp:448
msgid "Visual style of plot"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:475
+#: ../src/backend/filters/spectrumPlot.cpp:455
msgid "Colour of plotted spectrum"
msgstr ""
-#: ../src/backend/filters/spectrumPlot.cpp:709
-msgid "Insufficient memory for spectrum filter."
-msgstr "Nicht genügend Speicher für Spektrumfilter"
-
-#: ../src/backend/filters/spectrumPlot.cpp:711
-msgid "Bad bincount value in spectrum filter."
-msgstr "Falsche Binanzahl im Spektrumfilter."
-
-#: ../src/backend/filters/rangeFile.cpp:149
+#: ../src/backend/filters/rangeFile.cpp:151
msgid "Pre-Allocate"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:280 ../src/backend/filter.cpp:46
+#: ../src/backend/filters/rangeFile.cpp:282 ../src/backend/filter.cpp:48
msgid "Range"
msgstr "Range"
-#: ../src/backend/filters/rangeFile.cpp:569
+#: ../src/backend/filters/rangeFile.cpp:572
msgid "File to use for range data"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:581
+#: ../src/backend/filters/rangeFile.cpp:582
msgid "Drop unranged"
msgstr "Nicht gerangete ausschalten"
-#: ../src/backend/filters/rangeFile.cpp:583
+#: ../src/backend/filters/rangeFile.cpp:584
msgid "Remove unranged points when generating output"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:603
+#: ../src/backend/filters/rangeFile.cpp:594
+msgid "Legend"
+msgstr ""
+
+#: ../src/backend/filters/rangeFile.cpp:596
+msgid "Display colour legend for enabled ions"
+msgstr ""
+
+#: ../src/backend/filters/rangeFile.cpp:600
+msgid "View"
+msgstr ""
+
+#: ../src/backend/filters/rangeFile.cpp:616
msgid "All Ions"
msgstr "Alle Ionen"
-#: ../src/backend/filters/rangeFile.cpp:604
+#: ../src/backend/filters/rangeFile.cpp:617
msgid "Enable/disable all ions at once"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:612
+#: ../src/backend/filters/rangeFile.cpp:625
msgid "Species"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:619
+#: ../src/backend/filters/rangeFile.cpp:632
msgid "IonID "
msgstr "IonID "
-#: ../src/backend/filters/rangeFile.cpp:620
+#: ../src/backend/filters/rangeFile.cpp:633
msgid "Enable/disable specified ion"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:633
+#: ../src/backend/filters/rangeFile.cpp:643
msgid "Active Ion "
msgstr "Actives Ion "
-#: ../src/backend/filters/rangeFile.cpp:635
+#: ../src/backend/filters/rangeFile.cpp:645
msgid "If true, ion is used in output"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:649
+#: ../src/backend/filters/rangeFile.cpp:655
msgid "Colour "
msgstr "Farbe"
-#: ../src/backend/filters/rangeFile.cpp:652
+#: ../src/backend/filters/rangeFile.cpp:659
msgid "Colour used to represent ion"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:676
+#: ../src/backend/filters/rangeFile.cpp:682
msgid "All Ranges"
msgstr "Alle Range"
-#: ../src/backend/filters/rangeFile.cpp:677
+#: ../src/backend/filters/rangeFile.cpp:683
msgid "Enable/disable all ranges"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:695
+#: ../src/backend/filters/rangeFile.cpp:698
msgid "Active Rng "
msgstr "Activer Rng "
-#: ../src/backend/filters/rangeFile.cpp:698
+#: ../src/backend/filters/rangeFile.cpp:701
msgid ""
"Enable/disable specified range (ion must also be enabled to activiate range)"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:702
+#: ../src/backend/filters/rangeFile.cpp:705
msgid "Ion "
msgstr "Ion "
-#: ../src/backend/filters/rangeFile.cpp:705
+#: ../src/backend/filters/rangeFile.cpp:708
msgid "Name of ion associate to this range"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:714
+#: ../src/backend/filters/rangeFile.cpp:717
msgid "Start rng "
msgstr "Start rng "
-#: ../src/backend/filters/rangeFile.cpp:717
+#: ../src/backend/filters/rangeFile.cpp:720
msgid "Start value for range"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:722
+#: ../src/backend/filters/rangeFile.cpp:725
msgid "End rng "
msgstr "End rng "
-#: ../src/backend/filters/rangeFile.cpp:725
+#: ../src/backend/filters/rangeFile.cpp:728
msgid "Stopping value for range`"
msgstr ""
-#: ../src/backend/filters/rangeFile.cpp:1029
-msgid "Ranging aborted by user"
-msgstr "Ranging durch User abgebrochen"
-
-#: ../src/backend/filters/rangeFile.cpp:1031
-msgid "Insufficient memory for range"
-msgstr "Nicht genug Speicher für Range"
-
#: ../src/backend/state.cpp:137
msgid ""
"This file is a \"state\" file for the 3Depict program, and stores "
@@ -4686,25 +4613,25 @@ msgstr ""
msgid "Failed to allocate parser"
msgstr "Kann Parser nicht zuordnen"
-#: ../src/backend/state.cpp:326
+#: ../src/backend/state.cpp:325
msgid ""
"Unable to retrieve root node in input state file... Is this really a non-"
"empty XML file?"
msgstr ""
-#: ../src/backend/state.cpp:333
+#: ../src/backend/state.cpp:332
msgid "Base state node missing. Is this really a state XML file??"
msgstr ""
-#: ../src/backend/state.cpp:362
+#: ../src/backend/state.cpp:361
msgid "State was created by a newer version of this program.. "
msgstr "Status wurde von einer neueren Version dieses Programmes erstellt.. "
-#: ../src/backend/state.cpp:363
+#: ../src/backend/state.cpp:362
msgid "file reading will continue, but may fail."
msgstr "Datei wird weiter eingelesen kann aber unter Umständen fehlschlagen."
-#: ../src/backend/state.cpp:368
+#: ../src/backend/state.cpp:367
msgid ""
"Warning, unparseable version number in state file. File reading will "
"continue, but may fail"
@@ -4712,115 +4639,107 @@ msgstr ""
"Warnung: Nicht lesbare Versionsnummer in Statusdatei. Datei wird weiter "
"eingelesen kann aber unter Umständen fehlschlagen."
-#: ../src/backend/state.cpp:375
+#: ../src/backend/state.cpp:374
msgid "Unable to find the \"writer\" node"
msgstr "Kann \"writer\" node nicht finden"
-#: ../src/backend/state.cpp:385
+#: ../src/backend/state.cpp:384
msgid "Unable to find the \"backcolour\" node."
msgstr "Unable to find the \"backcolour\" node."
-#: ../src/backend/state.cpp:392
+#: ../src/backend/state.cpp:391
msgid "\"backcolour\" node missing \"r\" value."
msgstr "\"backcolour\" node fehlt \"r\" Wert."
-#: ../src/backend/state.cpp:397
+#: ../src/backend/state.cpp:396
msgid "Unable to interpret \"backColour\" node's \"r\" value."
msgstr "Kann \"backColour\" node's \"r\" Wert nicht interpretieren."
-#: ../src/backend/state.cpp:405
+#: ../src/backend/state.cpp:404
msgid "\"backcolour\" node missing \"g\" value."
msgstr "\"backcolour\" node fehlt \"g\" Wert."
-#: ../src/backend/state.cpp:411
+#: ../src/backend/state.cpp:410
msgid "Unable to interpret \"backColour\" node's \"g\" value."
msgstr "Kann \"backColour\" node's \"g\" Wert nicht interpretieren."
-#: ../src/backend/state.cpp:419
+#: ../src/backend/state.cpp:418
msgid "\"backcolour\" node missing \"b\" value."
msgstr "\"backcolour\" node fehlt \"b\" Wert."
-#: ../src/backend/state.cpp:425
+#: ../src/backend/state.cpp:424
msgid "Unable to interpret \"backColour\" node's \"b\" value."
msgstr "Kann \"backColour\" node's \"b\" Wert nicht interpretieren."
-#: ../src/backend/state.cpp:432
+#: ../src/backend/state.cpp:431
msgid "\"backcolour\"s rgb values must be in range [0,1]"
msgstr "\"backcolour\"s rgb Wert muss im Bereich [0,1] liegen"
-#: ../src/backend/state.cpp:460
+#: ../src/backend/state.cpp:459
msgid "Unable to find or interpret \"showaxis\" node"
msgstr "Kann \"showaxis\" node nicht interpretieren"
-#: ../src/backend/state.cpp:504
+#: ../src/backend/state.cpp:503
msgid "Unable to locate \"filtertree\" node."
msgstr "Kann \"filtertree\" node nicht finden."
-#: ../src/backend/state.cpp:520
+#: ../src/backend/state.cpp:519
msgid "Cameras section missing \"active\" node."
msgstr "Cameras section fehlt \"active\" node."
-#: ../src/backend/state.cpp:528
+#: ../src/backend/state.cpp:527
msgid "Unable to find property \"value\" for \"cameras->active\" node."
msgstr "Kann \"Eigenschaftswert\" für \"Kamera->aktiv\" Node nicht finden."
-#: ../src/backend/state.cpp:534
+#: ../src/backend/state.cpp:533
msgid "Unable to interpret property \"value\" for \"cameras->active\" node."
msgstr ""
"Kann \"Eigenschaftswert\" für \"Kamera->aktiv\" Node nicht interpretieren."
-#: ../src/backend/state.cpp:553
+#: ../src/backend/state.cpp:552
msgid "Failed to interpret camera state for camera : "
msgstr ""
-#: ../src/backend/state.cpp:561
+#: ../src/backend/state.cpp:560
msgid "Unable to interpret the camera type for camera : "
msgstr "Kann den Kameratype nicht interpretieren für :"
-#: ../src/backend/state.cpp:597
+#: ../src/backend/state.cpp:596
msgid "Unable to locate stash name for stash "
msgstr "Kann den Stashnamen für Stash nicht finden"
-#: ../src/backend/state.cpp:604
+#: ../src/backend/state.cpp:603
msgid "Empty stash name for stash "
msgstr "Leerer Stashname für Stash"
-#: ../src/backend/state.cpp:613
+#: ../src/backend/state.cpp:612
msgid "No filter tree for stash:"
msgstr ""
-#: ../src/backend/state.cpp:619
+#: ../src/backend/state.cpp:618
msgid "For stash "
msgstr "Für Stash "
-#: ../src/backend/state.cpp:651
+#: ../src/backend/state.cpp:650
msgid "Unrecognised effect :"
msgstr "Nichterkannter Effekt :"
-#: ../src/backend/state.cpp:661
+#: ../src/backend/state.cpp:660
msgid "Duplicate effect found"
msgstr "Doppelter Effekt gefunden"
-#: ../src/backend/state.cpp:661
+#: ../src/backend/state.cpp:660
msgid " cannot use."
msgstr "kann nicht verwenden."
-#: ../src/backend/state.cpp:671
+#: ../src/backend/state.cpp:670
msgid "Error reading effect : "
msgstr "Fehler beim Lesen:"
-#: ../src/backend/state.cpp:789
+#: ../src/backend/state.cpp:866
msgid "-merge"
msgstr ""
-#: ../src/backend/state.cpp:794
-msgid ""
-" Unable to merge stashes correctly. This is improbable, so please report "
-"this."
-msgstr ""
-" Kann stashes nicht korrekt zusammenführen. Dies ist nicht möglich bitte "
-"melden Sie das."
-
#: ../src/backend/filtertreeAnalyse.cpp:199
msgid ""
"Parent filter has no output, but filter requires input -- there is no point "
@@ -4873,94 +4792,127 @@ msgstr ""
msgid "Filter missing needed parent"
msgstr ""
-#: ../src/backend/filtertreeAnalyse.cpp:554
+#: ../src/backend/filtertreeAnalyse.cpp:555
msgid "Composition results possibly altered"
msgstr ""
-#: ../src/backend/filtertreeAnalyse.cpp:555
+#: ../src/backend/filtertreeAnalyse.cpp:556
msgid ""
"Filters and settings selected that could bias reported composition. Check to "
"see if species biasing may occcur in the filter tree - this warning is "
"provisional only."
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:40
+#: ../src/backend/APT/APTFileIO.cpp:43 ../src/backend/APT/APTFileIO.cpp:78
+#: ../src/backend/APT/APTFileIO.cpp:102
+msgid "Error opening file"
+msgstr "Fehler beim Öffnen der Datei"
+
+#: ../src/backend/APT/APTFileIO.cpp:44
+msgid "Only found header, no data"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:45
+msgid "Unable to reopen file after first scan"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:46
+msgid "Error whilst reading file contents"
+msgstr "Fehler beim Lesen des Dateiinhaltes"
+
+#: ../src/backend/APT/APTFileIO.cpp:47 ../src/backend/APT/APTFileIO.cpp:48
+msgid "Unexpected file format"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:49
+msgid "Insufficient memory to continue"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:53
msgid "Memory allocation failure on POS load"
msgstr "Speicherzuweisungsfeher beim Laden der pos-Datei"
-#: ../src/backend/APT/APTFileIO.cpp:41
+#: ../src/backend/APT/APTFileIO.cpp:54
msgid "Error opening pos file"
msgstr "Fehler beim Öffnen der pos-Datei"
-#: ../src/backend/APT/APTFileIO.cpp:42
+#: ../src/backend/APT/APTFileIO.cpp:55
msgid "Pos file empty"
msgstr "Pos-Datei ist leer"
-#: ../src/backend/APT/APTFileIO.cpp:43
+#: ../src/backend/APT/APTFileIO.cpp:56
msgid "Pos file size appears to have non-integer number of entries"
msgstr ""
"Pos-Dateigröße scheint eine nicht ganzzahlige Anzahl an Einträgen zu haben"
-#: ../src/backend/APT/APTFileIO.cpp:44
+#: ../src/backend/APT/APTFileIO.cpp:57
msgid "Error reading from pos file (after open)"
msgstr "Fehler beim Lesen aus pos-Datei (nach dem öffnen)"
-#: ../src/backend/APT/APTFileIO.cpp:45
+#: ../src/backend/APT/APTFileIO.cpp:58
msgid "Error - Found NaN in pos file"
msgstr "Fehler - Fand NaN in pos-Datei"
-#: ../src/backend/APT/APTFileIO.cpp:46
+#: ../src/backend/APT/APTFileIO.cpp:59
+msgid "Error - Found Inf in pos file"
+msgstr ""
+
+#: ../src/backend/APT/APTFileIO.cpp:60
msgid "Pos load aborted by interrupt."
msgstr "Pos laden durch Interrupt abgebrochen."
-#: ../src/backend/APT/APTFileIO.cpp:66
+#: ../src/backend/APT/APTFileIO.cpp:79
msgid "No numerical data found"
msgstr "Keine numerischen Daten gefunden"
-#: ../src/backend/APT/APTFileIO.cpp:67
+#: ../src/backend/APT/APTFileIO.cpp:80
msgid "Error re-opening file, after first scan"
msgstr "Fehler beim nochmaligen Öffnen der Datei nach dem ersten Scan"
-#: ../src/backend/APT/APTFileIO.cpp:68
+#: ../src/backend/APT/APTFileIO.cpp:81
msgid "Unable to read file contents after open"
msgstr "Kann den Dateiinhalt nach dem Öffnen nich lesen"
-#: ../src/backend/APT/APTFileIO.cpp:70
+#: ../src/backend/APT/APTFileIO.cpp:82
+msgid "Error interpreting field in file"
+msgstr "Fehler beim Interpretieren eine Feldes in der Datei"
+
+#: ../src/backend/APT/APTFileIO.cpp:83
msgid "Incorrect number of fields in file"
msgstr "Die Datei enthält eine falsche Anzahl von Feldern"
-#: ../src/backend/APT/APTFileIO.cpp:71 ../src/backend/APT/APTFileIO.cpp:93
+#: ../src/backend/APT/APTFileIO.cpp:84 ../src/backend/APT/APTFileIO.cpp:106
msgid "Unable to allocate memory to store data"
msgstr "Kann Speicher nicht zuordnen"
-#: ../src/backend/APT/APTFileIO.cpp:90
+#: ../src/backend/APT/APTFileIO.cpp:103
msgid "File is empty"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:91
+#: ../src/backend/APT/APTFileIO.cpp:104
msgid "Filesize does not match expected format"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:92
+#: ../src/backend/APT/APTFileIO.cpp:105
msgid "File version number not <4, as expected"
msgstr ""
-#: ../src/backend/APT/APTFileIO.cpp:94
+#: ../src/backend/APT/APTFileIO.cpp:107
msgid "Unable to detect endian-ness in file"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:47
+#: ../src/backend/APT/APTRanges.cpp:48
msgid "Error opening file, check name and permissions."
msgstr "Fehler beim Öffnen der Datei, überprüfe Namen und Berechtigungen."
-#: ../src/backend/APT/APTRanges.cpp:48
+#: ../src/backend/APT/APTRanges.cpp:49
msgid ""
"Error interpreting range file header, expecting ion count and range count, "
"respectively."
msgstr ""
"Fehler beim Rangedatei interpretieren, erwarte Ionenanzahl bzw. Rangeanzahl."
-#: ../src/backend/APT/APTRanges.cpp:49
+#: ../src/backend/APT/APTRanges.cpp:50
msgid ""
"Range file appears to be empty, check file is a proper range file and is not "
"empty."
@@ -4968,15 +4920,15 @@ msgstr ""
"Rangedatei scheint leer zu sein. Prüfe ob die Datei wirklich ein Rangedatei "
"und nicht leer ist."
-#: ../src/backend/APT/APTRanges.cpp:50
+#: ../src/backend/APT/APTRanges.cpp:51
msgid "Error reading the long name for ion."
msgstr "Fehler beim Lesen des langen Namens für Ion."
-#: ../src/backend/APT/APTRanges.cpp:51
+#: ../src/backend/APT/APTRanges.cpp:52
msgid "Error reading the short name for ion."
msgstr "Fehler beim Lesen des kurzen Namens für Ion."
-#: ../src/backend/APT/APTRanges.cpp:52
+#: ../src/backend/APT/APTRanges.cpp:53
msgid ""
"Error reading colour data in the file, expecting 3 decimal values, space "
"separated."
@@ -4984,39 +4936,39 @@ msgstr ""
"Fehler beim Lesen der Farbinformationen in der Datei. Erwarte 3, durch "
"Leerzeichen getrennte, Dezimalwerte."
-#: ../src/backend/APT/APTRanges.cpp:53
+#: ../src/backend/APT/APTRanges.cpp:54
msgid ""
"Tried skipping to table separator line (line with dashes), but did not find "
"it."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:54
+#: ../src/backend/APT/APTRanges.cpp:55
msgid ""
"Number of ions in the table header did not match the number specified at the "
"start of the file"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:55
+#: ../src/backend/APT/APTRanges.cpp:56
msgid ""
"Unexpected failure whilst trying to skip over range lead-in data (bit before "
"range start value)"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:56
+#: ../src/backend/APT/APTRanges.cpp:57
msgid ""
"Range table had an incorrect number of entries, should be 2 or 3 + number of "
"ranges"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:57
+#: ../src/backend/APT/APTRanges.cpp:58
msgid "Unable to read range start and end values"
msgstr "Kann Anfangs und Endwert des Range nicht lesen"
-#: ../src/backend/APT/APTRanges.cpp:58
+#: ../src/backend/APT/APTRanges.cpp:59
msgid "Unable to read range table entry"
msgstr "Kann Rangetabelleneintrag nich lesen"
-#: ../src/backend/APT/APTRanges.cpp:59
+#: ../src/backend/APT/APTRanges.cpp:60
msgid ""
"Error reading file, unexpected format, are you sure it is a proper range "
"file?"
@@ -5024,31 +4976,35 @@ msgstr ""
"Fehler beim Lesen der Datei: Unerwartetes Format, sind Sie sicher, dass dies "
"eine korrekte Rangedatei ist?"
-#: ../src/backend/APT/APTRanges.cpp:60
+#: ../src/backend/APT/APTRanges.cpp:61
msgid ""
"Too many ranges appeared to have range entries with no usable data (eg, all "
"blank)"
msgstr "Zu viele Ranges scheinen ungültige Einträge zu haben (z.B. alle leer)"
-#: ../src/backend/APT/APTRanges.cpp:61
+#: ../src/backend/APT/APTRanges.cpp:62
msgid ""
"Range file appears to contain malformed data, check things like start and "
"ends of m/c are not equal or flipped."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:62
+#: ../src/backend/APT/APTRanges.cpp:63
msgid "Range file appears to be inconsistent (eg, overlapping ranges)"
msgstr "Rangedatei schein inkonsistent zu sein (z.B. überlappende Ranges)"
-#: ../src/backend/APT/APTRanges.cpp:63
+#: ../src/backend/APT/APTRanges.cpp:64
msgid "No ion name mapping found for multiple ion."
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:64
+#: ../src/backend/APT/APTRanges.cpp:65
msgid "Polyatomic extension range matches multiple masses in first section"
msgstr ""
-#: ../src/backend/APT/APTRanges.cpp:1387
+#: ../src/backend/APT/APTRanges.cpp:66
+msgid "Range file is exceedingly large. Refusing to open"
+msgstr ""
+
+#: ../src/backend/APT/APTRanges.cpp:1403
msgid ""
"Range headings do not match order of the ions listed in the name "
"specifications. The name specification ordering will be used when reading "
@@ -5057,15 +5013,19 @@ msgid ""
"Check range-species associations actually match what you expect."
msgstr ""
-#: ../src/backend/filter.cpp:45
+#: ../src/backend/filter.cpp:46
+msgid "2D Plot"
+msgstr ""
+
+#: ../src/backend/filter.cpp:47
msgid "Draw"
msgstr "Zeichnen"
-#: ../src/backend/filter.cpp:47
+#: ../src/backend/filter.cpp:49
msgid "Voxel"
msgstr "Voxel"
-#: ../src/wx/wxcomponents.h:98
+#: ../src/wx/wxcomponents.h:82
msgid "treeCtrl"
msgstr ""
@@ -5073,7 +5033,7 @@ msgstr ""
msgid "Ion. Transform"
msgstr "Ion. Transformieren"
-#: ../src/backend/filters/ionColour.h:61
+#: ../src/backend/filters/ionColour.h:63
msgid "Spectral Colour"
msgstr "Spectral Farbe"
@@ -5089,7 +5049,7 @@ msgstr "Ion Sampler"
msgid "Ion info"
msgstr "Ioneninfo"
-#: ../src/backend/filters/dataLoad.h:136
+#: ../src/backend/filters/dataLoad.h:135
msgid "Pos Data"
msgstr "POS-Daten"
@@ -5097,7 +5057,7 @@ msgstr "POS-Daten"
msgid "Ext. Program"
msgstr "Ext. Programm"
-#: ../src/backend/filters/rangeFile.h:89
+#: ../src/backend/filters/rangeFile.h:93
msgid "Ranging"
msgstr "Ranging"
@@ -5212,5 +5172,158 @@ msgid ""
"views"
msgstr ""
+#~ msgid "Inconsistent number of columns found"
+#~ msgstr "Inkonsistente Anzahl an Spalten gefunden"
+
+#~ msgid "Tile "
+#~ msgstr "Tile "
+
+#~ msgid "Filter Defaults"
+#~ msgstr "Filtervoreinstellungen"
+
+#~ msgid "Notice"
+#~ msgstr "Notiz"
+
+#~ msgid "For security reasons, defaults are not modifiable for this filter"
+#~ msgstr ""
+#~ "Aus Sicherheitsgründen können die Voreinstellungen für diesen Filter "
+#~ "nicht geändert werden."
+
+#~ msgid "Pref"
+#~ msgstr "Pref"
+
+#~ msgid "New stash name...."
+#~ msgstr "Neuer Stashname..."
+
+#~ msgid ""
+#~ "Range Files (*rng; *env; *rrng)|*rng;*env;*rrng|RNG File (*.rng)|*.rng|"
+#~ "Environment File (*.env)|*.env|RRNG Files (*.rrng)|*.rrng|All Files (*)|*"
+#~ msgstr ""
+#~ "Rangedatei (*rng; *env; *rrng)|*rng;*env;*rrng|RNG File (*.rng)|*.rng|"
+#~ "Environment Datei (*.env)|*.env|RRNG Files (*.rrng)|*.rrng|Alle Dateien "
+#~ "(*)|*"
+
+#~ msgid "Next Fullscreen mode: none"
+#~ msgstr "Nächster Vollbildmodus: keiner"
+
+#~ msgid "Next Fullscreen mode: complete"
+#~ msgstr "Nächster Vollbildmodus: vollständig"
+
+#~ msgid "Next Fullscreen mode: with toolbars"
+#~ msgstr "Nächster Vollbildmodus: mit Werkzeugleisten"
+
+#~ msgid "Next Mode: No fullscreen"
+#~ msgstr "Nächster Modus: Kein Vollbild"
+
+#~ msgid "Next Mode: fullscreen w/o toolbar"
+#~ msgstr "Nächster Modus: Vollbild ohne Werkzeugleiste"
+
+#~ msgid "Next Mode: fullscreen with toolbar"
+#~ msgstr "Nächster Modus: Vollbild mit Werkzeugleiste"
+
+#~ msgid "displays this message"
+#~ msgstr "zeigt diese Nachricht"
+
+#~ msgid "inputfile"
+#~ msgstr "Eingabedatei"
+
+#~ msgid "Error processing command line"
+#~ msgstr "Fehler beim Ausführen der Kommandozeile"
+
+#~ msgid "Unable to set working directory"
+#~ msgstr "Kann Arbeitsverzeichnis nicht festlegen"
+
+#~ msgid "Error saving posfile result for external program"
+#~ msgstr "Fehler beim Speichern von Posdateiergebnis für externes Programm"
+
+#~ msgid "Error saving plot result for externalprogram"
+#~ msgstr "Fehler beim Speichern von Posdateiergebnis für externes Programm"
+
+#~ msgid "Error creating temporary directory"
+#~ msgstr "Fehler beim Anlegen des temporären Verzeichnisses"
+
+#~ msgid "Detected unusable number of columns in plot"
+#~ msgstr "Detected unusable number of columns in plot"
+
+#~ msgid "Unable to parse plot result from external program"
+#~ msgstr "Unable to parse plot result from external program"
+
+#~ msgid "Unable to load ions from external program"
+#~ msgstr "Kann Ionen von externem Programm nicht laden"
+
+#~ msgid "Unable to perform commandline substitution"
+#~ msgstr "Unable to perform commandline substitution"
+
+#~ msgid "Error executing external program"
+#~ msgstr "Fehler beim Ausführen von externem Programm"
+
+#~ msgid "Clustering aborted"
+#~ msgstr "Clustering abgebrochen"
+
+#~ msgid "No core ions for cluster"
+#~ msgstr "Keine Kernionen für Cluster"
+
+#~ msgid "No bulk ions for cluster"
+#~ msgstr "Keine Bulkionen für Cluster"
+
+#~ msgid "Voxelisation aborted"
+#~ msgstr "Voxelisation abgebrochen"
+
+#~ msgid "Out of memory"
+#~ msgstr "Zu wenig Speicher"
+
+#~ msgid "Unable to perform filter convolution"
+#~ msgstr "Kann Filter convolution nicht durchführen"
+
+#~ msgid "Voxelisation bounds are invalid"
+#~ msgstr "Voxelisation Grenzen sin ungültig"
+
+#~ msgid "Too many bins in comp. profile."
+#~ msgstr "Zu viele Bins im Konzentrationsprofil."
+
+#~ msgid "Not enough memory for comp. profile."
+#~ msgstr "Nicht genug Speicher für Konz.-Profil."
+
+#~ msgid "Aborted composition prof."
+#~ msgstr "Konzentrationspr. abgebr."
+
+#~ msgid "Spatial analysis aborted by user"
+#~ msgstr "Spatial analysis aborted by user"
+
+#~ msgid "Insufficient data to complete analysis."
+#~ msgstr "Ungenügend Daten zum Fertigstellen der Analyse."
+
+#~ msgid "Unable to allocate memory"
+#~ msgstr "Kann Speicher nicht zuweisen"
+
+#~ msgid "Downsample Aborted"
+#~ msgstr "Datenreduktion abgebrochen"
+
+#~ msgid "Insuffient memory for downsample"
+#~ msgstr "Nicht genug Speicher zur Datenreduktion"
+
+#~ msgid "Insufficient memory for operation"
+#~ msgstr "Nicht genügend Speicher für Operation"
+
+#~ msgid "Bug? Problem with qhull library, cannot run convex hull."
+#~ msgstr ""
+#~ "Bug? Problem mit qhull Bibliothek. Kann convex hull nicht ausführen."
+
+#~ msgid "Insufficient memory for spectrum filter."
+#~ msgstr "Nicht genügend Speicher für Spektrumfilter"
+
+#~ msgid "Bad bincount value in spectrum filter."
+#~ msgstr "Falsche Binanzahl im Spektrumfilter."
+
+#~ msgid "Ranging aborted by user"
+#~ msgstr "Ranging durch User abgebrochen"
+#~ msgid "Insufficient memory for range"
+#~ msgstr "Nicht genug Speicher für Range"
+#~ msgid ""
+#~ " Unable to merge stashes correctly. This is improbable, so please report "
+#~ "this."
+#~ msgstr ""
+#~ " Kann stashes nicht korrekt zusammenführen. Dies ist nicht möglich bitte "
+#~ "melden Sie das."
diff --git a/translations/makeTranslations b/translations/makeTranslations
index 6f176d8..1be87fe 100755
--- a/translations/makeTranslations
+++ b/translations/makeTranslations
@@ -6,7 +6,7 @@
#follow some random poorly documented hierarchy and naming system. (Looking at you gettextize!)
#extract program name from sources -- Now with added case sensitivity hack!
-PROGRAM_NAME=`cat ../src/common/basics.cpp | grep PROGRAM_NAME | awk -F= '{print $2}' | sed 's/;//g' | sed 's/\"//g' | sed 's/;//' | sed 's/^\s*//'`
+PROGRAM_NAME=`cat ../src/common/constants.cpp | grep PROGRAM_NAME | awk -F= '{print $2}' | sed 's/;//g' | sed 's/\"//g' | sed 's/;//' | sed 's/^\s*//'`
#Where do we want to install the translations? (if using this script).
TRANSLATION_INSTALL="/usr/share/locale/"
@@ -15,6 +15,10 @@ MAINTAINED_LOCALES="de_DE"
echo "Program name is $PROGRAM_NAME"
+if [ x"$PROGRAM_NAME" == x"" ] ; then
+ echo "Unable to extract program name. Aborting"
+ exit 1;
+fi
if [ $# -eq 0 ] ; then
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/3depict.git
More information about the debian-science-commits
mailing list