BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
InstrumentViewActions.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp
6 //! @brief Implements class InstrumentViewActions
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 
22 #include <QAction>
23 #include <QDebug>
24 #include <QItemSelectionModel>
25 #include <QMenu>
26 #include <QModelIndex>
27 #include <QVariant>
28 
30  : QObject(parent)
31  , m_addInstrumentMenu(nullptr)
32  , m_removeInstrumentAction(nullptr)
33  , m_cloneInstrumentAction(nullptr)
34  , m_model(nullptr)
35  , m_selectionModel(nullptr)
36 {
38 
40  new QAction(QIcon(":/images/delete.svg"), "Remove this instrument", this);
41 
43  new QAction(QIcon(":/images/content-copy.svg"), "Clone this instrument", this);
44 
45  connect(m_removeInstrumentAction, &QAction::triggered, this,
47  connect(m_cloneInstrumentAction, &QAction::triggered, this,
49 }
50 
52 {
53  delete m_addInstrumentMenu;
54 }
55 
57 {
58  m_model = model;
59 }
60 
61 void InstrumentViewActions::setSelectionModel(QItemSelectionModel* selectionModel)
62 {
63  m_selectionModel = selectionModel;
64 }
65 
66 //! Returns menu to create one of available instrument types.
67 
69 {
70  return m_addInstrumentMenu;
71 }
72 
73 //! Removes currently selected instrument.
74 
76 {
77  QModelIndex currentIndex = m_selectionModel->currentIndex();
78 
79  if (currentIndex.isValid())
80  m_model->removeRows(currentIndex.row(), 1, QModelIndex());
81 
83 }
84 
85 //! Clones currently selected instrument.
86 
88 {
89  QModelIndex currentIndex = m_selectionModel->currentIndex();
90 
91  if (currentIndex.isValid()) {
92  SessionItem* item = m_model->itemForIndex(currentIndex);
93  QString nameOfClone = suggestInstrumentName(item->itemName());
94  InstrumentItem* clone =
95  static_cast<InstrumentItem*>(m_model->insertNewItem(item->modelType()));
96  const QString idBackup = clone->id(); // will be overwritten by the following
97  for (auto child : item->children()) {
98  auto tag = item->tagFromItem(child);
99  m_model->copyItem(child, clone, tag);
100  }
101  clone->setId(idBackup);
102  clone->setItemName(nameOfClone);
103 
104  // copying non-uniform axis data
105  if (auto instrument = dynamic_cast<SpecularInstrumentItem*>(item)) {
106  auto axis_group = instrument->beamItem()->inclinationAxisGroup();
107 
108  auto donor_axis =
109  dynamic_cast<PointwiseAxisItem*>(axis_group->getItemOfType("PointwiseAxis"));
110  if (!donor_axis->containsNonXMLData())
111  return;
112 
113  auto acceptor_axis =
114  dynamic_cast<PointwiseAxisItem*>(dynamic_cast<SpecularInstrumentItem*>(clone)
115  ->beamItem()
116  ->inclinationAxisGroup()
117  ->getItemOfType("PointwiseAxis"));
118  acceptor_axis->init(*donor_axis->axis(), donor_axis->getUnitsLabel());
119  }
120  }
121 }
122 
124  const QModelIndex& indexAtPoint)
125 {
126  QMenu menu;
127 
128  setAllActionsEnabled(indexAtPoint.isValid());
129 
130  menu.addAction(m_cloneInstrumentAction);
131  menu.addAction(m_removeInstrumentAction);
132  menu.addSeparator();
133  menu.addMenu(m_addInstrumentMenu);
134  menu.exec(point);
135 }
136 
138 {
139  m_removeInstrumentAction->setEnabled(value);
140  m_cloneInstrumentAction->setEnabled(value);
141 }
142 
144 {
145  if (!m_selectionModel->hasSelection()) {
146  // select last item
147  QModelIndex itemIndex =
148  m_model->index(m_model->rowCount(QModelIndex()) - 1, 0, QModelIndex());
149  m_selectionModel->select(itemIndex, QItemSelectionModel::ClearAndSelect);
150  }
151 }
152 
153 QString InstrumentViewActions::suggestInstrumentName(const QString& currentName)
154 {
155  auto map_of_names = mapOfNames();
156 
157  int ncopies = map_of_names[currentName];
158  if (ncopies == 0) {
159  map_of_names[currentName] = 1;
160  return currentName;
161  } else {
162  map_of_names[currentName]++;
163  return QString("%1 (%2)").arg(currentName).arg(map_of_names[currentName]);
164  }
165 }
166 
168 {
169  QMap<QString, int> result;
170 
171  for (auto& name : ModelUtils::topItemNames(m_model)) {
172  int ncopy(1);
173  QRegExp regexp("\\((.*)\\)");
174  if (regexp.indexIn(name) >= 0)
175  ncopy = regexp.cap(1).toInt();
176  name.replace(regexp.cap(0), "");
177  name = name.trimmed();
178  result[name] = ncopy;
179  }
180 
181  return result;
182 }
183 
184 //! Constructs menu to add instruments of various types. The type of instrument
185 //! is encoded in QAction internal data.
186 
188 {
189  m_addInstrumentMenu = new QMenu("Add new instrument");
190  m_addInstrumentMenu->setToolTipsVisible(true);
191 
192  const auto addAction = [this](const QString& menuEntry, const QString& tooltip,
193  std::function<InstrumentItem*()> insertInstrument) {
194  auto action = m_addInstrumentMenu->addAction(menuEntry);
195  action->setToolTip(tooltip);
196 
197  connect(action, &QAction::triggered, [=]() {
198  InstrumentItem* instrument = insertInstrument();
199  instrument->setItemName(suggestInstrumentName(instrument->defaultName()));
200  updateSelection();
201 
202  // set default action to the just triggered action
203  m_addInstrumentMenu->setDefaultAction(action);
204  });
205  };
206 
207  addAction("GISAS", "Add GISAS instrument with default settings",
208  [this]() { return m_model->insertItem<GISASInstrumentItem>(); });
209 
210  addAction("OffSpecular", "Add OffSpecular instrument with default settings",
211  [this]() { return m_model->insertItem<OffSpecularInstrumentItem>(); });
212 
213  addAction("Specular", "Add Specular instrument with default settings",
214  [this]() { return m_model->insertItem<SpecularInstrumentItem>(); });
215 
216  addAction("DepthProbe", "Add DepthProbe instrument with default settings",
217  [this]() { return m_model->insertItem<DepthProbeInstrumentItem>(); });
218 
219  m_addInstrumentMenu->setDefaultAction(m_addInstrumentMenu->actions().front());
220 }
Defines DepthProbeInstrumentItem class.
Defines class GroupItem.
Defines InstrumentItems classes.
Defines class InstrumentViewActions.
Defines ModelUtils namespace.
Defines pointwise axis item.
Defines class SessionModel.
virtual QString defaultName() const =0
The default user visible name when creating an instrument.
void setAllActionsEnabled(bool value)
void onRemoveInstrument()
Removes currently selected instrument.
void onContextMenuRequest(const QPoint &point, const QModelIndex &indexAtPoint)
void onCloneInstrument()
Clones currently selected instrument.
void setModel(SessionModel *model)
void setSelectionModel(QItemSelectionModel *selectionModel)
QMap< QString, int > mapOfNames()
void initAddInstrumentMenu()
Constructs menu to add instruments of various types.
InstrumentViewActions(QWidget *parent=nullptr)
QItemSelectionModel * m_selectionModel
QMenu * instrumentMenu()
Returns menu to create one of available instrument types.
QString suggestInstrumentName(const QString &currentName)
Item for non-uniform axis with specified coordinates.
void init(const IAxis &axis, const QString &units_label)
QString itemName() const
Get item name, return display name if no name is set.
void setItemName(const QString &name)
Set item name, add property if necessary.
QVector< SessionItem * > children() const
Returns vector of all children.
QString modelType() const
Get model type.
QString tagFromItem(const SessionItem *item) const
Returns the tag name of given item when existing.
T * copyItem(const T *item_to_copy, SessionItem *new_parent=0, const QString &tag="")
Definition: SessionModel.h:136
SessionItem * itemForIndex(const QModelIndex &index) const
T * insertItem(SessionItem *parent=nullptr, int row=-1, QString tag="")
Definition: SessionModel.h:125
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
virtual int rowCount(const QModelIndex &parent) const
virtual bool removeRows(int row, int count, const QModelIndex &parent)
SessionItem * insertNewItem(QString model_type, SessionItem *parent_item=nullptr, int row=-1, QString tag="")
QStringList topItemNames(SessionModel *model, const QString &modelType="")
Returns list of top iten manes.
Definition: ModelUtils.cpp:20
QString const & name(EShape k)
Definition: particles.cpp:21