Showing the changes to interface/src/scripting/WindowScriptingInterface.cpp (1 of 2 files). Show all
Unified · Split
| @@ -27,7 +27,11 @@ WindowScriptingInterface* WindowScriptingInterface::getInstance() { · 26 unmodified lines | |||
| 27 | return &sharedInstance; | 27 | return &sharedInstance; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | WindowScriptingInterface::WindowScriptingInterface() { | 30 | WindowScriptingInterface::WindowScriptingInterface() : |
| 31 | _editDialog(NULL), | ||
| 32 | _nonBlockingFormActive(false), | ||
| 33 | _formResult(QDialog::Rejected) | ||
| 34 | { | ||
| 31 | } | 35 | } |
| 32 | 36 | ||
| 33 | QScriptValue WindowScriptingInterface::alert(const QString& message) { | 37 | QScriptValue 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 | ||
| 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 | |||
| 87 | /// Display an alert box | 111 | /// Display an alert box |
| 88 | /// \param const QString& message message to display | 112 | /// \param const QString& message message to display |
| 89 | /// \return QScriptValue::UndefinedValue | 113 | /// \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 | ||
| 153 | void WindowScriptingInterface::inlineButtonClicked() { | ||
| 154 | QPushButton* button = reinterpret_cast<QPushButton*>(sender()); | ||
| 155 | QString name = button->property("name").toString(); | ||
| 156 | emit inlineButtonClicked(name); | ||
| 157 | } | ||
| 158 | |||
| 129 | QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) { | 159 | QString 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 | ||
| 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 | |||
| 135 | /// Display a form layout with an edit box | 273 | /// Display a form layout with an edit box |
| 136 | /// \param const QString& title title to display | 274 | /// \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` otherwise | 279 | /// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise |
| 142 | QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptValue form) { | 280 | 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); | ||
| 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); | 338 | QDialog* 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 box | 429 | /// Display a prompt with a text box |