BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
PySampleWidget.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Views/InfoWidgets/PySampleWidget.cpp
6 //! @brief Implements class PySampleWidget
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
26 #include <QScrollBar>
27 #include <QTextEdit>
28 #include <QVBoxLayout>
29 
30 namespace {
31 const int accumulate_updates_during_msec = 20.;
32 }
33 
35  : QWidget(parent)
36  , m_textEdit(new QTextEdit)
37  , m_sampleModel(nullptr)
38  , m_instrumentModel(nullptr)
39  , m_highlighter(nullptr)
40  , m_updateTimer(new UpdateTimer(accumulate_updates_during_msec, this))
41  , m_warningSign(new WarningSign(m_textEdit))
42 {
43  m_textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
44 
45  auto mainLayout = new QVBoxLayout;
46  mainLayout->setContentsMargins(0, 0, 0, 0);
47  mainLayout->addWidget(m_textEdit);
48 
49  setLayout(mainLayout);
50 
51  m_textEdit->setReadOnly(true);
52  QFont textFont("Monospace");
53  m_textEdit->setFont(textFont);
55 }
56 
58 {
59  if (sampleModel != m_sampleModel) {
60  if (m_sampleModel)
61  setEditorConnected(false);
62  m_sampleModel = sampleModel;
63  }
64 }
65 
67 {
68  m_instrumentModel = instrumentModel;
69 }
70 
71 void PySampleWidget::onModifiedRow(const QModelIndex&, int, int)
72 {
74 }
75 
76 void PySampleWidget::onDataChanged(const QModelIndex& index, const QModelIndex&)
77 {
78  auto item = m_sampleModel->itemForIndex(index);
79  if (!item)
80  return;
81 
84 }
85 
86 //! Update the editor with the script content
88 {
89  if (!m_highlighter) {
91  m_textEdit->setLineWrapMode(QTextEdit::NoWrap);
92  }
93 
94  const int old_scrollbar_value = m_textEdit->verticalScrollBar()->value();
95 
96  QString code_snippet = generateCodeSnippet();
97 
98  if (!code_snippet.isEmpty())
99  m_textEdit->setText(code_snippet);
100  else
101  m_textEdit->clear();
102 
103  m_textEdit->verticalScrollBar()->setValue(old_scrollbar_value);
104 }
105 
107 {
108  if (isConnected) {
109  connect(m_sampleModel, &SampleModel::rowsInserted, this, &PySampleWidget::onModifiedRow,
110  Qt::UniqueConnection);
111  connect(m_sampleModel, &SampleModel::rowsRemoved, this, &PySampleWidget::onModifiedRow,
112  Qt::UniqueConnection);
113  connect(m_sampleModel, &SampleModel::dataChanged, this, &PySampleWidget::onDataChanged,
114  Qt::UniqueConnection);
115  connect(m_sampleModel, &SampleModel::modelReset, this, &PySampleWidget::updateEditor,
116  Qt::UniqueConnection);
117 
119  Qt::UniqueConnection);
120 
122 
123  } else {
124  disconnect(m_sampleModel, &SampleModel::rowsInserted, this, &PySampleWidget::onModifiedRow);
125  disconnect(m_sampleModel, &SampleModel::rowsRemoved, this, &PySampleWidget::onModifiedRow);
126  disconnect(m_sampleModel, &SampleModel::dataChanged, this, &PySampleWidget::onDataChanged);
127  disconnect(m_sampleModel, &SampleModel::modelReset, this, &PySampleWidget::updateEditor);
128 
130  }
131 }
132 
133 void PySampleWidget::showEvent(QShowEvent*)
134 {
135  setEditorConnected(isVisible());
136 }
137 
138 void PySampleWidget::hideEvent(QHideEvent*)
139 {
140  setEditorConnected(isVisible());
141 }
142 
143 //! generates string representing code snippet for all multi layers in the model
144 
146 {
147  m_warningSign->clear();
148  QString result;
149 
150  for (const MultiLayerItem* sampleItem : m_sampleModel->topItems<MultiLayerItem>()) {
151  try {
152  auto multilayer = DomainObjectBuilder::buildMultiLayer(*sampleItem);
153  if (!result.isEmpty())
154  result.append("\n");
155  result.append(QString::fromStdString(ExportToPython::sampleCode(*multilayer)));
156  } catch (const std::exception& ex) {
157  QString message =
158  QString("Generation of Python Script failed. Code is not complete.\n\n"
159  "It can happen if sample requires further assembling or some of sample "
160  "parameters are not valid. See details below.\n\n%1")
161  .arg(QString::fromStdString(ex.what()));
162 
164  }
165  }
166 
167  return result;
168 }
Defines class DesignerHelper.
Defines DomainObjectBuilder namespace.
Defines ExportToPython namespace.
Defines class MultiLayerItem.
Defines class MultiLayer.
Defines class PySampleWidget.
Defines class PythonSyntaxHighlighter.
Defines class SampleModel.
Defines namespace SessionItemUtils.
Defines class UpdateTimer.
Defines class WarningSign.
static int getPythonEditorFontSize()
void setEditorConnected(bool isConnected)
void onDataChanged(const QModelIndex &, const QModelIndex &)
QString generateCodeSnippet()
generates string representing code snippet for all multi layers in the model
void showEvent(QShowEvent *)
WarningSign * m_warningSign
QTextEdit * m_textEdit
void setInstrumentModel(InstrumentModel *instrumentModel)
InstrumentModel * m_instrumentModel
void hideEvent(QHideEvent *)
PySampleWidget(QWidget *parent=nullptr)
PythonSyntaxHighlighter * m_highlighter
void onModifiedRow(const QModelIndex &, int, int)
SampleModel * m_sampleModel
void updateEditor()
Update the editor with the script content.
void setSampleModel(SampleModel *sampleModel)
UpdateTimer * m_updateTimer
Implementation of highlighting for Python code.
Main model to hold sample items.
Definition: SampleModel.h:24
SessionItem * itemForIndex(const QModelIndex &index) const
QVector< T * > topItems() const
Definition: SessionModel.h:147
The UpdateTimer class accumulates update requests during certain period of time, and at the end of th...
Definition: UpdateTimer.h:27
void scheduleUpdate()
Definition: UpdateTimer.cpp:42
void timeToUpdate()
The WarningSign controls appearance of WarningSignWidget on top of parent widget.
Definition: WarningSign.h:25
void clear()
Clears warning message;.
Definition: WarningSign.cpp:40
void setWarningMessage(const QString &warningMessage)
Shows warning sign on the screen.
Definition: WarningSign.cpp:58
std::unique_ptr< MultiLayer > buildMultiLayer(const SessionItem &multilayer_item)
std::string sampleCode(const MultiLayer &multilayer)
bool IsPositionRelated(const SessionItem &item)
Returns true if current item is related to the position on sample editor canvas.