Creating Classes, Libraries and Functions for the Common SLS Detector GUI

git-svn-id: file:///afs/psi.ch/project/sls_det_software/svn/slsDetectorGui@1 af1100a4-978c-4157-bff7-07162d2ba061
This commit is contained in:
maliakal_d
2012-05-21 16:00:26 +00:00
commit 9f851d6156
49 changed files with 6522 additions and 0 deletions

View File

@ -0,0 +1,440 @@
/**
* @author Ian Johnson
* @version 1.0
*/
#include <iostream>
#include <stdlib.h>
#include <qwt_painter.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_widget.h>
#include <qwt_legend.h>
#include <qwt_scale_draw.h>
#include <qwt_scale_engine.h>
#include <qwt_math.h>
#include "SlsQt1DPlot.h"
using namespace std;
SlsQtH1D::SlsQtH1D(QString title,int n, double min, double max, double* data):QwtPlotCurve(title){
Initailize();
SetData(n,min,max,data);
}
SlsQtH1D::SlsQtH1D(QString title,int n, double* data_x, double* data_y):QwtPlotCurve(title){
Initailize();
SetData(n,data_x,data_y);
}
void SlsQtH1D::Initailize(){
ndata=n_array=0;
x=y=0;
pen_ptr = new QPen();
SetLineColor();
}
SlsQtH1D::~SlsQtH1D(){delete x;delete y;delete pen_ptr;}
void SlsQtH1D::Attach(SlsQt1DPlot* p){
attach((QwtPlot*) p);
p->NewHistogramAttached(this);
}
void SlsQtH1D::Detach(SlsQt1DPlot* p){
detach();
p->HistogramDetached(this);
}
int SlsQtH1D::SetLineColor(int c){
static int last_color = 1;
if(c<0) c=(last_color+1)%3;
if(c==0) pen_ptr->setColor(Qt::black);
else if(c==1) pen_ptr->setColor(Qt::red);
else pen_ptr->setColor(Qt::blue);
setPen(*pen_ptr);
return last_color=c;
}
int SlsQtH1D::SetLineWidth(int w){
pen_ptr->setWidth(w);
setPen(*pen_ptr);
return w;
}
void SlsQtH1D::SetLineStyle(int s){
if(s==1) pen_ptr->setStyle(Qt::DashLine);
else if(s==2) pen_ptr->setStyle(Qt::DotLine);
else if(s==3) pen_ptr->setStyle(Qt::DashDotLine);
else if(s==4) pen_ptr->setStyle(Qt::DashDotDotLine);
else if(s==5) pen_ptr->setStyle(Qt::CustomDashLine);
else pen_ptr->setStyle(Qt::SolidLine);
setPen(*pen_ptr);
}
void SlsQtH1D::SetData(int n, double xmin, double xmax, double *data){
n = SetUpArrays(n);
ndata=n;
if(xmin>xmax){
double t=xmin;
xmin=xmax;
xmax=t;
}
dx = (xmax-xmin)/n;
ymin=ymax= data ? data[0]:0;
firstXgt0=-1;
firstYgt0=-1;
for(int i=0;i<ndata;i++){
x[i] = i ? x[i-1]+dx:xmin;
y[i] = data ? data[i]:0;
if(data&&ymin>y[i]) ymin = y[i];
if(data&&ymax<y[i]) ymax = y[i];
if(x[i]>0&&(firstXgt0<0||firstXgt0>x[i])) firstXgt0=x[i];
if(y[i]>0&&(firstYgt0<0||firstYgt0>y[i])) firstYgt0=y[i];
}
// cout<<endl<<endl<<"one can think about correcting negative values in the data and recalling the setRawData function in setRawData when plotting on log scales"<<endl;
// if(firstXgt0<0)firstXgt0=0.001;
// if(firstYgt0<0)firstYgt0=0.001;
setRawData(x,y,ndata);
}
void SlsQtH1D::SetData(int n, double* data_x, double *data_y){
int reverse = (data_x&&n>0&&data_x[0]>data_x[n-1]) ? 1:0;
n = SetUpArrays(n);
ndata=n;
dx=-1; //signifies not regular intervals
ymin=ymax= data_y ? data_y[0]:0;
firstXgt0=-1;
firstYgt0=-1;
for(int i=0;i<ndata;i++){
int b = reverse ? n-i-1:i;
x[b] = data_x ? data_x[i]:0;
y[b] = data_y ? data_y[i]:0;
if(data_y&&ymin>y[b]) ymin = y[b];
if(data_y&&ymax<y[b]) ymax = y[b];
if(x[b]>0&&(firstXgt0<0||firstXgt0>x[b])) firstXgt0=x[b];
if(y[b]>0&&(firstYgt0<0||firstYgt0>y[b])) firstYgt0=y[b];
}
setRawData(x,y,ndata);
}
int SlsQtH1D::SetUpArrays(int n){
n = n<1 ? 1 : n; //overflow bin
if(n+1>n_array){
n_array = n+1;
if(x) delete x;
if(y) delete y;
x = new double [n_array];
y = new double [n_array];
}
return n;
}
double SlsQtH1D::FillBin(int bx, double v) {
bx = CheckIndex(bx);
return SetBinContent(bx,y[bx]+v);
}
double SlsQtH1D::Fill(double x, double v){return FillBin(FindBinIndex(x),v);}
double SlsQtH1D::SetBinContent(int bx,double v){
bx = CheckIndex(bx);
y[bx]=v;
if(bx<ndata){
if(y[bx]<ymin) ymin = y[bx];
if(y[bx]>0&&(firstYgt0<=0||y[bx]<firstYgt0)) firstYgt0 = y[bx];
if(y[bx]>ymax) ymax = y[bx];
}
return y[bx];
}
double SlsQtH1D::SetContent(double x,double v) {return SetBinContent(FindBinIndex(x),v); }
int SlsQtH1D::FindBinIndex(double px){
if(dx>0) CheckIndex(int((px-x[0])/dx));
//find closest bin
int b=0; for(;b<ndata;b++) if(x[b]>px) break;
if(b==0) return 0;
else if(fabs(px-x[b-1])<fabs(px-x[b])) return b-1;
return b;
}
int SlsQtH1D::CheckIndex(int bx){return (bx<0||bx>ndata) ? ndata : bx;}//ndata is the overflow bin
SlsQtH1D* SlsQtH1D::Add(double v){ for(int bx=0;bx<ndata;bx++) FillBin(bx,v); return this;}
//1d hist list stuff
SlsQtH1DList::SlsQtH1DList(SlsQtH1D* hist){
the_hist = hist;
the_next = 0;
}
SlsQtH1DList::~SlsQtH1DList(){
if(the_next) delete the_next;
}
SlsQtH1D* SlsQtH1DList::Add(SlsQtH1D* hist){
// cout<<"Adding: "<<hist<<endl;
SlsQtH1DList* hl=this;
while(hl){
if(hist==hl->the_hist) return hist; //already added
if(!hl->the_next) break;
hl=hl->the_next;
}
if(hl->the_hist) hl->the_next = new SlsQtH1DList(hist);
else hl->the_hist = hist;
// Print();
return hist;
}
void SlsQtH1DList::Print(){
// cout<<"Printing List"<<endl;
SlsQtH1DList* hl=this;
int i=0;
while(hl){
cout<<" "<<i++<<") "<<hl<<" "<<hl->the_hist<<" "<<hl->the_next<<endl;
hl=hl->the_next;
if(i>10) break;
}
}
void SlsQtH1DList::Remove(SlsQtH1D* hist){
// cout<<"Removing: "<<hist<<endl;
SlsQtH1DList* hl=this;
while(hl){ //every match will be removed
if(hl->the_hist!=hist) hl = hl->the_next;
else{ //match
if(!hl->the_next) hl->the_hist=0; // first the_hist is zero when there's no next
else{
SlsQtH1DList* t = hl->the_next;
hl->the_hist = t->the_hist;
hl->the_next = t->the_next;
t->the_next = 0;
delete t;
}
}
}
// Print();
}
//1d plot stuff
SlsQt1DPlot::SlsQt1DPlot(QWidget *parent):QwtPlot(parent){
// n_histograms_attached=0;
hline=vline=0;
hist_list = new SlsQtH1DList();
UnknownStuff();
alignScales();
SetupZoom();
// Assign a title
insertLegend(new QwtLegend(), QwtPlot::RightLegend);
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating);
axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating);
}
SlsQt1DPlot::~SlsQt1DPlot(){
delete hist_list;
if(hline) delete hline;
if(vline) delete vline;
}
void SlsQt1DPlot::CalculateNResetZoomBase(){
if(hist_list->Hist()) zoomer->SetZoomBase(hist_list->Hist());
SlsQtH1DList* hl = hist_list->Next();
while(hl){
if(hl->Hist()) zoomer->ExtendZoomBase(hl->Hist());
hl=hl->Next();
}
}
void SlsQt1DPlot::NewHistogramAttached(SlsQtH1D* h){
hist_list->Add(h);
CalculateNResetZoomBase();
if(!hist_list->Next()) UnZoom();
Update();
}
void SlsQt1DPlot::HistogramDetached(SlsQtH1D* h){
hist_list->Remove(h);
CalculateNResetZoomBase();
Update();
}
void SlsQt1DPlot::Update(){
replot();
}
void SlsQt1DPlot::SetTitle(const char* title){
setTitle(title);
}
void SlsQt1DPlot::SetXTitle(const char* title){
setAxisTitle(QwtPlot::xBottom,title);
}
void SlsQt1DPlot::SetYTitle(const char* title){
setAxisTitle(QwtPlot::yLeft,title);
}
void SlsQt1DPlot::SetLogX(bool yes){ SetLog(QwtPlot::xBottom,yes);}
void SlsQt1DPlot::SetLogY(bool yes){ SetLog(QwtPlot::yLeft,yes);}
void SlsQt1DPlot::SetLog(int axisId, bool yes){
if(axisId==QwtPlot::xBottom) zoomer->SetLogX(yes);
if(axisId==QwtPlot::yLeft) zoomer->SetLogY(yes);
zoomer->ResetZoomBase(); //needs to be done before setting Engine
//the old ones are deleted by in the setAxisScaleFunction() function see: 128 of file qwt_plot_axis.cpp
if(yes) setAxisScaleEngine(axisId,new QwtLog10ScaleEngine());
else setAxisScaleEngine(axisId,new QwtLinearScaleEngine());
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating);
axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating);
Update();
}
void SlsQt1DPlot::UnZoom(){
setAxisScale(QwtPlot::xBottom,zoomer->x(),zoomer->x()+zoomer->w());
setAxisScale(QwtPlot::yLeft,zoomer->y(),zoomer->y()+zoomer->h());
zoomer->setZoomBase();//Call replot for the attached plot before initializing the zoomer with its scales.
Update();
}
void SlsQt1DPlot::SetZoom(double xmin,double ymin,double x_width,double y_width){
setAxisScale(QwtPlot::xBottom,xmin,xmin+x_width);
setAxisScale(QwtPlot::yLeft ,ymin,ymin+y_width);
Update();
}
void SlsQt1DPlot::RemoveHLine(){
if(hline) hline->detach();
delete hline;
hline=0;
}
void SlsQt1DPlot::InsertHLine(double y){
if(!hline){
hline = new QwtPlotMarker();
hline->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
hline->setLineStyle(QwtPlotMarker::HLine);
hline->attach(this);
}
hline->setYValue(y);
}
void SlsQt1DPlot::RemoveVLine(){
if(vline) vline->detach();
delete vline;
vline=0;
}
void SlsQt1DPlot::InsertVLine(double x){
if(!vline){
vline = new QwtPlotMarker();
vline->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
vline->setLineStyle(QwtPlotMarker::VLine);
vline->attach(this);
}
vline->setXValue(x);
}
void SlsQt1DPlot::SetupZoom(){
// LeftButton for the zooming
// MidButton for the panning
// RightButton: zoom out by 1
// Ctrl+RighButton: zoom out to full size
zoomer = new SlsQt1DZoomer(canvas());
#if QT_VERSION < 0x040000
zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlButton);
#else
zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier);
#endif
zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton);
panner = new QwtPlotPanner(canvas());
panner->setAxisEnabled(QwtPlot::yRight, false);
panner->setMouseButton(Qt::MidButton);
// Avoid jumping when labels with more/less digits
// appear/disappear when scrolling vertically
const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
sd->setMinimumExtent( fm.width("100.00") );
const QColor c(Qt::darkBlue);
zoomer->setRubberBandPen(c);
zoomer->setTrackerPen(c);
}
// Set a plain canvas frame and align the scales to it
void SlsQt1DPlot::alignScales(){
// The code below shows how to align the scales to
// the canvas frame, but is also a good example demonstrating
// why the spreaded API needs polishing.
canvas()->setFrameStyle(QFrame::Box | QFrame::Plain );
canvas()->setLineWidth(1);
for(int i = 0; i < QwtPlot::axisCnt; i++ ){
QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i);
if(scaleWidget) scaleWidget->setMargin(0);
QwtScaleDraw *scaleDraw = (QwtScaleDraw *)axisScaleDraw(i);
if(scaleDraw) scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false);
}
}
void SlsQt1DPlot::UnknownStuff(){
// Disable polygon clipping
QwtPainter::setDeviceClipping(false);
// We don't need the cache here
canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
#if QT_VERSION >= 0x040000
#ifdef Q_WS_X11
// Qt::WA_PaintOnScreen is only supported for X11, but leads
// to substantial bugs with Qt 4.2.x/Windows
canvas()->setAttribute(Qt::WA_PaintOnScreen, true);
#endif
#endif
}

View File

@ -0,0 +1,99 @@
/**
* @author Ian Johnson
* @version 1.0
*/
#include <iostream>
#include <qwt_plot.h>
#include <qwt_scale_div.h>
#include "SlsQt1DPlot.h"
#include "SlsQt1DZoomer.h"
using namespace std;
void SlsQt1DZoomer::ResetZoomBase(){
SetZoomBase(x0,y0,x1-x0,y1-y0); //for going between log and nonlog plots
}
void SlsQt1DZoomer::SetZoomBase(double xmin,double ymin,double x_width, double y_width){
if(xIsLog&&xmin<=0){
double xmax = xmin+x_width;
xmin = firstXgt0*0.98;
if(xmax<=xmin) x_width=firstXgt0;
else x_width=xmax-xmin;
}
if(yIsLog&&ymin<=0){
double ymax = ymin+y_width;
ymin = firstYgt0*0.98;
if(ymax<=ymin) y_width=firstYgt0;
else y_width=ymax-ymin;
}
if(plot()){
if(xIsLog){
#if QWT_VERSION < 0x50200
float xmin_curr = plot()->axisScaleDiv(QwtPlot::xBottom)->lBound();
float xmax_curr = plot()->axisScaleDiv(QwtPlot::xBottom)->hBound();
#else
float xmin_curr = plot()->axisScaleDiv(QwtPlot::xBottom)->lowerBound();
float xmax_curr = plot()->axisScaleDiv(QwtPlot::xBottom)->upperBound();
#endif
if(xmin_curr<xmin) xmin_curr=xmin;
if(xmax_curr>xmin+x_width) xmax_curr=xmin+x_width;
plot()->setAxisScale(QwtPlot::xBottom,xmin_curr,xmax_curr);
}
if(yIsLog){
#if QWT_VERSION < 0x50200
float ymin_curr = plot()->axisScaleDiv(QwtPlot::yLeft)->lBound();
float ymax_curr = plot()->axisScaleDiv(QwtPlot::yLeft)->hBound();
#else
float ymin_curr = plot()->axisScaleDiv(QwtPlot::yLeft)->lowerBound();
float ymax_curr = plot()->axisScaleDiv(QwtPlot::yLeft)->upperBound();
#endif
if(ymin_curr<ymin) ymin_curr=ymin;
if(ymax_curr>ymin+y_width) ymax_curr=ymin+y_width;
plot()->setAxisScale(QwtPlot::yLeft,ymin_curr,ymax_curr);
}
plot()->replot();
}
setZoomBase(QwtDoubleRect(xmin,ymin,x_width,y_width));
}
void SlsQt1DZoomer::SetZoomBase(SlsQtH1D* h){
x0 = h->GetXMin()<0 ? h->GetXMin()*1.02 : h->GetXMin()/1.02;
x1 = h->GetXMax()<0 ? h->GetXMax()/1.02 : h->GetXMax()*1.02;
y0 = h->GetYMin()<0 ? h->GetYMin()*1.02 : h->GetYMin()/1.02;
y1 = h->GetYMax()<0 ? h->GetYMax()/1.02 : h->GetYMax()*1.02;
firstXgt0 = h->GetFirstXgtZero(); //for log plots
firstYgt0 = h->GetFirstYgtZero(); //for log plots
ResetZoomBase();
}
void SlsQt1DZoomer::ExtendZoomBase(SlsQtH1D* h){
double h_x0 = h->GetXMin()<0 ? h->GetXMin()*1.02 : h->GetXMin()/1.02;
double h_x1 = h->GetXMax()<0 ? h->GetXMax()/1.02 : h->GetXMax()*1.02;
double h_y0 = h->GetYMin()<0 ? h->GetYMin()*1.02 : h->GetYMin()/1.02;
double h_y1 = h->GetYMax()<0 ? h->GetYMax()/1.02 : h->GetYMax()*1.02;
if(h_x0<x0) x0 = h_x0;
if(h_x1>x1) x1 = h_x1;
if(h_y0<y0) y0 = h_y0;
if(h_y1>y1) y1 = h_y1;
if(h->GetFirstXgtZero()<firstXgt0) firstXgt0 = h->GetFirstXgtZero();
if(h->GetFirstYgtZero()<firstYgt0) firstYgt0 = h->GetFirstYgtZero();
// cout<<"extend "<<h_x0<<" "<<h_y0<<" "<<h_x1<<" "<<h_y1<<endl;
// cout<<"extend "<<x0<<" "<<y0<<" "<<x1-x0<<" "<<y1-y0<<endl;
ResetZoomBase();
}

View File

@ -0,0 +1,122 @@
/**
* @author Ian Johnson
* @version 1.0
*/
#include <iostream>
#include "SlsQt2DHist.h"
using std::cout;
using std::endl;
SlsQt2DHist::SlsQt2DHist(int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double ymax, double* d,double zmin,double zmax):QwtRasterData(){
interp=0;
nx_array=ny_array=0;data=0;
SetData(nbinsx,xmin,xmax,nbinsy,ymin,ymax,d,zmin,zmax);
}
SlsQt2DHist::~SlsQt2DHist(){if(data) delete data;}
int SlsQt2DHist::GetBinIndex(int bx, int by){
int b = bx*ny+by;
if(b<0 || b>=nb){
cout<<"GetBinIndex:: Incorrect indicies bx and by returning overflow bin;"<<endl;
return nb;
}
return b;
}
int SlsQt2DHist::FindBinIndex(double x, double y){
return GetBinIndex(int((x-x_min)/x_width),int((y-y_min)/y_width));
}
double SlsQt2DHist::GetBinValue(int bx,int by){
return data[GetBinIndex(bx,by)];
}
void SlsQt2DHist::SetBinValue(int bx,int by,double v){
z_mean_has_been_calculated = 0;
data[GetBinIndex(bx,by)] = v;
}
void SlsQt2DHist::SetData(int nbinsx, double xmin, double xmax, int nbinsy,double ymin, double ymax, double *d,double zmin,double zmax){
z_mean_has_been_calculated = 0;
if(xmax<xmin||ymax<ymin) cout<<"Warning input range invalid."<<endl;
x_width = (xmax - xmin)/nbinsx;
y_width = (ymax - ymin)/nbinsy;
if(x_min!=xmin||x_max!=xmax||y_min!=ymin||y_max!=ymax){
x_min=xmin;x_max=xmax;
y_min=ymin;y_max=ymax;
setBoundingRect(QwtDoubleRect(xmin,ymin,x_max-x_min,y_max-y_min));
}
if(nbinsx*nbinsy<1){
cout<<"Exitting: SlsQt2DHist::SetData() number of bins must be greater than zero."<<endl;
exit(1);
}
if(nbinsx*nbinsy>nx_array*ny_array){
if(data) delete data;
data = new double [nbinsx*nbinsy+1]; //one for under/overflow bin
nx_array = nbinsx;
ny_array = nbinsy;
}
nx=nbinsx;
ny=nbinsy;
nb=nx*ny;
data[nb]=0;//set over flow to zero
if(d){
memcpy(data,d,nb*sizeof(double));
SetMinMax(zmin,zmax);
}
}
void SlsQt2DHist::SetMinMax(double zmin,double zmax){
if(zmin<zmax){
z_min=zmin;
z_max=zmax;
}else{
z_mean_has_been_calculated = 1;
z_min=data[0];
z_mean=0;
z_max=data[0];
for(int i=0;i<nb;i++){
if(data[i]<z_min) z_min=data[i];
if(data[i]>z_max) z_max=data[i];
z_mean+=data[i];
}
z_mean/=nb;
if(z_min>0) z_min/=1.02; else z_min*=1.02;
if(z_max>0) z_max*=1.02; else z_max/=1.02;
}
}
double SlsQt2DHist::GetMean(){
if(!z_mean_has_been_calculated){
z_mean_has_been_calculated = 1;
z_mean=0;
for(int i=0;i<nb;i++) z_mean+=data[i];
z_mean/=nb;
}
return z_mean;
}
double SlsQt2DHist::SetMinimumToFirstGreaterThanZero(){
z_min=abs(z_max)+1;
for(int i=0;i<nb;i++){
if(data[i]>0&&data[i]<z_min) z_min=data[i];
}
return z_min;
}

View File

@ -0,0 +1,213 @@
/**
* @author Ian Johnson
* @version 1.0
*/
#include <iostream>
#include <qprinter.h>
#include <qtoolbutton.h>
#if QT_VERSION >= 0x040000
#include <qprintdialog.h>
#endif
#include <qwt_color_map.h>
#include <qwt_plot_spectrogram.h>
#include <qwt_scale_widget.h>
#include <qwt_scale_draw.h>
#include <qwt_plot_zoomer.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_layout.h>
#include <qwt_scale_engine.h>
#include "SlsQt2DPlot.h"
using namespace std;
SlsQt2DPlot::SlsQt2DPlot(QWidget *parent):QwtPlot(parent){
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating);
axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating);
d_spectrogram = new QwtPlotSpectrogram();
hist = new SlsQt2DHist();
SetupZoom();
SetupColorMap();
d_spectrogram->setData(*hist);
d_spectrogram->attach(this);
plotLayout()->setAlignCanvasToScales(true);
FillTestPlot();
Update();
}
void SlsQt2DPlot::SetupColorMap(){
colorMapLinearScale = new QwtLinearColorMap(Qt::darkCyan, Qt::red);
colorMapLinearScale->addColorStop(0.1, Qt::cyan);
colorMapLinearScale->addColorStop(0.4, Qt::blue);
colorMapLinearScale->addColorStop(0.6, Qt::green);
colorMapLinearScale->addColorStop(0.95, Qt::yellow);
d_spectrogram->setColorMap(*colorMapLinearScale);
colorMapLogScale = new QwtLinearColorMap(Qt::darkCyan, Qt::red);
colorMapLogScale->addColorStop((pow(10,2*0.10)-1)/99.0, Qt::cyan); //linear scale goes from 0 to 2 and log scale goes from 1 to 100
colorMapLogScale->addColorStop((pow(10,2*0.40)-1)/99.0,Qt::blue);
colorMapLogScale->addColorStop((pow(10,2*0.60)-1)/99.0,Qt::green);
colorMapLogScale->addColorStop((pow(10,2*0.95)-1)/99.0,Qt::yellow);
contourLevelsLinear = new QwtValueList();
for(double level=0.5;level<10.0;level+=1.0 ) (*contourLevelsLinear) += level;
d_spectrogram->setContourLevels(*contourLevelsLinear);
contourLevelsLog = new QwtValueList();
for(double level=0.5;level<10.0;level+=1.0 ) (*contourLevelsLog) += (pow(10,2*level/10.0)-1)/99.0 * 10;
// A color bar on the right axis
rightAxis = axisWidget(QwtPlot::yRight);
rightAxis->setTitle("Intensity");
rightAxis->setColorBarEnabled(true);
enableAxis(QwtPlot::yRight);
}
void SlsQt2DPlot::FillTestPlot(int mode){
static int nx = 50;
static int ny = 50;
static double *the_data=0;
if(the_data==0) the_data = new double [nx*ny];
double dmax = sqrt(pow(nx/2.0-0.5,2) + pow(ny/2.0-0.5,2));
for(int i=0;i<nx;i++){
for(int j=0;j<ny;j++){
double d = sqrt(pow(nx/2.0-(i+0.5),2) + pow(ny/2.0-(j+0.5),2));
if(mode%3) the_data[i+j*nx] = 10*d/dmax;
else the_data[i+j*nx] = 10*(1-d/dmax);
}
}
hist->SetData(nx,200,822,ny,-0.5,ny-0.5,the_data);
}
void SlsQt2DPlot::SetupZoom(){
// LeftButton for the zooming
// MidButton for the panning
// RightButton: zoom out by 1
// Ctrl+RighButton: zoom out to full size
zoomer = new SlsQt2DZoomer(canvas());
zoomer->SetHist(hist);
#if QT_VERSION < 0x040000
zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlButton);
#else
zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier);
#endif
zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton);
panner = new QwtPlotPanner(canvas());
panner->setAxisEnabled(QwtPlot::yRight, false);
panner->setMouseButton(Qt::MidButton);
// Avoid jumping when labels with more/less digits
// appear/disappear when scrolling vertically
const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
sd->setMinimumExtent( fm.width("100.00") );
const QColor c(Qt::darkBlue);
zoomer->setRubberBandPen(c);
zoomer->setTrackerPen(c);
}
void SlsQt2DPlot::UnZoom(){
zoomer->setZoomBase(QwtDoubleRect(hist->GetXMin(),hist->GetYMin(),hist->GetXMax()-hist->GetXMin(),hist->GetYMax()-hist->GetYMin()));
zoomer->setZoomBase();//Call replot for the attached plot before initializing the zoomer with its scales.
// zoomer->zoom(0);
}
void SlsQt2DPlot::SetZoom(double xmin,double ymin,double x_width,double y_width){
zoomer->setZoomBase(QwtDoubleRect(xmin,ymin,x_width,y_width));
}
void SlsQt2DPlot::SetZMinMax(double zmin,double zmax){
hist->SetMinMax(zmin,zmax);
}
void SlsQt2DPlot::Update(){
rightAxis->setColorMap(d_spectrogram->data().range(),d_spectrogram->colorMap());
if(!zoomer->zoomRectIndex()) UnZoom();
setAxisScale(QwtPlot::yRight,d_spectrogram->data().range().minValue(),
d_spectrogram->data().range().maxValue());
replot();
}
void SlsQt2DPlot::showContour(bool on){
d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ContourMode,on);
Update();
}
void SlsQt2DPlot::showSpectrogram(bool on){
// static int io=0;
// FillTestPlot(io++);
d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ImageMode, on);
d_spectrogram->setDefaultContourPen(on ? QPen() : QPen(Qt::NoPen));
Update();
}
void SlsQt2DPlot::InterpolatedPlot(bool on){
hist->Interpolate(on);
Update();
}
void SlsQt2DPlot::LogZ(bool on){
if(on){
//if(hist->GetMinimum()<=0) hist->SetMinimumToFirstGreaterThanZero();
d_spectrogram->setColorMap(*colorMapLogScale);
setAxisScaleEngine(QwtPlot::yRight,new QwtLog10ScaleEngine);
d_spectrogram->setContourLevels(*contourLevelsLog);
}else{
d_spectrogram->setColorMap(*colorMapLinearScale);
setAxisScaleEngine(QwtPlot::yRight,new QwtLinearScaleEngine);
d_spectrogram->setContourLevels(*contourLevelsLinear);
}
Update();
}
/*
void SlsQt2DPlot::printPlot(){
QPrinter printer;
printer.setOrientation(QPrinter::Landscape);
#if QT_VERSION < 0x040000
printer.setColorMode(QPrinter::Color);
printer.setOutputFileName("spectrogram.ps");
if (printer.setup())
#else
printer.setOutputFileName("spectrogram.pdf");
QPrintDialog dialog(&printer);
if ( dialog.exec() )
#endif
{
print(printer);
}
}
*/

View File

@ -0,0 +1,212 @@
/**
* @author Ian Johnson
* @version 1.0
*/
/*
#include <iostream>
#include <qgroupbox.h>
//#include <qgridlayout.h>
//#include <qlabel.h>
#include "SlsQt2DPlotLayout.h"
using namespace std;
SlsQt2DPlotLayout::SlsQt2DPlotLayout(QWidget *parent):QGroupBox(parent){
//the_layout=0;
the_plot = new SlsQt2DPlot(this);
// z_range_ne = new SlsQtNumberEntry(this,1,"Set the z axis range from",2,"to",2);
// z_range_ne->setFixedWidth(402);
ConnectSignalsAndSlots();
}
SlsQt2DPlotLayout::~SlsQt2DPlotLayout(){
//if(the_layout) delete the_layout;
delete the_plot;
// delete z_range_ne;
}
void SlsQt2DPlotLayout::ConnectSignalsAndSlots(){
connect(btnInterpolate, SIGNAL(toggled(bool)),the_plot, SLOT(InterpolatedPlot(bool)));
connect(btnContour, SIGNAL(toggled(bool)),the_plot, SLOT(showContour(bool)));
connect(btnLogz, SIGNAL(toggled(bool)),this,SLOT(SetZScaleToLog(bool)));
connect(z_range_ne,SIGNAL(CheckBoxChanged(bool)),this,SLOT(ResetRange()));
connect(z_range_ne,SIGNAL(AValueChanged(SlsQtNumberEntry*)),this,SLOT(ResetRange()));
btnInterpolate->setChecked(false);
btnContour->setChecked(false);
btnLogz->setChecked(false);
}
void SlsQt2DPlotLayout::UpdateNKeepSetRangeIfSet(){
if(z_range_ne->CheckBoxState()){
//just reset histogram range before update
the_plot->SetZMinMax(z_range_ne->GetValue(0),z_range_ne->GetValue(1));
}
the_plot->Update();
}
void SlsQt2DPlotLayout::ResetRange(){
//refind z limits
the_plot->SetZMinMax();
if(btnLogz->isChecked()) the_plot->SetZMinimumToFirstGreaterThanZero();
if(z_range_ne->CheckBoxState()){
//first time check validity
bool same = (z_range_ne->GetValue(0)==z_range_ne->GetValue(1)) ? 1:0;
if(!z_range_ne->IsValueOk(0)||same) z_range_ne->SetValue(the_plot->GetZMinimum(),0);
if(!z_range_ne->IsValueOk(1)||same) z_range_ne->SetValue(the_plot->GetZMaximum(),1);
z_range_ne->SetRange(the_plot->GetZMinimum(),z_range_ne->GetValue(1),0);
z_range_ne->SetRange(z_range_ne->GetValue(0),the_plot->GetZMaximum(),1);
//set histogram range
the_plot->SetZMinMax(z_range_ne->GetValue(0),z_range_ne->GetValue(1));
}
the_plot->Update();
}
void SlsQt2DPlotLayout::SetZScaleToLog(bool yes){
the_plot->LogZ(yes);
ResetRange();
}
void SlsQt2DPlotLayout::SetXTitle(QString st){
GetPlot()->axisWidget(QwtPlot::xBottom)->setTitle(st);
}
void SlsQt2DPlotLayout::SetYTitle(QString st){
GetPlot()->axisWidget(QwtPlot::yLeft)->setTitle(st);
}
void SlsQt2DPlotLayout::SetZTitle(QString st){
GetPlot()->axisWidget(QwtPlot::yRight)->setTitle(st);
}
*/
/**
* @author Ian Johnson
* @version 1.0
*/
#include <iostream>
#include <qgroupbox.h>
#include <qgridlayout.h>
#include <qlabel.h>
#include "SlsQt2DPlotLayout.h"
using namespace std;
SlsQt2DPlotLayout::SlsQt2DPlotLayout(QWidget *parent):QGroupBox(parent){
the_layout=0;
the_plot = new SlsQt2DPlot(this);
z_range_ne = new SlsQtNumberEntry(this,1,"Set the z axis range from",2,"to",2);
// z_range_ne->SetNDecimalsOfDoubleValidators(2);
z_range_ne->setFixedWidth(402);
z_range_ne->hide();
logsChecked = false;
Layout();
ConnectSignalsAndSlots();
}
SlsQt2DPlotLayout::~SlsQt2DPlotLayout(){
if(the_layout) delete the_layout;
delete the_plot;
delete z_range_ne;
}
void SlsQt2DPlotLayout::Layout(){
if(the_layout) delete the_layout;
the_layout = new QGridLayout(this);
the_layout->addWidget(the_plot,2,1,3,3);
the_layout->addWidget(z_range_ne,5,1,1,3);
the_layout->setMargin(12);
}
void SlsQt2DPlotLayout::ConnectSignalsAndSlots(){
connect(this, SIGNAL(InterpolateSignal(bool)), the_plot, SLOT(InterpolatedPlot(bool)));
connect(this, SIGNAL(ContourSignal(bool)), the_plot, SLOT(showContour(bool)));
connect(z_range_ne, SIGNAL(CheckBoxChanged(bool)), this, SLOT(ResetRange()));
connect(z_range_ne, SIGNAL(AValueChanged(SlsQtNumberEntry*)), this, SLOT(ResetRange()));
}
void SlsQt2DPlotLayout::UpdateNKeepSetRangeIfSet(){
if(z_range_ne->CheckBoxState()){
//just reset histogram range before update
the_plot->SetZMinMax(z_range_ne->GetValue(0),z_range_ne->GetValue(1));
}
the_plot->Update();
}
void SlsQt2DPlotLayout::ResetRange(){
//refind z limits
the_plot->SetZMinMax();
if(logsChecked) the_plot->SetZMinimumToFirstGreaterThanZero();
if(z_range_ne->CheckBoxState()){
//first time check validity
bool same = (z_range_ne->GetValue(0)==z_range_ne->GetValue(1)) ? 1:0;
if(!z_range_ne->IsValueOk(0)||same) z_range_ne->SetValue(the_plot->GetZMinimum(),0);
if(!z_range_ne->IsValueOk(1)||same) z_range_ne->SetValue(the_plot->GetZMaximum(),1);
z_range_ne->SetRange(the_plot->GetZMinimum(),z_range_ne->GetValue(1),0);
z_range_ne->SetRange(z_range_ne->GetValue(0),the_plot->GetZMaximum(),1);
//set histogram range
the_plot->SetZMinMax(z_range_ne->GetValue(0),z_range_ne->GetValue(1));
}
the_plot->Update();
}
void SlsQt2DPlotLayout::SetZScaleToLog(bool yes){
logsChecked=yes;
the_plot->LogZ(yes);
ResetRange();
}
void SlsQt2DPlotLayout::SetXTitle(QString st){
GetPlot()->axisWidget(QwtPlot::xBottom)->setTitle(st);
}
void SlsQt2DPlotLayout::SetYTitle(QString st){
GetPlot()->axisWidget(QwtPlot::yLeft)->setTitle(st);
}
void SlsQt2DPlotLayout::SetZTitle(QString st){
GetPlot()->axisWidget(QwtPlot::yRight)->setTitle(st);
}

View File

@ -0,0 +1,506 @@
/**
* @author Ian Johnson
* @version 1.0
*/
#include <iostream>
#include <math.h>
#include <qapplication.h>
#include <qmessagebox.h>
#include <qinputdialog.h>
#include <qlayout.h>
#include <qpixmap.h>
#include <qcombobox.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qspinbox.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qvalidator.h>
#include "SlsQtNumberEntry.h"
using namespace std;
SlsQtNumberEntry::SlsQtNumberEntry(QWidget *parent, int with_checkbox, char *start_string, int num_type, char* middle_string, int num2_type, int n_units, char** units, double* unit_factors,char* end_string):QWidget(parent){
SetupNumberEntry(with_checkbox,start_string,num_type,middle_string,num2_type,n_units,units,unit_factors,end_string);
}
//without unit drop box
SlsQtNumberEntry::SlsQtNumberEntry(QWidget *parent,int with_checkbox, char *start_string, int num_type, char* middle_string, int num2_type,char* end_string):QWidget(parent){
SetupNumberEntry(with_checkbox,start_string,num_type,middle_string,num2_type,0,0,0,end_string);
}
void SlsQtNumberEntry::SetupNumberEntry(int with_checkbox, char *start_string, int num_type, char* middle_string, int num2_type, int n_units, char** units, double* unit_factors,char* end_string){
layout = 0;
check_box = 0;
front_text = 0;
num_field[0] = 0;
spin_box[0] = 0;
validator_int[0] = 0;
validator_double[0] = 0;
middle_text = 0;
num_field[1] = 0;
spin_box[1] = 0;
validator_int[1] = 0;
validator_double[1] = 0;
unit_cbb = 0;
factors = 0;
back_text = 0;
if(with_checkbox) AddCheckBox();
SetFrontText(start_string);
SetupNumberField(num_type,0);
SetMiddleText(middle_string);
SetupNumberField(num2_type,1);
SetUnits(n_units,units,unit_factors);
SetBackText(end_string);
SetLayout();
}
SlsQtNumberEntry::~SlsQtNumberEntry(){
if(check_box) delete check_box;
if(front_text) delete front_text;
if(middle_text) delete middle_text;
if(validator_int[0]) delete validator_int[0];
if(validator_double[0]) delete validator_double[0];
if(num_field[0]) delete num_field[0];
if(spin_box[0]) delete spin_box[0];
if(validator_int[1]) delete validator_int[1];
if(validator_double[1]) delete validator_double[1];
if(num_field[1]) delete num_field[1];
if(spin_box[1]) delete spin_box[1];
if(unit_cbb) delete unit_cbb;
if(factors) delete factors;
if(back_text) delete back_text;
}
void SlsQtNumberEntry::AddCheckBox(){
if(check_box) delete check_box;
check_box = new QCheckBox(this);
connect(check_box,SIGNAL(clicked()),this,SLOT(CheckBoxClicked()));
SetLayout();
}
void SlsQtNumberEntry::SetFrontText(char* s) {SetText(s,&front_text); SetLayout();}
void SlsQtNumberEntry::SetMiddleText(char* s) {SetText(s,&middle_text); SetLayout();}
void SlsQtNumberEntry::SetBackText(char* s) {SetText(s,&back_text); SetLayout();};
void SlsQtNumberEntry::SetText(char* s, QLabel** pp){
if(*pp){delete *pp; *pp=0;}
if(s){
*pp = new QLabel(this);
(*pp)->setText(s);
}
SetLayout();
}
void SlsQtNumberEntry::SetupNumberField(int type, int which_number_field){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
num_field_enabled[i]=1;
if(spin_box[i]) { delete spin_box[i]; spin_box[i]=0;}
if(validator_int[i]) { delete validator_int[i]; validator_int[i]=0;}
if(validator_double[i]) { delete validator_double[i]; validator_double[i]=0;}
if(num_field[i]) { delete num_field[i]; num_field[i]=0;}
if(type>0&&type<3){
num_field[i] = new QLineEdit(this);
num_field[i]->setAlignment(Qt::AlignRight);
SetMinimumNumberWidth(3,i);
if(type==1){
validator_int[i] = new SlsQtIntValidator(num_field[i]);
num_field[i]->setValidator(validator_int[i]);
SetNumber(0,i);
}else{
validator_double[i] = new SlsQtDoubleValidator(num_field[i]);
num_field[i]->setValidator(validator_double[i]);
//default settings
SetNDecimalsOfDoubleValidator(3,i); //defalut value
SetNumber(0,i);
}
num_field[i]->setAlignment(Qt::AlignRight);
if(i==0){
connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(RefreshFirstNumberEntry()));
connect(num_field[i],SIGNAL(returnPressed()),this,SLOT(FirstValueEntered()));
connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(FirstValueEntered()));
}else{
connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(RefreshSecondNumberEntry()));
connect(num_field[i],SIGNAL(returnPressed()),this,SLOT(SecondValueEntered()));
connect(num_field[i],SIGNAL(lostFocus()),this,SLOT(SecondValueEntered()));
}
}else if(type==3){
spin_box[i] = new QSpinBox();
if(i==0) connect(spin_box[i],SIGNAL(editingFinished()),this,SLOT(FirstValueEntered()));
else connect(spin_box[i],SIGNAL(editingFinished()),this,SLOT(SecondValueEntered()));
spin_box[i]->setAlignment(Qt::AlignRight);
}
SetLayout();
}
void SlsQtNumberEntry::SetUnits(int n_units, char** units, double* unit_factors){
if(unit_cbb){ delete unit_cbb; unit_cbb=0;}
if(factors) { delete factors; factors=0;}
if(n_units>0&&units&&unit_factors){
unit_cbb = new QComboBox(this);
factors = new double [n_units];
for(int i=0;i<n_units;i++){
unit_cbb->insertItem(i,units[i]);
factors[i] = unit_factors[i];
}
connect(unit_cbb,SIGNAL(activated(int)),this,SLOT(UnitSelected()));
}
SetLayout();
}
void SlsQtNumberEntry::SetLayout(){
if(layout) delete layout;
layout = new QGridLayout(this);
int i = 0;
if(check_box) layout->addWidget(check_box,1,i++);
if(front_text) layout->addWidget(front_text,1,i++);
if(num_field[0]) layout->addWidget(num_field[0],1,i++);
if(spin_box[0]) layout->addWidget(spin_box[0],1,i++);
if(middle_text) layout->addWidget(middle_text,1,i++);
if(num_field[1]) layout->addWidget(num_field[1],1,i++);
if(spin_box[1]) layout->addWidget(spin_box[1],1,i++);
if(unit_cbb) layout->addWidget(unit_cbb,1,i++);
if(back_text) layout->addWidget(back_text,1,i++);
CheckBoxClicked();
}
void SlsQtNumberEntry::SetMinimumNumberWidth(int nchar_width,int which_number_field){
if(num_field[which_number_field]) num_field[which_number_field]
->setMinimumWidth(nchar_width*num_field[which_number_field]->minimumSizeHint().width());
if(spin_box[which_number_field]) spin_box[which_number_field]
->setMinimumWidth(nchar_width*spin_box[which_number_field]->minimumSizeHint().width());
}
void SlsQtNumberEntry::SetNDecimalsOfDoubleValidators(int ndecimals){
SetNDecimalsOfDoubleValidator(ndecimals,0);
SetNDecimalsOfDoubleValidator(ndecimals,1);
}
void SlsQtNumberEntry::SetNDecimalsOfDoubleValidator(int ndecimals, int which_number_field){
//0 -> standard, 1->scientific
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
if(validator_double[i]){
validator_double[i]->setDecimals(ndecimals);
SetNumber(GetNumber(i),i);
}
}
void SlsQtNumberEntry::SetMinimumUnitWidth(int nchar_width){
if(unit_cbb) unit_cbb->setMinimumWidth(nchar_width*unit_cbb->minimumSizeHint().width());
}
/*
double SlsQtNumberEntry::SetNumber(int v,int which_number_field){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
if(num_field[i]){
if(validator_int[i]){
QString s = QString::number(v);
validator_int[i]->fixup(s);
num_field[i]->setText(s);
}
if(validator_double[i]){
QString s = QString::number(v);
validator_double[i]->fixup(s);
num_field[i]->setText(s);
}
}else if(spin_box[i]){
spin_box[i]->setValue(v);
}else return 0;
return GetNumber(i);
}
*/
double SlsQtNumberEntry::SetNumber(double v,int which_number_field){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
if(num_field[i]){
if(validator_int[i]){
QString s = QString::number(v);
validator_int[i]->fixup(s);
num_field[i]->setText(s);
}
if(validator_double[i]){
QString s = QString::number(v);
validator_double[i]->fixup(s);
num_field[i]->setText(s);
}
}else if(spin_box[i]){
spin_box[i]->setValue(round(v));
}else return 0;
return GetNumber(i);
}
void SlsQtNumberEntry::SetRange(int min, int max,int which_number_field){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
if(min>max){
cout<<"Waring: SetRange(int,int) no effect min > max"<<endl;
}else{
if(validator_int[i]) validator_int[i]->setRange(min,max);
if(validator_double[i]) validator_double[i]->setRange(min,max,validator_double[i]->decimals());
if(spin_box[i]) spin_box[i]->setRange(min,max);
SetNumber(GetNumber(i),i);
}
}
void SlsQtNumberEntry::SetRange(double min, double max,int which_number_field){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
if(min>max){
cout<<"Waring: SetRange(double,double) no effect min >= max"<<endl;
}else{
if(validator_int[i]) cout<<"Waring can not call SetRange(double,double) with \"int\" type Validator"<<endl;
if(validator_double[i]) validator_double[i]->setRange(min,max,validator_double[i]->decimals());
if(spin_box[i]) spin_box[i]->setRange(min,max);
SetNumber(GetNumber(i),i);
}
}
bool SlsQtNumberEntry::CheckBoxState(){
if(check_box&&check_box->checkState()) return 1;
return 0;
}
void SlsQtNumberEntry::CheckBoxClicked(){
if(check_box){
if(check_box->checkState()) Enable();
else Disable();
emit CheckBoxChanged(check_box->checkState());
emit CheckBoxChanged(this);
}
}
void SlsQtNumberEntry::Disable(){ Enable(0); }
void SlsQtNumberEntry::Enable(bool en_flag){
if(check_box) check_box->setChecked(en_flag);
if(front_text) front_text->setEnabled(en_flag);
if(num_field[0]) num_field[0]->setEnabled(en_flag&&num_field_enabled[0]);
if(spin_box[0]) spin_box[0]->setEnabled(en_flag&&num_field_enabled[0]);
if(middle_text) middle_text->setEnabled(en_flag);
if(num_field[1]) num_field[1]->setEnabled(en_flag&&num_field_enabled[1]);
if(spin_box[1]) spin_box[1]->setEnabled(en_flag&&num_field_enabled[1]);
if(unit_cbb) unit_cbb->setEnabled(en_flag);
if(back_text) back_text->setEnabled(en_flag);
}
void SlsQtNumberEntry::DisableNumberField(int which_number_field){ EnableNumberField(which_number_field,0); }
void SlsQtNumberEntry::EnableNumberField(int which_number_field,bool en_flag){
if(which_number_field>=0||which_number_field<=1){
num_field_enabled[which_number_field]=en_flag;
if(num_field[which_number_field]) num_field[which_number_field]->setEnabled(num_field_enabled[which_number_field]);
if(spin_box[which_number_field]) spin_box[which_number_field]->setEnabled(num_field_enabled[which_number_field]);
}
}
void SlsQtNumberEntry::UnitSelected(){
emit UnitChanged(GetComboBoxValue());
emit UnitChanged(this);
emit AValueChanged(this);
emit FirstValueChanged(GetValueInt(0));
emit FirstValueChanged(GetValue(0));
emit FirstValueChanged(this);
emit SecondValueChanged(GetValueInt(1));
emit SecondValueChanged(GetValue(1));
emit SecondValueChanged(this);
}
void SlsQtNumberEntry::RefreshFirstNumberEntry() { RefreshNumberEntery(0);}
void SlsQtNumberEntry::RefreshSecondNumberEntry() { RefreshNumberEntery(1);}
void SlsQtNumberEntry::RefreshNumberEntery(int which_number_field){
//does not apply to spin boxes
if(num_field[which_number_field]){
SetNumber(GetNumber(which_number_field),which_number_field);
}
//refreshes the entery in a general format for ints and fixes doubles,
//for example removes leading zeros
//However, also moves curser position
}
void SlsQtNumberEntry::FirstValueEntered(){
emit AValueChanged(this);
emit FirstValueChanged(GetValue(0));
emit FirstValueChanged(GetValueInt(0));
emit FirstValueChanged(this);
}
void SlsQtNumberEntry::SecondValueEntered(){
emit AValueChanged(this);
emit SecondValueChanged(GetValue(1));
emit SecondValueChanged(GetValueInt(1));
emit SecondValueChanged(this);
}
bool SlsQtNumberEntry::Enabled(){
if(check_box && !check_box->checkState()) return 0;
return 1;
}
bool SlsQtNumberEntry::IsValueOk(int which_number_field){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
bool ok=0;
if(validator_int[i]) num_field[i]->text().toInt(&ok);
if(validator_double[i]) num_field[i]->text().toDouble(&ok);
if(spin_box[i]) ok=true;
return ok;
}
const char* SlsQtNumberEntry::GetFrontText(){
if(front_text) return front_text->text().toStdString().c_str();
return 0;
}
const char* SlsQtNumberEntry::GetMiddleText(){
if(middle_text) return middle_text->text().toStdString().c_str();
return 0;
}
const char* SlsQtNumberEntry::GetBackText(){
if(back_text) back_text->text().toStdString().c_str();
return 0;
}
int SlsQtNumberEntry::GetNumberInt(int which_number_field,bool* ok){
return round(GetNumber(which_number_field,ok));
}
double SlsQtNumberEntry::GetNumber(int which_number_field,bool* ok){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
if(ok) *ok = 1;
if(num_field[i]){
if(validator_int[i]) return num_field[i]->text().toInt(ok);
else return num_field[i]->text().toDouble(ok);
}
else if(spin_box[i]) return spin_box[i]->value();
else {if(ok) *ok=0;}
return 0;
}
double SlsQtNumberEntry::SetValue(double v,int which_number_field){
if(unit_cbb) SetNumber(round(v/GetComboBoxValue()),which_number_field);
else SetNumber(v,which_number_field);
return GetValue(which_number_field);
}
int SlsQtNumberEntry::GetValueInt(int which_number_field,bool* ok){
return round(GetValue(which_number_field,ok));
}
double SlsQtNumberEntry::GetValue(int which_number_field,bool* ok){
int i = (which_number_field<0||which_number_field>1) ? 0:which_number_field;
double v;
if(ok) *ok = 1;
if(num_field[i]){
if(validator_int[i]) v = num_field[i]->text().toInt(ok);
else v = num_field[i]->text().toDouble(ok);
}
else if(spin_box[i]) v = spin_box[i]->value();
else v = 1; //incase there is only a unit pulldown
if(unit_cbb) v *= GetComboBoxValue();
if(!num_field[i]&&!spin_box[i]&&!unit_cbb){v=0; if(ok) *ok=0;}
return v;
}
int SlsQtNumberEntry::SetComboBoxIndex(int index){
if(unit_cbb){
if(index<0||index>=unit_cbb->count()){
cout<<"usage error : can not set combo box index, index out of range."<<endl;
}else{
unit_cbb->setCurrentIndex(index);
}
}
else cout<<"usage error : can not set combo box index, no combo box."<<endl;
return GetComboBoxIndex();
}
int SlsQtNumberEntry::GetComboBoxIndex(){
if(unit_cbb) return unit_cbb->currentIndex();
cout<<"usage error : can not get combo box index, no combo box."<<endl;
return 0;
}
double SlsQtNumberEntry::GetComboBoxValue(){
if(unit_cbb) return factors[unit_cbb->currentIndex()];
cout<<"usage error : can not get combo box value, no combo box."<<endl;
return 0;
}
void SlsQtNumberEntry::PrintTheValue(){
cout<<endl<<endl<<"Printing value:"<<endl;
int n_not_printed = 0;
if(validator_int[0])
cout<<"The interger value has been changed to: "<<GetValue(0)<<endl;
else if(validator_double[0])
cout<<"The double value has been changed to: "<<GetValue(0)<<endl;
else n_not_printed++;
if(validator_int[1])
cout<<"and the integer value of the second field is: "<<GetValue(1)<<endl;
else if(validator_double[1])
cout<<"and the double value of the second field is: "<<GetValue(1)<<endl;
else n_not_printed++;
if(unit_cbb){
cout<<"ComboBox Status: "<<"Index: index = "<<GetComboBoxIndex()<<", v = "<<GetComboBoxValue()<<endl;
}
if(n_not_printed==2) cout<<"The value of the unit box is: "<<GetValue()<<endl;
}