BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
dataloaderdialog.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file gui2/dataloader/dataloaderdialog.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
24 #include "mvvm/utils/fileutils.h"
26 #include <QApplication>
27 #include <QDebug>
28 #include <QDialogButtonBox>
29 #include <QKeyEvent>
30 #include <QMessageBox>
31 #include <QPushButton>
32 #include <QSettings>
33 #include <QSplitter>
34 #include <QVBoxLayout>
35 #include <sstream>
36 
37 namespace gui2 {
38 
39 namespace {
40 
41 //! Wraps user method in try/catch and invoke it.
42 //! Provides busy-sign while executing, and warning dialog on exception catch.
43 template <typename T> void invoke_and_catch(T method)
44 {
45  QApplication::setOverrideCursor(Qt::WaitCursor);
46  try {
47  std::invoke(method);
48  QApplication::restoreOverrideCursor();
49  } catch (const std::exception& ex) {
50  QApplication::restoreOverrideCursor();
51  QMessageBox msgBox;
52 
53  QString message =
54  QString("Exception was thrown while trying to load files\n\n%1").arg(ex.what());
55  msgBox.setText(message);
56  msgBox.setIcon(msgBox.Critical);
57  msgBox.exec();
58  }
59 }
60 
61 const QString dialogsize_key = "dialogsize";
62 const QString splittersize_key = "splittersize";
63 
64 const QString dialogsize_setting_name()
65 {
66  return Constants::DataLoaderGroupKey + "/" + dialogsize_key;
67 }
68 
69 const QString splittersize_setting_name()
70 {
71  return Constants::DataLoaderGroupKey + "/" + splittersize_key;
72 }
73 
74 //! Returns string representing import summary: filename and columns used for import.
75 
76 std::string createImportDescription(const QString& file_name, const ColumnInfo& axis_info,
77  const ColumnInfo& intensity_info)
78 {
79  std::ostringstream ostr;
80  ostr << "file: '" << ModelView::Utils::WithTildeHomePath(file_name).toStdString() << "', ";
81  ostr << "columns: (" << axis_info.column << ", " << intensity_info.column << ")";
82  return ostr.str();
83 }
84 
85 } // namespace
86 
88  : QDialog(parent)
89  , m_toolBar(new DataLoaderToolBar)
90  , m_selectorPanel(new LoaderSelectorPanel)
91  , m_previewPanel(new LoaderPreviewPanel)
92  , m_splitter(new QSplitter)
93  , m_dataHandler(std::make_unique<DataHandler>())
94 {
95  m_splitter->setChildrenCollapsible(false);
96  m_splitter->addWidget(m_selectorPanel);
97  m_splitter->addWidget(m_previewPanel);
98 
99  auto button_box = new QDialogButtonBox;
100  auto button = button_box->addButton("Import data", QDialogButtonBox::AcceptRole);
101  button->setAutoDefault(false);
102  button->setDefault(false);
103 
104  button = button_box->addButton("Cancel", QDialogButtonBox::RejectRole);
105  button->setAutoDefault(false);
106  button->setDefault(false);
107 
108  connect(button_box, &QDialogButtonBox::accepted, this, &DataLoaderDialog::accept);
109  connect(button_box, &QDialogButtonBox::rejected, this, &DataLoaderDialog::reject);
110 
111  auto layout = new QVBoxLayout(this);
112  layout->addWidget(m_toolBar);
113  layout->addWidget(m_splitter);
114  layout->addWidget(button_box);
115 
116  initConnections();
117  setWindowTitle("Data import dialog");
118 
119  readSettings();
120 }
121 
123 {
124  writeSettings();
125 }
126 
127 //! Returns the result of whole parsing.
128 
129 std::vector<GraphImportData> DataLoaderDialog::graphImportData() const
130 {
131  return m_graphImportData;
132 }
133 
134 //! Set list of target canvas to define entr where to import.
135 
136 void DataLoaderDialog::setTargetCanvas(const std::vector<std::string>& canvas_names,
137  int current_index)
138 {
139  m_selectorPanel->setTargetCanvas(ModelView::Utils::toStringList(canvas_names), current_index);
140 }
141 
142 //! Returns index of target canvas for graph import.
143 
145 {
147 }
148 
149 //! Invokes file selector dialog.
150 
152 {
154 }
155 
156 QStringList DataLoaderDialog::fileNames() const
157 {
158  return m_selectorPanel->fileNames();
159 }
160 
161 //! Make dialog intact to enter-key to handle it by LoadSelectorPanel.
162 
163 void DataLoaderDialog::keyPressEvent(QKeyEvent* event)
164 {
165  if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
166  return;
167  QDialog::keyPressEvent(event);
168 }
169 
171 {
172  invoke_and_catch([this]() { onParseAllRequest(); });
173 
174  QDialog::accept();
175  close();
176 }
177 
178 //! Loads ASCII data from all files in a list.
179 
181 {
182  auto update_raw_data = [this]() {
183  m_dataHandler->updateRawData(
185  };
186  invoke_and_catch(update_raw_data);
187 }
188 
189 //! Show content of selected file in text/table views.
190 
192 {
193  auto selected_files = m_selectorPanel->selectedFileNames();
194  if (selected_files.empty()) {
196  return;
197  }
198 
199  auto data_to_parse = m_dataHandler->textData(selected_files.back().toStdString());
200 
201  // creating parser using current settings
202  auto parser = m_selectorPanel->createParser();
203  parser->process(data_to_parse);
204 
205  m_previewPanel->showData(parser.get());
206 }
207 
208 //! Parse all string data and generate graph data.
209 
211 {
212  m_graphImportData.clear();
213 
214  auto parser = m_selectorPanel->createParser();
215  for (const auto& name : m_selectorPanel->fileNames()) {
216  auto data_to_parse = m_dataHandler->textData(name.toStdString());
217 
218  parser->process(data_to_parse);
219  auto parsed_text = parser->parsedData();
220 
221  auto columns = m_previewPanel->columnInfo();
222  for (auto [axis_info, intensity_info] : Utils::CreateGraphInfoPairs(columns)) {
223  auto data = Utils::CreateData(parsed_text, axis_info, intensity_info);
224  data.graph_description = createImportDescription(name, axis_info, intensity_info);
225  m_graphImportData.emplace_back(data);
226  }
227  }
228 }
229 
230 //! Reads dialog settings.
231 
233 {
234  QSettings settings;
235 
236  if (settings.contains(dialogsize_setting_name()))
237  resize(settings.value(dialogsize_setting_name(), QSize(800, 600)).toSize());
238 
239  if (settings.contains(splittersize_setting_name())) {
240  QStringList splitter_sizes = QStringList() << "400"
241  << "400";
242  splitter_sizes = settings.value(splittersize_setting_name(), splitter_sizes).toStringList();
243  QList<int> sizes;
244  for (auto num : splitter_sizes)
245  sizes.push_back(num.toInt());
246  m_splitter->setSizes(sizes);
247  }
248 }
249 
250 //! Writes dialog settings.
251 
253 {
254  QSettings settings;
255  settings.setValue(dialogsize_setting_name(), size());
256 
257  QStringList splitter_sizes;
258  for (auto x : m_splitter->sizes())
259  splitter_sizes.push_back(QString::number(x));
260  settings.setValue(splittersize_setting_name(), splitter_sizes);
261 }
262 
263 //! Init interconnections of all widgets.
264 
266 {
267  // connect toolbar and LoaderSelectorPanel
272 
273  // updates raw data container when file list changed
276 
277  // update text/table view when file selection changed
280 
281  // update text/table view when parser properties changed
284 }
285 
286 } // namespace gui2
Defines class CLASS?
Handles raw data during the life time of DataHandlerDialog.
Definition: datahandler.h:28
LoaderSelectorPanel * m_selectorPanel
void readSettings()
Reads dialog settings.
std::vector< GraphImportData > m_graphImportData
void onLoadFilesRequest()
Loads ASCII data from all files in a list.
void keyPressEvent(QKeyEvent *event) override
Make dialog intact to enter-key to handle it by LoadSelectorPanel.
void onParseAllRequest()
Parse all string data and generate graph data.
int targetCanvasIndex() const
Returns index of target canvas for graph import.
void setTargetCanvas(const std::vector< std::string > &canvas_names, int current_index)
Set list of target canvas to define entr where to import.
LoaderPreviewPanel * m_previewPanel
QStringList fileNames() const
void writeSettings()
Writes dialog settings.
DataLoaderToolBar * m_toolBar
std::unique_ptr< DataHandler > m_dataHandler
std::vector< GraphImportData > graphImportData() const
Returns the result of whole parsing.
void initConnections()
Init interconnections of all widgets.
void onShowFilePreviewRequest()
Show content of selected file in text/table views.
void invokeFileSelectorDialog()
Invokes file selector dialog.
DataLoaderDialog(QWidget *parent=nullptr)
Tool bar for DataLoaderDialog.
Panel with settings for DataLoaderDialog.
void showData(const ParserInterface *parser)
Sets raw text to the TextView.
std::vector< ColumnInfo > columnInfo() const
Panel with settings for DataLoaderDialog.
std::unique_ptr< ParserInterface > createParser() const
QStringList selectedFileNames() const
void fileNamesChanged(const QStringList &file_names)
void setTargetCanvas(const QStringList &canvas_names, int current_index)
void fileSelectionChanged(const QStringList &file_names)
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
MVVM_VIEW_EXPORT QString WithTildeHomePath(const QString &path)
Returns a string where Linux path to the file is striped using '~/'.
Definition: widgetutils.cpp:79
MVVM_VIEW_EXPORT QStringList toStringList(const std::vector< std::string > &vec)
Converts vector of strings to QStringList.
MVVM_VIEW_EXPORT std::vector< std::string > fromStringList(const QStringList &string_list)
Converts vector of strings to QStringList.
QString const & name(EShape k)
Definition: particles.cpp:21
const QString DataLoaderGroupKey
Constants for QSettings.
Definition: app_constants.h:24
DAREFLCORE_EXPORT std::vector< std::pair< ColumnInfo, ColumnInfo > > CreateGraphInfoPairs(const std::vector< ColumnInfo > &column_info)
Pack ColumnInfo into pairs representing {AxisType, IntensityType}.
DAREFLCORE_EXPORT GraphImportData CreateData(const std::vector< std::vector< std::string >> &text_data, const ColumnInfo &axis, const ColumnInfo &intensity)
Creates structure from text data.
Based on Qt example "codeeditor" Copyright (C) 2016 The Qt Company Ltd.
Definition: app_constants.h:20
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?