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
27 return &sharedInstance;27 return &sharedInstance;
28}28}
29 29
30WindowScriptingInterface::WindowScriptingInterface() {30WindowScriptingInterface::WindowScriptingInterface() :
31 _editDialog(NULL),
32 _nonBlockingFormActive(false),
33 _formResult(QDialog::Rejected)
34{
31}35}
32 36
33QScriptValue WindowScriptingInterface::alert(const QString& message) {37QScriptValue WindowScriptingInterface::alert(const QString& message) {
@@ -84,6 +88,26 @@ QScriptValue WindowScriptingInterface::s3Browse(const QString& nameFilter) { · 50 unmodified lines
84 return retVal;88 return retVal;
85}89}
86 90
91void 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
96void WindowScriptingInterface::reloadNonBlockingForm(QScriptValue newValues) {
97 QMetaObject::invokeMethod(this, "doReloadNonBlockingForm", Qt::BlockingQueuedConnection,
98 Q_ARG(QScriptValue, newValues));
99}
100
101
102QScriptValue 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
87/// Display an alert box111/// Display an alert box
88/// \param const QString& message message to display112/// \param const QString& message message to display
89/// \return QScriptValue::UndefinedValue113/// \return QScriptValue::UndefinedValue
@@ -126,12 +150,126 @@ void WindowScriptingInterface::chooseDirectory() { · 36 unmodified lines
126 button->setText(buttonText);150 button->setText(buttonText);
127}151}
128 152
153void WindowScriptingInterface::inlineButtonClicked() {
154 QPushButton* button = reinterpret_cast<QPushButton*>(sender());
155 QString name = button->property("name").toString();
156 emit inlineButtonClicked(name);
157}
158
129QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) {159QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) {
130 // Converts string representation of RegExp from JavaScript format to Qt format.160 // Converts string representation of RegExp from JavaScript format to Qt format.
131 return string.mid(1, string.length() - 2) // No enclosing slashes.161 return string.mid(1, string.length() - 2) // No enclosing slashes.
132 .replace("\\/", "/"); // No escaping of forward slash.162 .replace("\\/", "/"); // No escaping of forward slash.
133}163}
134 164
165void 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
187void 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
213bool WindowScriptingInterface::nonBlockingFormActive() {
214 return _nonBlockingFormActive;
215}
216
217QScriptValue 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
135/// Display a form layout with an edit box273/// Display a form layout with an edit box
136/// \param const QString& title title to display274/// \param const QString& title title to display
137/// \param const QScriptValue form to display as an array of objects:275/// \param const QScriptValue form to display as an array of objects:
@@ -140,129 +278,152 @@ QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) { · 2 unmodified lines
140/// - button ("Cancel")278/// - button ("Cancel")
141/// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise279/// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise
142QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptValue form) {280QScriptValue 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);
143 285
144 if (form.isArray() && form.property("length").toInt32() > 0) {286 int result = editDialog->exec();
145 QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());287
146 editDialog->setWindowTitle(title);288 if (result == QDialog::Accepted) {
147 289 int e = -1;
148 bool cancelButton = false;290 int d = -1;
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;
169 for (int i = 0; i < form.property("length").toInt32(); ++i) {291 for (int i = 0; i < form.property("length").toInt32(); ++i) {
170 QScriptValue item = form.property(i);292 QScriptValue item = form.property(i);
293 QScriptValue value = item.property("value");
171 294
172 if (item.property("button").toString() != "") {295 if (item.property("button").toString() != "") {
173 cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel";296 // Nothing to do
174 297 } else if (item.property("type").toString() == "inlineButton") {
298 // Nothing to do
299 } else if (item.property("type").toString() == "header") {
300 // Nothing to do
175 } else if (item.property("directory").toString() != "") {301 } else if (item.property("directory").toString() != "") {
176 QString path = item.property("directory").toString();302 d += 1;
177 QString title = item.property("title").toString();303 value = _directories.at(d)->property("path").toString();
178 if (title == "") {304 item.setProperty("directory", value);
179 title = "Choose Directory";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 }
180 }321 }
181 QString displayAsString = item.property("displayAs").toString();322 if (ok) {
182 QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$");323 item.setProperty("value", value);
183 QString validateAsString = item.property("validateAs").toString();324 form.setProperty(i, item);
184 QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*");
185 QString errorMessage = item.property("errorMessage").toString();
186 if (errorMessage == "") {
187 errorMessage = "Invalid directory";
188 }325 }
326 }
327 }
328 }
329
330 delete editDialog;
331 _edits.clear();
332 _directories.clear();
333 return (result == QDialog::Accepted);
334}
189 335
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) : ".");
198 336
199 directory->setMinimumWidth(200);
200 directories.push_back(directory);
201 337
202 formLayout->addRow(new QLabel(item.property("label").toString()), directory);338QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue form) {
203 connect(directory, SIGNAL(clicked(bool)), SLOT(chooseDirectory()));339 QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());
340 editDialog->setWindowTitle(title);
204 341
205 } else {342 bool cancelButton = false;
206 QLineEdit* edit = new QLineEdit(item.property("value").toString());343
207 edit->setMinimumWidth(200);344 QVBoxLayout* layout = new QVBoxLayout();
208 edits.push_back(edit);345 editDialog->setLayout(layout);
209 formLayout->addRow(new QLabel(item.property("label").toString()), edit);346
210 }347 QScrollArea* area = new QScrollArea();
211 }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);
212 363
213 QDialogButtonBox* buttons = new QDialogButtonBox(364 if (item.property("button").toString() != "") {
214 QDialogButtonBox::Ok 365 cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel";
215 | (cancelButton ? QDialogButtonBox::Cancel : QDialogButtonBox::NoButton)366
216 );367 } else if (item.property("directory").toString() != "") {
217 connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept()));368 QString path = item.property("directory").toString();
218 connect(buttons, SIGNAL(rejected()), editDialog, SLOT(reject()));369 QString title = item.property("title").toString();
219 layout->addWidget(buttons);370 if (title == "") {
220 371 title = "Choose Directory";
221 int result = editDialog->exec();372 }
222 if (result == QDialog::Accepted) {373 QString displayAsString = item.property("displayAs").toString();
223 int e = -1;374 QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$");
224 int d = -1;375 QString validateAsString = item.property("validateAs").toString();
225 for (int i = 0; i < form.property("length").toInt32(); ++i) {376 QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*");
226 QScriptValue item = form.property(i);377 QString errorMessage = item.property("errorMessage").toString();
227 QScriptValue value = item.property("value");378 if (errorMessage == "") {
228 379 errorMessage = "Invalid directory";
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 }
257 }380 }
258 }
259
260 delete editDialog;
261 381
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 }
263 }416 }
264 417
265 return false;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;
266}427}
267 428
268/// Display a prompt with a text box429/// Display a prompt with a text box