BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
MaterialEditorDialog.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/View/MaterialEditor/MaterialEditorDialog.cpp
6 //! @brief Implements class MaterialEditorDialog
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2021
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
23 #include "GUI/View/Tool/EditUtil.h"
26 #include "ui_MaterialEditorDialog.h"
27 #include <QAction>
28 #include <QColorDialog>
29 #include <QMessageBox>
30 #include <QPushButton>
31 #include <QSettings>
32 #include <QToolBar>
33 #include <QVBoxLayout>
34 
36  : QDialog(parent)
37  , m_ui(new Ui::MaterialEditorDialog)
38  , m_sample(sample)
39 {
41 
43 
44  m_ui->setupUi(this);
45 
47  configScientificDoubleEdit(m_ui->deltaEdit, RealLimits::limitless());
48  configScientificDoubleEdit(m_ui->betaEdit, RealLimits::limitless());
49  configScientificDoubleEdit(m_ui->realEdit, RealLimits::limitless());
50  configScientificDoubleEdit(m_ui->imaginaryEdit, RealLimits::limitless());
51 
53  configSpinbox(m_ui->xSpinBox, 3, RealLimits::limitless());
54  configSpinbox(m_ui->ySpinBox, 3, RealLimits::limitless());
55  configSpinbox(m_ui->zSpinBox, 3, RealLimits::limitless());
56 
57  auto* addRefractiveMaterialAction = new QAction("Add material (refractive index)", parent);
58  addRefractiveMaterialAction->setIcon(QIcon(":/images/shape-square-plus.svg"));
59  addRefractiveMaterialAction->setToolTip("Add new material");
60  connect(addRefractiveMaterialAction, &QAction::triggered, this,
62 
63  auto* addSldMaterialAction = new QAction("Add material (SLD)", parent);
64  addSldMaterialAction->setIcon(QIcon(":/images/shape-square-plus.svg"));
65  addSldMaterialAction->setToolTip("Add new material");
66  connect(addSldMaterialAction, &QAction::triggered, this, &MaterialEditorDialog::addSldMaterial);
67 
68  m_cloneMaterialAction = new QAction("Copy", parent);
69  m_cloneMaterialAction->setIcon(QIcon(":/images/content-copy.svg"));
70  m_cloneMaterialAction->setToolTip("Copy selected material");
71  connect(m_cloneMaterialAction, &QAction::triggered, this,
73 
74  m_removeMaterialAction = new QAction("Remove", parent);
75  m_removeMaterialAction->setIcon(QIcon(":/images/delete.svg"));
76  m_removeMaterialAction->setToolTip("Remove selected material");
77  connect(m_removeMaterialAction, &QAction::triggered, this,
79 
80  m_ui->treeView->addAction(addRefractiveMaterialAction);
81  m_ui->treeView->addAction(addSldMaterialAction);
82  m_ui->treeView->addAction(m_cloneMaterialAction);
83  auto* separator = new QAction(this);
84  separator->setSeparator(true);
85  m_ui->treeView->addAction(separator);
86  m_ui->treeView->addAction(m_removeMaterialAction);
87  m_ui->treeView->setModel(m_model);
88  m_ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
89 
90  auto* toolbar = new QToolBar(this);
91  toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
92  toolbar->addAction(addRefractiveMaterialAction);
93  toolbar->addAction(addSldMaterialAction);
94  toolbar->addAction(m_cloneMaterialAction);
95  toolbar->addAction(m_removeMaterialAction);
96  m_ui->mainLayout->insertWidget(0, toolbar);
97 
100 
101  connect(m_ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this,
103 
104  connect(m_ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this,
106 
107  connect(m_ui->selectColorButton, &QPushButton::clicked, this,
109 
110  connect(m_ui->nameEdit, &QLineEdit::textEdited,
111  [&](const QString& t) { m_model->setMaterialItemName(currentIndex(), t); });
112 
113  connect(m_ui->xSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
114  [&](double value) { m_model->setX(currentIndex(), value); });
115 
116  connect(m_ui->ySpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
117  [&](double value) { m_model->setY(currentIndex(), value); });
118 
119  connect(m_ui->zSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
120  [&](double value) { m_model->setZ(currentIndex(), value); });
121 
122  connect(m_ui->deltaEdit, &QLineEdit::editingFinished,
123  [&]() { m_model->setDelta(currentIndex(), m_ui->deltaEdit->text().toDouble()); });
124 
125  connect(m_ui->betaEdit, &QLineEdit::editingFinished,
126  [&]() { m_model->setBeta(currentIndex(), m_ui->betaEdit->text().toDouble()); });
127 
128  connect(m_ui->realEdit, &QLineEdit::editingFinished,
129  [&]() { m_model->setRe(currentIndex(), m_ui->realEdit->text().toDouble()); });
130 
131  connect(m_ui->imaginaryEdit, &QLineEdit::editingFinished,
132  [&]() { m_model->setIm(currentIndex(), m_ui->imaginaryEdit->text().toDouble()); });
133 
134 
135  if (m_model->rowCount() > 0)
136  m_ui->treeView->setCurrentIndex(m_model->first());
137  else {
138  m_ui->sldGroupBox->hide();
139  m_ui->propertiesWidget->setEnabled(false);
140  }
141 }
142 
144 {
146 }
147 
149 {
151  QDialog::accept();
152 }
153 
154 QString MaterialEditorDialog::chooseMaterial(QWidget* parent, MultiLayerItem* sample,
155  const QString& identifierOfPreviousMaterial)
156 {
157  MaterialEditorDialog dialog(sample, parent);
158  dialog.setCurrentMaterial(identifierOfPreviousMaterial);
159  if (dialog.exec() == QDialog::Accepted)
160  if (MaterialItem* material = dialog.currentMaterial())
161  return material->identifier();
162 
163  return QString();
164 }
165 
167 {
168  MaterialEditorDialog dialog(sample, parent);
169  dialog.exec();
170 }
171 
173 {
174  setCurrentMaterial(m_model->addRefractiveMaterial("unnamed", 0.0, 0.0));
175 }
176 
178 {
179  setCurrentMaterial(m_model->addSLDMaterial("unnamed", 0.0, 0.0));
180 }
181 
183 {
184  if (currentIndex().isValid())
186 }
187 
189 {
190  MaterialItem* material = currentMaterial();
191  if (material == nullptr)
192  return;
193 
194  if (identifiersOfUsedMaterials().contains(material->identifier())) {
195  QMessageBox::warning(this, "Remove material",
196  "This material can't be removed - it is used in the current sample.");
197  return;
198  }
199 
201 }
202 
204 {
205  if (auto newColor = QColorDialog::getColor(currentMaterial()->color()); newColor.isValid())
206  m_model->setColor(currentIndex(), newColor);
207 
208  fill();
209 }
210 
212 {
213  m_removeMaterialAction->setEnabled(currentIndex().isValid());
214  m_cloneMaterialAction->setEnabled(currentIndex().isValid());
215 }
216 
218 {
219  return currentIndex().isValid() ? m_model->materialFromIndex(currentIndex()) : nullptr;
220 }
221 
223 {
224  auto* materialItem = currentMaterial();
225 
226  m_ui->propertiesWidget->setEnabled(materialItem != nullptr);
227  if (materialItem == nullptr) {
228  m_ui->refractiveGroupBox->show();
229  m_ui->sldGroupBox->hide();
230  for (auto* lineEdit : m_ui->propertiesWidget->findChildren<QLineEdit*>())
231  lineEdit->clear();
232  for (auto* spinBox : m_ui->propertiesWidget->findChildren<QDoubleSpinBox*>())
233  spinBox->clear();
234  return;
235  }
236 
237  m_ui->refractiveGroupBox->setVisible(materialItem->hasRefractiveIndex());
238  m_ui->sldGroupBox->setVisible(!materialItem->hasRefractiveIndex());
239 
240  m_ui->nameEdit->setText(materialItem->matItemName());
241  m_ui->colorInfo->setText(QString("[%1, %2, %3] (%4)")
242  .arg(materialItem->color().red())
243  .arg(materialItem->color().green())
244  .arg(materialItem->color().blue())
245  .arg(materialItem->color().alpha()));
246  QPixmap pixmap(m_ui->selectColorButton->iconSize());
247  pixmap.fill(materialItem->color());
248  m_ui->selectColorButton->setIcon(pixmap);
249 
250  if (materialItem->hasRefractiveIndex()) {
251  m_ui->deltaEdit->setText(QString::number(materialItem->delta().get(), 'g'));
252  m_ui->betaEdit->setText(QString::number(materialItem->beta().get(), 'g'));
253  } else {
254  m_ui->realEdit->setText(QString::number(materialItem->sldRe().get(), 'g'));
255  m_ui->imaginaryEdit->setText(QString::number(materialItem->sldIm().get(), 'g'));
256  }
257 
258  m_ui->xSpinBox->setValue(materialItem->magnetization().x());
259  m_ui->ySpinBox->setValue(materialItem->magnetization().y());
260  m_ui->zSpinBox->setValue(materialItem->magnetization().z());
261 }
262 
264 {
265  m_ui->treeView->setCurrentIndex(m_model->indexFromMaterial(m));
266 }
267 
268 void MaterialEditorDialog::setCurrentMaterial(const QString& identifier)
269 {
270  m_ui->treeView->setCurrentIndex(m_model->indexFromMaterial(identifier));
271 }
272 
274 {
275  return m_ui->treeView->currentIndex();
276 }
277 
279 {
280  QStringList result;
281  for (auto* p : m_sample->itemsWithMaterial())
282  result << p->materialIdentifier();
283  return result;
284 }
ApplicationSettings * appSettings
global pointer to the instance
Defines class ApplicationSettings.
Defines class DoubleDescriptor.
Defines class GUIHelpers functions.
Defines abstract item with a material property.
Defines class MaterialEditorDialog.
Defines class MaterialEditorModel.
Defines class MaterialItem.
Defines class MaterialItems.
Defines class MultiLayerItem.
Defines GUI::StyleUtils namespace.
void loadWindowSizeAndPos(QWidget *w)
void saveWindowSizeAndPos(const QWidget *w)
Dialog to select a material and also to edit the list of existing materials. The dialog operates on a...
MaterialItems m_tmpMaterialItems
static QString chooseMaterial(QWidget *parent, MultiLayerItem *sample, const QString &identifierOfPreviousMaterial)
Use this to choose a material. identifierOfPreviousMaterial is the material which should be selected ...
QAction * m_cloneMaterialAction
Materials for working within this dialog.
void setCurrentMaterial(const MaterialItem *m)
MaterialEditorDialog(MultiLayerItem *sample, QWidget *parent=nullptr)
MaterialItem * currentMaterial()
Ui::MaterialEditorDialog * m_ui
QModelIndex currentIndex() const
MaterialEditorModel * m_model
MultiLayerItem * m_sample
Model for the left list. Works on m_tmpMaterialItems.
QStringList identifiersOfUsedMaterials() const
Returns the list of material identifiers of the materials currently used in the sample....
static void editMaterials(QWidget *parent, MultiLayerItem *sample)
Use this to edit the list of existing materials.
void accept() override
updates original material model with the edited model
Model for list of materials, used in MaterialEditorDialog.
MaterialItem * materialFromIndex(const QModelIndex &index) const
QModelIndex indexFromMaterial(const MaterialItem *m) const
MaterialItem * addRefractiveMaterial(const QString &name, double delta, double beta)
void setColor(const QModelIndex &index, const QColor &color)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
MaterialItem * addSLDMaterial(const QString &name, double sld, double abs_term)
MaterialItem * cloneMaterial(const QModelIndex &index)
void removeMaterial(const QModelIndex &index)
QModelIndex first() const
QString identifier() const
void initFrom(const MaterialItems &from)
Copies the complete content, emitting signals for existing and changed materials.
MaterialItems & materialItems()
QVector< ItemWithMaterial * > itemsWithMaterial() const
Defines namespace GUI::Constants.
void setResizable(QDialog *dialog)
Make modal dialog resizable.
Definition: StyleUtils.cpp:100
void configSpinbox(QDoubleSpinBox *spinBox, int decimals, const RealLimits &limits)
Definition: EditUtil.cpp:47
void configScientificDoubleEdit(QLineEdit *edit, const RealLimits &limits)
Definition: EditUtil.cpp:33
void warning(QWidget *parent, const QString &title, const QString &text, const QString &detailedText)
Definition: MessageBox.cpp:37