Vuo  2.0.1
VuoInputEditorWithLineEditList.cc
Go to the documentation of this file.
1 
11 #include "VuoInputEditorIcon.hh"
12 
16 static QIcon * renderAddIcon(void)
17 {
18  return VuoInputEditorIcon::renderIcon(^(QPainter &p){
19  p.setPen(Qt::green);
20  p.setBrush(Qt::green);
21  p.drawEllipse(0, 0, 16, 16);
22  p.setPen(Qt::white);
23  p.setBrush(Qt::white);
24  p.drawRect(3, 6, 10, 4);
25  p.drawRect(6, 3, 4, 10);
26  });
27 }
28 
32 static QIcon * renderRemoveIcon(void)
33 {
34  return VuoInputEditorIcon::renderIcon(^(QPainter &p){
35  p.setPen(Qt::red);
36  p.setBrush(Qt::red);
37  p.drawEllipse(0, 0, 16, 16);
38  p.setPen(Qt::white);
39  p.setBrush(Qt::white);
40  p.drawRect(3, 6, 10, 4);
41  });
42 }
43 
44 const int VuoInputEditorWithLineEditList::horizontalSpacing = 5;
45 const int VuoInputEditorWithLineEditList::verticalSpacing = 4;
46 
50 VuoInputEditorWithLineEditList::VuoInputEditorWithLineEditList(bool allowAddingAndRemovingRows, int lineEditWidth)
52 {
53  this->allowAddingAndRemovingRows = allowAddingAndRemovingRows;
54  this->lineEditWidth = lineEditWidth;
55  addButton = NULL;
56  dialogLayout = NULL;
57 }
58 
62 void VuoInputEditorWithLineEditList::setUpDialog(QDialog &dialog, json_object *originalValue, json_object *details)
63 {
64  dialogLayout = new QVBoxLayout;
65  dialogLayout->setContentsMargins(0,0,0,0);
66  dialogLayout->setSizeConstraint(QLayout::SetFixedSize);
67  // dialog.setLayout(dialogLayout); // This repositions the dialog for some reason. Hence the workaround below.
68  QWidget *dialogTopLevelWidget = new QWidget(&dialog);
69  dialogTopLevelWidget->setLayout(dialogLayout);
70  dialogTopLevelWidget->show();
71 
72  if (allowAddingAndRemovingRows)
73  {
74  QIcon *addIcon = renderAddIcon();
75  addButton = new QToolButton;
76  addButton->setIcon(*addIcon);
77  addButton->adjustSize();
78  addButton->setFixedSize(addButton->size());
79  addButton->setFocusPolicy( (Qt::FocusPolicy)(addButton->focusPolicy() & ~Qt::TabFocus) );
80  connect(addButton, &QAbstractButton::clicked, this, &VuoInputEditorWithLineEditList::addRow);
81  delete addIcon;
82 
83  QHBoxLayout *addButtonLayout = new QHBoxLayout;
84  addButtonLayout->addSpacing(lineEditWidth);
85  addButtonLayout->addStretch();
86  addButtonLayout->addWidget(addButton);
87  addButtonLayout->setSpacing(horizontalSpacing);
88  addButtonLayout->setSizeConstraint(QLayout::SetFixedSize);
89 
90  dialogLayout->addLayout(addButtonLayout);
91  }
92 
93  QList<QString> values = convertToLineEditListFormat(originalValue);
94  foreach (QString value, values)
95  {
96  addRow();
97  lineEdits.back()->setText(value);
98  }
99 
100  if (! lineEdits.empty())
101  {
102  lineEdits.front()->setFocus();
103  lineEdits.front()->selectAll();
104  }
105 
106  updateUI();
107 }
108 
112 void VuoInputEditorWithLineEditList::addRow(void)
113 {
114  QDialog *dialog = getDialog();
115 
116  QLineEdit *lineEdit = new QLineEdit;
117  lineEdit->adjustSize();
118  lineEdit->resize(lineEditWidth, lineEdit->height());
119  lineEdit->setFixedSize(lineEdit->size());
120  lineEdits.append(lineEdit);
121 
122  QLayout *rowLayout = setUpRow(*dialog, lineEdit);
123  rowLayouts.append(rowLayout);
124  rowLayout->setSizeConstraint(QLayout::SetFixedSize);
125 
126  dialogLayout->insertLayout(rowLayouts.size() - 1, rowLayout);
127 
128  for (int i = 0; i < rowLayout->count(); ++i)
129  {
130  QWidget *widgetInRow = rowLayout->itemAt(i)->widget();
131  if (widgetInRow)
132  {
133  if (widgetInRow != lineEdit)
134  widgetInRow->setFocusPolicy( (Qt::FocusPolicy)(widgetInRow->focusPolicy() & ~Qt::TabFocus) );
135 
136  if (sender())
137  widgetInRow->show(); // Needed so the widget will be counted when recalculating the dialog size.
138  }
139  }
140 
141  lineEdit->setFocus();
142 
143  updateUI();
144 }
145 
149 void VuoInputEditorWithLineEditList::removeRow(void)
150 {
151  QAbstractButton *eventSender = dynamic_cast<QAbstractButton *>(sender());
152  int index = removeButtons.indexOf(eventSender);
153 
154  QLayout *rowLayout = rowLayouts.at(index);
155  tearDownRow(rowLayout);
156 
157  QLayoutItem *itemInRow;
158  while ((itemInRow = rowLayout->takeAt(0)) != NULL)
159  {
160  if (itemInRow->widget())
161  {
162  rowLayout->removeWidget( itemInRow->widget() );
163  delete itemInRow->widget();
164  }
165  delete itemInRow;
166  }
167 
168  dialogLayout->removeItem(rowLayout);
169  delete rowLayout;
170 
171  rowLayouts.removeAt(index);
172  lineEdits.removeAt(index);
173  removeButtons.removeAt(index);
174 
175  if (index < lineEdits.size())
176  lineEdits.at(index)->setFocus();
177  else if (index > 0 && index == lineEdits.size())
178  lineEdits.back()->setFocus();
179 
180  updateUI();
181 }
182 
189 QLayout * VuoInputEditorWithLineEditList::setUpRow(QDialog &dialog, QLineEdit *lineEdit)
190 {
191  QHBoxLayout *rowLayout = new QHBoxLayout;
192  rowLayout->setSpacing(horizontalSpacing);
193  rowLayout->addWidget(lineEdit);
194 
195  if (allowAddingAndRemovingRows)
196  {
197  QIcon *removeIcon = renderRemoveIcon();
198  QToolButton *removeButton = new QToolButton;
199  removeButton->setIcon(*removeIcon);
200  removeButton->adjustSize();
201  removeButton->setFixedSize(removeButton->size());
202  removeButton->move(lineEditWidth + horizontalSpacing, 0);
203  connect(removeButton, &QToolButton::clicked, this, &VuoInputEditorWithLineEditList::removeRow);
204  removeButtons.append(removeButton);
205  delete removeIcon;
206 
207  rowLayout->addStretch();
208  rowLayout->addWidget(removeButton);
209  }
210 
211  return rowLayout;
212 }
213 
223 {
224 }
225 
233 {
234  if (index < 0 || index >= rowLayouts.size())
235  return NULL;
236 
237  return rowLayouts.at(index);
238 }
239 
244 {
245  dialogLayout->addWidget(widget);
246  widget->setFocusPolicy( (Qt::FocusPolicy)(widget->focusPolicy() & ~Qt::TabFocus) );
247  widget->show();
248 
249  updateUI();
250 }
251 
258 {
259  dialogLayout->removeWidget(widget);
260 
261  updateUI();
262 }
263 
268 {
270 }
271 
276 {
277  QList<QString> texts;
278  foreach (QLineEdit *lineEdit, lineEdits)
279  {
280  texts.append(lineEdit->text());
281  }
282 
283  return texts;
284 }
285 
289 void VuoInputEditorWithLineEditList::updateUI(void)
290 {
291  static_cast<QWidget *>(dialogLayout->parent())->adjustSize();
292  getDialog()->adjustSize();
293 
294  if (! lineEdits.empty())
295  {
296  foreach (QLineEdit *lineEdit, lineEdits)
297  lineEdit->removeEventFilter(this);
298 
299  QLineEdit *firstLineEdit = lineEdits.front();
300  QLineEdit *lastLineEdit = lineEdits.back();
301 
302  setFirstWidgetInTabOrder(firstLineEdit);
303  setLastWidgetInTabOrder(lastLineEdit);
304  }
305 }
306 
311 {
312  return true;
313 }