15 #ifdef BORNAGAIN_PYTHON
19 #include "Base/Util/Assert.h"
20 #include "Base/Util/SysUtils.h"
32 #include "Sample/Multilayer/MultiLayer.h"
33 #include "Sample/Multilayer/PyImport.h"
34 #include <QApplication>
35 #include <QFileDialog>
36 #include <QTextStream>
43 std::string bornagainDir()
45 std::string pythonPath = BaseUtils::System::getenv(
"PYTHONPATH");
46 return pythonPath.empty() ? BABuild::buildLibDir() :
"";
52 QString getCandidate(
const QStringList& funcNames)
54 if (funcNames.isEmpty())
57 for (
auto str : funcNames) {
58 QString
name = str.toLower();
59 if (
name.contains(
"sample") ||
name.contains(
"sample"))
63 return funcNames.front();
68 QString fileNameToOpen()
72 QString result = QFileDialog::getOpenFileName(
75 : QFileDialog::DontUseNativeDialog);
77 if (!result.isEmpty())
86 QString readFile(
const QString& fileName)
89 if (file.open(QIODevice::ReadOnly | QIODevice::Text))
90 return QTextStream(&file).readAll();
92 const QString message =
93 "Can't read the file. \n\nPyImportAssistant::readFile -> Error: Can' t open the file '"
94 + fileName +
"' for reading.";
102 std::unique_ptr<MultiLayer> createMultiLayer(
const QString& snippet,
const QString& funcName)
104 std::unique_ptr<MultiLayer> result;
106 QApplication::setOverrideCursor(Qt::WaitCursor);
108 result = Py::Import::createFromPython(snippet.toStdString(), funcName.toStdString(),
110 }
catch (
const std::exception& ex) {
111 QApplication::restoreOverrideCursor();
112 QString message(
"Exception thrown while executing Python code to create sample.\n\n");
113 QString details = QString::fromStdString(std::string(ex.what()));
116 QApplication::restoreOverrideCursor();
123 QString selectPySampleFunction(
const QStringList& funcNames)
127 if (funcNames.empty()) {
128 QString message(
"Python code doesn't contain any functions.\n\n");
130 }
else if (funcNames.size() == 1)
131 return funcNames.front();
134 dialog.
addItems(funcNames, getCandidate(funcNames));
135 dialog.
setTextTop(
"Python code contains a few functions. Do you know by chance, "
136 "which one is intended to produce a valid MultiLayer?");
138 "Please select a valid function in combo box and press OK to continue.");
139 if (dialog.exec() == QDialog::Accepted)
149 QString getPySampleFunctionName(
const QString& snippet)
151 QStringList funcList;
153 QApplication::setOverrideCursor(Qt::WaitCursor);
155 auto funcs = Py::Import::listOfFunctions(snippet.toStdString(), bornagainDir());
157 }
catch (
const std::exception& ex) {
158 QApplication::restoreOverrideCursor();
159 QString message(
"Exception thrown while acquiring functions from Python code.\n\n");
160 QString details = QString::fromStdString(std::string(ex.what()));
165 QApplication::restoreOverrideCursor();
167 return selectPySampleFunction(funcList);
174 auto fileName = fileNameToOpen();
176 if (fileName.isEmpty())
179 QString snippet = readFile(fileName);
180 if (snippet.isEmpty())
183 QString funcName = getPySampleFunctionName(snippet);
184 if (funcName.isEmpty())
187 auto sample = createMultiLayer(snippet, funcName);
191 if (sample->sampleName() ==
"Unnamed")
202 QString message(
"Seems that import was successful.\n\n"
203 "Check SampleView for new sample and material editor for new materials.");
206 }
catch (
const std::exception& ex) {
207 QString message(
"Exception thrown while trying to build GUI models.\n"
208 "GUI models might be in inconsistent state.\n\n");
209 QString details = QString::fromStdString(std::string(ex.what()));
ApplicationSettings * appSettings
global pointer to the instance
Defines class ApplicationSettings.
Defines class ComboSelectorDialog.
Defines class DetailedMessageBox.
Defines class GUISampleBuilder.
Defines namespace GUI::Model::ObjectBuilder.
Defines class GUIHelpers functions.
Defines class Helpers functions.
Defines class ProjectManager.
Defines namespace GUI::Project::Utils.
Implements class PyImportAssistant.
Defines functions from namespace GUI::Util::String.
bool useNativeFileDialog() const
A dialog similar to standard QMessageBox with combo box selector.
void addItems(const QStringList &selection, const QString ¤tItem="")
void setTextTop(const QString &text)
void setTextBottom(const QString &text)
QString currentText() const
A dialog similar to standard QMessageBox intended for detailed warning messages. On the contrary to Q...
static ProjectManager * instance()
void setImportDir(const QString &dirname)
Sets user import directory in system settings.
QString userImportDir() const
Returns directory name which was used by the user to import files.
static QMainWindow * mainWindow
QString const & name(EShape k)
QString baseName(const QString &fileName)
Returns base name of file.
QString fileDir(const QString &fileName)
Returns file directory from the full file path.
QStringList fromStdStrings(const std::vector< std::string > &container)
void information(QWidget *parent, const QString &title, const QString &text, const QString &detailedText)
void warning(QWidget *parent, const QString &title, const QString &text, const QString &detailedText)
MultiLayerItem * itemizeSample(const MultiLayer &sample)
Populates GUI sample with domain sample.
std::unique_ptr< MultiLayer > importMultiLayer()
Show select-file dialog, try to import via python, return created sample.