ConfigDataTreeEditor.cpp
Go to the documentation of this file.
1 #include <DatabaseUtils/GUI/ConfigDataTreeEditor.h>
2 #include <DatabaseUtils/GUI/ConfigDataTreeModel.h>
3 #include <DatabaseUtils/GUI/BitmapEditor.h>
4 #include <DatabaseUtils/DAQConfig/DBColumnParams.h>
5 #include <QtGui/QInputDialog>
6 
7 using namespace dbutils::daqconfig;
8 
9 namespace dbutils {
10 namespace gui {
11 
12 /**
13  * Creates the tree display for editing configuration data from
14  * a single database table.
15  */
16 ConfigDataTreeEditor::
17 ConfigDataTreeEditor(QWidget *parent) : QTreeView(parent)
18 {
19  this->setAlternatingRowColors(true);
20  this->setSelectionBehavior(QAbstractItemView::SelectItems);
21  this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
22  this->setAnimated(false);
23  this->setAllColumnsShowFocus(true);
24 }
25 
26 void ConfigDataTreeEditor::mousePressEvent(QMouseEvent* event)
27 {
28  // first, do the standard processing for the mouse event
29  QTreeView::mousePressEvent(event);
30 
31  // next, check if we should show the popup menu (right-mouse)
32  if (event->type() == QEvent::MouseButtonPress &&
33  event->button() == Qt::RightButton) {
34 
35  if (! _popupMenu->isEmpty()) {
36  _popupMenu->popup(event->globalPos());
37  }
38  }
39 }
40 
42 loadData(boost::shared_ptr<daqconfig::ConfigDataTree> dataTree)
43 {
45  static_cast<ConfigDataTreeModel *>(this->model());
46 
47  if (model == 0) {
48  model = new ConfigDataTreeModel(this);
49  if (! model->loadData(dataTree)) {return false;}
50 
51  connect(model, SIGNAL(aChangeWasMade()),
52  this, SLOT(reactToDataModelChange()));
53  connect(model, SIGNAL(dataWasSaved()),
54  this, SLOT(reactToDataSave()));
55  connect(model, SIGNAL(dataChanged(const QModelIndex&,
56  const QModelIndex&)),
57  this, SLOT(refreshDisplayOfChildren(const QModelIndex&,
58  const QModelIndex&)));
59 
60  this->setModel(model);
61 
62  _popupMenu = new QMenu(this);
63  connect(this->selectionModel(),
64  SIGNAL(currentChanged(const QModelIndex &,
65  const QModelIndex &)),
66  this, SLOT(updatePopupMenu(const QModelIndex &)));
67  }
68  else {
69  if (! model->loadData(dataTree)) {return false;}
70  }
71 
72  this->expandAll();
73  for (int column = 0; column < model->columnCount(); ++column) {
74  this->resizeColumnToContents(column);
75  }
76  this->collapseAll();
77  this->expandToDepth(0);
78  return true;
79 }
80 
82 {
84  static_cast<ConfigDataTreeModel *>(this->model());
85 
86  if (model == 0) {return false;}
87 
88  return model->hasChanges();
89 }
90 
91 bool ConfigDataTreeEditor::saveChanges(const int64_t& oldSubsystemConfigId,
92  const int64_t& subsystemConfigId)
93 {
95  static_cast<ConfigDataTreeModel *>(this->model());
96 
97  if (model == 0) {return false;}
98 
99  return model->saveChanges(subsystemConfigId);
100 }
101 
102 void ConfigDataTreeEditor::updatePopupMenu(const QModelIndex& currentIndex)
103 {
104  _popupMenu->clear();
105  if (! currentIndex.isValid()) {return;}
106 
108  static_cast<ConfigDataTreeModel *>(this->model());
109  if (model == 0) {return;}
110 
111  // handle "mask" data columns
112  std::string dataColumnName;
113  bool dcnLookupWorked =
114  model->dataColumnNameForIndex(currentIndex, dataColumnName);
115  if (dcnLookupWorked && dataColumnName == "mask") {
116  QAction* obeAction = _popupMenu->addAction(tr("Open bitmap editor"));
117  QObject::connect(obeAction, SIGNAL(triggered()),
118  this, SLOT(editBitmap()));
119  return;
120  }
121 
122  // handle selector columns
123  std::string peerType = "";
124  std::string childType = "";
125  std::string selectorColumn;
126  if (model->selectorColumnNameForIndex(currentIndex, selectorColumn)) {
127  if (selectorColumn == DBColumnParams::DCMNAME_COLUMN_NAME) {
128  peerType = "DCM";
129  }
130  if (selectorColumn == DBColumnParams::FEBID_COLUMN_NAME) {
131  peerType = "FEB";
132  }
133  if (selectorColumn == DBColumnParams::PIXELID_COLUMN_NAME) {
134  peerType = "Pixel";
135  }
136  if (selectorColumn == DBColumnParams::HOSTNAME_COLUMN_NAME) {
137  peerType = "Host";
138  }
139  }
140  if (model->selectorColumnNameForChild(currentIndex, selectorColumn)) {
141  if (selectorColumn == DBColumnParams::DCMNAME_COLUMN_NAME) {
142  childType = "DCM";
143  }
144  if (selectorColumn == DBColumnParams::FEBID_COLUMN_NAME) {
145  childType = "FEB";
146  }
147  if (selectorColumn == DBColumnParams::PIXELID_COLUMN_NAME) {
148  childType = "Pixel";
149  }
150  if (selectorColumn == DBColumnParams::HOSTNAME_COLUMN_NAME) {
151  childType = "Host";
152  }
153  }
154 
155  _candidatesForInsertBefore = model->allowsInsertBefore(currentIndex);
156  _candidatesForInsertAfter = model->allowsInsertAfter(currentIndex);
157  _candidatesForChildInsert = model->allowsChildInsert(currentIndex);
158 
159  if (_candidatesForInsertBefore.size() > 0 &&
160  _candidatesForInsertAfter.size() == 0) {
161  std::string text = "Add " + peerType;
162  _addRowBeforeAction = _popupMenu->addAction(tr(text.c_str()));
163  QObject::connect(_addRowBeforeAction, SIGNAL(triggered()),
164  this, SLOT(addRowBefore()));
165  }
166  else if (_candidatesForInsertBefore.size() == 0 &&
167  _candidatesForInsertAfter.size() > 0) {
168  std::string text = "Add " + peerType;
169  _addRowAfterAction = _popupMenu->addAction(tr(text.c_str()));
170  QObject::connect(_addRowAfterAction, SIGNAL(triggered()),
171  this, SLOT(addRowAfter()));
172  }
173  else if (_candidatesForInsertBefore.size() > 0 &&
174  _candidatesForInsertAfter.size() > 0) {
175  std::string text = "Add " + peerType + " before this";
176  _addRowBeforeAction = _popupMenu->addAction(tr(text.c_str()));
177  QObject::connect(_addRowBeforeAction, SIGNAL(triggered()),
178  this, SLOT(addRowBefore()));
179  text = "Add " + peerType + " after this";
180  _addRowAfterAction = _popupMenu->addAction(tr(text.c_str()));
181  QObject::connect(_addRowAfterAction, SIGNAL(triggered()),
182  this, SLOT(addRowAfter()));
183  }
184 
185  if (_candidatesForChildInsert.size() > 0) {
186  std::string text = "Add " + childType;
187  _addChildRowAction = _popupMenu->addAction(tr(text.c_str()));
188  QObject::connect(_addChildRowAction, SIGNAL(triggered()),
189  this, SLOT(addChildRow()));
190  }
191 }
192 
194 {
196  static_cast<ConfigDataTreeModel *>(this->model());
197 
198  if (model == 0) {return true;}
199 
200  // TODO - implement the adding of an inital tree row
201  //return model->hasChanges();
202  return true;
203 }
204 
206 {
207  emit aChangeWasMade();
208 }
209 
211 {
212  emit dataWasSaved();
213 }
214 
216 refreshDisplayOfChildren(const QModelIndex& topLeft,
217  const QModelIndex& bottomRight)
218 {
219  // this is a hack to get the correct set of children to be displayed
220  // when we update a default value and remove some, but not all, of
221  // the children. Oddly, this->isExpanded(topLeft) doesn't seem to
222  // work, otherwise we would use it here...
223  this->collapse(topLeft);
224  this->expand(topLeft);
225 }
226 
228 {
229  bool status;
231  static_cast<ConfigDataTreeModel *>(this->model());
232  if (model == 0) {return;}
233 
234  QModelIndex currentIndex = this->selectionModel()->currentIndex();
235  std::string peerType;
236  if (model->selectorColumnNameForIndex(currentIndex, peerType)) {
237  if (peerType == DBColumnParams::FEBID_COLUMN_NAME) {
238  QString responseText =
239  QInputDialog::getItem(this, tr("Add FEB"), tr("FEB ID:"),
240  _candidatesForInsertBefore, 0, false,
241  &status);
242  if (status) {
243  model->addRowBefore(currentIndex, responseText);
244  }
245  }
246  else if (peerType == DBColumnParams::PIXELID_COLUMN_NAME) {
247  QString responseText =
248  QInputDialog::getItem(this, tr("Add Pixel"), tr("Pixel ID:"),
249  _candidatesForInsertBefore, 0, false,
250  &status);
251  if (status) {
252  model->addRowBefore(currentIndex, responseText);
253  }
254  }
255  else {
256  }
257  }
258 
259  this->updatePopupMenu(currentIndex);
260  this->resizeColumnToContents(0);
261 }
262 
264 {
265  bool status;
267  static_cast<ConfigDataTreeModel *>(this->model());
268  if (model == 0) {return;}
269 
270  QModelIndex currentIndex = this->selectionModel()->currentIndex();
271  std::string peerType;
272  if (model->selectorColumnNameForIndex(currentIndex, peerType)) {
273  if (peerType == DBColumnParams::DCMNAME_COLUMN_NAME) {
274  QString responseText =
275  QInputDialog::getText(this, tr("Add DCM"), tr("New DCM name:"),
277  _candidatesForInsertAfter[0], &status);
278  if (status) {
279  model->addRowAfter(currentIndex, responseText);
280  }
281  }
282  else if (peerType == DBColumnParams::FEBID_COLUMN_NAME) {
283  QString responseText =
284  QInputDialog::getItem(this, tr("Add FEB"), tr("FEB ID:"),
285  _candidatesForInsertAfter, 0, false,
286  &status);
287  if (status) {
288  model->addRowAfter(currentIndex, responseText);
289  }
290  }
291  else if (peerType == DBColumnParams::PIXELID_COLUMN_NAME) {
292  QString responseText =
293  QInputDialog::getItem(this, tr("Add Pixel"), tr("Pixel ID:"),
294  _candidatesForInsertAfter, 0, false,
295  &status);
296  if (status) {
297  model->addRowAfter(currentIndex, responseText);
298  }
299  }
300  else if (peerType == DBColumnParams::HOSTNAME_COLUMN_NAME) {
301  QString responseText =
302  QInputDialog::getText(this, tr("Add Host"), tr("New Host Name:"),
304  _candidatesForInsertAfter[0], &status);
305  if (status) {
306  model->addRowAfter(currentIndex, responseText);
307  }
308  }
309  else {
310  }
311  }
312 
313  this->updatePopupMenu(currentIndex);
314  this->resizeColumnToContents(0);
315 }
316 
318 {
319  bool status;
321  static_cast<ConfigDataTreeModel *>(this->model());
322  if (model == 0) {return;}
323 
324  QModelIndex currentIndex = this->selectionModel()->currentIndex();
325  std::string childType;
326  if (model->selectorColumnNameForChild(currentIndex, childType)) {
327  if (childType == DBColumnParams::DCMNAME_COLUMN_NAME) {
328  QString responseText =
329  QInputDialog::getText(this, tr("Add DCM"), tr("New DCM name:"),
331  _candidatesForChildInsert[0], &status);
332  if (status) {
333  model->addChildRow(currentIndex, responseText);
334  this->expand(currentIndex);
335  }
336  }
337  else if (childType == DBColumnParams::FEBID_COLUMN_NAME) {
338  QString responseText =
339  QInputDialog::getItem(this, tr("Add FEB"), tr("FEB ID:"),
340  _candidatesForChildInsert, 0, false,
341  &status);
342  if (status) {
343  model->addChildRow(currentIndex, responseText);
344  this->expand(currentIndex);
345  }
346  }
347  else if (childType == DBColumnParams::PIXELID_COLUMN_NAME) {
348  QString responseText =
349  QInputDialog::getItem(this, tr("Add Pixel"), tr("Pixel ID:"),
350  _candidatesForChildInsert, 0, false,
351  &status);
352  if (status) {
353  model->addChildRow(currentIndex, responseText);
354  this->expand(currentIndex);
355  }
356  }
357  else if (childType == DBColumnParams::HOSTNAME_COLUMN_NAME) {
358  QString responseText =
359  QInputDialog::getText(this, tr("Add Host"), tr("New Host Name:"),
361  _candidatesForChildInsert[0], &status);
362  if (status) {
363  model->addChildRow(currentIndex, responseText);
364  this->expand(currentIndex);
365  }
366  }
367  else {
368  }
369  }
370 
371  this->updatePopupMenu(currentIndex);
372  this->resizeColumnToContents(0);
373 }
374 
376 {
378  static_cast<ConfigDataTreeModel *>(this->model());
379  if (model == 0) {return;}
380 
381  QModelIndex currentIndex = this->selectionModel()->currentIndex();
382  QVariant value = model->data(currentIndex);
383 
384  int bitCount = 32;
385  std::string dataColumnType;
386  bool dctLookupWorked =
387  model->dataColumnTypeForIndex(currentIndex, dataColumnType);
388  if (dctLookupWorked && dataColumnType == "bigint") {
389  bitCount = 64;
390  }
391 
392  BitmapEditor editor(value.toString().toStdString(), bitCount, this);
393  int result = editor.exec();
394 
395  if (result == QDialog::Accepted) {
396  model->setData(currentIndex, editor.getResult().c_str());
397  }
398 }
399 
400 } // end of namespace gui
401 } // end of namespace dbutils
bool addChildRow(QModelIndex index, QString selectorColumnText, int position=0)
int status
Definition: fabricate.py:1613
QList< QString > allowsInsertBefore(const QModelIndex &index) const
bool dataColumnTypeForIndex(const QModelIndex &index, std::string &dataColumnType) const
bool loadData(boost::shared_ptr< daqconfig::ConfigDataTree > dataTree)
bool addRowBefore(const QModelIndex &index, QString selectorColumnText)
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
QList< QString > allowsChildInsert(const QModelIndex &index) const
bool dataColumnNameForIndex(const QModelIndex &index, std::string &dataColumnName) const
QList< QString > allowsInsertAfter(const QModelIndex &index) const
def connect(endpoint="tcp://127.0.0.1:5555")
Definition: g4zmq.py:15
const XML_Char int const XML_Char * value
Definition: expat.h:331
virtual bool saveChanges(const int64_t &subsystemConfigId)
void updatePopupMenu(const QModelIndex &currentIndex)
bool addRowAfter(const QModelIndex &index, QString selectorColumnText)
bool saveChanges(const int64_t &oldSubsystemConfigId, const int64_t &subsystemConfigId)
void refreshDisplayOfChildren(const QModelIndex &, const QModelIndex &)
virtual bool loadData(boost::shared_ptr< daqconfig::ConfigDataTree > dataTree)
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
void mousePressEvent(QMouseEvent *event)
const XML_Char XML_Content * model
Definition: expat.h:151
bool selectorColumnNameForChild(const QModelIndex &index, std::string &selectorColumnName) const
bool selectorColumnNameForIndex(const QModelIndex &index, std::string &selectorColumnName) const