History

Remove declarative form creation from WindowScriptingInterface

Bradley Austin Davis committed 10 years ago

Commit c1d45b01 parent 63df3454 files · +8 −911Browse files

Showing the changes to interface/src/scripting/WindowScriptingInterface.cpp (1 of 4 files). Show all

Unified · Split

interface/src/scripting/WindowScriptingInterface.cpp+7−424
@@ -27,11 +27,7 @@ · 26 unmodified lines
27 27
28#include "WindowScriptingInterface.h"28#include "WindowScriptingInterface.h"
29 29
30WindowScriptingInterface::WindowScriptingInterface() :30WindowScriptingInterface::WindowScriptingInterface() {
31 _editDialog(NULL),
32 _nonBlockingFormActive(false),
33 _formResult(QDialog::Rejected)
34{
35 const DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();31 const DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
36 connect(&domainHandler, &DomainHandler::connectedToDomain, this, &WindowScriptingInterface::domainChanged);32 connect(&domainHandler, &DomainHandler::connectedToDomain, this, &WindowScriptingInterface::domainChanged);
37 connect(qApp, &Application::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused);33 connect(qApp, &Application::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused);
@@ -98,14 +94,6 @@ QScriptValue WindowScriptingInterface::confirm(const QString& message) { · 60 unmodified lines
98 return retVal;94 return retVal;
99}95}
100 96
101QScriptValue WindowScriptingInterface::form(const QString& title, QScriptValue form) {
102 QScriptValue retVal;
103 QMetaObject::invokeMethod(this, "showForm", Qt::BlockingQueuedConnection,
104 Q_RETURN_ARG(QScriptValue, retVal),
105 Q_ARG(const QString&, title), Q_ARG(QScriptValue, form));
106 return retVal;
107}
108
109QScriptValue WindowScriptingInterface::prompt(const QString& message, const QString& defaultText) {97QScriptValue WindowScriptingInterface::prompt(const QString& message, const QString& defaultText) {
110 QScriptValue retVal;98 QScriptValue retVal;
111 QMetaObject::invokeMethod(this, "showPrompt", Qt::BlockingQueuedConnection,99 QMetaObject::invokeMethod(this, "showPrompt", Qt::BlockingQueuedConnection,
@@ -139,32 +127,6 @@ QScriptValue WindowScriptingInterface::s3Browse(const QString& nameFilter) { · 27 unmodified lines
139 return retVal;127 return retVal;
140}128}
141 129
142void WindowScriptingInterface::nonBlockingForm(const QString& title, QScriptValue form) {
143 QMetaObject::invokeMethod(this, "showNonBlockingForm", Qt::BlockingQueuedConnection,
144 Q_ARG(const QString&, title), Q_ARG(QScriptValue, form));
145}
146
147void WindowScriptingInterface::reloadNonBlockingForm(QScriptValue newValues) {
148 QMetaObject::invokeMethod(this, "doReloadNonBlockingForm", Qt::BlockingQueuedConnection,
149 Q_ARG(QScriptValue, newValues));
150}
151
152
153QScriptValue WindowScriptingInterface::getNonBlockingFormResult(QScriptValue form) {
154 QScriptValue retVal;
155 QMetaObject::invokeMethod(this, "doGetNonBlockingFormResult", Qt::BlockingQueuedConnection,
156 Q_RETURN_ARG(QScriptValue, retVal),
157 Q_ARG(QScriptValue, form));
158 return retVal;
159}
160
161QScriptValue WindowScriptingInterface::peekNonBlockingFormResult(QScriptValue form) {
162 QScriptValue retVal;
163 QMetaObject::invokeMethod(this, "doPeekNonBlockingFormResult", Qt::BlockingQueuedConnection,
164 Q_RETURN_ARG(QScriptValue, retVal),
165 Q_ARG(QScriptValue, form));
166 return retVal;
167}
168 130
169/// Display an alert box131/// Display an alert box
170/// \param const QString& message message to display132/// \param const QString& message message to display
@@ -217,402 +179,23 @@ void WindowScriptingInterface::inlineButtonClicked() { · 46 unmodified lines
217 emit inlineButtonClicked(name);179 emit inlineButtonClicked(name);
218}180}
219 181
220QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) {182QString WindowScriptingInterface::jsRegExp2QtRegExp(const QString& string) {
221 // Converts string representation of RegExp from JavaScript format to Qt format.183 // Converts string representation of RegExp from JavaScript format to Qt format.
222 return string.mid(1, string.length() - 2) // No enclosing slashes.184 return string.mid(1, string.length() - 2) // No enclosing slashes.
223 .replace("\\/", "/"); // No escaping of forward slash.185 .replace("\\/", "/"); // No escaping of forward slash.
224}186}
225 187
226void WindowScriptingInterface::showNonBlockingForm(const QString& title, QScriptValue form) {
227 if (!form.isArray() || (form.isArray() && form.property("length").toInt32() <= 0)) {
228 return;
229 }
230
231 // what should we do if someone calls us while we still think we have a dialog showing???
232 if (_nonBlockingFormActive) {
233 qDebug() << "Show Non-Blocking Form called when form already active.";
234 return;
235 }
236
237 _form = form;
238 _editDialog = createForm(title, _form);
239 _nonBlockingFormActive = true;
240
241 connect(_editDialog, SIGNAL(accepted()), this, SLOT(nonBlockingFormAccepted()));
242 connect(_editDialog, SIGNAL(rejected()), this, SLOT(nonBlockingFormRejected()));
243
244 _editDialog->setModal(true);
245 _editDialog->show();
246}
247
248void WindowScriptingInterface::doReloadNonBlockingForm(QScriptValue newValues) {
249 if (!newValues.isArray() || (newValues.isArray() && newValues.property("length").toInt32() <= 0)) {
250 return;
251 }
252
253 // what should we do if someone calls us while we still think we have a dialog showing???
254 if (!_editDialog) {
255 qDebug() << "Reload Non-Blocking Form called when no form is active.";
256 return;
257 }
258
259 for (int i = 0; i < newValues.property("length").toInt32(); ++i) {
260 QScriptValue item = newValues.property(i);
261
262 if (item.property("oldIndex").isValid()) {
263 int oldIndex = item.property("oldIndex").toInt32();
264 QScriptValue oldItem = _form.property(oldIndex);
265 if (oldItem.isValid()) {
266 QLineEdit* originalEdit = _edits[oldItem.property("editIndex").toInt32()];
267 originalEdit->setText(item.property("value").toString());
268 }
269 }
270 }
271}
272
273
274bool WindowScriptingInterface::nonBlockingFormActive() {
275 return _nonBlockingFormActive;
276}
277
278QScriptValue WindowScriptingInterface::doPeekNonBlockingFormResult(QScriptValue array) {
279 QScriptValue retVal;
280
281 int e = -1;
282 int d = -1;
283 int c = -1;
284 int h = -1;
285 for (int i = 0; i < _form.property("length").toInt32(); ++i) {
286 QScriptValue item = _form.property(i);
287 QScriptValue value = item.property("value");
288
289 if (item.property("button").toString() != "") {
290 // Nothing to do
291 } else if (item.property("type").toString() == "inlineButton") {
292 // Nothing to do
293 } else if (item.property("type").toString() == "header") {
294 // Nothing to do
295 } else if (item.property("directory").toString() != "") {
296 d += 1;
297 value = _directories.at(d)->property("path").toString();
298 item.setProperty("directory", value);
299 _form.setProperty(i, item);
300 } else if (item.property("options").isArray()) {
301 c += 1;
302 item.setProperty("value",
303 _combos.at(c)->currentIndex() < item.property("options").property("length").toInt32() ?
304 item.property("options").property(_combos.at(c)->currentIndex()) :
305 array.engine()->undefinedValue()
306 );
307 _form.setProperty(i, item);
308 } else if (item.property("type").toString() == "checkbox") {
309 h++;
310 value = _checks.at(h)->checkState() == Qt::Checked;
311 item.setProperty("value", value);
312 _form.setProperty(i, item);
313 } else {
314 e += 1;
315 bool ok = true;
316 if (value.isNumber()) {
317 value = _edits.at(e)->text().toDouble(&ok);
318 } else if (value.isString()) {
319 value = _edits.at(e)->text();
320 } else if (value.isBool()) {
321 if (_edits.at(e)->text() == "true") {
322 value = true;
323 } else if (_edits.at(e)->text() == "false") {
324 value = false;
325 } else {
326 ok = false;
327 }
328 }
329 if (ok) {
330 item.setProperty("value", value);
331 _form.setProperty(i, item);
332 }
333 }
334 }
335
336 array = _form;
337 return (_formResult == QDialog::Accepted);
338}
339
340QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue array) {
341 QScriptValue retVal;
342
343 if (_formResult == QDialog::Accepted) {
344 int e = -1;
345 int d = -1;
346 int c = -1;
347 int h = -1;
348 for (int i = 0; i < _form.property("length").toInt32(); ++i) {
349 QScriptValue item = _form.property(i);
350 QScriptValue value = item.property("value");
351
352 if (item.property("button").toString() != "") {
353 // Nothing to do
354 } else if (item.property("type").toString() == "inlineButton") {
355 // Nothing to do
356 } else if (item.property("type").toString() == "header") {
357 // Nothing to do
358 } else if (item.property("directory").toString() != "") {
359 d += 1;
360 value = _directories.at(d)->property("path").toString();
361 item.setProperty("directory", value);
362 _form.setProperty(i, item);
363 } else if (item.property("options").isArray()) {
364 c += 1;
365 item.setProperty("value",
366 _combos.at(c)->currentIndex() < item.property("options").property("length").toInt32() ?
367 item.property("options").property(_combos.at(c)->currentIndex()) :
368 array.engine()->undefinedValue()
369 );
370 _form.setProperty(i, item);
371 } else if (item.property("type").toString() == "checkbox") {
372 h++;
373 value = _checks.at(h)->checkState() == Qt::Checked;
374 item.setProperty("value", value);
375 _form.setProperty(i, item);
376 } else {
377 e += 1;
378 bool ok = true;
379 if (value.isNumber()) {
380 value = _edits.at(e)->text().toDouble(&ok);
381 } else if (value.isString()) {
382 value = _edits.at(e)->text();
383 } else if (value.isBool()) {
384 if (_edits.at(e)->text() == "true") {
385 value = true;
386 } else if (_edits.at(e)->text() == "false") {
387 value = false;
388 } else {
389 ok = false;
390 }
391 }
392 if (ok) {
393 item.setProperty("value", value);
394 _form.setProperty(i, item);
395 }
396 }
397 }
398 }
399
400 delete _editDialog;
401 _editDialog = NULL;
402 _form = QScriptValue();
403 _edits.clear();
404 _directories.clear();
405 _combos.clear();
406 _checks.clear();
407
408 array = _form;
409 return (_formResult == QDialog::Accepted);
410}
411
412
413/// Display a form layout with an edit box
414/// \param const QString& title title to display
415/// \param const QScriptValue form to display as an array of objects:
416/// - label, value
417/// - label, directory, title, display regexp, validate regexp, error message
418/// - button ("Cancel")
419/// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise
420QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptValue form) {
421 if (form.isArray() && form.property("length").toInt32() <= 0) {
422 return false;
423 }
424 QDialog* editDialog = createForm(title, form);
425
426 int result = editDialog->exec();
427
428 if (result == QDialog::Accepted) {
429 int e = -1;
430 int d = -1;
431 int c = -1;
432 int h = -1;
433 for (int i = 0; i < form.property("length").toInt32(); ++i) {
434 QScriptValue item = form.property(i);
435 QScriptValue value = item.property("value");
436
437 if (item.property("button").toString() != "") {
438 // Nothing to do
439 } else if (item.property("type").toString() == "inlineButton") {
440 // Nothing to do
441 } else if (item.property("type").toString() == "header") {
442 // Nothing to do
443 } else if (item.property("directory").toString() != "") {
444 d += 1;
445 value = _directories.at(d)->property("path").toString();
446 item.setProperty("directory", value);
447 form.setProperty(i, item);
448 } else if (item.property("options").isArray()) {
449 c += 1;
450 item.setProperty("value",
451 _combos.at(c)->currentIndex() < item.property("options").property("length").toInt32() ?
452 item.property("options").property(_combos.at(c)->currentIndex()) :
453 form.engine()->undefinedValue()
454 );
455 form.setProperty(i, item);
456 } else if (item.property("type").toString() == "checkbox") {
457 h++;
458 value = _checks.at(h)->checkState() == Qt::Checked;
459 item.setProperty("value", value);
460 form.setProperty(i, item);
461 } else {
462 e += 1;
463 bool ok = true;
464 if (value.isNumber()) {
465 value = _edits.at(e)->text().toDouble(&ok);
466 } else if (value.isString()) {
467 value = _edits.at(e)->text();
468 } else if (value.isBool()) {
469 if (_edits.at(e)->text() == "true") {
470 value = true;
471 } else if (_edits.at(e)->text() == "false") {
472 value = false;
473 } else {
474 ok = false;
475 }
476 }
477 if (ok) {
478 item.setProperty("value", value);
479 form.setProperty(i, item);
480 }
481 }
482 }
483 }
484
485 delete editDialog;
486 _combos.clear();
487 _checks.clear();
488 _edits.clear();
489 _directories.clear();
490 return (result == QDialog::Accepted);
491}
492
493
494
495QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue form) {
496 QDialog* editDialog = new QDialog(qApp->getWindow());
497 editDialog->setWindowTitle(title);
498
499 bool cancelButton = false;
500
501 QVBoxLayout* layout = new QVBoxLayout();
502 editDialog->setLayout(layout);
503
504 QScrollArea* area = new QScrollArea();
505 layout->addWidget(area);
506 area->setWidgetResizable(true);
507 QWidget* container = new QWidget();
508 QFormLayout* formLayout = new QFormLayout();
509 container->setLayout(formLayout);
510 container->sizePolicy().setHorizontalStretch(1);
511 formLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
512 formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
513 formLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop);
514 formLayout->setLabelAlignment(Qt::AlignLeft);
515
516 area->setWidget(container);
517
518 for (int i = 0; i < form.property("length").toInt32(); ++i) {
519 QScriptValue item = form.property(i);
520
521 if (item.property("button").toString() != "") {
522 cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel";
523
524 } else if (item.property("directory").toString() != "") {
525 QString path = item.property("directory").toString();
526 QString title = item.property("title").toString();
527 if (title == "") {
528 title = "Choose Directory";
529 }
530 QString displayAsString = item.property("displayAs").toString();
531 QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$");
532 QString validateAsString = item.property("validateAs").toString();
533 QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*");
534 QString errorMessage = item.property("errorMessage").toString();
535 if (errorMessage == "") {
536 errorMessage = "Invalid directory";
537 }
538
539 QPushButton* directory = new QPushButton(displayAs.cap(1));
540 directory->setProperty("title", title);
541 directory->setProperty("path", path);
542 directory->setProperty("displayAs", displayAs);
543 directory->setProperty("validateAs", validateAs);
544 directory->setProperty("errorMessage", errorMessage);
545 displayAs.indexIn(path);
546 directory->setText(displayAs.cap(1) != "" ? displayAs.cap(1) : ".");
547
548 directory->setMinimumWidth(200);
549 _directories.push_back(directory);
550
551 formLayout->addRow(new QLabel(item.property("label").toString()), directory);
552 connect(directory, SIGNAL(clicked(bool)), SLOT(chooseDirectory()));
553
554 } else if (item.property("type").toString() == "inlineButton") {
555 QString buttonLabel = item.property("buttonLabel").toString();
556
557 QPushButton* inlineButton = new QPushButton(buttonLabel);
558 inlineButton->setMinimumWidth(200);
559 inlineButton->setProperty("name", item.property("name").toString());
560 formLayout->addRow(new QLabel(item.property("label").toString()), inlineButton);
561 connect(inlineButton, SIGNAL(clicked(bool)), SLOT(inlineButtonClicked()));
562
563 } else if (item.property("type").toString() == "header") {
564 formLayout->addRow(new QLabel(item.property("label").toString()));
565 } else if (item.property("options").isArray()) {
566 QComboBox* combo = new QComboBox();
567 combo->setMinimumWidth(200);
568 qint32 options_count = item.property("options").property("length").toInt32();
569 for (qint32 i = 0; i < options_count; i++) {
570 combo->addItem(item.property("options").property(i).toString());
571 }
572 _combos.push_back(combo);
573 formLayout->addRow(new QLabel(item.property("label").toString()), combo);
574 } else if (item.property("type").toString() == "checkbox") {
575 QCheckBox* check = new QCheckBox();
576 check->setTristate(false);
577 check->setCheckState(item.property("value").toString() == "true" ? Qt::Checked : Qt::Unchecked);
578 _checks.push_back(check);
579 formLayout->addRow(new QLabel(item.property("label").toString()), check);
580 } else {
581 QLineEdit* edit = new QLineEdit(item.property("value").toString());
582 edit->setMinimumWidth(200);
583 int editIndex = _edits.size();
584 _edits.push_back(edit);
585 item.setProperty("editIndex", editIndex);
586 formLayout->addRow(new QLabel(item.property("label").toString()), edit);
587 }
588 }
589
590 QDialogButtonBox* buttons = new QDialogButtonBox(
591 QDialogButtonBox::Ok
592 | (cancelButton ? QDialogButtonBox::Cancel : QDialogButtonBox::NoButton)
593 );
594 connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept()));
595 connect(buttons, SIGNAL(rejected()), editDialog, SLOT(reject()));
596 layout->addWidget(buttons);
597
598 return editDialog;
599}
600
601/// Display a prompt with a text box188/// Display a prompt with a text box
602/// \param const QString& message message to display189/// \param const QString& message message to display
603/// \param const QString& defaultText default text in the text box190/// \param const QString& defaultText default text in the text box
604/// \return QScriptValue string text value in text box if the dialog was accepted, `null` otherwise.191/// \return QScriptValue string text value in text box if the dialog was accepted, `null` otherwise.
605QScriptValue WindowScriptingInterface::showPrompt(const QString& message, const QString& defaultText) {192QScriptValue WindowScriptingInterface::showPrompt(const QString& message, const QString& defaultText) {
606 QInputDialog promptDialog(qApp->getWindow());193 bool ok = false;
607 promptDialog.setWindowTitle("");194 QString result = OffscreenUi::getText(nullptr, "", message, QLineEdit::Normal, defaultText, &ok);
608 promptDialog.setLabelText(message);195 if (!ok) {
609 promptDialog.setTextValue(defaultText);196 return QScriptValue::NullValue;
610 promptDialog.setFixedSize(600, 200);
611
612 if (promptDialog.exec() == QDialog::Accepted) {
613 return QScriptValue(promptDialog.textValue());
614 }197 }
615 return QScriptValue::NullValue;198 return QScriptValue(result);
616}199}
617 200
618/// Display a file dialog. If `directory` is an invalid file or directory the browser will start at the current201/// Display a file dialog. If `directory` is an invalid file or directory the browser will start at the current