History

add support for non blocking forms

ZappoMan committed 12 years ago

Commit a1006301 parent c815ee52 files · +295 −109Browse files

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

Unified · Split

interface/src/scripting/WindowScriptingInterface.cpp+269−108
@@ -27,7 +27,11 @@ WindowScriptingInterface* WindowScriptingInterface::getInstance() { · 26 unmodified lines
2727 return &sharedInstance;
2828 }
2929
30−WindowScriptingInterface::WindowScriptingInterface() {
30+WindowScriptingInterface::WindowScriptingInterface() :
31+ _editDialog(NULL),
32+ _nonBlockingFormActive(false),
33+ _formResult(QDialog::Rejected)
34+{
3135 }
3236
3337 QScriptValue WindowScriptingInterface::alert(const QString& message) {
@@ -84,6 +88,26 @@ QScriptValue WindowScriptingInterface::s3Browse(const QString& nameFilter) { · 50 unmodified lines
8488 return retVal;
8589 }
8690
91+void WindowScriptingInterface::nonBlockingForm(const QString& title, QScriptValue form) {
92+ QMetaObject::invokeMethod(this, "showNonBlockingForm", Qt::BlockingQueuedConnection,
93+ Q_ARG(const QString&, title), Q_ARG(QScriptValue, form));
94+}
95+
96+void WindowScriptingInterface::reloadNonBlockingForm(QScriptValue newValues) {
97+ QMetaObject::invokeMethod(this, "doReloadNonBlockingForm", Qt::BlockingQueuedConnection,
98+ Q_ARG(QScriptValue, newValues));
99+}
100+
101+
102+QScriptValue WindowScriptingInterface::getNonBlockingFormResult(QScriptValue form) {
103+ QScriptValue retVal;
104+ QMetaObject::invokeMethod(this, "doGetNonBlockingFormResult", Qt::BlockingQueuedConnection,
105+ Q_RETURN_ARG(QScriptValue, retVal),
106+ Q_ARG(QScriptValue, form));
107+ return retVal;
108+}
109+
110+
87111 /// Display an alert box
88112 /// \param const QString& message message to display
89113 /// \return QScriptValue::UndefinedValue
@@ -126,12 +150,126 @@ void WindowScriptingInterface::chooseDirectory() { · 36 unmodified lines
126150 button->setText(buttonText);
127151 }
128152
153+void WindowScriptingInterface::inlineButtonClicked() {
154+ QPushButton* button = reinterpret_cast<QPushButton*>(sender());
155+ QString name = button->property("name").toString();
156+ emit inlineButtonClicked(name);
157+}
158+
129159 QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) {
130160 // Converts string representation of RegExp from JavaScript format to Qt format.
131161 return string.mid(1, string.length() - 2) // No enclosing slashes.
132162 .replace("\\/", "/"); // No escaping of forward slash.
133163 }
134164
165+void WindowScriptingInterface::showNonBlockingForm(const QString& title, QScriptValue form) {
166+ if (!form.isArray() || (form.isArray() && form.property("length").toInt32() <= 0)) {
167+ return;
168+ }
169+
170+ // what should we do if someone calls us while we still think we have a dialog showing???
171+ if (_editDialog) {
172+ qDebug() << "Show Non-Blocking Form called when form already active.";
173+ return;
174+ }
175+
176+ _form = form;
177+ _editDialog = createForm(title, _form);
178+ _nonBlockingFormActive = true;
179+
180+ connect(_editDialog, SIGNAL(accepted()), this, SLOT(nonBlockingFormAccepted()));
181+ connect(_editDialog, SIGNAL(rejected()), this, SLOT(nonBlockingFormRejected()));
182+
183+ _editDialog->setModal(true);
184+ _editDialog->show();
185+}
186+
187+void WindowScriptingInterface::doReloadNonBlockingForm(QScriptValue newValues) {
188+ if (!newValues.isArray() || (newValues.isArray() && newValues.property("length").toInt32() <= 0)) {
189+ return;
190+ }
191+
192+ // what should we do if someone calls us while we still think we have a dialog showing???
193+ if (!_editDialog) {
194+ qDebug() << "Reload Non-Blocking Form called when no form is active.";
195+ return;
196+ }
197+
198+ for (int i = 0; i < newValues.property("length").toInt32(); ++i) {
199+ QScriptValue item = newValues.property(i);
200+
201+ if (item.property("oldIndex").isValid()) {
202+ int oldIndex = item.property("oldIndex").toInt32();
203+ QScriptValue oldItem = _form.property(oldIndex);
204+ if (oldItem.isValid()) {
205+ QLineEdit* originalEdit = _edits[oldItem.property("editIndex").toInt32()];
206+ originalEdit->setText(item.property("value").toString());
207+ }
208+ }
209+ }
210+}
211+
212+
213+bool WindowScriptingInterface::nonBlockingFormActive() {
214+ return _nonBlockingFormActive;
215+}
216+
217+QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue array) {
218+ QScriptValue retVal;
219+
220+ if (_formResult == QDialog::Accepted) {
221+ int e = -1;
222+ int d = -1;
223+ for (int i = 0; i < _form.property("length").toInt32(); ++i) {
224+ QScriptValue item = _form.property(i);
225+ QScriptValue value = item.property("value");
226+
227+ if (item.property("button").toString() != "") {
228+ // Nothing to do
229+ } else if (item.property("type").toString() == "inlineButton") {
230+ // Nothing to do
231+ } else if (item.property("type").toString() == "header") {
232+ // Nothing to do
233+ } else if (item.property("directory").toString() != "") {
234+ d += 1;
235+ value = _directories.at(d)->property("path").toString();
236+ item.setProperty("directory", value);
237+ _form.setProperty(i, item);
238+ } else {
239+ e += 1;
240+ bool ok = true;
241+ if (value.isNumber()) {
242+ value = _edits.at(e)->text().toDouble(&ok);
243+ } else if (value.isString()) {
244+ value = _edits.at(e)->text();
245+ } else if (value.isBool()) {
246+ if (_edits.at(e)->text() == "true") {
247+ value = true;
248+ } else if (_edits.at(e)->text() == "false") {
249+ value = false;
250+ } else {
251+ ok = false;
252+ }
253+ }
254+ if (ok) {
255+ item.setProperty("value", value);
256+ _form.setProperty(i, item);
257+ }
258+ }
259+ }
260+ }
261+
262+ delete _editDialog;
263+ _editDialog = NULL;
264+ _form = QScriptValue();
265+ _edits.clear();
266+ _directories.clear();
267+
268+ array = _form;
269+ return (_formResult == QDialog::Accepted);
270+}
271+
272+
135273 /// Display a form layout with an edit box
136274 /// \param const QString& title title to display
137275 /// \param const QScriptValue form to display as an array of objects:
@@ -140,129 +278,152 @@ QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) { · 2 unmodified lines
140278 /// - button ("Cancel")
141279 /// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise
142280 QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptValue form) {
281+ if (form.isArray() && form.property("length").toInt32() <= 0) {
282+ return false;
283+ }
284+ QDialog* editDialog = createForm(title, form);
143285
144− if (form.isArray() && form.property("length").toInt32() > 0) {
145− QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());
146− editDialog->setWindowTitle(title);
147−
148− bool cancelButton = false;
149−
150− QVBoxLayout* layout = new QVBoxLayout();
151− editDialog->setLayout(layout);
152−
153− QScrollArea* area = new QScrollArea();
154− layout->addWidget(area);
155− area->setWidgetResizable(true);
156− QWidget* container = new QWidget();
157− QFormLayout* formLayout = new QFormLayout();
158− container->setLayout(formLayout);
159− container->sizePolicy().setHorizontalStretch(1);
160− formLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
161− formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
162− formLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop);
163− formLayout->setLabelAlignment(Qt::AlignLeft);
164−
165− area->setWidget(container);
166−
167− QVector<QLineEdit*> edits;
168− QVector<QPushButton*> directories;
286+ int result = editDialog->exec();
287+
288+ if (result == QDialog::Accepted) {
289+ int e = -1;
290+ int d = -1;
169291 for (int i = 0; i < form.property("length").toInt32(); ++i) {
170292 QScriptValue item = form.property(i);
293+ QScriptValue value = item.property("value");
171294
172295 if (item.property("button").toString() != "") {
173− cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel";
174−
296+ // Nothing to do
297+ } else if (item.property("type").toString() == "inlineButton") {
298+ // Nothing to do
299+ } else if (item.property("type").toString() == "header") {
300+ // Nothing to do
175301 } else if (item.property("directory").toString() != "") {
176− QString path = item.property("directory").toString();
177− QString title = item.property("title").toString();
178− if (title == "") {
179− title = "Choose Directory";
302+ d += 1;
303+ value = _directories.at(d)->property("path").toString();
304+ item.setProperty("directory", value);
305+ form.setProperty(i, item);
306+ } else {
307+ e += 1;
308+ bool ok = true;
309+ if (value.isNumber()) {
310+ value = _edits.at(e)->text().toDouble(&ok);
311+ } else if (value.isString()) {
312+ value = _edits.at(e)->text();
313+ } else if (value.isBool()) {
314+ if (_edits.at(e)->text() == "true") {
315+ value = true;
316+ } else if (_edits.at(e)->text() == "false") {
317+ value = false;
318+ } else {
319+ ok = false;
320+ }
180321 }
181− QString displayAsString = item.property("displayAs").toString();
182− QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$");
183− QString validateAsString = item.property("validateAs").toString();
184− QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*");
185− QString errorMessage = item.property("errorMessage").toString();
186− if (errorMessage == "") {
187− errorMessage = "Invalid directory";
322+ if (ok) {
323+ item.setProperty("value", value);
324+ form.setProperty(i, item);
188325 }
326+ }
327+ }
328+ }
329+
330+ delete editDialog;
331+ _edits.clear();
332+ _directories.clear();
333+ return (result == QDialog::Accepted);
334+}
189335
190− QPushButton* directory = new QPushButton(displayAs.cap(1));
191− directory->setProperty("title", title);
192− directory->setProperty("path", path);
193− directory->setProperty("displayAs", displayAs);
194− directory->setProperty("validateAs", validateAs);
195− directory->setProperty("errorMessage", errorMessage);
196− displayAs.indexIn(path);
197− directory->setText(displayAs.cap(1) != "" ? displayAs.cap(1) : ".");
198336
199− directory->setMinimumWidth(200);
200− directories.push_back(directory);
201337
202− formLayout->addRow(new QLabel(item.property("label").toString()), directory);
203− connect(directory, SIGNAL(clicked(bool)), SLOT(chooseDirectory()));
338+QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue form) {
339+ QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());
340+ editDialog->setWindowTitle(title);
204341
205− } else {
206− QLineEdit* edit = new QLineEdit(item.property("value").toString());
207− edit->setMinimumWidth(200);
208− edits.push_back(edit);
209− formLayout->addRow(new QLabel(item.property("label").toString()), edit);
210− }
211− }
342+ bool cancelButton = false;
343+
344+ QVBoxLayout* layout = new QVBoxLayout();
345+ editDialog->setLayout(layout);
346+
347+ QScrollArea* area = new QScrollArea();
348+ layout->addWidget(area);
349+ area->setWidgetResizable(true);
350+ QWidget* container = new QWidget();
351+ QFormLayout* formLayout = new QFormLayout();
352+ container->setLayout(formLayout);
353+ container->sizePolicy().setHorizontalStretch(1);
354+ formLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
355+ formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
356+ formLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop);
357+ formLayout->setLabelAlignment(Qt::AlignLeft);
358+
359+ area->setWidget(container);
360+
361+ for (int i = 0; i < form.property("length").toInt32(); ++i) {
362+ QScriptValue item = form.property(i);
212363
213− QDialogButtonBox* buttons = new QDialogButtonBox(
214− QDialogButtonBox::Ok
215− | (cancelButton ? QDialogButtonBox::Cancel : QDialogButtonBox::NoButton)
216− );
217− connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept()));
218− connect(buttons, SIGNAL(rejected()), editDialog, SLOT(reject()));
219− layout->addWidget(buttons);
220−
221− int result = editDialog->exec();
222− if (result == QDialog::Accepted) {
223− int e = -1;
224− int d = -1;
225− for (int i = 0; i < form.property("length").toInt32(); ++i) {
226− QScriptValue item = form.property(i);
227− QScriptValue value = item.property("value");
228−
229− if (item.property("button").toString() != "") {
230− // Nothing to do
231− } else if (item.property("directory").toString() != "") {
232− d += 1;
233− value = directories.at(d)->property("path").toString();
234− item.setProperty("directory", value);
235− form.setProperty(i, item);
236− } else {
237− e += 1;
238− bool ok = true;
239− if (value.isNumber()) {
240− value = edits.at(e)->text().toDouble(&ok);
241− } else if (value.isString()) {
242− value = edits.at(e)->text();
243− } else if (value.isBool()) {
244− if (edits.at(e)->text() == "true") {
245− value = true;
246− } else if (edits.at(e)->text() == "false") {
247− value = false;
248− } else {
249− ok = false;
250− }
251− }
252− if (ok) {
253− item.setProperty("value", value);
254− form.setProperty(i, item);
255− }
256− }
364+ if (item.property("button").toString() != "") {
365+ cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel";
366+
367+ } else if (item.property("directory").toString() != "") {
368+ QString path = item.property("directory").toString();
369+ QString title = item.property("title").toString();
370+ if (title == "") {
371+ title = "Choose Directory";
372+ }
373+ QString displayAsString = item.property("displayAs").toString();
374+ QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$");
375+ QString validateAsString = item.property("validateAs").toString();
376+ QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*");
377+ QString errorMessage = item.property("errorMessage").toString();
378+ if (errorMessage == "") {
379+ errorMessage = "Invalid directory";
257380 }
258− }
259−
260− delete editDialog;
261381
262− return (result == QDialog::Accepted);
382+ QPushButton* directory = new QPushButton(displayAs.cap(1));
383+ directory->setProperty("title", title);
384+ directory->setProperty("path", path);
385+ directory->setProperty("displayAs", displayAs);
386+ directory->setProperty("validateAs", validateAs);
387+ directory->setProperty("errorMessage", errorMessage);
388+ displayAs.indexIn(path);
389+ directory->setText(displayAs.cap(1) != "" ? displayAs.cap(1) : ".");
390+
391+ directory->setMinimumWidth(200);
392+ _directories.push_back(directory);
393+
394+ formLayout->addRow(new QLabel(item.property("label").toString()), directory);
395+ connect(directory, SIGNAL(clicked(bool)), SLOT(chooseDirectory()));
396+
397+ } else if (item.property("type").toString() == "inlineButton") {
398+ QString buttonLabel = item.property("buttonLabel").toString();
399+
400+ QPushButton* inlineButton = new QPushButton(buttonLabel);
401+ inlineButton->setMinimumWidth(200);
402+ inlineButton->setProperty("name", item.property("name").toString());
403+ formLayout->addRow(new QLabel(item.property("label").toString()), inlineButton);
404+ connect(inlineButton, SIGNAL(clicked(bool)), SLOT(inlineButtonClicked()));
405+
406+ } else if (item.property("type").toString() == "header") {
407+ formLayout->addRow(new QLabel(item.property("label").toString()));
408+ } else {
409+ QLineEdit* edit = new QLineEdit(item.property("value").toString());
410+ edit->setMinimumWidth(200);
411+ int editIndex = _edits.size();
412+ _edits.push_back(edit);
413+ item.setProperty("editIndex", editIndex);
414+ formLayout->addRow(new QLabel(item.property("label").toString()), edit);
415+ }
263416 }
264−
265− return false;
417+
418+ QDialogButtonBox* buttons = new QDialogButtonBox(
419+ QDialogButtonBox::Ok
420+ | (cancelButton ? QDialogButtonBox::Cancel : QDialogButtonBox::NoButton)
421+ );
422+ connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept()));
423+ connect(buttons, SIGNAL(rejected()), editDialog, SLOT(reject()));
424+ layout->addWidget(buttons);
425+
426+ return editDialog;
266427 }
267428
268429 /// Display a prompt with a text box