History

Merge branch 'master' of github.com:highfidelity/hifi into 19831

Ryan Huffman committed 12 years ago

Commit 4315d632 parents 50c8b96 49af620111 files · +3432 −2440Browse files

Showing the changes to interface/src/scripting/WindowScriptingInterface.cpp (1 of 111 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::hasFocus() {
@@ -106,6 +110,26 @@ QScriptValue WindowScriptingInterface::s3Browse(const QString& nameFilter) { · 72 unmodified lines
106110 return retVal;
107111 }
108112
113+void WindowScriptingInterface::nonBlockingForm(const QString& title, QScriptValue form) {
114+ QMetaObject::invokeMethod(this, "showNonBlockingForm", Qt::BlockingQueuedConnection,
115+ Q_ARG(const QString&, title), Q_ARG(QScriptValue, form));
116+}
117+
118+void WindowScriptingInterface::reloadNonBlockingForm(QScriptValue newValues) {
119+ QMetaObject::invokeMethod(this, "doReloadNonBlockingForm", Qt::BlockingQueuedConnection,
120+ Q_ARG(QScriptValue, newValues));
121+}
122+
123+
124+QScriptValue WindowScriptingInterface::getNonBlockingFormResult(QScriptValue form) {
125+ QScriptValue retVal;
126+ QMetaObject::invokeMethod(this, "doGetNonBlockingFormResult", Qt::BlockingQueuedConnection,
127+ Q_RETURN_ARG(QScriptValue, retVal),
128+ Q_ARG(QScriptValue, form));
129+ return retVal;
130+}
131+
132+
109133 /// Display an alert box
110134 /// \param const QString& message message to display
111135 /// \return QScriptValue::UndefinedValue
@@ -148,12 +172,126 @@ void WindowScriptingInterface::chooseDirectory() { · 36 unmodified lines
148172 button->setText(buttonText);
149173 }
150174
175+void WindowScriptingInterface::inlineButtonClicked() {
176+ QPushButton* button = reinterpret_cast<QPushButton*>(sender());
177+ QString name = button->property("name").toString();
178+ emit inlineButtonClicked(name);
179+}
180+
151181 QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) {
152182 // Converts string representation of RegExp from JavaScript format to Qt format.
153183 return string.mid(1, string.length() - 2) // No enclosing slashes.
154184 .replace("\\/", "/"); // No escaping of forward slash.
155185 }
156186
187+void WindowScriptingInterface::showNonBlockingForm(const QString& title, QScriptValue form) {
188+ if (!form.isArray() || (form.isArray() && form.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() << "Show Non-Blocking Form called when form already active.";
195+ return;
196+ }
197+
198+ _form = form;
199+ _editDialog = createForm(title, _form);
200+ _nonBlockingFormActive = true;
201+
202+ connect(_editDialog, SIGNAL(accepted()), this, SLOT(nonBlockingFormAccepted()));
203+ connect(_editDialog, SIGNAL(rejected()), this, SLOT(nonBlockingFormRejected()));
204+
205+ _editDialog->setModal(true);
206+ _editDialog->show();
207+}
208+
209+void WindowScriptingInterface::doReloadNonBlockingForm(QScriptValue newValues) {
210+ if (!newValues.isArray() || (newValues.isArray() && newValues.property("length").toInt32() <= 0)) {
211+ return;
212+ }
213+
214+ // what should we do if someone calls us while we still think we have a dialog showing???
215+ if (!_editDialog) {
216+ qDebug() << "Reload Non-Blocking Form called when no form is active.";
217+ return;
218+ }
219+
220+ for (int i = 0; i < newValues.property("length").toInt32(); ++i) {
221+ QScriptValue item = newValues.property(i);
222+
223+ if (item.property("oldIndex").isValid()) {
224+ int oldIndex = item.property("oldIndex").toInt32();
225+ QScriptValue oldItem = _form.property(oldIndex);
226+ if (oldItem.isValid()) {
227+ QLineEdit* originalEdit = _edits[oldItem.property("editIndex").toInt32()];
228+ originalEdit->setText(item.property("value").toString());
229+ }
230+ }
231+ }
232+}
233+
234+
235+bool WindowScriptingInterface::nonBlockingFormActive() {
236+ return _nonBlockingFormActive;
237+}
238+
239+QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue array) {
240+ QScriptValue retVal;
241+
242+ if (_formResult == QDialog::Accepted) {
243+ int e = -1;
244+ int d = -1;
245+ for (int i = 0; i < _form.property("length").toInt32(); ++i) {
246+ QScriptValue item = _form.property(i);
247+ QScriptValue value = item.property("value");
248+
249+ if (item.property("button").toString() != "") {
250+ // Nothing to do
251+ } else if (item.property("type").toString() == "inlineButton") {
252+ // Nothing to do
253+ } else if (item.property("type").toString() == "header") {
254+ // Nothing to do
255+ } else if (item.property("directory").toString() != "") {
256+ d += 1;
257+ value = _directories.at(d)->property("path").toString();
258+ item.setProperty("directory", value);
259+ _form.setProperty(i, item);
260+ } else {
261+ e += 1;
262+ bool ok = true;
263+ if (value.isNumber()) {
264+ value = _edits.at(e)->text().toDouble(&ok);
265+ } else if (value.isString()) {
266+ value = _edits.at(e)->text();
267+ } else if (value.isBool()) {
268+ if (_edits.at(e)->text() == "true") {
269+ value = true;
270+ } else if (_edits.at(e)->text() == "false") {
271+ value = false;
272+ } else {
273+ ok = false;
274+ }
275+ }
276+ if (ok) {
277+ item.setProperty("value", value);
278+ _form.setProperty(i, item);
279+ }
280+ }
281+ }
282+ }
283+
284+ delete _editDialog;
285+ _editDialog = NULL;
286+ _form = QScriptValue();
287+ _edits.clear();
288+ _directories.clear();
289+
290+ array = _form;
291+ return (_formResult == QDialog::Accepted);
292+}
293+
294+
157295 /// Display a form layout with an edit box
158296 /// \param const QString& title title to display
159297 /// \param const QScriptValue form to display as an array of objects:
@@ -162,129 +300,152 @@ QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) { · 2 unmodified lines
162300 /// - button ("Cancel")
163301 /// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise
164302 QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptValue form) {
303+ if (form.isArray() && form.property("length").toInt32() <= 0) {
304+ return false;
305+ }
306+ QDialog* editDialog = createForm(title, form);
165307
166− if (form.isArray() && form.property("length").toInt32() > 0) {
167− QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());
168− editDialog->setWindowTitle(title);
169−
170− bool cancelButton = false;
171−
172− QVBoxLayout* layout = new QVBoxLayout();
173− editDialog->setLayout(layout);
174−
175− QScrollArea* area = new QScrollArea();
176− layout->addWidget(area);
177− area->setWidgetResizable(true);
178− QWidget* container = new QWidget();
179− QFormLayout* formLayout = new QFormLayout();
180− container->setLayout(formLayout);
181− container->sizePolicy().setHorizontalStretch(1);
182− formLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
183− formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
184− formLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop);
185− formLayout->setLabelAlignment(Qt::AlignLeft);
186−
187− area->setWidget(container);
188−
189− QVector<QLineEdit*> edits;
190− QVector<QPushButton*> directories;
308+ int result = editDialog->exec();
309+
310+ if (result == QDialog::Accepted) {
311+ int e = -1;
312+ int d = -1;
191313 for (int i = 0; i < form.property("length").toInt32(); ++i) {
192314 QScriptValue item = form.property(i);
315+ QScriptValue value = item.property("value");
193316
194317 if (item.property("button").toString() != "") {
195− cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel";
196−
318+ // Nothing to do
319+ } else if (item.property("type").toString() == "inlineButton") {
320+ // Nothing to do
321+ } else if (item.property("type").toString() == "header") {
322+ // Nothing to do
197323 } else if (item.property("directory").toString() != "") {
198− QString path = item.property("directory").toString();
199− QString title = item.property("title").toString();
200− if (title == "") {
201− title = "Choose Directory";
324+ d += 1;
325+ value = _directories.at(d)->property("path").toString();
326+ item.setProperty("directory", value);
327+ form.setProperty(i, item);
328+ } else {
329+ e += 1;
330+ bool ok = true;
331+ if (value.isNumber()) {
332+ value = _edits.at(e)->text().toDouble(&ok);
333+ } else if (value.isString()) {
334+ value = _edits.at(e)->text();
335+ } else if (value.isBool()) {
336+ if (_edits.at(e)->text() == "true") {
337+ value = true;
338+ } else if (_edits.at(e)->text() == "false") {
339+ value = false;
340+ } else {
341+ ok = false;
342+ }
202343 }
203− QString displayAsString = item.property("displayAs").toString();
204− QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$");
205− QString validateAsString = item.property("validateAs").toString();
206− QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*");
207− QString errorMessage = item.property("errorMessage").toString();
208− if (errorMessage == "") {
209− errorMessage = "Invalid directory";
344+ if (ok) {
345+ item.setProperty("value", value);
346+ form.setProperty(i, item);
210347 }
348+ }
349+ }
350+ }
351+
352+ delete editDialog;
353+ _edits.clear();
354+ _directories.clear();
355+ return (result == QDialog::Accepted);
356+}
211357
212− QPushButton* directory = new QPushButton(displayAs.cap(1));
213− directory->setProperty("title", title);
214− directory->setProperty("path", path);
215− directory->setProperty("displayAs", displayAs);
216− directory->setProperty("validateAs", validateAs);
217− directory->setProperty("errorMessage", errorMessage);
218− displayAs.indexIn(path);
219− directory->setText(displayAs.cap(1) != "" ? displayAs.cap(1) : ".");
220358
221− directory->setMinimumWidth(200);
222− directories.push_back(directory);
223359
224− formLayout->addRow(new QLabel(item.property("label").toString()), directory);
225− connect(directory, SIGNAL(clicked(bool)), SLOT(chooseDirectory()));
360+QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue form) {
361+ QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());
362+ editDialog->setWindowTitle(title);
226363
227− } else {
228− QLineEdit* edit = new QLineEdit(item.property("value").toString());
229− edit->setMinimumWidth(200);
230− edits.push_back(edit);
231− formLayout->addRow(new QLabel(item.property("label").toString()), edit);
232− }
233− }
364+ bool cancelButton = false;
365+
366+ QVBoxLayout* layout = new QVBoxLayout();
367+ editDialog->setLayout(layout);
368+
369+ QScrollArea* area = new QScrollArea();
370+ layout->addWidget(area);
371+ area->setWidgetResizable(true);
372+ QWidget* container = new QWidget();
373+ QFormLayout* formLayout = new QFormLayout();
374+ container->setLayout(formLayout);
375+ container->sizePolicy().setHorizontalStretch(1);
376+ formLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
377+ formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
378+ formLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop);
379+ formLayout->setLabelAlignment(Qt::AlignLeft);
380+
381+ area->setWidget(container);
382+
383+ for (int i = 0; i < form.property("length").toInt32(); ++i) {
384+ QScriptValue item = form.property(i);
234385
235− QDialogButtonBox* buttons = new QDialogButtonBox(
236− QDialogButtonBox::Ok
237− | (cancelButton ? QDialogButtonBox::Cancel : QDialogButtonBox::NoButton)
238− );
239− connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept()));
240− connect(buttons, SIGNAL(rejected()), editDialog, SLOT(reject()));
241− layout->addWidget(buttons);
242−
243− int result = editDialog->exec();
244− if (result == QDialog::Accepted) {
245− int e = -1;
246− int d = -1;
247− for (int i = 0; i < form.property("length").toInt32(); ++i) {
248− QScriptValue item = form.property(i);
249− QScriptValue value = item.property("value");
250−
251− if (item.property("button").toString() != "") {
252− // Nothing to do
253− } else if (item.property("directory").toString() != "") {
254− d += 1;
255− value = directories.at(d)->property("path").toString();
256− item.setProperty("directory", value);
257− form.setProperty(i, item);
258− } else {
259− e += 1;
260− bool ok = true;
261− if (value.isNumber()) {
262− value = edits.at(e)->text().toDouble(&ok);
263− } else if (value.isString()) {
264− value = edits.at(e)->text();
265− } else if (value.isBool()) {
266− if (edits.at(e)->text() == "true") {
267− value = true;
268− } else if (edits.at(e)->text() == "false") {
269− value = false;
270− } else {
271− ok = false;
272− }
273− }
274− if (ok) {
275− item.setProperty("value", value);
276− form.setProperty(i, item);
277− }
278− }
386+ if (item.property("button").toString() != "") {
387+ cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel";
388+
389+ } else if (item.property("directory").toString() != "") {
390+ QString path = item.property("directory").toString();
391+ QString title = item.property("title").toString();
392+ if (title == "") {
393+ title = "Choose Directory";
394+ }
395+ QString displayAsString = item.property("displayAs").toString();
396+ QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$");
397+ QString validateAsString = item.property("validateAs").toString();
398+ QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*");
399+ QString errorMessage = item.property("errorMessage").toString();
400+ if (errorMessage == "") {
401+ errorMessage = "Invalid directory";
279402 }
280− }
281−
282− delete editDialog;
283403
284− return (result == QDialog::Accepted);
404+ QPushButton* directory = new QPushButton(displayAs.cap(1));
405+ directory->setProperty("title", title);
406+ directory->setProperty("path", path);
407+ directory->setProperty("displayAs", displayAs);
408+ directory->setProperty("validateAs", validateAs);
409+ directory->setProperty("errorMessage", errorMessage);
410+ displayAs.indexIn(path);
411+ directory->setText(displayAs.cap(1) != "" ? displayAs.cap(1) : ".");
412+
413+ directory->setMinimumWidth(200);
414+ _directories.push_back(directory);
415+
416+ formLayout->addRow(new QLabel(item.property("label").toString()), directory);
417+ connect(directory, SIGNAL(clicked(bool)), SLOT(chooseDirectory()));
418+
419+ } else if (item.property("type").toString() == "inlineButton") {
420+ QString buttonLabel = item.property("buttonLabel").toString();
421+
422+ QPushButton* inlineButton = new QPushButton(buttonLabel);
423+ inlineButton->setMinimumWidth(200);
424+ inlineButton->setProperty("name", item.property("name").toString());
425+ formLayout->addRow(new QLabel(item.property("label").toString()), inlineButton);
426+ connect(inlineButton, SIGNAL(clicked(bool)), SLOT(inlineButtonClicked()));
427+
428+ } else if (item.property("type").toString() == "header") {
429+ formLayout->addRow(new QLabel(item.property("label").toString()));
430+ } else {
431+ QLineEdit* edit = new QLineEdit(item.property("value").toString());
432+ edit->setMinimumWidth(200);
433+ int editIndex = _edits.size();
434+ _edits.push_back(edit);
435+ item.setProperty("editIndex", editIndex);
436+ formLayout->addRow(new QLabel(item.property("label").toString()), edit);
437+ }
285438 }
286−
287− return false;
439+
440+ QDialogButtonBox* buttons = new QDialogButtonBox(
441+ QDialogButtonBox::Ok
442+ | (cancelButton ? QDialogButtonBox::Cancel : QDialogButtonBox::NoButton)
443+ );
444+ connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept()));
445+ connect(buttons, SIGNAL(rejected()), editDialog, SLOT(reject()));
446+ layout->addWidget(buttons);
447+
448+ return editDialog;
288449 }
289450
290451 /// Display a prompt with a text box