Fixed text file permissions
[snark14.git] / tools / Display / range.cpp
1 /** @file range.cpp
2     @package snark14Display
3     @author Bruno M. Carvalho and Deniz Sarioz
4     licensed under (open-source) QPL v1.0
5     which accompanies this distribution in the file QPL
6 */
7
8 #include "range.hpp"
9 #include "variables.hpp"
10 #include "SnarkDisplay.hpp"
11
12 #include <stdio.h>
13 #include <qcheckbox.h>
14 #include <qframe.h>
15 #include <qlabel.h>
16 #include <qlineedit.h>
17 #include <qpushbutton.h>
18 #include <qslider.h>
19 #include <qlayout.h>
20 #include <qvariant.h>
21 #include <qtooltip.h>
22 #include <qwhatsthis.h>
23 #include <qmessagebox.h>
24
25
26 /* 
27  *  Constructs a rangewindow which is a child of 'parent', with the 
28  *  name 'name' and widget flags set to 'f' 
29  *
30  *  The dialog will by default be modeless, unless you set 'modal' to
31  *  TRUE to construct a modal dialog.
32  */
33 rangewindow::rangewindow( QWidget* parent,  const char* name, bool modal, WFlags fl )
34     : QDialog( parent, name, modal, fl )
35 {
36
37     if ( !name )
38         setName( "rangewindow" );
39     resize( 460, 280 ); 
40     setMinimumSize( QSize( 460, 280 ) );
41     setMaximumSize( QSize( 460, 280 ) );
42     setCaption( tr( "Global Features Window" ) );
43
44     maxval=globalmax;
45     minval=globalmin;
46     Range=maxval-minval;
47     lowglobalthresh=globalmin;
48     highglobalthresh=globalmax;
49     status=false;
50
51     // need to connect these three checkboxes to meaningful things
52     int cbsRowTop = 20;
53     int cbsRowLeft = 50;
54     int cbsRowDiff = 145;
55     int cbsWidth = 130;
56     int cbsHeight = 15;
57     allGlobals = new QCheckBox( this, "allGlobalsCheckBox" );
58     allGlobals->setGeometry( QRect ( cbsRowLeft, cbsRowTop, 
59                                      cbsWidth, cbsHeight ) );
60     allGlobals->setText("Global Thresholds");
61     // DO connect to both!... no, latter calls former.
62     //    QObject::connect(allGlobals,SIGNAL(toggled(bool)),this,SLOT(signalAllGlobals(bool)));
63     QObject::connect(allGlobals,SIGNAL(toggled(bool)),parent, SLOT(signalAllGlobals(bool)));
64
65     allDifference = new QCheckBox( this, "allDifferenceCheckBox" );
66     allDifference->setGeometry( QRect ( cbsRowLeft + cbsRowDiff, cbsRowTop, 
67                                         cbsWidth, cbsHeight ) );
68     allDifference->setText("Difference");
69     // must also set global threshold extrema based on whether or not this is selected
70     QObject::connect(allDifference,SIGNAL(toggled(bool)),this,SLOT(signalAllDifference(bool)));
71     // first this, then the rest!
72     QObject::connect(allDifference,SIGNAL(toggled(bool)),parent,SLOT(signalAllDifference(bool)));
73
74     // removed per Gabor's suggestion in 2nd reopening of bug #146
75     // don't go too crazy with commenting everything out
76     //    allIntensity = new QCheckBox( this, "allIntensityCheckBox" );
77     //    allIntensity->setGeometry( QRect ( cbsRowLeft + 2*cbsRowDiff, cbsRowTop,
78     //                                 cbsWidth, cbsHeight ) );
79     //    allIntensity->setText("Intensity");
80     //    QObject::connect(allIntensity,SIGNAL(toggled(bool)),parent,SLOT(signalAllIntensity(bool)));
81     // for intensity, nothing to do in 'this' since it is orthogonal to difference
82
83     lowtrheshframe = new QFrame( this, "lowtrheshframe" );
84     lowtrheshframe->setGeometry( QRect( 15, 60, 430, 70 ) ); 
85     lowtrheshframe->setFrameShape( QFrame::StyledPanel );
86     lowtrheshframe->setFrameShadow( QFrame::Raised );
87
88     lowthresh = new QLineEdit( lowtrheshframe, "lowthresh" );
89     lowthresh->setGeometry( QRect( 185, 20, 140, 30 ) ); 
90     char s[12];
91     sprintf(s,"%10.7f",lowglobalthresh);
92     lowthresh->setText(s);
93
94     setlowbutton = new QPushButton( lowtrheshframe, "setlowbutton" );
95     setlowbutton->setGeometry( QRect( 335, 15, 90, 40 ) ); 
96     setlowbutton->setText( tr( "Set Value" ) );
97     QObject::connect(setlowbutton,SIGNAL(clicked()),this,SLOT(updateLowthreshslider()));
98     QObject::connect(setlowbutton,SIGNAL(clicked()),parent,SLOT(updateGlobalThreshs()));
99
100     lowthreshslider = new QSlider( lowtrheshframe, "lowthreshslider" );
101     lowthreshslider->setGeometry( QRect( 15, 30, 150, 20 ) ); 
102     lowthreshslider->setOrientation( QSlider::Horizontal );
103     lowthreshslider->setRange(0,1000000000);
104     lowthreshslider->setValue(0);
105     QObject::connect(lowthreshslider,SIGNAL(valueChanged(int)),this,SLOT(updateLowthresh()));
106     QObject::connect(lowthreshslider,SIGNAL(valueChanged(int)),parent,SLOT(updateGlobalThreshs()));
107
108     lowthershlabel = new QLabel( lowtrheshframe, "lowthershlabel" );
109     lowthershlabel->setGeometry( QRect( 35, 10, 110, 20 ) ); 
110     lowthershlabel->setText( tr( "Low Threshold" ) );
111
112     highthreshframe = new QFrame( this, "highthreshframe" );
113     highthreshframe->setGeometry( QRect( 15, 140, 430, 70 ) ); 
114     highthreshframe->setFrameShape( QFrame::StyledPanel );
115     highthreshframe->setFrameShadow( QFrame::Raised );
116
117     highthresh = new QLineEdit( highthreshframe, "highthresh" );
118     highthresh->setGeometry( QRect( 185, 20, 140, 30 ) ); 
119     sprintf(s,"%10.7f",highglobalthresh);
120     highthresh->setText(s);
121
122     sethighbutton = new QPushButton( highthreshframe, "sethighbutton" );
123     sethighbutton->setGeometry( QRect( 335, 15, 90, 40 ) ); 
124     sethighbutton->setText( tr( "Set Value" ) );
125     QObject::connect(sethighbutton,SIGNAL(clicked()),this,SLOT(updateHighthreshslider()));
126     QObject::connect(sethighbutton,SIGNAL(clicked()),parent,SLOT(updateGlobalThreshs()));
127
128     highthreshslider = new QSlider( highthreshframe, "highthreshslider" );
129     highthreshslider->setGeometry( QRect( 15, 30, 150, 20 ) ); 
130     highthreshslider->setOrientation( QSlider::Horizontal );
131     highthreshslider->setRange(0,1000000000);
132     highthreshslider->setValue(1000000000);
133     QObject::connect(highthreshslider,SIGNAL(valueChanged(int)),this,SLOT(updateHighthresh()));
134     QObject::connect(highthreshslider,SIGNAL(valueChanged(int)),parent,SLOT(updateGlobalThreshs()));
135
136     highthreshlabel = new QLabel( highthreshframe, "highthreshlabel" );
137     highthreshlabel->setGeometry( QRect( 35, 10, 110, 20 ) ); 
138     highthreshlabel->setText( tr( "High Threshold" ) );
139
140     Line2 = new QFrame( this, "Line2" );
141     Line2->setGeometry( QRect( 0, 215, 460, 16 ) ); 
142     Line2->setProperty( "frameShape", (int)QFrame::HLine );
143     Line2->setFrameShadow( QFrame::Sunken );
144     Line2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
145     Line2->setProperty( "frameShape", (int)QFrame::HLine );
146
147 //     applybutton = new QPushButton( this, "applybutton" );
148 //     applybutton->setGeometry( QRect( 40, 230, 180, 40 ) ); 
149 //     applybutton->setText( tr( "Apply Global Thresholds" ) );
150 //     // a-ha!  clicked signal is connected to the PARENT's updateGlobalThreshs()... 
151 //     //      apply is not a toggle button so this makes sense
152 //     QObject::connect(applybutton,SIGNAL(clicked()),parent,SLOT(updateGlobalThreshs()));
153
154     closebutton = new QPushButton( this, "closebutton" );
155     //    closebutton->setGeometry( QRect( 300, 230, 100, 40 ) ); 
156     closebutton->setGeometry( QRect( 180, 230, 100, 40 ) ); 
157     closebutton->setText( tr( "Close" ) );
158     QObject::connect(closebutton,SIGNAL(clicked()),this,SLOT(closeWindow()));
159
160     signalAllGlobals( false );
161 }
162
163 /*  
164  *  Destroys the object and frees any allocated resources
165  */
166 rangewindow::~rangewindow()
167 {
168     // no need to delete child widgets, Qt does it all for us
169 }
170
171
172 /** update the text in lowthresh textbox based on the value of low threshold slider */
173 void rangewindow::updateLowthresh()
174 {
175   int v = lowthreshslider->value();
176   if(v > highthreshslider->value()) { // cap it
177     lowthreshslider->setValue(highthreshslider->value());
178     lowglobalthresh = highglobalthresh;
179     lowthresh->setText(highthresh->text());
180   } else {
181     lowglobalthresh = (((double)v)/1000000000)*Range+minval;
182     char s[12];
183     sprintf(s,"%10.7f", lowglobalthresh);
184     lowthresh->setText(s);
185   }
186 }
187
188
189 void rangewindow::updateLowthreshslider()
190 {
191   double fv; // floating-point value entered
192   int v=0;   // integer position of slider
193   bool ok=false;
194   fv=lowthresh->text().toDouble(&ok); 
195   if(ok) { // value in lowthresh text box parsed OK
196     if((fv<minval) || (fv>maxval)) {
197       QMessageBox::information(this,"SnarkDisplay","Error!\n"
198                                "Entered threshold value must be within valid range");
199       updateLowthresh();
200       lowthresh->setFocus();
201     } else {
202       if(fv>0) {
203         v=(int)(((fv-minval)/Range)*1000000000+0.5);
204       } else {
205         v=(int)(((fv-minval)/Range)*1000000000-0.5);
206       }
207       lowthreshslider->setValue(v);
208     }
209   } else {
210     QMessageBox::information(this,"SnarkDisplay","Error!\n"
211                              "Invalid Low Threshold value.");
212   }
213 } // --rangewindow::updateLowthreshslider()
214
215
216 /** update the text in highthresh textbox based on the value of high threshold slider */
217 void rangewindow::updateHighthresh()
218 {
219   int v = highthreshslider->value();
220   if(v < lowthreshslider->value()) { // cap it
221     highthreshslider->setValue(lowthreshslider->value());
222     highglobalthresh = lowglobalthresh;
223     highthresh->setText(highthresh->text());
224   } else {
225     highglobalthresh = (((double)v)/1000000000)*Range+minval;
226     char s[12];
227     sprintf(s,"%10.7f", highglobalthresh);
228     highthresh->setText(s);
229   }
230 } // --rangewindow::updateHighthresh()
231
232
233 void rangewindow::updateHighthreshslider()
234 {
235   double fv;
236   int v=0;
237   bool ok=false;
238   fv=highthresh->text().toDouble(&ok);
239   if(ok) {
240     if((fv>maxval) || (fv<minval)) {
241       QMessageBox::information(this,"SnarkDisplay","Error!\n"
242                                "Entered threshold value must be within valid range");
243       updateHighthresh();
244       highthresh->setFocus();
245     } else {
246       highglobalthresh=fv;
247       //    status=true;
248       //      if(fv>maxval) {
249       //        maxval=fv;
250       //        Range=maxval-minval;
251       //      }
252       if(fv>0) {
253         v=(int)(((fv-minval)/Range)*1000000000+0.5);
254       } else {
255         v=(int)(((fv-minval)/Range)*1000000000-0.5);
256       }
257       //      if(v>highthreshslider->maxValue()) 
258       //        highthreshslider->setMaxValue(v);
259       highthreshslider->setValue(v);
260       //    status=false;
261     }
262   } else {
263     QMessageBox::information(this,"SnarkDisplay","Error!\n"
264                              "Invalid High Threshold value.");
265   }
266 } // --rangewindow::updateHighthreshslider()
267
268
269 /** en/disable fields in this window only 
270     based on parameter indicating whether global thresholds should apply to all images
271 */
272 void rangewindow::signalAllGlobals(bool on) {
273   lowthresh->setEnabled(on);
274   setlowbutton->setEnabled(on);
275   lowthreshslider->setEnabled(on);
276   lowthershlabel->setEnabled(on);
277   highthreshframe->setEnabled(on);
278   highthresh->setEnabled(on);
279   sethighbutton->setEnabled(on);
280   highthreshslider->setEnabled(on);
281   highthreshlabel->setEnabled(on);
282   // applybutton->setEnabled(on);
283 }
284
285 /** apply correct thresholds based on whether difference (for all) is selected or not*/
286 void rangewindow::signalAllDifference(bool on) {
287   if(on) {
288     maxval=globaldiffmax;
289     minval=globaldiffmin;
290   } else {
291     maxval=globalmax;
292     minval=globalmin;
293   }
294   Range=maxval-minval;
295   lowglobalthresh=minval;
296   highglobalthresh=maxval;
297   updateLowthresh();
298   updateHighthresh();
299 }  // --rangewindow::signalAllDifference()
300
301
302
303 void rangewindow::closeWindow() {
304   if(allGlobals->isOn()) allGlobals->toggle(); // triggers the appropriate signal-slot mechanism
305   if(allDifference->isOn()) allDifference->toggle();
306   accept();
307 }
308
309
310 void rangewindow::closeEvent(QCloseEvent* e) {
311   if(allGlobals->isOn()) allGlobals->toggle(); // triggers the appropriate signal-slot mechanism
312   if(allDifference->isOn()) allDifference->toggle();
313   e->accept();
314 }