BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
PyImportAssistant Class Reference

Assists in importing Python object to GUI models. More...

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

Public Member Functions

 PyImportAssistant (MainWindow *mainwin)
 
void exec ()
 

Private Member Functions

std::unique_ptr< MultiLayercreateMultiLayer (const QString &snippet, const QString &funcName)
 Creates a multi-layer by executing a funcName in embedded Python. More...
 
QString fileNameToOpen ()
 Lets user to select Python file on disk. More...
 
QString getPySampleFunctionName (const QString &snippet)
 Returns the name of function which might generate a MultiLayer in Python code snippet. More...
 
void populateModels (const MultiLayer &multilayer, const QString &sampleName)
 Populates GUI models with domain multilayer. More...
 
QString readFile (const QString &fileName)
 Read content of text file and returns it as a multi-line string. More...
 
void saveImportDir (const QString &fileName)
 Saves file location as a future import dir. More...
 
QString selectPySampleFunction (const QStringList &funcNames)
 Lets user select a function name which generates a MultiLayer. More...
 

Private Attributes

MainWindowm_mainWindow
 

Detailed Description

Assists in importing Python object to GUI models.

Definition at line 28 of file PyImportAssistant.h.

Constructor & Destructor Documentation

◆ PyImportAssistant()

PyImportAssistant::PyImportAssistant ( MainWindow mainwin)

Definition at line 65 of file PyImportAssistant.cpp.

65  : QObject(mainwin), m_mainWindow(mainwin)
66 {
67 }
MainWindow * m_mainWindow

Member Function Documentation

◆ createMultiLayer()

std::unique_ptr< MultiLayer > PyImportAssistant::createMultiLayer ( const QString &  snippet,
const QString &  funcName 
)
private

Creates a multi-layer by executing a funcName in embedded Python.

Function is supposed to be in code provided by 'snippet'.

Definition at line 189 of file PyImportAssistant.cpp.

191 {
192  std::unique_ptr<MultiLayer> result;
193 
194  QApplication::setOverrideCursor(Qt::WaitCursor);
195  try {
196  result = PyImport::createFromPython(snippet.toStdString(), funcName.toStdString(),
197  bornagainDir());
198 
199  } catch (const std::exception& ex) {
200  QApplication::restoreOverrideCursor();
201  QString message("Exception thrown while executing Python code to create multilayer.\n\n");
202  QString details = QString::fromStdString(std::string(ex.what()));
203  DetailedMessageBox(m_mainWindow, "Python failure", message, details).exec();
204  }
205  QApplication::restoreOverrideCursor();
206 
207  return result;
208 }
A dialog similar to standard QMessageBox intended for detailed warning messages.
std::unique_ptr< MultiLayer > createFromPython(const std::string &script, const std::string &functionName, const std::string &path="")
Creates a multi layer by running python code in embedded interpreter.
Definition: PyImport.cpp:34

References PyImport::createFromPython(), and m_mainWindow.

Referenced by exec().

Here is the call graph for this function:

◆ exec()

void PyImportAssistant::exec ( )

Definition at line 69 of file PyImportAssistant.cpp.

70 {
71  auto fileName = fileNameToOpen();
72 
73  if (fileName.isEmpty())
74  return;
75 
76  QString snippet = readFile(fileName);
77  if (snippet.isEmpty())
78  return;
79 
80  QString funcName = getPySampleFunctionName(snippet);
81  if (funcName.isEmpty())
82  return;
83 
84  auto multilayer = createMultiLayer(snippet, funcName);
85  if (!multilayer)
86  return;
87 
88  populateModels(*multilayer, GUIHelpers::baseName(fileName));
89 }
QString fileNameToOpen()
Lets user to select Python file on disk.
QString readFile(const QString &fileName)
Read content of text file and returns it as a multi-line string.
QString getPySampleFunctionName(const QString &snippet)
Returns the name of function which might generate a MultiLayer in Python code snippet.
void populateModels(const MultiLayer &multilayer, const QString &sampleName)
Populates GUI models with domain multilayer.
std::unique_ptr< MultiLayer > createMultiLayer(const QString &snippet, const QString &funcName)
Creates a multi-layer by executing a funcName in embedded Python.
QString baseName(const QString &fileName)
Returns base name of file.
Definition: GUIHelpers.cpp:204

References GUIHelpers::baseName(), createMultiLayer(), fileNameToOpen(), getPySampleFunctionName(), populateModels(), and readFile().

Referenced by ActionManager::onImportFromPythonScript().

Here is the call graph for this function:

◆ fileNameToOpen()

QString PyImportAssistant::fileNameToOpen ( )
private

Lets user to select Python file on disk.

Definition at line 93 of file PyImportAssistant.cpp.

94 {
95  QString dirname = AppSvc::projectManager()->userImportDir();
96 
97  QString result = QFileDialog::getOpenFileName(m_mainWindow, "Open python script", dirname,
98  "Python scripts (*.py)");
99 
100  saveImportDir(result);
101 
102  return result;
103 }
static ProjectManager * projectManager()
Definition: AppSvc.cpp:18
QString userImportDir() const
Returns directory name which was used by the user to import files.
void saveImportDir(const QString &fileName)
Saves file location as a future import dir.

References m_mainWindow, AppSvc::projectManager(), saveImportDir(), and ProjectManager::userImportDir().

Referenced by exec().

Here is the call graph for this function:

◆ getPySampleFunctionName()

QString PyImportAssistant::getPySampleFunctionName ( const QString &  snippet)
private

Returns the name of function which might generate a MultiLayer in Python code snippet.

Pop-ups dialog and asks user for help in the case of doubts.

Definition at line 137 of file PyImportAssistant.cpp.

138 {
139  QStringList funcList;
140 
141  QApplication::setOverrideCursor(Qt::WaitCursor);
142  try {
143  auto funcs = PyImport::listOfFunctions(snippet.toStdString(), bornagainDir());
144  funcList = GUIHelpers::fromStdStrings(funcs);
145 
146  } catch (const std::exception& ex) {
147  QApplication::restoreOverrideCursor();
148  QString message("Exception thrown while acquiring functions from Python code.\n\n");
149  QString details = QString::fromStdString(std::string(ex.what()));
150  DetailedMessageBox(m_mainWindow, "Python failure", message, details).exec();
151 
152  return "";
153  }
154  QApplication::restoreOverrideCursor();
155 
156  return selectPySampleFunction(funcList);
157 }
QString selectPySampleFunction(const QStringList &funcNames)
Lets user select a function name which generates a MultiLayer.
QStringList fromStdStrings(const std::vector< std::string > &container)
Definition: GUIHelpers.cpp:233
std::vector< std::string > listOfFunctions(const std::string &script, const std::string &path="")
Returns list of functions defined in the script.
Definition: PyImport.cpp:86

References GUIHelpers::fromStdStrings(), PyImport::listOfFunctions(), m_mainWindow, and selectPySampleFunction().

Referenced by exec().

Here is the call graph for this function:

◆ populateModels()

void PyImportAssistant::populateModels ( const MultiLayer multilayer,
const QString &  sampleName 
)
private

Populates GUI models with domain multilayer.

Definition at line 212 of file PyImportAssistant.cpp.

213 {
214  try {
215  QString name = sampleName;
216  if (multilayer.getName() != "MultiLayer")
217  name = QString::fromStdString(multilayer.getName());
218 
220  m_mainWindow->materialModel(), multilayer, name);
221 
222  QString message("Seems that import was successfull.\n\n"
223  "Check SampleView for new sample and material editor for new materials.");
224  GUIHelpers::information(m_mainWindow, "PyImport", message);
225 
226  } catch (const std::exception& ex) {
227  QString message("Exception thrown while trying to build GUI models.\n"
228  "GUI models might be in unconsistent state.\n\n");
229  QString details = QString::fromStdString(std::string(ex.what()));
230  DetailedMessageBox(m_mainWindow, "GUIObjectBuilder failure", message, details).exec();
231  }
232 }
const std::string & getName() const
SampleModel * sampleModel()
Definition: mainwindow.cpp:144
MaterialModel * materialModel()
Definition: mainwindow.cpp:134
void information(QWidget *parent, const QString &title, const QString &text, const QString &detailedText)
Definition: GUIHelpers.cpp:54
SessionItem * populateSampleModel(SampleModel *sampleModel, MaterialModel *materialModel, const MultiLayer &sample, const QString &sample_name="")
QString const & name(EShape k)
Definition: particles.cpp:21

References IParametricComponent::getName(), GUIHelpers::information(), m_mainWindow, MainWindow::materialModel(), RealSpace::Particles::name(), GUIObjectBuilder::populateSampleModel(), and MainWindow::sampleModel().

Referenced by exec().

Here is the call graph for this function:

◆ readFile()

QString PyImportAssistant::readFile ( const QString &  fileName)
private

Read content of text file and returns it as a multi-line string.

Pop-ups warning dialog in the case of failure.

Definition at line 118 of file PyImportAssistant.cpp.

119 {
120  QString result;
121 
122  try {
123  result = ProjectUtils::readTextFile(fileName);
124 
125  } catch (const std::exception& ex) {
126  QString message("Can't read the file. \n\n");
127  message += QString::fromStdString(std::string(ex.what()));
128  GUIHelpers::warning(m_mainWindow, "File read failure.", message);
129  }
130 
131  return result;
132 }
void warning(QWidget *parent, const QString &title, const QString &text, const QString &detailedText)
Definition: GUIHelpers.cpp:74
QString readTextFile(const QString &fileName)
Returns multi-lione string representing content of text file.

References m_mainWindow, ProjectUtils::readTextFile(), and GUIHelpers::warning().

Referenced by exec().

Here is the call graph for this function:

◆ saveImportDir()

void PyImportAssistant::saveImportDir ( const QString &  fileName)
private

Saves file location as a future import dir.

Definition at line 107 of file PyImportAssistant.cpp.

108 {
109  if (fileName.isEmpty())
110  return;
111 
113 }
void setImportDir(const QString &dirname)
Sets user import directory in system settings.
QString fileDir(const QString &fileName)
Returns file directory from the full file path.
Definition: GUIHelpers.cpp:193

References GUIHelpers::fileDir(), AppSvc::projectManager(), and ProjectManager::setImportDir().

Referenced by fileNameToOpen().

Here is the call graph for this function:

◆ selectPySampleFunction()

QString PyImportAssistant::selectPySampleFunction ( const QStringList &  funcNames)
private

Lets user select a function name which generates a MultiLayer.

Definition at line 161 of file PyImportAssistant.cpp.

162 {
163  QString result;
164 
165  if (funcNames.empty()) {
166  QString message("Python code doesn't contain any functions.\n\n");
167  GUIHelpers::warning(m_mainWindow, "Python failure", message);
168 
169  } else if (funcNames.size() == 1) {
170  return funcNames.front();
171 
172  } else {
173  ComboSelectorDialog dialog;
174  dialog.addItems(funcNames, getCandidate(funcNames));
175  dialog.setTextTop("Python code contains a few functions. Do you know by chance, "
176  "which one is intended to produce a valid MultiLayer?");
177  dialog.setTextBottom(
178  "Please select a valid function in combo box and press OK to continue.");
179  if (dialog.exec() == QDialog::Accepted)
180  result = dialog.currentText();
181  }
182 
183  return result;
184 }
A dialog similar to standard QMessageBox with combo box selector.
void addItems(const QStringList &selection, const QString &currentItem="")
void setTextTop(const QString &text)
void setTextBottom(const QString &text)
QString currentText() const

References ComboSelectorDialog::addItems(), ComboSelectorDialog::currentText(), m_mainWindow, ComboSelectorDialog::setTextBottom(), ComboSelectorDialog::setTextTop(), and GUIHelpers::warning().

Referenced by getPySampleFunctionName().

Here is the call graph for this function:

Member Data Documentation

◆ m_mainWindow

MainWindow* PyImportAssistant::m_mainWindow
private

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