BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
SpecularDataImportWidget Class Reference

Description

Widget to define and show 1D (specular) imports by data loaders, e.g. CSV file import Contains space for the loader-defined import properties, a table for the raw and the imported data and a graph to show the plot of the imported data. The UI is defined via QtDesigner (.ui file)

Definition at line 37 of file SpecularDataImportWidget.h.

Inheritance diagram for SpecularDataImportWidget:
[legend]
Collaboration diagram for SpecularDataImportWidget:
[legend]

Public Member Functions

 SpecularDataImportWidget (QWidget *parent=nullptr)
 
QList< QAction * > actionList () override
 
SessionItemcurrentItem ()
 
const SessionItemcurrentItem () const
 
void setItem (SessionItem *realDataItem) override
 

Protected Member Functions

void hideEvent (QHideEvent *) override
 
void showEvent (QShowEvent *) override
 
virtual void subscribeToItem ()
 
virtual void unsubscribeFromItem ()
 

Private Slots

void onContextMenuRequest (const QPoint &point)
 
void onPlotAxisClicked (QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
 

Private Member Functions

QString currentFileName () const
 
void fillLoaderCombo ()
 
void onCreateNewFormatButton ()
 
void onFormatSelectionChanged ()
 
void onPropertiesChanged ()
 
RealDataItemrealDataItem ()
 
const RealDataItemrealDataItem () const
 
AbstractDataLoaderselectedLoader ()
 
SpecularDataItemspecularDataItem ()
 
void updatePreview ()
 
void updatePropertiesEdits ()
 

Private Attributes

SessionItemControllerm_itemController
 
AbstractDataLoader1Dm_loader
 
Ui::SpecularDataImportWidget * m_ui
 

Constructor & Destructor Documentation

◆ SpecularDataImportWidget()

SpecularDataImportWidget::SpecularDataImportWidget ( QWidget *  parent = nullptr)

Definition at line 35 of file SpecularDataImportWidget.cpp.

36  : SessionItemWidget(parent)
37  , m_ui(new Ui::SpecularDataImportWidget)
38  , m_loader(nullptr)
39 {
40  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
41 
42  m_ui->setupUi(this);
43  m_ui->warningsIcon->setFixedSize(20, 20);
44  m_ui->warningsIcon->setPixmap(QPixmap(":/images/warning_16x16.png"));
45 
46  m_ui->linkedInstrumentGroup->hide(); // #baimport - remove from UI if not used in the future
47 
48  // #baUserDefLoaders - remove next line when implementation is complete
49  m_ui->createNewFormatButton->hide();
50 
53 
54  connect(m_ui->formatSelectionComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
56  connect(m_ui->createNewFormatButton, &QPushButton::clicked, this,
58 
59  connect(m_ui->originalRowCheckBox, &QCheckBox::stateChanged, this,
61 
62  connect(m_ui->rawDataCheckBox, &QCheckBox::stateChanged, this,
64 
65  connect(m_ui->calculatedDataCheckBox, &QCheckBox::stateChanged, this,
67 
68  connect(m_ui->specularDataCanvas->customPlot(), &QCustomPlot::axisClick, this,
70 
71  m_ui->specularDataCanvas->enableDeprecatedOnMousePress(false); // we have an own handler
72 
73  m_ui->plotToolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
74  for (auto* action : m_ui->specularDataCanvas->actionList())
75  m_ui->plotToolbar->addAction(action);
76 }
SessionItemWidget(QWidget *parent=nullptr)
Ui::SpecularDataImportWidget * m_ui
AbstractDataLoader1D * m_loader
void onPlotAxisClicked(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)

References fillLoaderCombo(), m_ui, onCreateNewFormatButton(), onFormatSelectionChanged(), onPlotAxisClicked(), updatePreview(), and updatePropertiesEdits().

Here is the call graph for this function:

Member Function Documentation

◆ actionList()

QList< QAction * > SpecularDataImportWidget::actionList ( )
overridevirtual

Reimplemented from SessionItemWidget.

Definition at line 98 of file SpecularDataImportWidget.cpp.

99 {
100  return {};
101 }

Referenced by onContextMenuRequest().

◆ currentFileName()

QString SpecularDataImportWidget::currentFileName ( ) const
private

Definition at line 363 of file SpecularDataImportWidget.cpp.

364 {
365  return realDataItem()->nativeFileName();
366 }
QString nativeFileName() const
const RealDataItem * realDataItem() const

References RealDataItem::nativeFileName(), and realDataItem().

Here is the call graph for this function:

◆ currentItem() [1/2]

◆ currentItem() [2/2]

const SessionItem * SessionItemWidget::currentItem ( ) const
inherited

Definition at line 46 of file SessionItemWidget.cpp.

47 {
48  return m_itemController->currentItem();
49 }
SessionItemController * m_itemController

References SessionItemController::currentItem(), and SessionItemWidget::m_itemController.

Here is the call graph for this function:

◆ fillLoaderCombo()

void SpecularDataImportWidget::fillLoaderCombo ( )
private

Definition at line 153 of file SpecularDataImportWidget.cpp.

154 {
155  QSignalBlocker b(m_ui->formatSelectionComboBox);
156  m_ui->formatSelectionComboBox->clear();
157  for (auto* loader : DataLoaders1D::instance().recentlyUsedLoaders())
158  m_ui->formatSelectionComboBox->addItem(loader->name());
159  for (auto* loader : DataLoaders1D::instance().loaders())
160  m_ui->formatSelectionComboBox->addItem(loader->name());
161 
162  // e.g. legacy loader is not present in the combo by default. Add it here so it can be selected
163  if (m_loader != nullptr)
164  if (m_ui->formatSelectionComboBox->findText(m_loader->name()) < 0)
165  m_ui->formatSelectionComboBox->addItem(m_loader->name());
166 }
virtual QString name() const =0
The name shown in the format selection combo.
static DataLoaders1D & instance()
The one and only instance.

References DataLoaders1D::instance(), m_loader, m_ui, and AbstractDataLoader::name().

Referenced by SpecularDataImportWidget(), onCreateNewFormatButton(), and setItem().

Here is the call graph for this function:

◆ hideEvent()

void SessionItemWidget::hideEvent ( QHideEvent *  )
overrideprotectedinherited

Definition at line 56 of file SessionItemWidget.cpp.

57 {
59 }
void unsubscribe()
Fully unsubscribes the parent from listening item's signals. Controller stays active to track item de...

References SessionItemWidget::m_itemController, and SessionItemController::unsubscribe().

Here is the call graph for this function:

◆ onContextMenuRequest

void SpecularDataImportWidget::onContextMenuRequest ( const QPoint &  point)
privateslot

Definition at line 103 of file SpecularDataImportWidget.cpp.

104 {
105  QMenu menu;
106  for (auto* action : actionList())
107  menu.addAction(action);
108  menu.exec(point);
109 }
QList< QAction * > actionList() override

References actionList().

Here is the call graph for this function:

◆ onCreateNewFormatButton()

void SpecularDataImportWidget::onCreateNewFormatButton ( )
private

Definition at line 326 of file SpecularDataImportWidget.cpp.

327 {
328  bool ok;
329  QString name = QInputDialog::getText(
330  this, "New format", "Please enter a name for the new format", QLineEdit::Normal, "", &ok);
331  if (!ok || name.isEmpty())
332  return;
333 
335 
336  fillLoaderCombo();
337  m_ui->formatSelectionComboBox->setCurrentText(name);
339 }
void cloneAsUserDefinedLoader(AbstractDataLoader1D *loader, const QString &name)
clones the loader as a user defined loader and puts it in DataLoaders1D store
QString const & name(EShape k)
Definition: particles.cpp:20

References cloneAsUserDefinedLoader(), fillLoaderCombo(), m_loader, m_ui, GUI::RealSpace::Particles::name(), and onFormatSelectionChanged().

Referenced by SpecularDataImportWidget().

Here is the call graph for this function:

◆ onFormatSelectionChanged()

void SpecularDataImportWidget::onFormatSelectionChanged ( )
private

Definition at line 195 of file SpecularDataImportWidget.cpp.

196 {
197  if (m_loader && m_loader->fileContent().isEmpty()) {
198  QSignalBlocker b(m_ui->formatSelectionComboBox);
199  m_ui->formatSelectionComboBox->setCurrentText(m_loader->name());
200 
202  "Changing the loader is not possible because the original file "
203  "contents are not available any more.");
204 
205  return;
206  }
207 
208  if (m_loader)
209  m_loader->disconnect(this);
210 
211  m_loader = dynamic_cast<AbstractDataLoader1D*>(selectedLoader()->clone());
216  QApplication::setOverrideCursor(Qt::WaitCursor);
219  QApplication::restoreOverrideCursor();
220 
222  updatePreview();
225 }
Abstract base class for reflectometry data loaders.
virtual void guessSettings()
Guess appropriate settings (for example the separator in a CSV file). Is called only once,...
void importSettingsChanged()
Emitted whenever an import setting changed.
virtual void setFileContents(const QByteArray &fileContent)=0
Sets the file contents to be imported. If the file was a compressed file, then the decompressed conte...
virtual void processContents()=0
Process the file contents. Can be called more than once, e.g. if the import settings have changed....
virtual void initWithDefaultImportSettings()
Set import settings to defaults.
virtual QByteArray fileContent() const
Returns the original file content. If not available any more (like for legacy project file import),...
virtual AbstractDataLoader * clone() const =0
Create a complete clone, including all internal states.
void setRealDataItem(RealDataItem *item)
Define the real data item on which the import shall work.
AbstractDataLoader * dataLoader() const
void setDataLoader(AbstractDataLoader *loader)
Takes ownership of loader.
AbstractDataLoader * selectedLoader()
static QMainWindow * mainWindow
Definition: Globals.h:22
void information(QWidget *parent, const QString &title, const QString &text, const QString &detailedText)
Definition: MessageBox.cpp:22

References AbstractDataLoader::clone(), RealDataItem::dataLoader(), AbstractDataLoader::fileContent(), AbstractDataLoader::guessSettings(), AbstractDataLoader::importSettingsChanged(), GUI::View::Helpers::information(), AbstractDataLoader::initWithDefaultImportSettings(), m_loader, m_ui, GUI::Global::mainWindow, AbstractDataLoader::name(), onPropertiesChanged(), AbstractDataLoader::processContents(), realDataItem(), selectedLoader(), RealDataItem::setDataLoader(), AbstractDataLoader::setFileContents(), AbstractDataLoader::setRealDataItem(), updatePreview(), and updatePropertiesEdits().

Referenced by SpecularDataImportWidget(), and onCreateNewFormatButton().

Here is the call graph for this function:

◆ onPlotAxisClicked

void SpecularDataImportWidget::onPlotAxisClicked ( QCPAxis *  axis,
QCPAxis::SelectablePart  part,
QMouseEvent *  event 
)
privateslot

Definition at line 111 of file SpecularDataImportWidget.cpp.

113 {
114  if (event->button() == Qt::RightButton && axis->axisType() == QCPAxis::atLeft) {
115  QMenu menu;
116 
117  auto* lin = new QAction("Linear");
118  connect(lin, &QAction::triggered, [=]() { specularDataItem()->setLog(false); });
119  lin->setCheckable(true);
120  lin->setChecked(!specularDataItem()->isLog());
121 
122  auto* log = new QAction("Logarithmic");
123  connect(log, &QAction::triggered, [=]() { specularDataItem()->setLog(true); });
124  log->setCheckable(true);
125  log->setChecked(specularDataItem()->isLog());
126 
127  auto* ag = new QActionGroup(&menu);
128  ag->addAction(lin);
129  ag->addAction(log);
130 
131  menu.addAction(lin);
132  menu.addAction(log);
133 
134  menu.exec(event->globalPos());
135  }
136 }
void setLog(bool log_flag)

References SpecularDataItem::isLog(), SpecularDataItem::setLog(), and specularDataItem().

Referenced by SpecularDataImportWidget().

Here is the call graph for this function:

◆ onPropertiesChanged()

void SpecularDataImportWidget::onPropertiesChanged ( )
private

Definition at line 341 of file SpecularDataImportWidget.cpp.

342 {
343  m_loader->applyImportSettings(); // #baimport: may be duplicate
344  QApplication::setOverrideCursor(Qt::WaitCursor);
346  QApplication::restoreOverrideCursor();
347 
348  // If there is a linked instrument, any change in import settings can break the compatibility.
349  // Therefore check the compatibility and break the link if necessary
350  ASSERT(gSessionData->projectDocument.has_value());
351  const auto* linkedInstrument =
352  gSessionData->projectDocument.value()->collectedItems()->findInstrumentById(
353  realDataItem()->instrumentId());
354 
355  if (linkedInstrument != nullptr)
356  if (!linkedInstrument->alignedWith(realDataItem()))
358 
359 
360  updatePreview();
361 }
SessionData * gSessionData
global pointer to the single instance
Definition: SessionData.cpp:17
virtual void applyImportSettings()
Read all values from the properties UI into the internal variables.
void unlinkFromInstrument()
std::optional< ProjectDocument * > projectDocument
Definition: SessionData.h:27

References AbstractDataLoader::applyImportSettings(), gSessionData, m_loader, AbstractDataLoader::processContents(), SessionData::projectDocument, realDataItem(), RealDataItem::unlinkFromInstrument(), and updatePreview().

Referenced by onFormatSelectionChanged(), and setItem().

Here is the call graph for this function:

◆ realDataItem() [1/2]

RealDataItem * SpecularDataImportWidget::realDataItem ( )
private

Definition at line 148 of file SpecularDataImportWidget.cpp.

149 {
150  return dynamic_cast<RealDataItem*>(currentItem());
151 }
Provides access to experimental data, for display and fitting. Owns an AbstractDataLoader.
Definition: RealDataItem.h:33

References SessionItemWidget::currentItem().

Here is the call graph for this function:

◆ realDataItem() [2/2]

const RealDataItem * SpecularDataImportWidget::realDataItem ( ) const
private

Definition at line 143 of file SpecularDataImportWidget.cpp.

144 {
145  return dynamic_cast<const RealDataItem*>(currentItem());
146 }

References SessionItemWidget::currentItem().

Referenced by currentFileName(), onFormatSelectionChanged(), onPropertiesChanged(), and setItem().

Here is the call graph for this function:

◆ selectedLoader()

AbstractDataLoader * SpecularDataImportWidget::selectedLoader ( )
private

Definition at line 184 of file SpecularDataImportWidget.cpp.

185 {
186  const QString name = m_ui->formatSelectionComboBox->currentText();
187 
188  for (auto* loader : DataLoaders1D::instance().loaders())
189  if (name == loader->name())
190  return loader;
191 
192  return nullptr;
193 }

References DataLoaders1D::instance(), m_ui, and GUI::RealSpace::Particles::name().

Referenced by onFormatSelectionChanged().

Here is the call graph for this function:

◆ setItem()

void SpecularDataImportWidget::setItem ( SessionItem realDataItem)
overridevirtual

Reimplemented from SessionItemWidget.

Definition at line 78 of file SpecularDataImportWidget.cpp.

79 {
80  SessionItemWidget::setItem(_realDataItem);
81  m_ui->specularDataCanvas->setItem(specularDataItem());
82 
84  ASSERT(m_loader); // only items which have a loader are allowed for this widget. Every other
85  // items do not support this widget
86 
88 
89  QSignalBlocker b(m_ui->formatSelectionComboBox);
90  m_ui->formatSelectionComboBox->setCurrentText(m_loader->name());
91 
93  updatePreview();
96 }
virtual void setItem(SessionItem *item)

References RealDataItem::dataLoader(), fillLoaderCombo(), AbstractDataLoader::importSettingsChanged(), m_loader, m_ui, AbstractDataLoader::name(), onPropertiesChanged(), realDataItem(), SessionItemWidget::setItem(), specularDataItem(), updatePreview(), and updatePropertiesEdits().

Here is the call graph for this function:

◆ showEvent()

void SessionItemWidget::showEvent ( QShowEvent *  )
overrideprotectedinherited

Definition at line 51 of file SessionItemWidget.cpp.

52 {
54 }
void subscribe()
Subscribe parent to item's signals.

References SessionItemWidget::m_itemController, and SessionItemController::subscribe().

Here is the call graph for this function:

◆ specularDataItem()

SpecularDataItem * SpecularDataImportWidget::specularDataItem ( )
private

Definition at line 138 of file SpecularDataImportWidget.cpp.

139 {
141 }
SpecularDataItem * specularDataItem(SessionItem *parent)
Returns SpecularDataItem contained as a child in givent parent.

References SessionItemWidget::currentItem(), and GUI::Model::DataItemUtils::specularDataItem().

Referenced by onPlotAxisClicked(), and setItem().

Here is the call graph for this function:

◆ subscribeToItem()

◆ unsubscribeFromItem()

virtual void SessionItemWidget::unsubscribeFromItem ( )
inlineprotectedvirtualinherited

◆ updatePreview()

void SpecularDataImportWidget::updatePreview ( )
private

Definition at line 227 of file SpecularDataImportWidget.cpp.

228 {
229  QApplication::setOverrideCursor(Qt::WaitCursor);
230 
231  if (m_loader) {
232  auto* oldModel = m_ui->dataResultView->selectionModel(); // sic!! according to Qt docu
233  // of QAbstractItemView::setModel
234  auto* resultModel = m_loader->createResultModel();
235  if (resultModel != nullptr) {
236  const auto originalSections = resultModel->sectionsOfColumnType(
238 
239  const auto rawSections =
240  resultModel->sectionsOfColumnType(AbstractDataLoaderResultModel::ColumnType::raw);
241 
242  const auto processedSections = resultModel->sectionsOfColumnType(
244 
245  QSignalBlocker b1(m_ui->originalRowCheckBox);
246  QSignalBlocker b2(m_ui->rawDataCheckBox);
247  QSignalBlocker b3(m_ui->calculatedDataCheckBox);
248 
249  if (originalSections.isEmpty()) {
250  m_ui->originalRowCheckBox->setChecked(false);
251  m_ui->originalRowCheckBox->setEnabled(false);
252  } else
253  m_ui->originalRowCheckBox->setEnabled(true);
254 
255  if (rawSections.isEmpty()) {
256  m_ui->rawDataCheckBox->setChecked(false);
257  m_ui->rawDataCheckBox->setEnabled(false);
258  } else
259  m_ui->rawDataCheckBox->setEnabled(true);
260 
261  if (processedSections.isEmpty()) {
262  m_ui->calculatedDataCheckBox->setChecked(false);
263  m_ui->calculatedDataCheckBox->setEnabled(false);
264  } else
265  m_ui->calculatedDataCheckBox->setEnabled(true);
266 
267  m_ui->dataResultView->setModel(resultModel);
268  auto* horHeader = m_ui->dataResultView->horizontalHeader();
269 
270  for (int section : originalSections)
271  horHeader->setSectionHidden(section, !m_ui->originalRowCheckBox->isChecked());
272 
273  for (int section : rawSections)
274  horHeader->setSectionHidden(section, !m_ui->rawDataCheckBox->isChecked());
275 
276  for (int section : processedSections)
277  horHeader->setSectionHidden(section, !m_ui->calculatedDataCheckBox->isChecked());
278 
279  // if the result model has a line column, then do not show the vertical header view
280  const bool hasLinesColumn =
281  !resultModel->sectionsOfColumnType(AbstractDataLoaderResultModel::ColumnType::line)
282  .isEmpty();
283  m_ui->dataResultView->verticalHeader()->setHidden(hasLinesColumn);
284 
285  m_ui->dataResultView->resizeColumnsToContents();
286  } else
287  m_ui->dataResultView->setModel(nullptr);
288 
289  delete oldModel;
290  }
291 
292  if (m_loader && m_loader->numErrors() > 0) {
293  m_ui->warningsIcon->show();
294  m_ui->warningsLabel->show();
295  m_ui->warningsListWidget->show();
296  m_ui->warningsListWidget->clear();
297 
298  auto warnings = m_loader->lineUnrelatedErrors();
299  const int nLineRelatedWarnings = m_loader->numErrors() - warnings.size();
300 
301  if (nLineRelatedWarnings == 1)
302  warnings << "1 line related warning. Please check the data tab on the right for more "
303  "information.";
304  else if (nLineRelatedWarnings > 1)
305  warnings
306  << QString(
307  "%1 line related warnings. Please check the data tab on the right for more "
308  "information.")
309  .arg(nLineRelatedWarnings);
310 
311  if (warnings.size() > 1)
312  for (auto& w : warnings)
313  w.prepend("* ");
314 
315  for (auto& w : warnings)
316  new QListWidgetItem(w, m_ui->warningsListWidget);
317  } else {
318  m_ui->warningsIcon->hide();
319  m_ui->warningsLabel->hide();
320  m_ui->warningsListWidget->hide();
321  }
322 
323  QApplication::restoreOverrideCursor();
324 }
QVector< int > sectionsOfColumnType(ColumnType type) const
The table header sections which belong to the given column type. Empty if this column type is not pre...
virtual AbstractDataLoaderResultModel * createResultModel() const
Create a table model which contains the import information like original file content,...
virtual int numErrors() const
Number of errors found while processing the content. An error means that either a particular content ...
virtual QStringList lineUnrelatedErrors() const
Errors not related to a particular line.

References AbstractDataLoader::createResultModel(), AbstractDataLoaderResultModel::fileContent, AbstractDataLoaderResultModel::line, AbstractDataLoader::lineUnrelatedErrors(), m_loader, m_ui, AbstractDataLoader::numErrors(), AbstractDataLoaderResultModel::processed, AbstractDataLoaderResultModel::raw, and AbstractDataLoaderResultModel::sectionsOfColumnType().

Referenced by SpecularDataImportWidget(), onFormatSelectionChanged(), onPropertiesChanged(), and setItem().

Here is the call graph for this function:

◆ updatePropertiesEdits()

void SpecularDataImportWidget::updatePropertiesEdits ( )
private

Definition at line 168 of file SpecularDataImportWidget.cpp.

169 {
170  for (auto* child : m_ui->propertiesWidget->children())
171  delete child;
172 
173  if (m_ui->propertiesWidget->layout())
174  delete m_ui->propertiesWidget->layout();
175 
176  if (m_loader)
177  m_loader->populateImportSettingsWidget(m_ui->propertiesWidget);
178 
179  const bool hasChildren = !m_ui->propertiesWidget->children().empty();
180 
181  m_ui->propertiesWidget->setVisible(hasChildren);
182 }
virtual void populateImportSettingsWidget(QWidget *parent)
Fills the widget on the import dialog pane. The implementation here in the base class does nothing (m...

References m_loader, m_ui, and AbstractDataLoader::populateImportSettingsWidget().

Referenced by SpecularDataImportWidget(), onFormatSelectionChanged(), and setItem().

Here is the call graph for this function:

Member Data Documentation

◆ m_itemController

◆ m_loader

◆ m_ui

Ui::SpecularDataImportWidget* SpecularDataImportWidget::m_ui
private

The documentation for this class was generated from the following files: