Split of jkqtcommon/jkqtptools.h into several smaller units

This commit is contained in:
jkriege2 2019-05-22 22:20:00 +02:00
parent 0daa30cd45
commit 212233aed6
18 changed files with 1439 additions and 1000 deletions

View File

@ -1,17 +1,32 @@
/*!
\defgroup jkqtptools Tool Functions and Definitions for JKQTPlotter
\defgroup jkqtptools Support Function library (e.g. for JKQTPlotter)
This group contains a set of tools that I've written over the years to enhance the
C++ standard library.
This group contains several tool functions and datatypesthat are neccessary for
JKQTPlotter, JKQTMathtext and the other major classes in this library, but may
also be used separately. The functions and datatypes are sorted into several
functionaly groups.
\defgroup jkqtpplotterclasses_tools Support Classes/Structs/Functions for JKQTPlotter&JKQTBasePlotter
\defgroup jkqtptools_algorithms Diverse Algorithms
\ingroup jkqtptools
\defgroup jkqtptools_math Tools for Mathematical Computations & Equation Parsing
\defgroup jkqtptools_math Mathematical Computations & Equation Parsing
\ingroup jkqtptools
\defgroup jkqtptools_string String Tool Functions
\defgroup jkqtptools_math_basic Basic Math Functions
\ingroup jkqtptools_math
\defgroup jkqtptools_math_statistics Tools for Statistical Computations
\ingroup jkqtptools_math
\defgroup jkqtptools_math_array Data Array Tools
\ingroup jkqtptools_math
\defgroup jkqtptools_math_linalg Linear Algebra Tools
\ingroup jkqtptools_math
\defgroup jkqtptools_string String/String-Conversion Tool Functions
\ingroup jkqtptools
\defgroup jkqtptools_qt Additional Tools for Qt
@ -26,6 +41,12 @@ C++ standard library.
\defgroup jkqtptools_debugging Debugging Tools
\ingroup jkqtptools
\defgroup jkqtptools_codestructuring Code Structuring Tools
\ingroup jkqtptools
\defgroup jkqtptools_enums Enums for JKQTPlotter (including String Conversion)
\ingroup jkqtptools
@ -56,6 +77,9 @@ Examples:
- \ref JKQTPlotterImagePlotRGBOpenCV
.
\defgroup jkqtpplottersupprt Support Classes and Functions
\ingroup jkqtplotter
\defgroup jkqtpplotterclasses Plotter Class & Plotter Widget
\ingroup jkqtplotter

View File

@ -12,10 +12,18 @@
}
HEADERS += $$PWD/jkqtcommon/jkqtp_imexport.h \
$$PWD/jkqtcommon/jkqtptools.h
$$PWD/jkqtcommon/jkqtptools.h \
$$PWD/jkqtcommon/jkqtptoolsdebugging.h \
$$PWD/jkqtcommon/jkqtpcommonmathtools.h \
$$PWD/jkqtcommon/jkqtpalgorithms.h \
$$PWD/jkqtcommon/jkqtpstringtools.h
SOURCES += $$PWD/jkqtcommon/jkqtptools.cpp
SOURCES += $$PWD/jkqtcommon/jkqtptools.cpp \
$$PWD/jkqtcommon/jkqtptoolsdebugging.cpp \
$$PWD/jkqtcommon/jkqtpcommonmathtools.cpp \
$$PWD/jkqtcommon/jkqtpalgorithms.cpp \
$$PWD/jkqtcommon/jkqtpstringtools.cpp
INCLUDEPATH += $$PWD

View File

@ -0,0 +1,24 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
the Free Software Foundation, either version 2.1 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 Lesser General Public License (LGPL) for more details.
You should have received a copy of the GNU Lesser General Public License (LGPL)
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jkqtcommon/jkqtpalgorithms.h"

View File

@ -0,0 +1,156 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTPALGORITHMS_H_INCLUDED
#define JKQTPALGORITHMS_H_INCLUDED
#include "jkqtcommon/jkqtp_imexport.h"
/*! \brief swap two elements \a l and \a r in an array \a a
\ingroup jkqtptools_algorithms
*/
template <class T>
inline void jkqtpSwap(T* a, int l, int r){
const T tmp=a[l];
a[l]=a[r];
a[r]=tmp;
}
/*! \brief QuickSort (recursive implementation)
\ingroup jkqtptools_algorithms
\internal
implementation from http://www.linux-related.de/index.html?/coding/sort/sort_quick.htm
*/
template <class T>
inline void jkqtpQuicksort(T* a, int l, int r){
if(r>l){
int i=l-1;
int j=r;
for(;;){
while(a[++i]<a[r]);
while(a[--j]>a[r] && j>i);
if(i>=j) break;
jkqtpSwap<T>(a, i, j);
}
jkqtpSwap<T>(a, i, r);
jkqtpQuicksort(a, l, i-1);
jkqtpQuicksort(a, i+1, r);
}
}
/*! \brief QuickSort (recursive implementation), sorts \a a2 alongside \a a, using \a a as sort criterion
\ingroup jkqtptools_algorithms
\internal
implementation from http://www.linux-related.de/index.html?/coding/sort/sort_quick.htm
*/
template <class T, class T2>
inline void jkqtpQuicksortDual(T* a, T2* a2, int l, int r){
if(r>l){
int i=l-1;
int j=r;
for(;;){
while(a[++i]<a[r]);
while(a[--j]>a[r] && j>i);
if(i>=j) break;
jkqtpSwap(a, i, j);
jkqtpSwap(a2, i, j);
}
jkqtpSwap(a, i, r);
jkqtpSwap(a2, i, r);
jkqtpQuicksortDual(a, a2, l, i-1);
jkqtpQuicksortDual(a, a2, i+1, r);
}
}
/*! \brief sort the given array and return the result in \a output (implies a copy!!!)
\ingroup jkqtptools_algorithms
\param input array to be sorted
\param N size of the array input
\param output if \c !=nullptr data is written here (the memory location pointed at by \a output has to have at least the length \a N !!!),
otherwise the array input is sorted inplace.
*/
template <class T>
inline void jkqtpQuicksort(const T* input, long long N, T* output) {
if ((!input)) return ;
if (N<=0) return;
T* data=output;
memcpy(output, input, N*sizeof(T));
jkqtpQuicksort(data, 0, N-1);
}
/*! \brief sort the given arrays, using \a input as sort criterion
\ingroup jkqtptools_algorithms
\param input array to be sorted (the sort criterion)
\param input2 array to be sorted (sorted alongside \a input )
\param N size of the array input
*/
template <class T, class T2>
inline void jkqtpQuicksortDual(T* input, T2* input2, int N) {
if ((!input)) return ;
if (N<=0) return;
jkqtpQuicksortDual(input, input2, 0, N-1);
}
/*! \brief sort the given arrays, using \a input as sort criterion, returns the results in \a output and \a output2 (implied copies of the data!)
\ingroup jkqtptools_algorithms
\param input array to be sorted (the sort criterion)
\param input2 array to be sorted (sorted alongside \a input )
\param N size of the array input
\param output result is written here (the memory location pointed at by \a output has to have at least the length \a N !!!),
otherwise the array input is sorted inplace.
\param output2 result is written here (the memory location pointed at by \a output has to have at least the length \a N !!!),
otherwise the array input is sorted inplace.
*/
template <class T, class T2>
inline void jkqtpQuicksortDual(const T* input, const T2* input2, int N, T* output, T2* output2) {
if ((!input)) return ;
if (N<=0) return;
T* data=output;
memcpy(output, input, N*sizeof(T));
T2* data2=output2;
memcpy(output2, input2, N*sizeof(T2));
jkqtpQuicksortDual(data, data2, 0, N-1);
}
#endif // JKQTPALGORITHMS_H_INCLUDED

View File

@ -0,0 +1,25 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
the Free Software Foundation, either version 2.1 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 Lesser General Public License (LGPL) for more details.
You should have received a copy of the GNU Lesser General Public License (LGPL)
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jkqtcommon/jkqtpcommonmathtools.h"
#include <cmath>

View File

@ -0,0 +1,159 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTPCOMMONMATHTOOLS_H_INCLUDED
#define JKQTPCOMMONMATHTOOLS_H_INCLUDED
#include "jkqtcommon/jkqtp_imexport.h"
#include <cmath>
#include <QPoint>
#include <QPointF>
#include <vector>
/*! \brief \f$ \sqrt{\pi}=2.50662827463 \f$
\ingroup jkqtptools_math_basic
*/
#define JKQTPSTATISTICS_SQRT_2PI 2.50662827463
/** \brief double-value NotANumber
* \ingroup jkqtptools_math_basic
*/
#define JKQTP_DOUBLE_NAN (std::numeric_limits<double>::signaling_NaN())
/** \brief float-value NotANumber
* \ingroup jkqtptools_math_basic
*/
#define JKQTP_FLOAT_NAN (std::numeric_limits<float>::signaling_NaN())
/** \brief double-value NotANumber
* \ingroup jkqtptools_math_basic
*/
#define JKQTP_NAN JKQTP_DOUBLE_NAN
/** \brief wandelt einen Datentyp in einen double um, wird von JKQTPDatastore zur Wandlung benutzt
* \ingroup jkqtptools_math_basic
*
* Diese Funktion nutzt per default static_cast<double>(), kann aber für spezielle Datentypen überschrieben werden, etwa für bool
*/
template<typename T>
inline constexpr double jkqtp_todouble(const T& d) {
return static_cast<double>(d);
}
/** \brief wandelt einen boolean in einen double um, wird von JKQTPDatastore zur Wandlung benutzt,
* Spezialisierung für bool (true -> 1.0, false -> 0.0)
* \ingroup jkqtptools_math_basic */
template<>
inline constexpr double jkqtp_todouble(const bool& d) {
return static_cast<double>((d)?1.0:0.0);
}
/** \brief round a double using round() and convert it to a specified type T (static_cast!)
* \ingroup jkqtptools_math_basic */
template<typename T>
inline T jkqtp_roundTo(const double& v) {
return static_cast<T>(round(v));
}
/** \brief compare two floats \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
* \ingroup jkqtptools_math_basic */
inline bool jkqtp_approximatelyEqual(float a, float b, float epsilon=2.0*std::numeric_limits<float>::epsilon())
{
return fabsf(a - b) <= epsilon;
}
/** \brief compare two doubles \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
* \ingroup jkqtptools_math_basic */
inline bool jkqtp_approximatelyEqual(double a, double b, double epsilon=2.0*std::numeric_limits<double>::epsilon())
{
return fabs(a - b) <= epsilon;
}
/** \brief returns the quare of the value \a v, i.e. \c v*v
* \ingroup jkqtptools_math_basic */
template<typename T>
inline T jkqtp_sqr(const T& v) {
return v*v;
}
/*! \brief 4-th power of a number
\ingroup jkqtptools_math_basic
*/
template <class T>
inline T jkqtp_pow4(T x) {
const T xx=x*x;
return xx*xx;
}
/*! \brief cube of a number
\ingroup jkqtptools_math_basic
*/
template <class T>
inline T jkqtp_cube(T x) {
return x*x*x;
}
/*! \brief calculates the sign of number \a x
\ingroup jkqtptools_math_basic
*/
template <class T>
inline T jkqtp_sign(T x) {
if (x<0) return -1;
//else if (x==0) return 0;
else return 1;
}
/** \brief calculate the distance between two QPointF points
* \ingroup jkqtptools_math_basic
*
*/
inline double jkqtp_distance(const QPointF& p1, const QPointF& p2){
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
}
/** \brief calculate the distance between two QPoint points
* \ingroup jkqtptools_math_basic
*
*/
inline double jkqtp_distance(const QPoint& p1, const QPoint& p2){
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
}
/** \brief check whether the dlotaing point number is OK (i.e. non-inf, non-NAN)
* \ingroup jkqtptools_math_basic
*/
template <typename T>
inline bool JKQTPIsOKFloat(T v) {
return std::isfinite(v)&&(!std::isinf(v))&&(!std::isnan(v));
}
#endif // JKQTPCOMMONMATHTOOLS_H_INCLUDED

View File

@ -0,0 +1,564 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
the Free Software Foundation, either version 2.1 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 Lesser General Public License (LGPL) for more details.
You should have received a copy of the GNU Lesser General Public License (LGPL)
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jkqtcommon/jkqtpstringtools.h"
#include <cmath>
#include <QDebug>
#include <QSet>
#include <QApplication>
#include <QClipboard>
#include <QKeyEvent>
#include <QAction>
#include <QLocale>
#include <QDialog>
#include <QCheckBox>
#include <QGridLayout>
#include <QLabel>
#include <QPrinter>
#include <QHeaderView>
#include <QPrintDialog>
#include <QDialogButtonBox>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <ctype.h>
#include <sstream>
#include <locale>
std::string jkqtp_tolower(const std::string& s){
std::string d;
d="";
std::locale loc;
if (s.length()>0) {
for (unsigned long i=0; i<s.length(); i++) {
d+=std::tolower(s[i], loc);
}
}
return d;
};
bool jkqtp_strtobool(const std::string& data){
std::string d=jkqtp_tolower(data);
if (d=="true") return true;
if (d=="t") return true;
if (d=="1") return true;
if (d=="j") return true;
if (d=="y") return true;
if (d=="yes") return true;
if (d=="ja") return true;
return false;
}
std::string jkqtp_toupper(const std::string& s){
std::string d;
d="";
std::locale loc;
if (s.length()>0) {
for (unsigned long i=0; i<s.length(); i++) {
d+=std::toupper(s[i], loc);
}
}
return d;
};
std::string jkqtp_format(const std::string& templ, ...){
va_list ap;
char buffer[4096];
va_start (ap, templ);
vsprintf (buffer, templ.c_str(), ap);
va_end (ap);
std::string ret(buffer);
return ret;
};
std::string jkqtp_bytestostr(double bytes){
double data=bytes;
std::string form="%.0lf";
std::string res=jkqtp_format(form,data);
form="%.3lf";
if (fabs(data)>=1024.0) res=jkqtp_format(form,data/1024.0)+" k";
if (fabs(data)>=1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0))+" M";
if (fabs(data)>=1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0))+" ";
if (fabs(data)>=1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0))+" G";
if (fabs(data)>=1024.0*1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0*1024.0))+" T";
if (fabs(data)>=1024.0*1024.0*1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0*1024.0*1024.0))+" E";
if (fabs(data)==0) res="0 ";
return res+"Bytes";
}
std::string jkqtp_inttostr(long data){
return jkqtp_format("%ld", data);
};
std::string jkqtp_inttohex(long data){
return jkqtp_format("%lX", data);
};
std::string jkqtp_uinttostr(unsigned long data){
std::ostringstream ost;
ost<<data;
return ost.str();
};
std::string jkqtp_floattostr(double data, int past_comma, bool remove_trail0, double belowIsZero){
if (belowIsZero>0) {
if (fabs(data)<belowIsZero) return std::string("0");
}
std::string form="%."+jkqtp_inttostr(past_comma)+"lf";
//std::string form="%lf";
if (past_comma<=0) form="%lf";
std::string r=jkqtp_format(form,data);
//std::cout<<r<<std::endl;
if (remove_trail0 && (jkqtp_tolower(r).find('e')==std::string::npos)) {
if (data==0) return "0";
//size_t cp=r.find(".");
//if (cp<r.size()) return r;
std::string re;
size_t dpos=r.find('.');
if (dpos==std::string::npos) {
return r;
} else {
long i=r.size()-1;
bool nonz=false;
while (i>=0) {
//std::cout<<i<<"\n";
if (r[i]!='0') {
nonz=true;
}
if (nonz || (i<long(dpos))) {
if (re.size()==0 && r[i]=='.') {
// swallow decimal dot, if only 0 folowed
} else {
re=r[i]+re;
}
}
i--;
}
return re;
}
}
return r;
}
std::string jkqtp_floattounitstr(double dataa, const std::string& unitname){
if (dataa==0) return jkqtp_floattostr(dataa)+unitname;
std::string u="";
double factor=1;
double data=fabs(dataa);
if (data>=1e3) { u="k"; factor=1e3; }
if (data>=1e6) { u="M"; factor=1e6; }
if (data>=1e9) { u="G"; factor=1e9; }
if (data>=1e12) { u="T"; factor=1e12; }
if (data>=1e15) { u="P"; factor=1e15; }
if (data>=1e18) { u="E"; factor=1e18; }
if (data<1) {u="m"; factor=1e-3; }
if (data<1e-3) {u="u"; factor=1e-6; }
if (data<1e-6) {u="n"; factor=1e-9; }
if (data<1e-9) {u="p"; factor=1e-12; }
if (data<1e-12) {u="f"; factor=1e-15; }
if (data<1e-15) {u="a"; factor=1e-18; }
return jkqtp_floattostr(dataa/factor)+u+unitname;
};
std::string jkqtp_floattounitstr(double data, int past_comma, bool remove_trail0){
if (data==0) return "0";
std::string form="%."+jkqtp_inttostr(past_comma)+"lf";
std::string res=jkqtp_format(form,data);
if (fabs(data)>=1e3) res=jkqtp_format(form,data/1e3)+"k";
if (fabs(data)>=1e6) res=jkqtp_format(form,data/1e6)+"M";
if (fabs(data)>=1e9) res=jkqtp_format(form,data/1e9)+"G";
if (fabs(data)>=1e12) res=jkqtp_format(form,data/1e12)+"T";
if (fabs(data)>=1e15) res=jkqtp_format(form,data/1e15)+"P";
if (fabs(data)<1) res=jkqtp_format(form,data/1e-3)+"m";
if (fabs(data)<1e-3) res=jkqtp_format(form,data/1e-6)+"u";
if (fabs(data)<1e-6) res=jkqtp_format(form,data/1e-9)+"n";
if (fabs(data)<1e-9) res=jkqtp_format(form,data/1e-12)+"f";
if (fabs(data)==0) res=jkqtp_format(form,data);
if (remove_trail0) {
if (data==0) return "0";
if (res.find('.')==std::string::npos) return res;
size_t i=res.size()-1;
while (i>0 && res[i]=='0') {
i--;
}
if (res[i]=='.') i--; // remove decimal divider
return res.erase(i+1);
}
return res;
}
std::string jkqtp_floattolatexstr(double data, int past_comma, bool remove_trail0, double belowIsZero, double minNoExponent, double maxNoExponent){
if ((belowIsZero>0) && (fabs(data)<belowIsZero)) return "\\rm{0}";
if (data==0) return "\\rm{0}";
double adata=fabs(data);
std::string res=jkqtp_floattostr(data, past_comma, remove_trail0);
/*std::string form="%."+inttostr(past_comma)+"lf";
std::string res=jkqtp_format(form,data);
std::string s="";
if (data<0) s="-";*/
long exp=(long)floor(log(adata)/log(10.0));
//std::cout<<"data="<<data<<" res="<<res<<" exp="<<exp<<" past_comma="<<past_comma<<std::endl;
//if (exp==0 || exp==-1 || exp==1) return res;
if ((minNoExponent<=fabs(data)) && (fabs(data)<=maxNoExponent)) return res;
//if ((-past_comma<exp) && (exp<past_comma)) return res;
//std::cout<<"adata="<<adata<<" log(adata)/log(10)="<<log(adata)/log(10.0)<<" exp="<<exp<<" adata/pow(10, exp)="<<adata/pow(10.0, (double)exp)<<"\n";
std::string v=jkqtp_floattostr(data/pow(10.0, static_cast<double>(exp)), past_comma, remove_trail0);
//std::cout<<"floattolatexstr: v="<<v<<" exp="<<exp<<std::endl;
if (v!="1" && v!="10") return v+std::string("{\\times}10^{")+jkqtp_inttostr(exp)+"}";
if (v=="10") exp=exp+1;
return std::string("10^{")+jkqtp_inttostr(exp)+"}";
}
std::string jkqtp_floattohtmlstr(double data, int past_comma, bool remove_trail0, double belowIsZero, double minNoExponent, double maxNoExponent){
std::string result;
if ((belowIsZero>0) && (fabs(data)<belowIsZero)) return "0";
if (data==0) return "0";
double adata=fabs(data);
std::string res=jkqtp_floattostr(data, past_comma, remove_trail0);
long exp=(long)floor(log(adata)/log(10.0));
if ((minNoExponent<=fabs(data)) && (fabs(data)<maxNoExponent)) return res;
//if ((-past_comma<exp) && (exp<past_comma)) result= res;
else {
std::string v=jkqtp_floattostr(data/pow(10.0, static_cast<double>(exp)), past_comma, remove_trail0);
if (v!="1") result= v+std::string("&times;10<sup>")+jkqtp_inttostr(exp)+"</sup>";
else result=std::string("10<sup>")+jkqtp_inttostr(exp)+"</sup>";
}
//std::cout<<"floattohtmlstr("<<data<<") = '"<<result<<"'\n";
return result;
}
QString jkqtp_QPenStyle2String(Qt::PenStyle style) {
switch(style) {
case Qt::DashLine: return "dash";
case Qt::DotLine: return "dot";
case Qt::DashDotLine: return "dashdot";
case Qt::DashDotDotLine: return "dashdotdot";
default:
case Qt::SolidLine: return "solid";
}
}
Qt::PenStyle jkqtp_String2QPenStyle(const QString& style) {
QString s=style.toLower().trimmed();
if (s=="dash" || s=="--") return Qt::DashLine;
if (s=="dot" || s=="." || s=="..") return Qt::DotLine;
if (s=="dashdot" || s=="-.") return Qt::DashDotLine;
if (s=="dashdotdot" || s=="-..") return Qt::DashDotDotLine;
if (s=="solid" || s=="-") return Qt::SolidLine;
return Qt::SolidLine;
}
QString jkqtp_QBrushStyle2String(Qt::BrushStyle style) {
switch(style) {
case Qt::NoBrush: return "none";
case Qt::Dense1Pattern: return "d1";
case Qt::Dense2Pattern: return "d2";
case Qt::Dense3Pattern: return "d3";
case Qt::Dense4Pattern: return "d4";
case Qt::Dense5Pattern: return "d5";
case Qt::Dense6Pattern: return "d6";
case Qt::Dense7Pattern: return "d7";
case Qt::HorPattern: return "hor";
case Qt::VerPattern: return "ver";
case Qt::CrossPattern: return "cross";
case Qt::BDiagPattern: return "bdiag";
case Qt::FDiagPattern: return "vdiag";
case Qt::DiagCrossPattern: return "diagcross";
/*case Qt::LinearGradientPattern: return "lingrad";
case Qt::RadialGradientPattern: return "radgrad";
case Qt::ConicalGradientPattern: return "congrad";*/
default:
case Qt::SolidPattern: return "solid";
}
}
Qt::BrushStyle jkqtp_String2QBrushStyle(const QString& style) {
QString s=style.toLower().trimmed();
if (s=="none") return Qt::NoBrush;
if (s=="d1") return Qt::Dense1Pattern;
if (s=="d2") return Qt::Dense2Pattern;
if (s=="d3") return Qt::Dense3Pattern;
if (s=="d4") return Qt::Dense4Pattern;
if (s=="d5") return Qt::Dense5Pattern;
if (s=="d6") return Qt::Dense6Pattern;
if (s=="d7") return Qt::Dense7Pattern;
if (s=="hor") return Qt::HorPattern;
if (s=="ver") return Qt::VerPattern;
if (s=="cross") return Qt::CrossPattern;
if (s=="bdiag") return Qt::BDiagPattern;
if (s=="vdiag") return Qt::FDiagPattern;
if (s=="diagcross") return Qt::DiagCrossPattern;
/*if (s=="lingrad") return Qt::LinearGradientPattern;
if (s=="radgrad") return Qt::RadialGradientPattern;
if (s=="congrad") return Qt::ConicalGradientPattern;*/
return Qt::SolidPattern;
}
std::string jkqtp_booltostr(bool data){
if (data) return "true";
return "false";
}
#ifdef rgb
# undef rgb
#endif
#define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b)
static const struct RGBData {
const char *name;
unsigned int value;
} rgbTbl[] = {
{ "aliceblue", rgb(240, 248, 255) },
{ "antiquewhite", rgb(250, 235, 215) },
{ "aqua", rgb( 0, 255, 255) },
{ "aquamarine", rgb(127, 255, 212) },
{ "azure", rgb(240, 255, 255) },
{ "beige", rgb(245, 245, 220) },
{ "bisque", rgb(255, 228, 196) },
{ "black", rgb( 0, 0, 0) },
{ "blanchedalmond", rgb(255, 235, 205) },
{ "blue", rgb( 0, 0, 255) },
{ "blueviolet", rgb(138, 43, 226) },
{ "brown", rgb(165, 42, 42) },
{ "burlywood", rgb(222, 184, 135) },
{ "cadetblue", rgb( 95, 158, 160) },
{ "chartreuse", rgb(127, 255, 0) },
{ "chocolate", rgb(210, 105, 30) },
{ "coral", rgb(255, 127, 80) },
{ "cornflowerblue", rgb(100, 149, 237) },
{ "cornsilk", rgb(255, 248, 220) },
{ "crimson", rgb(220, 20, 60) },
{ "cyan", rgb( 0, 255, 255) },
{ "darkblue", rgb( 0, 0, 139) },
{ "darkcyan", rgb( 0, 139, 139) },
{ "darkgoldenrod", rgb(184, 134, 11) },
{ "darkgray", rgb(169, 169, 169) },
{ "darkgreen", rgb( 0, 100, 0) },
{ "darkgrey", rgb(169, 169, 169) },
{ "darkkhaki", rgb(189, 183, 107) },
{ "darkmagenta", rgb(139, 0, 139) },
{ "darkolivegreen", rgb( 85, 107, 47) },
{ "darkorange", rgb(255, 140, 0) },
{ "darkorchid", rgb(153, 50, 204) },
{ "darkred", rgb(139, 0, 0) },
{ "darksalmon", rgb(233, 150, 122) },
{ "darkseagreen", rgb(143, 188, 143) },
{ "darkslateblue", rgb( 72, 61, 139) },
{ "darkslategray", rgb( 47, 79, 79) },
{ "darkslategrey", rgb( 47, 79, 79) },
{ "darkturquoise", rgb( 0, 206, 209) },
{ "darkviolet", rgb(148, 0, 211) },
{ "deeppink", rgb(255, 20, 147) },
{ "deepskyblue", rgb( 0, 191, 255) },
{ "dimgray", rgb(105, 105, 105) },
{ "dimgrey", rgb(105, 105, 105) },
{ "dodgerblue", rgb( 30, 144, 255) },
{ "firebrick", rgb(178, 34, 34) },
{ "floralwhite", rgb(255, 250, 240) },
{ "forestgreen", rgb( 34, 139, 34) },
{ "fuchsia", rgb(255, 0, 255) },
{ "gainsboro", rgb(220, 220, 220) },
{ "ghostwhite", rgb(248, 248, 255) },
{ "gold", rgb(255, 215, 0) },
{ "goldenrod", rgb(218, 165, 32) },
{ "gray", rgb(128, 128, 128) },
{ "green", rgb( 0, 128, 0) },
{ "greenyellow", rgb(173, 255, 47) },
{ "grey", rgb(128, 128, 128) },
{ "honeydew", rgb(240, 255, 240) },
{ "hotpink", rgb(255, 105, 180) },
{ "indianred", rgb(205, 92, 92) },
{ "indigo", rgb( 75, 0, 130) },
{ "ivory", rgb(255, 255, 240) },
{ "khaki", rgb(240, 230, 140) },
{ "lavender", rgb(230, 230, 250) },
{ "lavenderblush", rgb(255, 240, 245) },
{ "lawngreen", rgb(124, 252, 0) },
{ "lemonchiffon", rgb(255, 250, 205) },
{ "lightblue", rgb(173, 216, 230) },
{ "lightcoral", rgb(240, 128, 128) },
{ "lightcyan", rgb(224, 255, 255) },
{ "lightgoldenrodyellow", rgb(250, 250, 210) },
{ "lightgray", rgb(211, 211, 211) },
{ "lightgreen", rgb(144, 238, 144) },
{ "lightgrey", rgb(211, 211, 211) },
{ "lightpink", rgb(255, 182, 193) },
{ "lightsalmon", rgb(255, 160, 122) },
{ "lightseagreen", rgb( 32, 178, 170) },
{ "lightskyblue", rgb(135, 206, 250) },
{ "lightslategray", rgb(119, 136, 153) },
{ "lightslategrey", rgb(119, 136, 153) },
{ "lightsteelblue", rgb(176, 196, 222) },
{ "lightyellow", rgb(255, 255, 224) },
{ "lime", rgb( 0, 255, 0) },
{ "limegreen", rgb( 50, 205, 50) },
{ "linen", rgb(250, 240, 230) },
{ "magenta", rgb(255, 0, 255) },
{ "maroon", rgb(128, 0, 0) },
{ "mediumaquamarine", rgb(102, 205, 170) },
{ "mediumblue", rgb( 0, 0, 205) },
{ "mediumorchid", rgb(186, 85, 211) },
{ "mediumpurple", rgb(147, 112, 219) },
{ "mediumseagreen", rgb( 60, 179, 113) },
{ "mediumslateblue", rgb(123, 104, 238) },
{ "mediumspringgreen", rgb( 0, 250, 154) },
{ "mediumturquoise", rgb( 72, 209, 204) },
{ "mediumvioletred", rgb(199, 21, 133) },
{ "midnightblue", rgb( 25, 25, 112) },
{ "mintcream", rgb(245, 255, 250) },
{ "mistyrose", rgb(255, 228, 225) },
{ "moccasin", rgb(255, 228, 181) },
{ "navajowhite", rgb(255, 222, 173) },
{ "navy", rgb( 0, 0, 128) },
{ "oldlace", rgb(253, 245, 230) },
{ "olive", rgb(128, 128, 0) },
{ "olivedrab", rgb(107, 142, 35) },
{ "orange", rgb(255, 165, 0) },
{ "orangered", rgb(255, 69, 0) },
{ "orchid", rgb(218, 112, 214) },
{ "palegoldenrod", rgb(238, 232, 170) },
{ "palegreen", rgb(152, 251, 152) },
{ "paleturquoise", rgb(175, 238, 238) },
{ "palevioletred", rgb(219, 112, 147) },
{ "papayawhip", rgb(255, 239, 213) },
{ "peachpuff", rgb(255, 218, 185) },
{ "peru", rgb(205, 133, 63) },
{ "pink", rgb(255, 192, 203) },
{ "plum", rgb(221, 160, 221) },
{ "powderblue", rgb(176, 224, 230) },
{ "purple", rgb(128, 0, 128) },
{ "red", rgb(255, 0, 0) },
{ "rosybrown", rgb(188, 143, 143) },
{ "royalblue", rgb( 65, 105, 225) },
{ "saddlebrown", rgb(139, 69, 19) },
{ "salmon", rgb(250, 128, 114) },
{ "sandybrown", rgb(244, 164, 96) },
{ "seagreen", rgb( 46, 139, 87) },
{ "seashell", rgb(255, 245, 238) },
{ "sienna", rgb(160, 82, 45) },
{ "silver", rgb(192, 192, 192) },
{ "skyblue", rgb(135, 206, 235) },
{ "slateblue", rgb(106, 90, 205) },
{ "slategray", rgb(112, 128, 144) },
{ "slategrey", rgb(112, 128, 144) },
{ "snow", rgb(255, 250, 250) },
{ "springgreen", rgb( 0, 255, 127) },
{ "steelblue", rgb( 70, 130, 180) },
{ "tan", rgb(210, 180, 140) },
{ "teal", rgb( 0, 128, 128) },
{ "thistle", rgb(216, 191, 216) },
{ "tomato", rgb(255, 99, 71) },
{ "transparent", 0 },
{ "turquoise", rgb( 64, 224, 208) },
{ "violet", rgb(238, 130, 238) },
{ "wheat", rgb(245, 222, 179) },
{ "white", rgb(255, 255, 255) },
{ "whitesmoke", rgb(245, 245, 245) },
{ "yellow", rgb(255, 255, 0) },
{ "yellowgreen", rgb(154, 205, 50) }
};
static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData);
QString jkqtp_rgbtostring(unsigned char r, unsigned char g, unsigned char b, unsigned char a, bool useSpecialTransparencySyntax) {
if (a==255) {// only for non-transparent colors
for (int i=0; i<rgbTblSize; i++) {
if (rgb(r,g,b)==rgbTbl[i].value) {
return rgbTbl[i].name;
}
}
return QString("#%1%2%3").arg(static_cast<int>(r), 2,16,QLatin1Char('0')).arg(static_cast<int>(g), 2,16,QLatin1Char('0')).arg(static_cast<int>(b), 2,16,QLatin1Char('0'));
}
// if we reach this, we have an unnamed transparent color
if (useSpecialTransparencySyntax) {
QString col=jkqtp_rgbtostring(r,g,b,255,false);
return QString("%1,%2").arg(col).arg(static_cast<int>(a), 0, 10);
//return QString("%1,%2%%").arg(col).arg(static_cast<int>(a)*100/255, 0, 10);
} else {
return QString("#%1%2%3%4").arg(static_cast<int>(r), 2,16,QLatin1Char('0')).arg(static_cast<int>(g), 2,16,QLatin1Char('0')).arg(static_cast<int>(b), 2,16,QLatin1Char('0')).arg(static_cast<int>(a), 2,16,QLatin1Char('0'));
}
}
QString jkqtp_QColor2String(QColor color, bool useSpecialTransparencySyntax) {
return jkqtp_rgbtostring(static_cast<unsigned char>((color).red()),
static_cast<unsigned char>((color).green()),
static_cast<unsigned char>((color).blue()),
static_cast<unsigned char>((color).alpha()),
useSpecialTransparencySyntax);
}
QColor jkqtp_String2QColor(const QString &color)
{
QRegExp rxP("(.+)\\s*,\\s*(\\d+\\.?\\d+)\\%");
QRegExp rxNP("(.+)\\s*,\\s*([\\d]+)");
if (rxP.exactMatch(color)) {
QColor col(rxP.cap(1));
double a=QLocale::c().toDouble(rxP.cap(2));
col.setAlphaF(a/100.0);
return col;
}
if (rxNP.exactMatch(color)) {
QColor col(rxNP.cap(1));
double a=QLocale::c().toInt(rxNP.cap(2));
col.setAlphaF(a/255.0);
return col;
}
return QColor(color);
}
std::string jkqtp_to_valid_variable_name(const std::string& input) {
std::string out="";
for (size_t i=0; i<input.size(); i++) {
if (isalpha(input[i])) {
out=out+input[i];
}
if ((isdigit(input[i]))&&(out.size()>0)) out=out+input[i];
if ((input[i]=='_')&&(out.size()>0)) out=out+input[i];
}
return out;
}
std::string jkqtp_chartostr(char data){
std::ostringstream ost;
ost<<data;
return ost.str();
}

View File

@ -0,0 +1,179 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTPSTRINGTOOLS_H_INCLUDED
#define JKQTPSTRINGTOOLS_H_INCLUDED
#include "jkqtcommon/jkqtp_imexport.h"
#include <QString>
#include <QLocale>
#include <QPainter>
/** \brief converts a QT::PenStyle into a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString jkqtp_QPenStyle2String(Qt::PenStyle style);
/** \brief converts a QString into a Qt::PenStyle
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT Qt::PenStyle jkqtp_String2QPenStyle(const QString& style);
/** \brief converts a QT::BrushStyle into a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString jkqtp_QBrushStyle2String(Qt::BrushStyle style);
/** \brief converts a QString into a Qt::BrushStyle
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT Qt::BrushStyle jkqtp_String2QBrushStyle(const QString& style);
/** \brief convert a double to a string, using the loacle "C"
* \ingroup jkqtptools_string
*/
inline QString JKQTPCDoubleToQString(double value) {
QLocale loc=QLocale::c();
loc.setNumberOptions(QLocale::OmitGroupSeparator);
return loc.toString(value, 'g', 18);
}
/** \brief convert a double to a string
* \ingroup jkqtptools_string
*/
inline QString JKQTPDoubleToQString(double value, int prec = 10, char f = 'g', QChar decimalSeparator='.') {
QLocale loc=QLocale::c();
loc.setNumberOptions(QLocale::OmitGroupSeparator);
QString res=loc.toString(value, f, prec);
if (loc.decimalPoint()!=decimalSeparator) {
res=res.replace(loc.decimalPoint(), decimalSeparator);
}
return res;
}
/** \brief convert a string to lower-case characters
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_tolower(const std::string& s);
/** \brief convert a string to a boolean
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT bool jkqtp_strtobool(const std::string& data);
/** \brief convert a string to upper-case
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_toupper(const std::string& s);
/** \brief std::string wrapper around sprintf()
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_format(const std::string& templ, ...);
/** \brief convert a number of bytes to a string, formatting e.g. 1024 as 1kB, ...
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_bytestostr(double bytes);
/** \brief convert an integer to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_inttostr(long data);
/** \brief convert an integer to a hex string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_inttohex(long data);
/** \brief convert an unsigned int to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_uinttostr(unsigned long data);
/** \brief convert a double to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattostr(double data, int past_comma=-1, bool remove_trail0=false, double belowIsZero=1e-16);
/** \brief convert a double to a string, encoding powers of ten as characters, e.g. \c jkqtp_floattounitstr(1000,"g") will result in "1kg"
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattounitstr(double dataa, const std::string& unitname);
/** \brief convert a boolean to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_booltostr(bool data);
/** \brief converts a RGBA color into a string
* \ingroup jkqtptools_string
*
* This returns a QString which contains the name of named colors and the RGBA values in a QT readable form othertwise.
*
* \param r red value of the color to convert
* \param g green value of the color to convert
* \param b blue value of the color to convert
* \param a alpha value of the color to convert
* \param useSpecialTransparencySyntax is set (\c true ), the function uses a special syntax to denote color and transparency: \c color,trans
*/
JKQTP_LIB_EXPORT QString jkqtp_rgbtostring(unsigned char r, unsigned char g, unsigned char b, unsigned char a=255, bool useSpecialTransparencySyntax=true);
/** \brief converts a QColor into a string using the jkqtp_rgbtostring() method.
* \ingroup jkqtptools_string
*
* This returns a QString which contains the name of named colors and the RGBA values in a QT readable form othertwise.
*/
JKQTP_LIB_EXPORT QString jkqtp_QColor2String(QColor color, bool useSpecialTransparencySyntax=true);
/** \brief converts a QString into a QColor, compatible with jkqtp_QColor2String(QColor color);
* \ingroup jkqtptools_string
*
* This returns a QString which contains the name of named colors and the RGBA values in a QT readable form othertwise.
*/
JKQTP_LIB_EXPORT QColor jkqtp_String2QColor(const QString& color);
/** \brief clean a string to be usable as a variable name, e.g. in an expression parser, or a C++-expression
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_to_valid_variable_name(const std::string& input);
/** \brief convert a double to a string, encoding powers of ten as characters, e.g. \c jkqtp_floattounitstr(1000) will result in "1k"
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattounitstr(double data, int past_comma=5, bool remove_trail0=false);
/** \brief convert a double to a string, encoding powers of ten as exponent in LaTeX notation (e.g. <code>-1.23\\cdot 10^{-5}</code>)
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattolatexstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
/** \brief convert a double to a string, encoding powers of ten as exponent with HTML tags
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattohtmlstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
/** \brief convert a character to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_chartostr(char data);
#endif // JKQTPSTRINGTOOLS_H_INCLUDED

View File

@ -46,285 +46,6 @@ Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
#include <locale>
std::string jkqtp_tolower(const std::string& s){
std::string d;
d="";
std::locale loc;
if (s.length()>0) {
for (unsigned long i=0; i<s.length(); i++) {
d+=std::tolower(s[i], loc);
}
}
return d;
};
bool jkqtp_strtobool(const std::string& data){
std::string d=jkqtp_tolower(data);
if (d=="true") return true;
if (d=="t") return true;
if (d=="1") return true;
if (d=="j") return true;
if (d=="y") return true;
if (d=="yes") return true;
if (d=="ja") return true;
return false;
}
std::string jkqtp_toupper(const std::string& s){
std::string d;
d="";
std::locale loc;
if (s.length()>0) {
for (unsigned long i=0; i<s.length(); i++) {
d+=std::toupper(s[i], loc);
}
}
return d;
};
std::string jkqtp_format(const std::string& templ, ...){
va_list ap;
char buffer[4096];
va_start (ap, templ);
vsprintf (buffer, templ.c_str(), ap);
va_end (ap);
std::string ret(buffer);
return ret;
};
std::string jkqtp_bytestostr(double bytes){
double data=bytes;
std::string form="%.0lf";
std::string res=jkqtp_format(form,data);
form="%.3lf";
if (fabs(data)>=1024.0) res=jkqtp_format(form,data/1024.0)+" k";
if (fabs(data)>=1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0))+" M";
if (fabs(data)>=1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0))+" ";
if (fabs(data)>=1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0))+" G";
if (fabs(data)>=1024.0*1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0*1024.0))+" T";
if (fabs(data)>=1024.0*1024.0*1024.0*1024.0*1024.0*1024.0) res=jkqtp_format(form,data/(1024.0*1024.0*1024.0*1024.0*1024.0*1024.0))+" E";
if (fabs(data)==0) res="0 ";
return res+"Bytes";
}
std::string jkqtp_inttostr(long data){
return jkqtp_format("%ld", data);
};
std::string jkqtp_inttohex(long data){
return jkqtp_format("%lX", data);
};
std::string jkqtp_uinttostr(unsigned long data){
std::ostringstream ost;
ost<<data;
return ost.str();
};
std::string jkqtp_floattostr(double data, int past_comma, bool remove_trail0, double belowIsZero){
if (belowIsZero>0) {
if (fabs(data)<belowIsZero) return std::string("0");
}
std::string form="%."+jkqtp_inttostr(past_comma)+"lf";
//std::string form="%lf";
if (past_comma<=0) form="%lf";
std::string r=jkqtp_format(form,data);
//std::cout<<r<<std::endl;
if (remove_trail0 && (jkqtp_tolower(r).find('e')==std::string::npos)) {
if (data==0) return "0";
//size_t cp=r.find(".");
//if (cp<r.size()) return r;
std::string re;
size_t dpos=r.find('.');
if (dpos==std::string::npos) {
return r;
} else {
long i=r.size()-1;
bool nonz=false;
while (i>=0) {
//std::cout<<i<<"\n";
if (r[i]!='0') {
nonz=true;
}
if (nonz || (i<long(dpos))) {
if (re.size()==0 && r[i]=='.') {
// swallow decimal dot, if only 0 folowed
} else {
re=r[i]+re;
}
}
i--;
}
return re;
}
}
return r;
}
std::string jkqtp_floattounitstr(double dataa, const std::string& unitname){
if (dataa==0) return jkqtp_floattostr(dataa)+unitname;
std::string u="";
double factor=1;
double data=fabs(dataa);
if (data>=1e3) { u="k"; factor=1e3; }
if (data>=1e6) { u="M"; factor=1e6; }
if (data>=1e9) { u="G"; factor=1e9; }
if (data>=1e12) { u="T"; factor=1e12; }
if (data>=1e15) { u="P"; factor=1e15; }
if (data>=1e18) { u="E"; factor=1e18; }
if (data<1) {u="m"; factor=1e-3; }
if (data<1e-3) {u="u"; factor=1e-6; }
if (data<1e-6) {u="n"; factor=1e-9; }
if (data<1e-9) {u="p"; factor=1e-12; }
if (data<1e-12) {u="f"; factor=1e-15; }
if (data<1e-15) {u="a"; factor=1e-18; }
return jkqtp_floattostr(dataa/factor)+u+unitname;
};
std::string jkqtp_floattounitstr(double data, int past_comma, bool remove_trail0){
if (data==0) return "0";
std::string form="%."+jkqtp_inttostr(past_comma)+"lf";
std::string res=jkqtp_format(form,data);
if (fabs(data)>=1e3) res=jkqtp_format(form,data/1e3)+"k";
if (fabs(data)>=1e6) res=jkqtp_format(form,data/1e6)+"M";
if (fabs(data)>=1e9) res=jkqtp_format(form,data/1e9)+"G";
if (fabs(data)>=1e12) res=jkqtp_format(form,data/1e12)+"T";
if (fabs(data)>=1e15) res=jkqtp_format(form,data/1e15)+"P";
if (fabs(data)<1) res=jkqtp_format(form,data/1e-3)+"m";
if (fabs(data)<1e-3) res=jkqtp_format(form,data/1e-6)+"u";
if (fabs(data)<1e-6) res=jkqtp_format(form,data/1e-9)+"n";
if (fabs(data)<1e-9) res=jkqtp_format(form,data/1e-12)+"f";
if (fabs(data)==0) res=jkqtp_format(form,data);
if (remove_trail0) {
if (data==0) return "0";
if (res.find('.')==std::string::npos) return res;
size_t i=res.size()-1;
while (i>0 && res[i]=='0') {
i--;
}
if (res[i]=='.') i--; // remove decimal divider
return res.erase(i+1);
}
return res;
}
std::string jkqtp_floattolatexstr(double data, int past_comma, bool remove_trail0, double belowIsZero, double minNoExponent, double maxNoExponent){
if ((belowIsZero>0) && (fabs(data)<belowIsZero)) return "\\rm{0}";
if (data==0) return "\\rm{0}";
double adata=fabs(data);
std::string res=jkqtp_floattostr(data, past_comma, remove_trail0);
/*std::string form="%."+inttostr(past_comma)+"lf";
std::string res=jkqtp_format(form,data);
std::string s="";
if (data<0) s="-";*/
long exp=(long)floor(log(adata)/log(10.0));
//std::cout<<"data="<<data<<" res="<<res<<" exp="<<exp<<" past_comma="<<past_comma<<std::endl;
//if (exp==0 || exp==-1 || exp==1) return res;
if ((minNoExponent<=fabs(data)) && (fabs(data)<=maxNoExponent)) return res;
//if ((-past_comma<exp) && (exp<past_comma)) return res;
//std::cout<<"adata="<<adata<<" log(adata)/log(10)="<<log(adata)/log(10.0)<<" exp="<<exp<<" adata/pow(10, exp)="<<adata/pow(10.0, (double)exp)<<"\n";
std::string v=jkqtp_floattostr(data/pow(10.0, static_cast<double>(exp)), past_comma, remove_trail0);
//std::cout<<"floattolatexstr: v="<<v<<" exp="<<exp<<std::endl;
if (v!="1" && v!="10") return v+std::string("{\\times}10^{")+jkqtp_inttostr(exp)+"}";
if (v=="10") exp=exp+1;
return std::string("10^{")+jkqtp_inttostr(exp)+"}";
}
std::string jkqtp_floattohtmlstr(double data, int past_comma, bool remove_trail0, double belowIsZero, double minNoExponent, double maxNoExponent){
std::string result;
if ((belowIsZero>0) && (fabs(data)<belowIsZero)) return "0";
if (data==0) return "0";
double adata=fabs(data);
std::string res=jkqtp_floattostr(data, past_comma, remove_trail0);
long exp=(long)floor(log(adata)/log(10.0));
if ((minNoExponent<=fabs(data)) && (fabs(data)<maxNoExponent)) return res;
//if ((-past_comma<exp) && (exp<past_comma)) result= res;
else {
std::string v=jkqtp_floattostr(data/pow(10.0, static_cast<double>(exp)), past_comma, remove_trail0);
if (v!="1") result= v+std::string("&times;10<sup>")+jkqtp_inttostr(exp)+"</sup>";
else result=std::string("10<sup>")+jkqtp_inttostr(exp)+"</sup>";
}
//std::cout<<"floattohtmlstr("<<data<<") = '"<<result<<"'\n";
return result;
}
QString jkqtp_QPenStyle2String(Qt::PenStyle style) {
switch(style) {
case Qt::DashLine: return "dash";
case Qt::DotLine: return "dot";
case Qt::DashDotLine: return "dashdot";
case Qt::DashDotDotLine: return "dashdotdot";
default:
case Qt::SolidLine: return "solid";
}
}
Qt::PenStyle jkqtp_String2QPenStyle(const QString& style) {
QString s=style.toLower().trimmed();
if (s=="dash" || s=="--") return Qt::DashLine;
if (s=="dot" || s=="." || s=="..") return Qt::DotLine;
if (s=="dashdot" || s=="-.") return Qt::DashDotLine;
if (s=="dashdotdot" || s=="-..") return Qt::DashDotDotLine;
if (s=="solid" || s=="-") return Qt::SolidLine;
return Qt::SolidLine;
}
QString jkqtp_QBrushStyle2String(Qt::BrushStyle style) {
switch(style) {
case Qt::NoBrush: return "none";
case Qt::Dense1Pattern: return "d1";
case Qt::Dense2Pattern: return "d2";
case Qt::Dense3Pattern: return "d3";
case Qt::Dense4Pattern: return "d4";
case Qt::Dense5Pattern: return "d5";
case Qt::Dense6Pattern: return "d6";
case Qt::Dense7Pattern: return "d7";
case Qt::HorPattern: return "hor";
case Qt::VerPattern: return "ver";
case Qt::CrossPattern: return "cross";
case Qt::BDiagPattern: return "bdiag";
case Qt::FDiagPattern: return "vdiag";
case Qt::DiagCrossPattern: return "diagcross";
/*case Qt::LinearGradientPattern: return "lingrad";
case Qt::RadialGradientPattern: return "radgrad";
case Qt::ConicalGradientPattern: return "congrad";*/
default:
case Qt::SolidPattern: return "solid";
}
}
Qt::BrushStyle jkqtp_String2QBrushStyle(const QString& style) {
QString s=style.toLower().trimmed();
if (s=="none") return Qt::NoBrush;
if (s=="d1") return Qt::Dense1Pattern;
if (s=="d2") return Qt::Dense2Pattern;
if (s=="d3") return Qt::Dense3Pattern;
if (s=="d4") return Qt::Dense4Pattern;
if (s=="d5") return Qt::Dense5Pattern;
if (s=="d6") return Qt::Dense6Pattern;
if (s=="d7") return Qt::Dense7Pattern;
if (s=="hor") return Qt::HorPattern;
if (s=="ver") return Qt::VerPattern;
if (s=="cross") return Qt::CrossPattern;
if (s=="bdiag") return Qt::BDiagPattern;
if (s=="vdiag") return Qt::FDiagPattern;
if (s=="diagcross") return Qt::DiagCrossPattern;
/*if (s=="lingrad") return Qt::LinearGradientPattern;
if (s=="radgrad") return Qt::RadialGradientPattern;
if (s=="congrad") return Qt::ConicalGradientPattern;*/
return Qt::SolidPattern;
}
@ -732,287 +453,6 @@ JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos) {
QPolygonF jkqtpRotateRect(QRectF r, double angle) {
QPolygonF p;
QMatrix m;
m.rotate(angle);
p.append(m.map(r.bottomLeft()));
p.append(m.map(r.bottomRight()));
p.append(m.map(r.topRight()));
p.append(m.map(r.topLeft()));
return p;
}
std::string jkqtp_booltostr(bool data){
if (data) return "true";
return "false";
}
#ifdef rgb
# undef rgb
#endif
#define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b)
static const struct RGBData {
const char *name;
unsigned int value;
} rgbTbl[] = {
{ "aliceblue", rgb(240, 248, 255) },
{ "antiquewhite", rgb(250, 235, 215) },
{ "aqua", rgb( 0, 255, 255) },
{ "aquamarine", rgb(127, 255, 212) },
{ "azure", rgb(240, 255, 255) },
{ "beige", rgb(245, 245, 220) },
{ "bisque", rgb(255, 228, 196) },
{ "black", rgb( 0, 0, 0) },
{ "blanchedalmond", rgb(255, 235, 205) },
{ "blue", rgb( 0, 0, 255) },
{ "blueviolet", rgb(138, 43, 226) },
{ "brown", rgb(165, 42, 42) },
{ "burlywood", rgb(222, 184, 135) },
{ "cadetblue", rgb( 95, 158, 160) },
{ "chartreuse", rgb(127, 255, 0) },
{ "chocolate", rgb(210, 105, 30) },
{ "coral", rgb(255, 127, 80) },
{ "cornflowerblue", rgb(100, 149, 237) },
{ "cornsilk", rgb(255, 248, 220) },
{ "crimson", rgb(220, 20, 60) },
{ "cyan", rgb( 0, 255, 255) },
{ "darkblue", rgb( 0, 0, 139) },
{ "darkcyan", rgb( 0, 139, 139) },
{ "darkgoldenrod", rgb(184, 134, 11) },
{ "darkgray", rgb(169, 169, 169) },
{ "darkgreen", rgb( 0, 100, 0) },
{ "darkgrey", rgb(169, 169, 169) },
{ "darkkhaki", rgb(189, 183, 107) },
{ "darkmagenta", rgb(139, 0, 139) },
{ "darkolivegreen", rgb( 85, 107, 47) },
{ "darkorange", rgb(255, 140, 0) },
{ "darkorchid", rgb(153, 50, 204) },
{ "darkred", rgb(139, 0, 0) },
{ "darksalmon", rgb(233, 150, 122) },
{ "darkseagreen", rgb(143, 188, 143) },
{ "darkslateblue", rgb( 72, 61, 139) },
{ "darkslategray", rgb( 47, 79, 79) },
{ "darkslategrey", rgb( 47, 79, 79) },
{ "darkturquoise", rgb( 0, 206, 209) },
{ "darkviolet", rgb(148, 0, 211) },
{ "deeppink", rgb(255, 20, 147) },
{ "deepskyblue", rgb( 0, 191, 255) },
{ "dimgray", rgb(105, 105, 105) },
{ "dimgrey", rgb(105, 105, 105) },
{ "dodgerblue", rgb( 30, 144, 255) },
{ "firebrick", rgb(178, 34, 34) },
{ "floralwhite", rgb(255, 250, 240) },
{ "forestgreen", rgb( 34, 139, 34) },
{ "fuchsia", rgb(255, 0, 255) },
{ "gainsboro", rgb(220, 220, 220) },
{ "ghostwhite", rgb(248, 248, 255) },
{ "gold", rgb(255, 215, 0) },
{ "goldenrod", rgb(218, 165, 32) },
{ "gray", rgb(128, 128, 128) },
{ "green", rgb( 0, 128, 0) },
{ "greenyellow", rgb(173, 255, 47) },
{ "grey", rgb(128, 128, 128) },
{ "honeydew", rgb(240, 255, 240) },
{ "hotpink", rgb(255, 105, 180) },
{ "indianred", rgb(205, 92, 92) },
{ "indigo", rgb( 75, 0, 130) },
{ "ivory", rgb(255, 255, 240) },
{ "khaki", rgb(240, 230, 140) },
{ "lavender", rgb(230, 230, 250) },
{ "lavenderblush", rgb(255, 240, 245) },
{ "lawngreen", rgb(124, 252, 0) },
{ "lemonchiffon", rgb(255, 250, 205) },
{ "lightblue", rgb(173, 216, 230) },
{ "lightcoral", rgb(240, 128, 128) },
{ "lightcyan", rgb(224, 255, 255) },
{ "lightgoldenrodyellow", rgb(250, 250, 210) },
{ "lightgray", rgb(211, 211, 211) },
{ "lightgreen", rgb(144, 238, 144) },
{ "lightgrey", rgb(211, 211, 211) },
{ "lightpink", rgb(255, 182, 193) },
{ "lightsalmon", rgb(255, 160, 122) },
{ "lightseagreen", rgb( 32, 178, 170) },
{ "lightskyblue", rgb(135, 206, 250) },
{ "lightslategray", rgb(119, 136, 153) },
{ "lightslategrey", rgb(119, 136, 153) },
{ "lightsteelblue", rgb(176, 196, 222) },
{ "lightyellow", rgb(255, 255, 224) },
{ "lime", rgb( 0, 255, 0) },
{ "limegreen", rgb( 50, 205, 50) },
{ "linen", rgb(250, 240, 230) },
{ "magenta", rgb(255, 0, 255) },
{ "maroon", rgb(128, 0, 0) },
{ "mediumaquamarine", rgb(102, 205, 170) },
{ "mediumblue", rgb( 0, 0, 205) },
{ "mediumorchid", rgb(186, 85, 211) },
{ "mediumpurple", rgb(147, 112, 219) },
{ "mediumseagreen", rgb( 60, 179, 113) },
{ "mediumslateblue", rgb(123, 104, 238) },
{ "mediumspringgreen", rgb( 0, 250, 154) },
{ "mediumturquoise", rgb( 72, 209, 204) },
{ "mediumvioletred", rgb(199, 21, 133) },
{ "midnightblue", rgb( 25, 25, 112) },
{ "mintcream", rgb(245, 255, 250) },
{ "mistyrose", rgb(255, 228, 225) },
{ "moccasin", rgb(255, 228, 181) },
{ "navajowhite", rgb(255, 222, 173) },
{ "navy", rgb( 0, 0, 128) },
{ "oldlace", rgb(253, 245, 230) },
{ "olive", rgb(128, 128, 0) },
{ "olivedrab", rgb(107, 142, 35) },
{ "orange", rgb(255, 165, 0) },
{ "orangered", rgb(255, 69, 0) },
{ "orchid", rgb(218, 112, 214) },
{ "palegoldenrod", rgb(238, 232, 170) },
{ "palegreen", rgb(152, 251, 152) },
{ "paleturquoise", rgb(175, 238, 238) },
{ "palevioletred", rgb(219, 112, 147) },
{ "papayawhip", rgb(255, 239, 213) },
{ "peachpuff", rgb(255, 218, 185) },
{ "peru", rgb(205, 133, 63) },
{ "pink", rgb(255, 192, 203) },
{ "plum", rgb(221, 160, 221) },
{ "powderblue", rgb(176, 224, 230) },
{ "purple", rgb(128, 0, 128) },
{ "red", rgb(255, 0, 0) },
{ "rosybrown", rgb(188, 143, 143) },
{ "royalblue", rgb( 65, 105, 225) },
{ "saddlebrown", rgb(139, 69, 19) },
{ "salmon", rgb(250, 128, 114) },
{ "sandybrown", rgb(244, 164, 96) },
{ "seagreen", rgb( 46, 139, 87) },
{ "seashell", rgb(255, 245, 238) },
{ "sienna", rgb(160, 82, 45) },
{ "silver", rgb(192, 192, 192) },
{ "skyblue", rgb(135, 206, 235) },
{ "slateblue", rgb(106, 90, 205) },
{ "slategray", rgb(112, 128, 144) },
{ "slategrey", rgb(112, 128, 144) },
{ "snow", rgb(255, 250, 250) },
{ "springgreen", rgb( 0, 255, 127) },
{ "steelblue", rgb( 70, 130, 180) },
{ "tan", rgb(210, 180, 140) },
{ "teal", rgb( 0, 128, 128) },
{ "thistle", rgb(216, 191, 216) },
{ "tomato", rgb(255, 99, 71) },
{ "transparent", 0 },
{ "turquoise", rgb( 64, 224, 208) },
{ "violet", rgb(238, 130, 238) },
{ "wheat", rgb(245, 222, 179) },
{ "white", rgb(255, 255, 255) },
{ "whitesmoke", rgb(245, 245, 245) },
{ "yellow", rgb(255, 255, 0) },
{ "yellowgreen", rgb(154, 205, 50) }
};
static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData);
QString jkqtp_rgbtostring(unsigned char r, unsigned char g, unsigned char b, unsigned char a, bool useSpecialTransparencySyntax) {
if (a==255) {// only for non-transparent colors
for (int i=0; i<rgbTblSize; i++) {
if (rgb(r,g,b)==rgbTbl[i].value) {
return rgbTbl[i].name;
}
}
return QString("#%1%2%3").arg(static_cast<int>(r), 2,16,QLatin1Char('0')).arg(static_cast<int>(g), 2,16,QLatin1Char('0')).arg(static_cast<int>(b), 2,16,QLatin1Char('0'));
}
// if we reach this, we have an unnamed transparent color
if (useSpecialTransparencySyntax) {
QString col=jkqtp_rgbtostring(r,g,b,255,false);
return QString("%1,%2").arg(col).arg(static_cast<int>(a), 0, 10);
//return QString("%1,%2%%").arg(col).arg(static_cast<int>(a)*100/255, 0, 10);
} else {
return QString("#%1%2%3%4").arg(static_cast<int>(r), 2,16,QLatin1Char('0')).arg(static_cast<int>(g), 2,16,QLatin1Char('0')).arg(static_cast<int>(b), 2,16,QLatin1Char('0')).arg(static_cast<int>(a), 2,16,QLatin1Char('0'));
}
}
QString jkqtp_QColor2String(QColor color, bool useSpecialTransparencySyntax) {
return jkqtp_rgbtostring(static_cast<unsigned char>((color).red()),
static_cast<unsigned char>((color).green()),
static_cast<unsigned char>((color).blue()),
static_cast<unsigned char>((color).alpha()),
useSpecialTransparencySyntax);
}
QColor jkqtp_String2QColor(const QString &color)
{
QRegExp rxP("(.+)\\s*,\\s*(\\d+\\.?\\d+)\\%");
QRegExp rxNP("(.+)\\s*,\\s*([\\d]+)");
if (rxP.exactMatch(color)) {
QColor col(rxP.cap(1));
double a=QLocale::c().toDouble(rxP.cap(2));
col.setAlphaF(a/100.0);
return col;
}
if (rxNP.exactMatch(color)) {
QColor col(rxNP.cap(1));
double a=QLocale::c().toInt(rxNP.cap(2));
col.setAlphaF(a/255.0);
return col;
}
return QColor(color);
}
std::string jkqtp_to_valid_variable_name(const std::string& input) {
std::string out="";
for (size_t i=0; i<input.size(); i++) {
if (isalpha(input[i])) {
out=out+input[i];
}
if ((isdigit(input[i]))&&(out.size()>0)) out=out+input[i];
if ((input[i]=='_')&&(out.size()>0)) out=out+input[i];
}
return out;
}
int JKQTPAutoOutputTimer::global_indent=0;
JKQTPAutoOutputTimer::JKQTPAutoOutputTimer(const QString& message) :
QElapsedTimer()
{
this->indent=QString(global_indent, QLatin1Char(' '));
global_indent+=4;
this->message=message;
#if QT_VERSION >= 0x040800
qDebug()<<this->indent<<"TIMER_START: "<<message;
#else
qDebug()<<this->indent<<"TIMER_START: "<<message;
#endif
start();
}
JKQTPAutoOutputTimer::~JKQTPAutoOutputTimer()
{
#if QT_VERSION >= 0x040800
qDebug()<<this->indent<<"TIMER_END: "<<message<<" DUR: "<<double(nsecsElapsed())/1.0e6<<"ms";
#else
qDebug()<<this->indent<<"TIMER_END: "<<message<<" DUR: "<<double(elapsed())/1.0e3<<"ms";
#endif
global_indent-=4;
}
void JKQTPAutoOutputTimer::write(const QString& message) const {
#if QT_VERSION >= 0x040800
qDebug()<<this->indent<<"TIMER_MESSAGE: "<<this->message<<" "<<message<<" DUR: "<<double(nsecsElapsed())/1.0e6<<"ms";
#else
qDebug()<<this->indent<<"TIMER_MESSAGE: "<<this->message<<" "<<message<<" DUR: "<<double(elapsed())/1.0e3<<"ms";
#endif
}
std::string jkqtp_chartostr(char data){
std::ostringstream ost;
ost<<data;
return ost.str();
}
QString JKQTPSpecialLineType2String(JKQTPSpecialLineType pos)
{

View File

@ -25,9 +25,7 @@
#include <QString>
#include <QElapsedTimer>
#include <QLocale>
#include <QPainter>
#include <cfloat>
#include <QPrinter>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
@ -45,6 +43,10 @@
#include <cstdint>
#include <stdexcept>
#include <cctype>
#include "jkqtpstringtools.h"
#include "jkqtptoolsdebugging.h"
#include "jkqtpcommonmathtools.h"
#include "jkqtpalgorithms.h"
#ifndef __WINDOWS__
@ -75,24 +77,23 @@
class JKQTPEnhancedPainter; // forward
class JKQTBasePlotter; // forward declaration
/** \brief double-value NotANumber
* \ingroup jkqtptools_math
*/
#define JKQTP_DOUBLE_NAN (std::numeric_limits<double>::signaling_NaN())
/** \brief float-value NotANumber
* \ingroup jkqtptools_math
*/
#define JKQTP_FLOAT_NAN (std::numeric_limits<float>::signaling_NaN())
/** \brief double-value NotANumber
* \ingroup jkqtptools_math
*/
#define JKQTP_NAN JKQTP_DOUBLE_NAN
/** \brief C++11 finally construct
* \ingroup jkqtptools
/** \brief C++11 finally construct (executes a callable-object when the edestructor is executed)
* \ingroup jkqtptools_codestructuring
*
* Typical usage:
* \code
* {
* // the instruction 'painter.restore()' will be executed at the end
* // of the block, when __finalpaint is destroyed (see (*) below)
* JKQTPFinalAct __finalpaint([&painter]() { painter.restore(); });
*
* // ...
* // do something ...
* // ...
*
* } // (*) 'painter.restore()' is executed before the end of this block!
* \endcode
*
* \see JKQTPFinally()
*/
@ -123,8 +124,23 @@ private:
bool invoke_;
};
/** \brief C++11 finally construct
* \ingroup jkqtptools_math
/** \brief C++11 finally construct (executes a callable-object at the end of a scope)
* \ingroup jkqtptools_codestructuring
*
* Typical usage:
* \code
* {
* // the instruction 'painter.restore()' will be executed at the end
* // of the block, when __finalpaint is destroyed (see (*) below)
* auto __finalpaint=JKQTPFinally([&painter]() { painter.restore(); });
*
* // ...
* // do something ...
* // ...
*
* } // (*) 'painter.restore()' is executed before the end of this block!
* \endcode
*
* \see JKQTPFinalAct
*/
template <class F>
@ -133,8 +149,23 @@ inline JKQTPFinalAct<F> JKQTPFinally(const F& f) noexcept
return JKQTPFinalAct<F>(f);
}
/** \brief C++11 finally construct
* \ingroup jkqtptools_math
/** \brief C++11 finally construct (executes a callable-object at the end of a scope)
* \ingroup jkqtptools_codestructuring
*
* Typical usage:
* \code
* {
* // the instruction 'painter.restore()' will be executed at the end
* // of the block, when __finalpaint is destroyed (see (*) below)
* auto __finalpaint=JKQTPFinally([&painter]() { painter.restore(); });
*
* // ...
* // do something ...
* // ...
*
* } // (*) 'painter.restore()' is executed before the end of this block!
* \endcode
*
* \see JKQTPFinalAct
*/
template <class F>
@ -143,17 +174,10 @@ inline JKQTPFinalAct<F> JKQTPFinally(F&& f) noexcept
return JKQTPFinalAct<F>(std::forward<F>(f));
}
/** \brief check whether the dlotaing point number is OK (i.e. non-inf, non-NAN)
* \ingroup jkqtptools
*/
template <typename T>
inline bool JKQTPIsOKFloat(T v) {
return std::isfinite(v)&&(!std::isinf(v))&&(!std::isnan(v));
}
/** \brief Styles in which to mark single positions during user actions in JKQTPlotter
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPUserActionMarkerType {
@ -164,13 +188,13 @@ enum JKQTPUserActionMarkerType {
/** \brief convert a JKQTPUserActionMarkerType to a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see String2JKQTPUserActionMarkerType(), JKQTPUserActionMarkerType
*/
JKQTP_LIB_EXPORT QString JKQTPUserActionMarkerType2String(JKQTPUserActionMarkerType act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (created by JKQTPUserActionMarkerType2String() ) to JKQTPUserActionMarkerType
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see JKQTPUserActionMarkerType2String(), JKQTPUserActionMarkerType
*/
@ -180,7 +204,7 @@ JKQTP_LIB_EXPORT JKQTPUserActionMarkerType String2JKQTPUserActionMarkerType(cons
/** \brief Availble action this JKQtPlotter can perform when mouse events occur.
* This allows you to e.g. draw rectangles or lines over the plot and receive a signal, when the drawing finishes
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPMouseDragActions {
@ -198,20 +222,20 @@ enum JKQTPMouseDragActions {
/** \brief convert a JKQTPMouseDragActions to a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see String2JKQTPMouseDragActions(), JKQTPMouseDragActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseDragActions2String(JKQTPMouseDragActions act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (created by JKQTPMouseDragActions2String() ) to JKQTPMouseDragActions
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see JKQTPMouseDragActions2String(), JKQTPMouseDragActions
*/
JKQTP_LIB_EXPORT JKQTPMouseDragActions String2JKQTPMouseDragActions(const QString &button);
/** \brief actions that can be bound to a double-click of the mouse
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPMouseDoubleClickActions {
jkqtpdcaClickZoomsIn=0, /*!< \brief a double-click zooms into the plot at the current mouse location */
@ -222,20 +246,20 @@ enum JKQTPMouseDoubleClickActions {
};
/** \brief convert a JKQTPMouseDoubleClickActions to a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see String2JKQTPMouseDoubleClickActions(), JKQTPMouseDoubleClickActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseDoubleClickActions2String(JKQTPMouseDoubleClickActions act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (created by JKQTPMouseDoubleClickActions2String() ) to JKQTPMouseDoubleClickActions
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see JKQTPMouseDoubleClickActions2String(), JKQTPMouseDoubleClickActions
*/
JKQTP_LIB_EXPORT JKQTPMouseDoubleClickActions String2JKQTPMouseDoubleClickActions(const QString &act);
/** \brief actions that can be bound to a mouse wheel event
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPMouseWheelActions {
jkqtpmwaZoomByWheel=0, /*!< \brief use the mouse-wheel for zooming */
@ -243,20 +267,20 @@ enum JKQTPMouseWheelActions {
};
/** \brief convert a JKQTPMouseWheelActions to a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see String2JKQTPMouseWheelActions(), JKQTPMouseWheelActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseWheelActions2String(JKQTPMouseWheelActions act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (created by JKQTPMouseWheelActions2String() ) to JKQTPMouseWheelActions
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see JKQTPMouseWheelActions2String(), JKQTPMouseWheelActions
*/
JKQTP_LIB_EXPORT JKQTPMouseWheelActions String2JKQTPMouseWheelActions(const QString &act);
/** \brief modes for the context menu
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPContextMenuModes {
jkqtpcmmStandardContextMenu=0, /*!< \brief only show the standard context menu \image html zoomin_mouse_contextmenu.gif "Zooming with the mouse" */
@ -266,50 +290,43 @@ enum JKQTPContextMenuModes {
};
/** \brief convert a JKQTPContextMenuModes to a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see String2JKQTPContextMenuModes(), JKQTPContextMenuModes
*/
JKQTP_LIB_EXPORT QString JKQTPContextMenuModes2String(JKQTPContextMenuModes act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (created by JKQTPContextMenuModes2String() ) to JKQTPContextMenuModes
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*
* \see JKQTPContextMenuModes2String(), JKQTPContextMenuModes
*/
JKQTP_LIB_EXPORT JKQTPContextMenuModes String2JKQTPContextMenuModes(const QString &act);
/** \brief data structure for storage of assigned JKQTPMouseDragActions \see JKQTPMouseDragActionsHashMapIterator
* \ingroup jkqtpplottersupprt */
typedef QHash<QPair<Qt::MouseButton,Qt::KeyboardModifiers>, JKQTPMouseDragActions> JKQTPMouseDragActionsHashMap;
/** \brief iterator for JKQTPMouseDragActionsHashMap \see JKQTPMouseDragActionsHashMap
* \ingroup jkqtpplottersupprt */
typedef JKQTPMouseDragActionsHashMap::const_iterator JKQTPMouseDragActionsHashMapIterator;
/** \brief data structure for storage of assigned JKQTPMouseWheelActions \see JKQTPMouseWheelActionsHashMapIterator
* \ingroup jkqtpplottersupprt */
typedef QHash<Qt::KeyboardModifiers, JKQTPMouseWheelActions> JKQTPMouseWheelActionsHashMap;
/** \brief iterator for JKQTPMouseWheelActionsHashMap \see JKQTPMouseWheelActionsHashMap
* \ingroup jkqtpplottersupprt */
typedef JKQTPMouseWheelActionsHashMap::const_iterator JKQTPMouseWheelActionsHashMapIterator;
/** \brief data structure for storage of assigned JKQTPMouseDoubleClickActions \see JKQTPMouseDoubleClickActionsHashMapIterator
* \ingroup jkqtpplottersupprt */
typedef QHash<QPair<Qt::MouseButton,Qt::KeyboardModifiers>, JKQTPMouseDoubleClickActions> JKQTPMouseDoubleClickActionsHashMap;
/** \brief iterator for JKQTPMouseDoubleClickActionsHashMap \see JKQTPMouseDoubleClickActionsHashMap
* \ingroup jkqtpplottersupprt */
typedef JKQTPMouseDoubleClickActionsHashMap::const_iterator JKQTPMouseDoubleClickActionsHashMapIterator;
/** \brief converts a QT::PenStyle into a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString jkqtp_QPenStyle2String(Qt::PenStyle style);
/** \brief converts a QString into a Qt::PenStyle
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT Qt::PenStyle jkqtp_String2QPenStyle(const QString& style);
/** \brief converts a QT::BrushStyle into a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString jkqtp_QBrushStyle2String(Qt::BrushStyle style);
/** \brief converts a QString into a Qt::BrushStyle
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT Qt::BrushStyle jkqtp_String2QBrushStyle(const QString& style);
/** \brief Specifies how a fill-color is derived from a given color
* \ingroup jkqtptools
* \ingroup jkqtpplotter_styling
*/
enum JKQTPColorDerivationMode {
@ -326,14 +343,14 @@ enum JKQTPColorDerivationMode {
};
/** \brief use a JKQTPColorDerivationMode to derive a color from \a col as specified
* \ingroup jkqtptools_drawing
* \ingroup jkqtpplotter_styling
*
* \see JKQTPColorDerivationMode
*/
JKQTP_LIB_EXPORT QColor JKQTPGetDerivedColor(JKQTPColorDerivationMode mode, const QColor& col);
/** \brief construct a QColor, based on the given \a color, but with alpha set to the specified value \a alphaF
* \ingroup jkqtptools_drawing
* \ingroup jkqtpplotter_styling
* \see QColorWithAlpha()
*/
inline QColor QColorWithAlphaF(const QColor& color, qreal alphaF) {
@ -343,7 +360,7 @@ inline QColor QColorWithAlphaF(const QColor& color, qreal alphaF) {
}
/** \brief construct a QColor, based on the given \a color, but with alpha set to the specified value \a alpha
* \ingroup jkqtptools_drawing
* \ingroup jkqtpplotter_styling
* \see QColorWithAlphaF()
*/
inline QColor QColorWithAlpha(const QColor& color, int alpha) {
@ -353,13 +370,13 @@ inline QColor QColorWithAlpha(const QColor& color, int alpha) {
}
/** \brief convert a JKQTPColorDerivationMode to a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools_string
* \ingroup jkqtpplotter_styling
*
* \see String2JKQTPColorDerivationMode(), JKQTPColorDerivationMode
*/
JKQTP_LIB_EXPORT QString JKQTPColorDerivationMode2String(JKQTPColorDerivationMode mode);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (created by JKQTPColorDerivationMode2String() ) to JKQTPColorDerivationMode
* \ingroup jkqtptools_string
* \ingroup jkqtpplotter_styling
*
* \see JKQTPColorDerivationMode2String(), JKQTPColorDerivationMode
*/
@ -367,7 +384,7 @@ JKQTP_LIB_EXPORT JKQTPColorDerivationMode String2JKQTPColorDerivationMode(const
/** \brief display mode for an axis
* \ingroup jkqtptools */
* \ingroup jkqtpplottersupprt */
enum JKQTPCADrawMode {
JKQTPCADMcomplete=0, /*!< \brief draw axis with ticks, ticklabels and axis label */
JKQTPCADMLineTicksTickLabels, /*!< \brief draw axis with ticks, line and tick labels */
@ -382,40 +399,40 @@ enum JKQTPCADrawMode {
};
/** \brief determines whether JKQTPCADrawMode has the line
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasLine(JKQTPCADrawMode pos);
/** \brief determines whether JKQTPCADrawMode has ticks
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasTicks(JKQTPCADrawMode pos);
/** \brief determines whether JKQTPCADrawMode has tick labels
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasTickLabels(JKQTPCADrawMode pos);
/** \brief determines whether JKQTPCADrawMode has the axis label
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasAxisLabel(JKQTPCADrawMode pos);
/** \brief converts a JKQTPCADrawMode variable into a human-readable string
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT QString JKQTPCADrawMode2String(JKQTPCADrawMode pos);
/** \brief converts a string into a JKQTPCADrawMode
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT JKQTPCADrawMode String2JKQTPCADrawMode(const QString& pos);
/** \brief display mode for the axis labels
* \ingroup jkqtptools */
* \ingroup jkqtpplottersupprt */
enum JKQTPCALabelType {
JKQTPCALTdefault, /*!< \brief simply print the numbers \image html JKQTPCALTdefault.png */
JKQTPCALTexponentCharacter, /*!< \brief print the numbers and show a unit character, i.e. \c 5µ for \f$ 5\cdot 10^{-6} \f$ , \c 3k for \f$ 3\cdot 10^3 \f$ ... */
@ -428,7 +445,7 @@ enum JKQTPCALabelType {
/** \brief mode of the axis ticks
* \ingroup jkqtptools */
* \ingroup jkqtpplottersupprt */
enum JKQTPLabelTickMode {
JKQTPLTMLinOrPower=0, /*!< \brief linear, or log, depending on whether the axis is log */
JKQTPLTMLin, /*!< \brief always linear (even for log-axes) */
@ -436,28 +453,28 @@ enum JKQTPLabelTickMode {
};
/** \brief converts a JKQTPLabelTickMode variable into a human-readable string
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT QString JKQTPLabelTickMode2String(JKQTPLabelTickMode pos);
/** \brief converts a string into a JKQTPLabelTickMode
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT JKQTPLabelTickMode String2JKQTPLabelTickMode(const QString& pos);
/** \brief converts a JKQTPCALabelType variable into a human-readable string
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT QString JKQTPCALabelType2String(JKQTPCALabelType pos);
/** \brief converts a string into a JKQTPCALabelType
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT JKQTPCALabelType String2JKQTPCALabelType(const QString& pos);
/** \brief position of the axis labels
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPLabelPosition {
JKQTPLabelMin=0, /*!< \brief the axis label is near the min value of the axis (left/bottom) */
@ -467,17 +484,17 @@ enum JKQTPLabelPosition {
/** \brief converts a JKQTPLabelPosition variable into a human-readable string
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT QString JKQTPLabelPosition2String(JKQTPLabelPosition pos);
/** \brief converts a string into a JKQTPLabelPosition
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT JKQTPLabelPosition String2JKQTPLabelPosition(const QString& pos);
/** \brief position of the key
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPKeyPosition {
JKQTPKeyOutsideTopRight=0, /*!< \brief the key is positioned on the right side of the graph */
@ -496,17 +513,17 @@ enum JKQTPKeyPosition {
/** \brief converts a JKQTPLabelPosition variable into a human-readable string
* \ingroup jkqjkqtptools_stringtptools
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT QString JKQTPKeyPosition2String(JKQTPKeyPosition pos);
/** \brief converts a string into a JKQTPLabelPosition
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT JKQTPKeyPosition String2JKQTPKeyPosition(const QString& pos);
/** \brief layout of the key
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPKeyLayout {
JKQTPKeyLayoutOneColumn, /*!< \brief the key consists of one column */
@ -516,19 +533,19 @@ enum JKQTPKeyLayout {
/** \brief converts a JKQTPKeyLayout variable into a human-readable string
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT QString JKQTPKeyLayout2String(JKQTPKeyLayout pos);
/** \brief converts a String into a JKQTPKeyLayout
* \ingroup jkqtptools_string
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT JKQTPKeyLayout String2JKQTPKeyLayout(const QString& pos);
/** \brief used to represent the position of other graphs in \ref jkqtplotter_base_saveprint
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
* \internal
*/
struct JKQTPGridPrintingItem {
@ -543,7 +560,7 @@ struct JKQTPGridPrintingItem {
/** \brief plot styles for the error information
* \ingroup jkqtptools
* \ingroup jkqtplotter_basegraphserrors
*/
enum JKQTPErrorPlotstyle {
JKQTPErrorEllipses=10, /*!< \brief an ellipse spanned by the errors \image html JKQTPErrorEllipses.png */
@ -563,17 +580,17 @@ enum JKQTPErrorPlotstyle {
/** \brief converts a JKQTPErrorPlotstyle variable into a human-readable string
* \ingroup jkqtptools_string
* \ingroup jkqtplotter_basegraphserrors
*/
JKQTP_LIB_EXPORT QString JKQTPErrorPlotstyle2String(JKQTPErrorPlotstyle pos);
/** \brief converts a String into a JKQTPErrorPlotstyle
* \ingroup jkqtptools_string
* \ingroup jkqtplotter_basegraphserrors
*/
JKQTP_LIB_EXPORT JKQTPErrorPlotstyle String2JKQTPErrorPlotstyle(const QString& pos);
/** \brief plot styles for a graph
* \ingroup jkqtptools
* \ingroup jkqtpplottersupprt
*/
enum JKQTPGraphPlotstyle {
JKQTPLines, /*!< \brief plot y=f(x), connect the datapoints by straight lines */
@ -588,7 +605,7 @@ enum JKQTPGraphPlotstyle {
};
/** \brief symbols that can be used to plot a datapoint for a graph
* \ingroup jkqtptools
* \ingroup jkqtptools_drawing
*/
enum JKQTPGraphSymbols {
JKQTPNoSymbol=0, /*!< \brief plots no symbol at all (usefull together with error bars) */
@ -669,291 +686,24 @@ enum JKQTPGraphSymbols {
};
/** \brief converts a JKQTPGraphSymbols variable into a identifier string
* \ingroup jkqtptools_string
* \ingroup jkqtptools_drawing
*/
JKQTP_LIB_EXPORT QString JKQTPGraphSymbols2String(JKQTPGraphSymbols pos);
/** \brief converts a JKQTPGraphSymbols variable into a human-readable string
* \ingroup jkqtptools_string
* \ingroup jkqtptools_drawing
*/
JKQTP_LIB_EXPORT QString JKQTPGraphSymbols2NameString(JKQTPGraphSymbols pos);
/** \brief converts a String into a JKQTPGraphSymbols
* \ingroup jkqtptools_string
* \ingroup jkqtptools_drawing
*/
JKQTP_LIB_EXPORT JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos);
/** \brief convert a double to a string, using the loacle "C"
* \ingroup jkqtptools_string
*/
inline QString JKQTPCDoubleToQString(double value) {
QLocale loc=QLocale::c();
loc.setNumberOptions(QLocale::OmitGroupSeparator);
return loc.toString(value, 'g', 18);
}
/** \brief convert a double to a string
* \ingroup jkqtptools_string
*/
inline QString JKQTPDoubleToQString(double value, int prec = 10, char f = 'g', QChar decimalSeparator='.') {
QLocale loc=QLocale::c();
loc.setNumberOptions(QLocale::OmitGroupSeparator);
QString res=loc.toString(value, f, prec);
if (loc.decimalPoint()!=decimalSeparator) {
res=res.replace(loc.decimalPoint(), decimalSeparator);
}
return res;
}
/** \brief rotate a rectangle by given angle (rotates all points around the center of the rectangle and returns it as a QPolygonF)
* \ingroup jkqtptools_math
*/
JKQTP_LIB_EXPORT QPolygonF jkqtpRotateRect(QRectF r, double angle);
/*! \brief swap two elements \a l and \a r in an array \a a
\ingroup jkqtptools
*/
template <class T>
inline void jkqtpSwap(T* a, int l, int r){
const T tmp=a[l];
a[l]=a[r];
a[r]=tmp;
}
/*! \brief QuickSort (recursive implementation)
\ingroup jkqtptools
implementation from http://www.linux-related.de/index.html?/coding/sort/sort_quick.htm
*/
template <class T>
inline void jkqtpQuicksort(T* a, int l, int r){
if(r>l){
int i=l-1;
int j=r;
for(;;){
while(a[++i]<a[r]);
while(a[--j]>a[r] && j>i);
if(i>=j) break;
jkqtpSwap<T>(a, i, j);
}
jkqtpSwap<T>(a, i, r);
jkqtpQuicksort(a, l, i-1);
jkqtpQuicksort(a, i+1, r);
}
}
/*! \brief QuickSort (recursive implementation), sorts \a a2 alongside \a a, using \a a as sort criterion
\ingroup jkqtptools
implementation from http://www.linux-related.de/index.html?/coding/sort/sort_quick.htm
*/
template <class T, class T2>
inline void jkqtpQuicksort(T* a, T2* a2, int l, int r){
if(r>l){
int i=l-1;
int j=r;
for(;;){
while(a[++i]<a[r]);
while(a[--j]>a[r] && j>i);
if(i>=j) break;
jkqtpSwap(a, i, j);
jkqtpSwap(a2, i, j);
}
jkqtpSwap(a, i, r);
jkqtpSwap(a2, i, r);
jkqtpQuicksort(a, a2, l, i-1);
jkqtpQuicksort(a, a2, i+1, r);
}
}
/*! \brief sort the given arrays, using \a input as sort criterion
\ingroup jkqtptools
\param input array to be sorted
\param input2 array to be sorted
\param N size of the array input
\param output if \c !=nullptr data is written here (the memory location pointed at by \a output has to have at least the length \a N !!!),
otherwise the array input is sorted inplace.
\param output2 if \c !=nullptr data is written here (the memory location pointed at by \a output has to have at least the length \a N !!!),
otherwise the array input is sorted inplace.
*/
template <class T, class T2>
inline void jkqtpSort(T* input, T2* input2, int N, T* output=nullptr, T2* output2=nullptr) {
if ((!input)) return ;
if (N<=0) return;
T* data=input;
if (output!=nullptr) {
data=output;
memcpy(output, input, N*sizeof(T));
}
T2* data2=input2;
if (output2!=nullptr && input2!=nullptr) {
data2=output2;
memcpy(output2, input2, N*sizeof(T2));
}
jkqtpQuicksort(data, data2, 0, N-1);
}
/** \brief RAII construct that times its lifetime, outputting properly indented qDebug()-message
* \ingroup jkqtptools_debugging
*/
class JKQTP_LIB_EXPORT JKQTPAutoOutputTimer : public QElapsedTimer
{
public:
explicit JKQTPAutoOutputTimer(const QString& message);
~JKQTPAutoOutputTimer();
void write(const QString& message) const;
protected:
QString message;
QString indent;
static int global_indent;
};
/** \brief convert a string to lower-case characters
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_tolower(const std::string& s);
/** \brief convert a string to a boolean
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT bool jkqtp_strtobool(const std::string& data);
/** \brief convert a string to upper-case
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_toupper(const std::string& s);
/** \brief std::string wrapper around sprintf()
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_format(const std::string& templ, ...);
/** \brief convert a number of bytes to a string, formatting e.g. 1024 as 1kB, ...
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_bytestostr(double bytes);
/** \brief convert an integer to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_inttostr(long data);
/** \brief convert an integer to a hex string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_inttohex(long data);
/** \brief convert an unsigned int to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_uinttostr(unsigned long data);
/** \brief convert a double to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattostr(double data, int past_comma=-1, bool remove_trail0=false, double belowIsZero=1e-16);
/** \brief convert a double to a string, encoding powers of ten as characters, e.g. \c jkqtp_floattounitstr(1000,"g") will result in "1kg"
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattounitstr(double dataa, const std::string& unitname);
/** \brief convert a boolean to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_booltostr(bool data);
/** \brief converts a RGBA color into a string
* \ingroup jkqtptools_string
*
* This returns a QString which contains the name of named colors and the RGBA values in a QT readable form othertwise.
*
* \param r red value of the color to convert
* \param g green value of the color to convert
* \param b blue value of the color to convert
* \param a alpha value of the color to convert
* \param useSpecialTransparencySyntax is set (\c true ), the function uses a special syntax to denote color and transparency: \c color,trans
*/
JKQTP_LIB_EXPORT QString jkqtp_rgbtostring(unsigned char r, unsigned char g, unsigned char b, unsigned char a=255, bool useSpecialTransparencySyntax=true);
/** \brief converts a QColor into a string using the jkqtp_rgbtostring() method.
* \ingroup jkqtptools_string
*
* This returns a QString which contains the name of named colors and the RGBA values in a QT readable form othertwise.
*/
JKQTP_LIB_EXPORT QString jkqtp_QColor2String(QColor color, bool useSpecialTransparencySyntax=true);
/** \brief converts a QString into a QColor, compatible with jkqtp_QColor2String(QColor color);
* \ingroup jkqtptools_string
*
* This returns a QString which contains the name of named colors and the RGBA values in a QT readable form othertwise.
*/
JKQTP_LIB_EXPORT QColor jkqtp_String2QColor(const QString& color);
/** \brief clean a string to be usable as a variable name, e.g. in an expression parser, or a C++-expression
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_to_valid_variable_name(const std::string& input);
/** \brief convert a double to a string, encoding powers of ten as characters, e.g. \c jkqtp_floattounitstr(1000) will result in "1k"
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattounitstr(double data, int past_comma=5, bool remove_trail0=false);
/** \brief convert a double to a string, encoding powers of ten as exponent in LaTeX notation (e.g. <code>-1.23\\cdot 10^{-5}</code>)
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattolatexstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
/** \brief convert a double to a string, encoding powers of ten as exponent with HTML tags
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_floattohtmlstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
/** \brief convert a character to a string
* \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT std::string jkqtp_chartostr(char data);
/** \brief wandelt einen Datentyp in einen double um, wird von JKQTPDatastore zur Wandlung benutzt
* \ingroup jkqtptools_math
*
* Diese Funktion nutzt per default static_cast<double>(), kann aber für spezielle Datentypen überschrieben werden, etwa für bool
*/
template<typename T>
inline constexpr double jkqtp_todouble(const T& d) {
return static_cast<double>(d);
}
/** \brief wandelt einen boolean in einen double um, wird von JKQTPDatastore zur Wandlung benutzt,
* Spezialisierung für bool (true -> 1.0, false -> 0.0)
* \ingroup jkqtptools_math */
template<>
inline constexpr double jkqtp_todouble(const bool& d) {
return static_cast<double>((d)?1.0:0.0);
}
/** \brief plot styles for the error information
* \ingroup jkqtptools
* \ingroup jkqtplotter_linesymbolgraphs_simple
*
* \see JKQTPSpecialLineTypeComboBox
*/
@ -967,60 +717,15 @@ enum JKQTPSpecialLineType {
/** \brief converts a JKQTPSpecialLineType variable into a human-readable string
* \ingroup jkqtptools
* \ingroup jkqtplotter_linesymbolgraphs_simple
*/
JKQTP_LIB_EXPORT QString JKQTPSpecialLineType2String(JKQTPSpecialLineType pos);
/** \brief converts a String into a JKQTPSpecialLineType
* \ingroup jkqtptools
* \ingroup jkqtplotter_linesymbolgraphs_simple
*/
JKQTP_LIB_EXPORT JKQTPSpecialLineType String2JKQTPSpecialLineType(const QString& pos);
/** \brief round a double using round() and convert it to a specified type T (static_cast!)
* \ingroup jkqtptools_math */
template<typename T>
inline T jkqtp_roundTo(const double& v) {
return static_cast<T>(round(v));
}
/** \brief compare two floats \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
* \ingroup jkqtptools_math */
inline bool jkqtp_approximatelyEqual(float a, float b, float epsilon=2.0*std::numeric_limits<float>::epsilon())
{
return fabsf(a - b) <= epsilon;
}
/** \brief compare two doubles \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
* \ingroup jkqtptools_math */
inline bool jkqtp_approximatelyEqual(double a, double b, double epsilon=2.0*std::numeric_limits<double>::epsilon())
{
return fabs(a - b) <= epsilon;
}
/** \brief returns the quare of the value \a v, i.e. \c v*v
* \ingroup jkqtptools_math */
template<typename T>
inline T jkqtp_sqr(const T& v) {
return v*v;
}
/** \brief calculate the distance between two QPointF points
* \ingroup jkqtptools_math
*
*/
inline double jkqtp_distance(const QPointF& p1, const QPointF& p2){
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
}
/** \brief calculate the distance between two QPoint points
* \ingroup jkqtptools_math
*
*/
inline double jkqtp_distance(const QPoint& p1, const QPoint& p2){
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
}

View File

@ -0,0 +1,64 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL) as published by
the Free Software Foundation, either version 2.1 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 Lesser General Public License (LGPL) for more details.
You should have received a copy of the GNU Lesser General Public License (LGPL)
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jkqtcommon/jkqtptoolsdebugging.h"
#include <QDebug>
#include <QApplication>
int JKQTPAutoOutputTimer::global_indent=0;
JKQTPAutoOutputTimer::JKQTPAutoOutputTimer(const QString& message) :
QElapsedTimer()
{
this->indent=QString(global_indent, QLatin1Char(' '));
global_indent+=4;
this->message=message;
#if QT_VERSION >= 0x040800
qDebug()<<this->indent<<"TIMER_START: "<<message;
#else
qDebug()<<this->indent<<"TIMER_START: "<<message;
#endif
start();
}
JKQTPAutoOutputTimer::~JKQTPAutoOutputTimer()
{
#if QT_VERSION >= 0x040800
qDebug()<<this->indent<<"TIMER_END: "<<message<<" DUR: "<<double(nsecsElapsed())/1.0e6<<"ms";
#else
qDebug()<<this->indent<<"TIMER_END: "<<message<<" DUR: "<<double(elapsed())/1.0e3<<"ms";
#endif
global_indent-=4;
}
void JKQTPAutoOutputTimer::write(const QString& message) const {
#if QT_VERSION >= 0x040800
qDebug()<<this->indent<<"TIMER_MESSAGE: "<<this->message<<" "<<message<<" DUR: "<<double(nsecsElapsed())/1.0e6<<"ms";
#else
qDebug()<<this->indent<<"TIMER_MESSAGE: "<<this->message<<" "<<message<<" DUR: "<<double(elapsed())/1.0e3<<"ms";
#endif
}

View File

@ -0,0 +1,71 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
This software is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JKQTPDEBUGGINGTOOLS_H_INCLUDED
#define JKQTPDEBUGGINGTOOLS_H_INCLUDED
#include "jkqtcommon/jkqtp_imexport.h"
#include <QString>
#include <QElapsedTimer>
#ifndef __WINDOWS__
# if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)
# define __WINDOWS__
# endif
#endif
#ifndef __LINUX__
# if defined(linux)
# define __LINUX__
# endif
#endif
#undef JKTOOLS_TIMER_USE_TIME
#if defined(__WINDOWS__)
#include<windows.h>
#elif defined(__LINUX__)
#include <sys/time.h>
#else
#define JKTOOLS_TIMER_USE_TIME
#endif
/** \brief RAII construct that times its lifetime, outputting properly indented qDebug()-message
* \ingroup jkqtptools_debugging
*/
class JKQTP_LIB_EXPORT JKQTPAutoOutputTimer : public QElapsedTimer
{
public:
explicit JKQTPAutoOutputTimer(const QString& message);
~JKQTPAutoOutputTimer();
void write(const QString& message) const;
protected:
QString message;
QString indent;
static int global_indent;
};
#endif // JKQTPDEBUGGINGTOOLS_H_INCLUDED

View File

@ -57,11 +57,11 @@ class JKQTPGraph; // forward
class JKQTPPlotElement; // forward
/** \brief initialized Qt-ressources necessary for JKQTBasePlotter
* \ingroup jkqtpplotterclasses_tools */
* \ingroup jkqtpplottersupprt */
JKQTP_LIB_EXPORT void initJKQTBasePlotterResources();
/** \brief virtual base-class for exporter classes that can be used to save data inot a file
* \ingroup jkqtpplotterclasses_tools */
* \ingroup jkqtpplottersupprt */
class JKQTP_LIB_EXPORT JKQTPSaveDataAdapter {
public:
virtual ~JKQTPSaveDataAdapter() ;
@ -71,7 +71,7 @@ class JKQTP_LIB_EXPORT JKQTPSaveDataAdapter {
/** \brief Service from this class to implement a special QPaintDevice as a plugin, that can be registered to JKQTBasePlotter/JKQTPlotter
* and then be used to export graphics, use registerPaintDeviceAdapter() to register such a plass
* \ingroup jkqtpplotterclasses_tools*/
* \ingroup jkqtpplottersupprt */
class JKQTP_LIB_EXPORT JKQTPPaintDeviceAdapter {
public:
virtual ~JKQTPPaintDeviceAdapter() {}
@ -561,7 +561,7 @@ class JKQTP_LIB_EXPORT JKQTBasePlotter: public QObject {
/** \brief represents a pen, when plotting in JKQTPlotter/JKQTBasePlotter
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
*
* \see getPlotStyle()
*/
@ -1210,7 +1210,7 @@ class JKQTP_LIB_EXPORT JKQTBasePlotter: public QObject {
/** \brief internal tool class for text sizes
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
* \internal */
struct JKQTP_LIB_EXPORT textSizeData {
explicit textSizeData();
@ -1218,7 +1218,7 @@ class JKQTP_LIB_EXPORT JKQTBasePlotter: public QObject {
};
/** \brief internal tool class for text-sizess in a plot key
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
* \internal */
struct JKQTP_LIB_EXPORT textSizeKey {
explicit textSizeKey(const QFont& f, const QString& text, QPaintDevice *pd);
@ -2255,7 +2255,7 @@ class JKQTP_LIB_EXPORT JKQTBasePlotter: public QObject {
};
/** \brief qHash()-specialization
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
*/
inline uint qHash(const JKQTBasePlotter::textSizeKey& data) {
return qHash(data.f.family())+qHash(data.text);

View File

@ -571,7 +571,7 @@ void JKQTPSingleColumnGraph::intSortData()
datas<<xv;
}
jkqtpSort(datas.data(), sortedIndices.data(), datas.size());
jkqtpQuicksortDual(datas.data(), sortedIndices.data(), datas.size());
}
@ -632,7 +632,7 @@ void JKQTPXYGraph::intSortData()
datas<<xv;
}
jkqtpSort(datas.data(), sortedIndices.data(), datas.size());
jkqtpQuicksortDual(datas.data(), sortedIndices.data(), datas.size());
} else if (sortData==JKQTPXYLineGraph::SortedY) {
@ -643,7 +643,7 @@ void JKQTPXYGraph::intSortData()
datas<<xv;
}
jkqtpSort(datas.data(), sortedIndices.data(), datas.size());
jkqtpQuicksortDual(datas.data(), sortedIndices.data(), datas.size());
}
}

View File

@ -1278,7 +1278,7 @@ void JKQTPBoxplotVerticalGraph::intSortData()
datas<<xv;
}
jkqtpSort(datas.data(), sortedIndices.data(), datas.size());
jkqtpQuicksortDual(datas.data(), sortedIndices.data(), datas.size());
}

View File

@ -50,7 +50,7 @@
#define JKQTPLOTTER_H
/** \brief initialized Qt-ressources necessary for JKQTPlotter
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
*/
JKQTP_LIB_EXPORT void initJKQTPlotterResources();
@ -1340,7 +1340,7 @@ class JKQTP_LIB_EXPORT JKQTPlotter: public QWidget {
/** \brief ties a MouseActionMode to a mouse-button and a keyboard-modifier
* \internal
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
*/
struct JKQTP_LIB_EXPORT MouseDragAction {
/** \brief constructs an invalid object */
@ -1669,7 +1669,7 @@ class JKQTP_LIB_EXPORT JKQTPlotter: public QWidget {
/** \brief qHash-variant used by JKQTPlotter
* \internal
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
*/
template<>
inline uint qHash(const QPair<Qt::MouseButton,Qt::KeyboardModifiers> &key, uint seed ) noexcept(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed))) {
@ -1678,7 +1678,7 @@ inline uint qHash(const QPair<Qt::MouseButton,Qt::KeyboardModifiers> &key, uint
/** \brief qHash-variant used by JKQTPlotter
* \internal
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
*/
template<>
inline uint qHash(const Qt::MouseButton &key, uint /*seed*/ ) noexcept(noexcept(qHash(key))) {
@ -1687,7 +1687,7 @@ inline uint qHash(const Qt::MouseButton &key, uint /*seed*/ ) noexcept(noexcept(
/** \brief qHash-variant used by JKQTPlotter
* \internal
* \ingroup jkqtpplotterclasses_tools
* \ingroup jkqtpplottersupprt
*/
template<>
inline uint qHash(const Qt::KeyboardModifiers &key, uint /*seed*/ ) noexcept(noexcept(qHash(key))) {

View File

@ -25,6 +25,19 @@ Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
const double JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH= 0.02;
QPolygonF jkqtpRotateRect(QRectF r, double angle) {
QPolygonF p;
QMatrix m;
m.rotate(angle);
p.append(m.map(r.bottomLeft()));
p.append(m.map(r.bottomRight()));
p.append(m.map(r.topRight()));
p.append(m.map(r.topLeft()));
return p;
}
void JKQTPPlotSymbol(QPaintDevice& paintDevice, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor) {
JKQTPEnhancedPainter p(&paintDevice);
JKQTPPlotSymbol(p, x, y, symbol, size, symbolLineWidth, color, fillColor);

View File

@ -27,6 +27,7 @@
class JKQTPEnhancedPainter; // forward
/*! \brief tool class with static values used by JKQTPlotter/JKQTBasePlotter
\ingroup jkqtptools_drawing
*/
@ -36,6 +37,12 @@ JKQTP_LIB_EXPORT struct JKQTPlotterDrawingTools {
static const double ABS_MIN_LINEWIDTH;
};
/** \brief rotate a rectangle by given angle (rotates all points around the center of the rectangle and returns it as a QPolygonF)
* \ingroup jkqtptools_drawing
*/
JKQTP_LIB_EXPORT QPolygonF jkqtpRotateRect(QRectF r, double angle);
/*! \brief plot the specified symbol at pixel position x,y
\ingroup jkqtptools_drawing