/* * Title: PhaseTableWin.cpp * Author: M.Thomas BEAM Ltd * Date: 2007-02-13 * * Contents: State Table Setup * * Mod Rec: * */ #include <PhaseTableWin.h> #include <qlayout.h> #include <qpushbutton.h> #include <qvgroupbox.h> #include <qmessagebox.h> #include <qlabel.h> #include <qfiledialog.h> #include <qcheckbox.h> #include <BFile.h> #include <BQComboBox.h> #include <qgroupbox.h> #include <qvbox.h> #include <qlistbox.h> #include <qvalidator.h> #include <qtable.h> #include <Globals.h> #include <math.h> #include <TmsD.h> #include <TmsC.h> #include <TmsS.h> #include <TmsLib.h> const unsigned int MAX_CYCLE_STATES = 9; using namespace Tms; static ComboDefinition phaseNames[] = { { 0, "Calibration", CyclePeriodCalibration, 1 }, { 1, "Event 0", CyclePeriodEvent0, 0 }, { 2, "Event 1", CyclePeriodEvent1, 0 }, { 3, "Event 2", CyclePeriodEvent2, 0 }, { 4, "Event 3", CyclePeriodEvent3, 0 }, { 5, "Event 4", CyclePeriodEvent4, 0 }, { 6, "Event 5", CyclePeriodEvent5, 0 }, { 7, "Event 6", CyclePeriodEvent6, 0 }, { 8, "Event 7", CyclePeriodEvent7, 0 }, { 9, "Event 8", CyclePeriodEvent8, 0 }, { 10, "Event 9", CyclePeriodEvent9, 0 }, { 0,0,0,0 } }; PhaseTableWin::PhaseTableWin(QWidget* parent,Control& c) : ocontrol(c) { QGridLayout* grid; BString s; int row = 0; int col = 0; QVGroupBox* baseParams; QVGroupBox* positions; QVGroupBox * loadParams; QWidget* w; QGridLayout* v; oparams.cycleType = ""; oparams.info = ""; oparams.pllInitialFrequency = 0; oparams.pllInitialFrequencyDelay = 0; oparams.pllFrefGain = 0; oparams.pllGain = 0; oparams.channel = 0; for (unsigned int n = 0; n < MAX_CYCLE_STATES;n++) { CycleParamState s; oparams.getDefaultState(s); ocycleStates.append(s); } QValidator* validatorInt = new QIntValidator(-(int)pow(2,31), (int)pow(2,31), this ); QValidator* validatorDouble = new QDoubleValidator(this ); QRegExpValidator* validatorHex = new QRegExpValidator(this); QRegExp rx; rx.setPattern("0x[0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f]"); validatorHex->setRegExp(rx); grid = new QGridLayout(this,5,3); grid->setMargin(10); grid->setSpacing(10); s = "<p><b>Cycle Parameters<b></p>"; s += "<p>Select Cycle parameters file to be loaded</p>"; // Load Cycle Parameters createGridGroupBox(loadParams,"Load Cycle Parameters",w,v); ocycleTypes = new QListBox(w,"cycleList"); oloadFromTms = new QPushButton("Load from TMS",w); ofilename = new QLineEdit(w,"S"); oselectFile = new QPushButton("Select",w); oloadFromFile = new QPushButton("Load from File",w); row = 0; col = 0; v->addWidget(new QLabel("Load from TMS",w),row,col); v->addMultiCellWidget(ocycleTypes,row,row + 8,col + 1,col +1); v->addWidget(oloadFromTms,row,col + 3); row = 9;col = 0; v->addWidget(new QLabel("Load from File",w),row,0); v->addWidget(ofilename,row,col + 1); v->addWidget(oselectFile,row,col +2); v->addWidget(oloadFromFile,row,col +3); // Base Paramters // Should have classed a GridGroupBox ! createGridGroupBox(baseParams,"Base Parameters",w,v); ocycleType = new QLineEdit(w,""); oinfo = new QLineEdit(w,""); opllCycleStartFrequency = new QLineEdit(w,"");opllCycleStartFrequency->setValidator(validatorInt); opllInitialFrequency = new QLineEdit(w,"");opllInitialFrequency->setValidator(validatorInt); opllInitialFrequencyDelay = new QLineEdit(w,"");opllInitialFrequencyDelay->setValidator(validatorInt); opllFrefGain = new QLineEdit(w,"");opllFrefGain->setValidator(validatorInt); opllGain = new QLineEdit(w,"");opllGain->setValidator(validatorInt); opllDdsMinimum = new QLineEdit(w,"");opllDdsMinimum->setValidator(validatorInt); opllDdsMaximum = new QLineEdit(w,"");opllDdsMaximum->setValidator(validatorInt); row = 0;col = 0; addEditorToGrid(v,w,"Cycle Type", ocycleType,row,col); row++; addEditorToGrid(v,w,"Info", oinfo,row,col); row++; addEditorToGrid(v,w,"Pll Cycle Start Frequency", opllCycleStartFrequency,row,col); row++; addEditorToGrid(v,w,"Pll Initial Frequency", opllInitialFrequency,row,col); row++; addEditorToGrid(v,w,"Pll Initial Frequency Delay (ms)", opllInitialFrequencyDelay,row,col); row++; addEditorToGrid(v,w,"Pll Fref Gain", opllFrefGain,row,col); row++; addEditorToGrid(v,w,"Pll Gain (shift right)", opllGain,row,col); row++; addEditorToGrid(v,w,"Pll Dds Max", opllDdsMinimum,row,col); row++; addEditorToGrid(v,w,"Pll Dds Min", opllDdsMaximum,row,col); row++; // Positions createGridGroupBox(positions,"Positions",w,v); ophaseDelays = new QTable(40,1,w,""); ooffset = new QSpinBox(w,""); oaddOffsets = new QPushButton("Add Offset to all channels",w); oloadDefaults = new QPushButton("Load Defaults",w,""); ophaseDelays->horizontalHeader()->setLabel( 0, "Phase Offset" ); ophaseDelays->setColumnStretchable (0,true); ooffset->setMaxValue(512); ooffset->setMinValue(-512); ooffset->setWrapping(true); row = 0; col = 0; addEditorToGrid(v,w,"Positions",ophaseDelays,row,col); row++; addEditorToGrid(v,w,"Offset", ooffset,row,col); row++; v->addWidget(oloadDefaults,row,0);v->addWidget(oaddOffsets,row,1); // State Setup createGridGroupBox(ostateSetups,"State Setup",w,v); oenableModifications = new QCheckBox("Enable Modifications",w,""); ophaseNames = new BQComboBox(phaseNames,w,""); oaddNextState = new QPushButton("Add next state",w,""); odelLastState = new QPushButton("Delete Last State",w,""); obunchMask = new QLineEdit(w,"");obunchMask->setValidator(validatorHex); omean1Mask = new QLineEdit(w,"");omean1Mask->setValidator(validatorHex); omean2Mask = new QLineEdit(w,"");omean2Mask->setValidator(validatorHex); oloHarmonic = new QLineEdit(w,"");oloHarmonic->setValidator(validatorInt); ouseLoFref = new QCheckBox("Use Lo Fref",w,""); oacquireData = new QCheckBox("Acquire Data",w,""); oloPhase = new QLineEdit(w,"");oloPhase->setValidator(validatorDouble); ogateWidth = new QLineEdit(w,"");ogateWidth->setValidator(validatorDouble); ogatePhase = new QLineEdit(w,"");ogatePhase->setValidator(validatorDouble); oblrWidth = new QLineEdit(w,"");oblrWidth->setValidator(validatorDouble); oblrPhase = new QLineEdit(w,"");oblrPhase->setValidator(validatorDouble); oenableModifications->setMaximumWidth(200); oaddNextState->setMaximumWidth(200); odelLastState->setMaximumWidth(200); obunchMask->setMaximumWidth(200); omean1Mask->setMaximumWidth(200); omean2Mask->setMaximumWidth(200); oloHarmonic->setMaximumWidth(200); oloPhase->setMaximumWidth(200); ouseLoFref->setMaximumWidth(200); oacquireData->setMaximumWidth(200); ogateWidth->setMaximumWidth(200); ogatePhase->setMaximumWidth(200); oblrWidth->setMaximumWidth(200); oblrPhase->setMaximumWidth(200); row = 0;col = 0; v->addWidget(oenableModifications,row,0); v->addWidget(ophaseNames,row,col + 1); v->addWidget(oaddNextState,row,col+2); v->addWidget(odelLastState,row,col+3); row++; addEditorToGrid(v,w,"Lo Harmonic", oloHarmonic,row,col); addEditorToGrid(v,w,"Lo Phase", oloPhase,row,col + 2);row++; addEditorToGrid(v,w,"Bunch Mask", obunchMask,row,col); addEditorToGrid(v,w,"Mean1Mask", omean1Mask,row,col + 2); addEditorToGrid(v,w,"Mean2Mask", omean2Mask,row,col + 4); row++; v->addWidget(ouseLoFref,row,col+1); v->addWidget(oacquireData,row,col+3); row++; addEditorToGrid(v,w,"Gate Width", ogateWidth,row,col); addEditorToGrid(v,w,"Gate Phase", ogatePhase,row,col + 2); row++; addEditorToGrid(v,w,"Blr Width", oblrWidth,row,col); addEditorToGrid(v,w,"Blr Phase", oblrPhase,row,col + 2); row++; // Control Buttons QHBox * controls = new QHBox(this,"controls"); oupload = new QPushButton("Upload",controls); osaveFile = new QPushButton("Save to file",controls); controls->setSpacing(20); oupload->setMaximumWidth(200); osaveFile->setMaximumWidth(200); row = 0; grid->addMultiCellWidget(loadParams,row,row,0,2); row++; grid->addWidget(baseParams,row,0); grid->addWidget(positions,row,1); row++; grid->addMultiCellWidget(ostateSetups,row,row,0,2); row++; grid->addWidget(controls,row,0); row++; connect(oloadFromFile,SIGNAL(clicked()),this,SLOT(loadFromFile())); connect(oloadFromTms,SIGNAL(clicked()),this,SLOT(loadFromTms())); connect(oselectFile,SIGNAL(clicked()),this,SLOT(selectFile())); connect(oaddOffsets,SIGNAL(clicked()),this,SLOT(addOffsets())); connect(oloadDefaults,SIGNAL(clicked()),this,SLOT(loadDefaults())); connect(osaveFile,SIGNAL(clicked()),this,SLOT(saveFile())); connect(oupload,SIGNAL(clicked()),this,SLOT(saveTms())); connect(ophaseNames,SIGNAL(activated(int)),this,SLOT(cycleStateComboPressed())); connect(obunchMask,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(omean1Mask,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(omean2Mask,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(oloHarmonic,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(oloPhase,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(ogateWidth,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(ogatePhase,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(oblrWidth,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(oblrPhase,SIGNAL(textChanged(const QString &)),this,SLOT(setCyclePhaseParams())); connect(ouseLoFref,SIGNAL(toggled(bool)),this,SLOT(setCyclePhaseParams())); connect(oacquireData,SIGNAL(toggled(bool)),this,SLOT(setCyclePhaseParams())); connect(oenableModifications,SIGNAL(toggled(bool)),this,SLOT(enableStateEdit())); connect(oaddNextState,SIGNAL(clicked()),this,SLOT(addNextState())); connect(odelLastState,SIGNAL(clicked()),this,SLOT(delLastState())); connect(&ocontrol,SIGNAL(newConnection()),this,SLOT(update())); } PhaseTableWin::~PhaseTableWin() {} void PhaseTableWin::show() { QWidget::show(); update(); } void PhaseTableWin::update() { if (! isVisible()) return; updateCycleTypes(); // Cycle Types list is retrieved from server updateCycleInfo(); updateCycleParamState(); } void PhaseTableWin::updateCycleParamState() { BIter i; CycleParamState s; ComboDefinition* d = phaseNames; int n = ophaseNames->currentItem(); ocycleStates.clear(); ophaseNames->clear(); oparams.getStates(ocycleStates); for (ocycleStates.start(i);! ocycleStates.isEnd(i);ocycleStates.next(i)) { ophaseNames->insertItem(d->label); d++; } if (ophaseNames->count() > n) { ophaseNames->setCurrentItem(n); refreshParamState(ocycleStates[n]); } else { ophaseNames->setCurrentItem(0); refreshParamState(ocycleStates[0]); } } /* updateCycleType() - Get the list on known cycle types from server and populate selection list. * */ BError PhaseTableWin::updateCycleTypes() { BError err; BIter i; BList<CycleParamItem> l; if (err = ocontrol.getControlList(l)) { return err; } ocycleTypes->clear(); for (l.start(i);! l.isEnd(i);l.next(i)) { ocycleTypes->insertItem(l[i].cycleType.retStr()); } return err; } /* updateCycleInfo() - Given cycle params (oparams) update the Gui to * should the cycle information. */ void PhaseTableWin::updateCycleInfo() { ocycleType->setText(oparams.cycleType.retStr()); oinfo->setText(oparams.info.retStr()); oinfo->setCursorPosition(0); opllCycleStartFrequency->setText(uIntToStr(oparams.pllCycleStartFrequency)); opllInitialFrequency->setText(uIntToStr(oparams.pllInitialFrequency)); opllInitialFrequencyDelay->setText(uIntToStr(oparams.pllInitialFrequencyDelay)); opllFrefGain->setText(uIntToStr(oparams.pllFrefGain)); opllGain->setText(uIntToStr(oparams.pllGain)); opllDdsMinimum->setText(uIntToStr(oparams.pllDdsMinimum)); opllDdsMaximum->setText(uIntToStr(oparams.pllDdsMaximum)); for(unsigned int i = 0; i < oparams.frefPhaseDelay.size(); i++ ) { BString s; s.printf("%d",oparams.frefPhaseDelay[i]); ophaseDelays->setText(i,0,s.retStr()); } } void PhaseTableWin::setParams() { bool ok; oparams.cycleType = ocycleType->text().ascii(); oparams.info = oinfo->text().ascii(); oparams.pllCycleStartFrequency = opllCycleStartFrequency->text().toUInt(&ok); oparams.pllInitialFrequency = opllInitialFrequency->text().toUInt(&ok); oparams.pllInitialFrequencyDelay = opllInitialFrequencyDelay->text().toUInt(&ok); oparams.pllFrefGain = opllFrefGain->text().toUInt(&ok); oparams.pllGain = opllGain->text().toUInt(&ok); oparams.pllDdsMinimum = opllDdsMinimum->text().toUInt(&ok); oparams.pllDdsMaximum = opllDdsMaximum->text().toUInt(&ok); for(unsigned int i = 0; i < oparams.frefPhaseDelay.size(); i++ ) { oparams.frefPhaseDelay[i] = ophaseDelays->text(i,0).toInt(&ok); } setCyclePhaseParams(); if (oenableModifications->isChecked()) oparams.setStates(ocycleStates); } void PhaseTableWin::setCyclePhaseParams() { bool ok; int n; n = ophaseNames->currentItem(); ocycleStates[n].bunchMask = obunchMask->text().toUInt(&ok,16); ocycleStates[n].mean1Mask = omean1Mask->text().toUInt(&ok,16); ocycleStates[n].mean2Mask = omean2Mask->text().toUInt(&ok,16); ocycleStates[n].loHarmonic = oloHarmonic->text().toUInt(&ok); ocycleStates[n].loPhase = oloPhase->text().toDouble(&ok); ocycleStates[n].useLoFref = ouseLoFref->isChecked(); ocycleStates[n].acquireData = oacquireData->isChecked(); ocycleStates[n].gateWidth = ogateWidth->text().toDouble(&ok); ocycleStates[n].gatePhase = ogatePhase->text().toDouble(&ok); ocycleStates[n].blrWidth = oblrWidth->text().toDouble(&ok); ocycleStates[n].blrPhase = oblrPhase->text().toDouble(&ok); } void PhaseTableWin::cycleStateComboPressed() { int n = ophaseNames->currentItem(); refreshParamState(ocycleStates[n]); } void PhaseTableWin::refreshParamState(CycleParamState s) { bool allowEdit = oenableModifications->isChecked(); obunchMask->setText(uIntToHexStr(s.bunchMask)); omean1Mask->setText(uIntToHexStr(s.mean1Mask)); omean2Mask->setText(uIntToHexStr(s.mean2Mask)); oloHarmonic->setText(uIntToStr(s.loHarmonic)); ouseLoFref->setChecked(s.useLoFref); oacquireData->setChecked(s.acquireData); oloPhase->setText(doubleToStr(s.loPhase));; ogateWidth->setText(doubleToStr(s.gateWidth)); ogatePhase->setText(doubleToStr(s.gatePhase)); oblrWidth->setText(doubleToStr(s.blrWidth)); oblrPhase->setText(doubleToStr(s.blrPhase)); oaddNextState->setEnabled(allowEdit); odelLastState->setEnabled(allowEdit); obunchMask->setEnabled(allowEdit); omean1Mask->setEnabled(allowEdit); omean2Mask->setEnabled(allowEdit); oloHarmonic->setEnabled(allowEdit); oloPhase->setEnabled(allowEdit); ouseLoFref->setEnabled(allowEdit); oacquireData->setEnabled(allowEdit); ogateWidth->setEnabled(allowEdit); ogatePhase->setEnabled(allowEdit); oblrWidth->setEnabled(allowEdit); oblrPhase->setEnabled(allowEdit); } void PhaseTableWin::enableStateEdit() { BString msg; if (oenableModifications->isChecked()) { msg = "<p>Enabling the state setup will overwrite all state/phase table information</p>"; msg += "<p>Are you sure you wish to continue ?</p>"; if (! confirmDialog("BEWARE",msg)) { oenableModifications->disconnect(); oenableModifications->setChecked(false); connect(oenableModifications,SIGNAL(toggled(bool)),this,SLOT(enableStateEdit())); return; } } update(); } void PhaseTableWin::addNextState() { BIter i; CycleParamState s; ComboDefinition* d = phaseNames; if (ocycleStates.number() >= MAX_CYCLE_STATES) { warningDialog("Adding Additional State",BError(1,"Maximum number of state exceeded")); return; } oparams.getDefaultState(s); ocycleStates.append(s); ophaseNames->clear(); for (ocycleStates.start(i);! ocycleStates.isEnd(i);ocycleStates.next(i)) { ophaseNames->insertItem(d->label); d++; } ophaseNames->setCurrentItem(ophaseNames->count() - 1); refreshParamState(s); } void PhaseTableWin::delLastState() { BIter i; CycleParamState s; ComboDefinition* d = phaseNames; if (ocycleStates.number() < 3) { warningDialog("Deleteing State",BError(1,"A minimum of two states are required")); return; } ocycleStates.deleteLast(); ophaseNames->clear(); for (ocycleStates.start(i);! ocycleStates.isEnd(i);ocycleStates.next(i)) { ophaseNames->insertItem(d->label); d++; } ophaseNames->setCurrentItem(ophaseNames->count() - 1); refreshParamState(ocycleStates.rear()); } void PhaseTableWin::loadDefaults() { CycleParamEdit::getdefaultPickupPositions(oparams.frefPhaseDelay); update(); } void PhaseTableWin::saveFile() { BError err; BFile f; BString fname; setParams(); fname = ofilename->text().ascii(); QString s = QFileDialog::getSaveFileName("/usr/tms/stateTables","Tms Cycle Parameters File (*.spt)",this,"save file dialog","Specify filename"); fname = s.ascii(); if (fname.len() == 0) return; if (QFile::exists(fname.retStr())){ BString msg = "The specified file already exists are you "; msg += BString("positive you wish to over write the file"); if (! confirmDialog("Confirm Action",msg)) { return; } } if(err = oparams.writeToFile(fname)) { warningDialog("Cycle Parameters - Save",err); return; } ofilename->setText(fname.retStr()); gstatusbar->message("Cycle Parameters Saved",2000); } void PhaseTableWin::loadFromFile() { BError err; BFile f; BString fname; disconnect(oenableModifications,SIGNAL(toggled(bool)),this,SLOT(enableStateEdit())); oenableModifications->setChecked(false); connect(oenableModifications,SIGNAL(toggled(bool)),this,SLOT(enableStateEdit())); fname = ofilename->text().ascii(); if (err = f.open(fname,"r")) { warningDialog("Cycle Parameters - Reading",err); return; } if(err = oparams.readFromFile(fname)) { warningDialog("Cycle Parameters - Read Parsing",err); return; } update(); gstatusbar->message("Cycle Parameters Read",2000); } void PhaseTableWin::saveTms() { BError err; setParams(); if (err = ocontrol.setControlInfo(oparams)) { warningDialog("Upload of Cycle Params",err); return; } update(); gstatusbar->message("Cycle Parameters Uploaded",2000); } void PhaseTableWin::loadFromTms() { BError err; BString type = ocycleTypes->currentText().ascii(); disconnect(oenableModifications,SIGNAL(toggled(bool)),this,SLOT(enableStateEdit())); oenableModifications->setChecked(false); connect(oenableModifications,SIGNAL(toggled(bool)),this,SLOT(enableStateEdit())); if (err = ocontrol.getControlInfo(type,0,oparams)) { BString msg; msg.printf("Attempting to access cycle type (%s) ",type.retStr()); msg += err.getString(); err.set(err.getErrorNo(),msg); warningDialog("Load from Tms",msg); return; } update(); } void PhaseTableWin::selectFile() { QString s = QFileDialog::getOpenFileName( "/usr/tms/stateTables", "Tms Cycle Parameters File (*.spt)", this, "open file dialog", "Choose a file" ); ofilename->setText(s); } void PhaseTableWin::warningDialog(BString title, BError err){ BString m; QMessageBox b; m = BString("<h5>") + title + "</h5><p>" + err.getString() + "</p>"; b.setMinimumWidth(300); b.setCaption("tmsControlGui - Warning"); b.setIcon(QMessageBox::Warning); b.setText(m.retStr()); b.exec(); } int PhaseTableWin::confirmDialog(BString title,BString msg){ BString s; s = BString("<h5>") + title + "</h5><p>" + msg + "</p>"; QMessageBox mb( "tmsControlGui - Question", s.retStr(), QMessageBox::Information, QMessageBox::Yes | QMessageBox::Default, QMessageBox::Cancel | QMessageBox::Escape, QMessageBox::NoButton ); switch( mb.exec() ) { case QMessageBox::Yes: return 1; break; case QMessageBox::No: return 0; break; case QMessageBox::Cancel: return 0; break; } return 0; } void PhaseTableWin::addOffsets() { int val = ooffset->value(); for(unsigned int i = 0; i < oparams.frefPhaseDelay.size(); i++ ) { int a; a = oparams.frefPhaseDelay[i] + val; a &= 0x1ff; oparams.frefPhaseDelay[i] = a; } update(); } void PhaseTableWin::addEditorToGrid(QGridLayout* g,QWidget* w,BString label,QWidget* editor,int row,int col) { g->addWidget(new QLabel(label.retStr(),w,""),row,col); g->addWidget(editor,row,col + 1); } void PhaseTableWin::createGridGroupBox(QVGroupBox*& g,BString title,QWidget*& w,QGridLayout*& l) { g = new QVGroupBox(title.retStr(),this,title.retStr()); w = new QWidget(g,""); l = new QGridLayout(w); l->setSpacing(10); } QString PhaseTableWin::uIntToStr(UInt32 val) { QString s; s.sprintf("%u",val); return s; } QString PhaseTableWin::doubleToStr(double val) { QString s; s.sprintf("%f",val); return s; } QString PhaseTableWin::uIntToHexStr(UInt32 val) { QString s; s.sprintf("0x%x",val); return s; }