void AMSamplePlateMoveActionEditor::populateSamplePositions(){ samplePositionSelectorBox_->clear(); int currentPositionIndex = 0; if(samplePlateSelectorBox_->currentIndex() == 0) samplePositionSelectorBox_->addItem("No Plate Selected", QVariant(-1)); else{ samplePositionSelectorBox_->addItem("No Sample Selected", QVariant(-1)); AMSamplePlate samplePlate; if(!samplePlate.loadFromDb(AMDatabase::database("user"), samplePlateSelectorBox_->itemData(samplePlateSelectorBox_->currentIndex()).toInt()) ){ AMErrorMon::alert(this, AMSAMPLEPLATEMOVEACTIONEDITOR_ATTEMPTED_TO_LOAD_BAD_PLATE, QString("The sample move action editor attempted to load a sample plate from the database that doesn't exist, id is %1.").arg(samplePlateSelectorBox_->itemData(samplePlateSelectorBox_->currentIndex()).toInt())); return; } QString sampleIdsSearchString; QMap<int, int> sampleIndexToPlateIndex; for(int x = 0; x < samplePlate.count(); x++){ sampleIndexToPlateIndex.insert(samplePlate.at(x).sampleId(), x); sampleIdsSearchString.append( QString("%1,").arg(samplePlate.at(x).sampleId()) ); } QSqlQuery q2 = AMDatabase::database("user")->select(AMDbObjectSupport::s()->tableNameForClass<AMSample>(), "id,name", QString("id IN (%1)").arg(sampleIdsSearchString.remove(sampleIdsSearchString.count()-1, 1)) ); q2.exec(); QString name; int sampleId; while(q2.next()) { sampleId = q2.value(0).toInt(); name = q2.value(1).toString(); samplePositionSelectorBox_->addItem(name, sampleIndexToPlateIndex.value(sampleId)); if(sampleIndexToPlateIndex.value(sampleId) == info_->samplePositionIndex()) currentPositionIndex = samplePositionSelectorBox_->count()-1; } q2.finish(); } samplePositionSelectorBox_->blockSignals(true); samplePositionSelectorBox_->setCurrentIndex(currentPositionIndex); samplePositionSelectorBox_->blockSignals(false); }
QString AMSamplePlateMoveActionInfo::samplePositionName() const{ if(samplePlateId() == -1) return "No Plate Selected"; if(samplePositionIndex() < 0) return "No Sample Selected"; AMSamplePlate samplePlate; if(!samplePlate.loadFromDb(AMDatabase::database("user"), samplePlateId_)) return "Plate Error"; if(samplePositionIndex() > samplePlate.count()) return "Sample Index Error"; AMSample actualSample; if(!actualSample.loadFromDb(AMDatabase::database("user"), samplePlate.at(samplePositionIndex()).sampleId())) return "Sample Error"; return actualSample.name(); }
void REIXSSampleMoveActionInfo::updateDescriptions() { // Working off a stored sample plate? if(samplePlateId_ > 0) { AMSamplePlate plate; if(!plate.loadFromDb(AMDatabase::database("user"), samplePlateId_) || sampleIndex_ >= plate.count() || sampleIndex_ < 0) { setShortDescription("Sample Move to [Invalid Sample Plate]"); setLongDescription("Sample Move to [Invalid Sample Plate]"); return; } // AMControlInfoList positions = plate.at(sampleIndex_).position(); QString sampleName = AMSample::sampleNameForId(plate.database(), plate.at(sampleIndex_).sampleId()); QString shortDesc = QString("Move to sample '%1' on plate '%2'.").arg(sampleName).arg(plate.name()); // Problem with appending the positions: currently we don't update the description when that sample is re-marked, so this position string could be misleading in that situation. Just leave it out. // QStringList posString; // for(int i=0, cc=positions.count(); i<cc; ++i) { // const AMControlInfo& pos = positions.at(i); // posString << QString("%1: %2 %3 ").arg(pos.contextKnownDescription()).arg(pos.value()).arg(pos.units()); // } // shortDesc.append(" (").append(posString.join(QString())).append(")"); setShortDescription(shortDesc); setLongDescription(shortDesc); } // working off a fixed position. else { QString shortDesc = QString("Sample Move: X: %1 mm Y: %2 mm Z: %3 mm Theta: %4 deg") .arg(x_) .arg(y_) .arg(z_) .arg(theta_); setShortDescription(shortDesc); setLongDescription(shortDesc); } }
const AMControlInfoList* AMSamplePlateMoveActionInfo::samplePosition(){ if( (samplePlateId_ == -1) || (samplePositionIndex_ == -1) ) return 0; //NULL AMSamplePlate samplePlate; if(!samplePlate.loadFromDb(AMDatabase::database("user"), samplePlateId_)){ AMErrorMon::alert(this, AMSAMPLEPLATEMOVEACTIONINFO_INVALID_SAMPLEPLATE_ID, QString("Failed to generate sample move information, there is no plate with id %1 in the database").arg(samplePlateId_)); //return samplePosition_; return 0; //NULL } int samplePositionId = -1; if(samplePositionIndex_ < samplePlate.count()){ //samplePositionId = samplePlate.at(samplePositionIndex_).id(); samplePositionId = samplePlate.at(samplePositionIndex_).position().id(); } /* int indexOfSamplePosition = -1; for(int x = 0; x < samplePlate.count(); x++){ if(samplePlate.at(x).id() == samplePositionIndex_){ indexOfSamplePosition = x; break; } } */ if(samplePositionId < 0){ AMErrorMon::alert(this, AMSAMPLEPLATEMOVEACTIONINFO_INVALID_SAMPLEPOSITION_INDEX, QString("Failed to generate sample move information, there is no position at index %1 on plate %2").arg(samplePositionIndex_).arg(samplePlateId_)); //return samplePosition_; return 0; //NULL } samplePosition_ = new AMControlInfoList(); if(!samplePosition_->loadFromDb(AMDatabase::database("user"), samplePositionId)){ AMErrorMon::alert(this, AMSAMPLEPLATEMOVEACTIONINFO_INVALID_SAMPLEPOSITION_ID, QString("Failed to generate sample move information, there is no position with id %1 on plate %2").arg(samplePositionIndex_).arg(samplePlateId_)); return 0; //NULL } return samplePosition_; }
REIXSSampleMoveActionEditor::REIXSSampleMoveActionEditor(REIXSSampleMoveActionInfo *info, QWidget *parent) : QFrame(parent) { info_ = info; // Create GUI: fromSample_ = new QRadioButton("Sample on Plate"); fromPositions_ = new QRadioButton("Defined Position"); QVBoxLayout* vl = new QVBoxLayout(); vl->addWidget(fromSample_); vl->addWidget(fromPositions_); vl->setContentsMargins(0,0,0,0); QHBoxLayout* hl = new QHBoxLayout(); sample_ = new QComboBox(); x_ = new QDoubleSpinBox(); x_->setRange(-100, 100); x_->setDecimals(2); y_ = new QDoubleSpinBox(); y_->setRange(-100, 100); y_->setDecimals(2); z_ = new QDoubleSpinBox(); z_->setRange(-1000, 1000); z_->setDecimals(2); theta_ = new QDoubleSpinBox(); theta_->setRange(-360, 360); theta_->setDecimals(2); hl->addLayout(vl); hl->addStretch(0); hl->addWidget(sample_); hl->addStretch(0); hl->addWidget(new QLabel("X:")); hl->addWidget(x_); hl->addWidget(new QLabel("Y:")); hl->addWidget(y_); hl->addWidget(new QLabel("Z:")); hl->addWidget(z_); hl->addWidget(new QLabel("Theta:")); hl->addWidget(theta_); setLayout(hl); // Initialize GUI: // Fill the sample choices based on the beamline's _current_ sample plate. This is a dubious choice, and couples this widget to the beamline class. AMSamplePlate* samplePlate = REIXSBeamline::bl()->samplePlate(); for(int i=0, cc=samplePlate->count(); i<cc; ++i) { int sampleId = samplePlate->at(i).sampleId(); AMSample s; s.loadFromDb(AMDatabase::database("user"), sampleId); sample_->addItem(s.name(), sampleId); } if(samplePlate->id() == info_->samplePlateId() && info_->samplePlateId() > 0) { // If the beamline's current sample plate id matches the samplePlateId() of our action, set the currently-selected sample to match. sample_->setCurrentIndex(info_->sampleIndex()); } // Mode 1: move to sample plate / sample: if(info_->samplePlateId() > 0) { fromSample_->setChecked(true); sample_->setEnabled(true); x_->setEnabled(false); y_->setEnabled(false); z_->setEnabled(false); theta_->setEnabled(false); } // Mode 2: move to fixed position: else { fromPositions_->setChecked(true); sample_->setEnabled(false); x_->setEnabled(true); y_->setEnabled(true); z_->setEnabled(true); theta_->setEnabled(true); x_->setValue(info_->x()); y_->setValue(info_->y()); z_->setValue(info_->z()); theta_->setValue(info_->theta()); } // make connections: connect(sample_, SIGNAL(activated(int)), this, SLOT(onSampleActivated(int))); connect(fromSample_, SIGNAL(toggled(bool)), this, SLOT(onFromSampleToggled(bool))); // connect editing finished for all spin boxes... connect(x_, SIGNAL(editingFinished()), this, SLOT(onSpinBoxEditingFinished())); connect(y_, SIGNAL(editingFinished()), this, SLOT(onSpinBoxEditingFinished())); connect(z_, SIGNAL(editingFinished()), this, SLOT(onSpinBoxEditingFinished())); connect(theta_, SIGNAL(editingFinished()), this, SLOT(onSpinBoxEditingFinished())); }