Exemplo n.º 1
0
void AMSamplePlateSelector::onDatabaseUpdated(const QString &tableName, int id) {

	if(tableName != samplePlateTableName_ )
		return;

	if(id < 1)	// invalid ids here mean need a full table update
		return onDatabaseCreated(tableName, id);

	int index = ui_.plateComboBox->findData(id, AM::IdRole);
	// do we have it?
	if(index == -1)
		return;

	/// \badcode Assuming here that it was this object that caused the update with a storeToDb, so the updated values are already inside it. This will be incorrect if someone else updated the database behind our back.  Maybe we need to implement some kind of locking, or some way to tell if this is "our" object's update or caused by another edit.
	if(id == plate_->id()) {
		// update combo box entries:
		ui_.plateComboBox->setItemData(index, plate_->name(), Qt::DisplayRole);
		ui_.plateComboBox->setItemData(index, plate_->dateTime(), AM::DateTimeRole);
		ui_.plateComboBox->setItemData(index, "created " + AMDateTimeUtils::prettyDateTime(plate_->dateTime()), AM::DescriptionRole);

		// update editor widgets
		ui_.nameEdit->setText(plate_->name());
		ui_.createdLabel->setText(AMDateTimeUtils::prettyDateTime(plate_->dateTime()));
		ui_.notesEditor->setText("todo");
	}
	else {
		AMSamplePlate p;
		/// \todo optimize to not require a full loadFromDb.  All we care about is the name and the dateTime... don't need to load all the samples and positions.
		p.loadFromDb(AMDatabase::database("user"), id);
		ui_.plateComboBox->setItemData(index, p.name(), Qt::DisplayRole);
		ui_.plateComboBox->setItemData(index, p.dateTime(), AM::DateTimeRole);
		ui_.plateComboBox->setItemData(index, "created " + AMDateTimeUtils::prettyDateTime(p.dateTime()), AM::DescriptionRole);
	}
}
QString AMSamplePlateMoveActionInfo::samplePlateName() const{
	if(samplePlateId() == -1)
		return "No Plate Selected";

	AMSamplePlate samplePlate;
	if(!samplePlate.loadFromDb(AMDatabase::database("user"), samplePlateId_))
		return "Plate Error";

	return samplePlate.name();
}
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 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);
}
Exemplo n.º 5
0
void AMSamplePlateSelector::onFinishCreatingNewPlate() {

	// restore usual connections for the name edit box...
	disconnect(ui_.nameEdit, SIGNAL(editingFinished()), this, SLOT(onFinishCreatingNewPlate()));

	ui_.nameEdit->clearFocus();
	connect(ui_.nameEdit, SIGNAL(textEdited(QString)), this, SLOT(onNameEdited(QString)));
	connect(ui_.nameEdit, SIGNAL(editingFinished()), this, SLOT(onPlateEditingFinished()));

	QString newName = ui_.nameEdit->text();
	if(newName.isEmpty())
		return;

	AMSamplePlate newPlate;
	newPlate.setName(ui_.nameEdit->text());
	if(newPlate.storeToDb(AMDatabase::database("user")))
		changeSamplePlate(newPlate.id());

	// this update will be picked up by our 'onDatabaseUpdated()' slot

}
Exemplo n.º 6
0
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()));
}