Showing the changes to interface/src/scripting/WindowScriptingInterface.cpp (1 of 111 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::hasFocus() { | 37 | QScriptValue WindowScriptingInterface::hasFocus() { |
| @@ -106,6 +110,26 @@ QScriptValue WindowScriptingInterface::s3Browse(const QString& nameFilter) { · 72 unmodified lines | |||
| 106 | return retVal; | 110 | return retVal; |
| 107 | } | 111 | } |
| 108 | 112 | ||
| 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 | |||
| 109 | /// Display an alert box | 133 | /// Display an alert box |
| 110 | /// \param const QString& message message to display | 134 | /// \param const QString& message message to display |
| 111 | /// \return QScriptValue::UndefinedValue | 135 | /// \return QScriptValue::UndefinedValue |
| @@ -148,12 +172,126 @@ void WindowScriptingInterface::chooseDirectory() { · 36 unmodified lines | |||
| 148 | button->setText(buttonText); | 172 | button->setText(buttonText); |
| 149 | } | 173 | } |
| 150 | 174 | ||
| 175 | void WindowScriptingInterface::inlineButtonClicked() { | ||
| 176 | QPushButton* button = reinterpret_cast<QPushButton*>(sender()); | ||
| 177 | QString name = button->property("name").toString(); | ||
| 178 | emit inlineButtonClicked(name); | ||
| 179 | } | ||
| 180 | |||
| 151 | QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) { | 181 | QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) { |
| 152 | // Converts string representation of RegExp from JavaScript format to Qt format. | 182 | // Converts string representation of RegExp from JavaScript format to Qt format. |
| 153 | return string.mid(1, string.length() - 2) // No enclosing slashes. | 183 | return string.mid(1, string.length() - 2) // No enclosing slashes. |
| 154 | .replace("\\/", "/"); // No escaping of forward slash. | 184 | .replace("\\/", "/"); // No escaping of forward slash. |
| 155 | } | 185 | } |
| 156 | 186 | ||
| 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 | |||
| 157 | /// Display a form layout with an edit box | 295 | /// Display a form layout with an edit box |
| 158 | /// \param const QString& title title to display | 296 | /// \param const QString& title title to display |
| 159 | /// \param const QScriptValue form to display as an array of objects: | 297 | /// \param const QScriptValue form to display as an array of objects: |
| @@ -162,129 +300,152 @@ QString WindowScriptingInterface::jsRegExp2QtRegExp(QString string) { · 2 unmodified lines | |||
| 162 | /// - button ("Cancel") | 300 | /// - button ("Cancel") |
| 163 | /// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise | 301 | /// \return QScriptValue `true` if 'OK' was clicked, `false` otherwise |
| 164 | QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptValue form) { | 302 | 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); | ||
| 165 | 307 | ||
| 166 | if (form.isArray() && form.property("length").toInt32() > 0) { | 308 | int result = editDialog->exec(); |
| 167 | QDialog* editDialog = new QDialog(Application::getInstance()->getWindow()); | 309 | |
| 168 | editDialog->setWindowTitle(title); | 310 | if (result == QDialog::Accepted) { |
| 169 | 311 | int e = -1; | |
| 170 | bool cancelButton = false; | 312 | int d = -1; |
| 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; | ||
| 191 | for (int i = 0; i < form.property("length").toInt32(); ++i) { | 313 | for (int i = 0; i < form.property("length").toInt32(); ++i) { |
| 192 | QScriptValue item = form.property(i); | 314 | QScriptValue item = form.property(i); |
| 315 | QScriptValue value = item.property("value"); | ||
| 193 | 316 | ||
| 194 | if (item.property("button").toString() != "") { | 317 | if (item.property("button").toString() != "") { |
| 195 | cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel"; | 318 | // Nothing to do |
| 196 | 319 | } else if (item.property("type").toString() == "inlineButton") { | |
| 320 | // Nothing to do | ||
| 321 | } else if (item.property("type").toString() == "header") { | ||
| 322 | // Nothing to do | ||
| 197 | } else if (item.property("directory").toString() != "") { | 323 | } else if (item.property("directory").toString() != "") { |
| 198 | QString path = item.property("directory").toString(); | 324 | d += 1; |
| 199 | QString title = item.property("title").toString(); | 325 | value = _directories.at(d)->property("path").toString(); |
| 200 | if (title == "") { | 326 | item.setProperty("directory", value); |
| 201 | title = "Choose Directory"; | 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 | } | ||
| 202 | } | 343 | } |
| 203 | QString displayAsString = item.property("displayAs").toString(); | 344 | if (ok) { |
| 204 | QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$"); | 345 | item.setProperty("value", value); |
| 205 | QString validateAsString = item.property("validateAs").toString(); | 346 | form.setProperty(i, item); |
| 206 | QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*"); | ||
| 207 | QString errorMessage = item.property("errorMessage").toString(); | ||
| 208 | if (errorMessage == "") { | ||
| 209 | errorMessage = "Invalid directory"; | ||
| 210 | } | 347 | } |
| 348 | } | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | delete editDialog; | ||
| 353 | _edits.clear(); | ||
| 354 | _directories.clear(); | ||
| 355 | return (result == QDialog::Accepted); | ||
| 356 | } | ||
| 211 | 357 | ||
| 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) : "."); | ||
| 220 | 358 | ||
| 221 | directory->setMinimumWidth(200); | ||
| 222 | directories.push_back(directory); | ||
| 223 | 359 | ||
| 224 | formLayout->addRow(new QLabel(item.property("label").toString()), directory); | 360 | QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue form) { |
| 225 | connect(directory, SIGNAL(clicked(bool)), SLOT(chooseDirectory())); | 361 | QDialog* editDialog = new QDialog(Application::getInstance()->getWindow()); |
| 362 | editDialog->setWindowTitle(title); | ||
| 226 | 363 | ||
| 227 | } else { | 364 | bool cancelButton = false; |
| 228 | QLineEdit* edit = new QLineEdit(item.property("value").toString()); | 365 | |
| 229 | edit->setMinimumWidth(200); | 366 | QVBoxLayout* layout = new QVBoxLayout(); |
| 230 | edits.push_back(edit); | 367 | editDialog->setLayout(layout); |
| 231 | formLayout->addRow(new QLabel(item.property("label").toString()), edit); | 368 | |
| 232 | } | 369 | QScrollArea* area = new QScrollArea(); |
| 233 | } | 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); | ||
| 234 | 385 | ||
| 235 | QDialogButtonBox* buttons = new QDialogButtonBox( | 386 | if (item.property("button").toString() != "") { |
| 236 | QDialogButtonBox::Ok | 387 | cancelButton = cancelButton || item.property("button").toString().toLower() == "cancel"; |
| 237 | | (cancelButton ? QDialogButtonBox::Cancel : QDialogButtonBox::NoButton) | 388 | |
| 238 | ); | 389 | } else if (item.property("directory").toString() != "") { |
| 239 | connect(buttons, SIGNAL(accepted()), editDialog, SLOT(accept())); | 390 | QString path = item.property("directory").toString(); |
| 240 | connect(buttons, SIGNAL(rejected()), editDialog, SLOT(reject())); | 391 | QString title = item.property("title").toString(); |
| 241 | layout->addWidget(buttons); | 392 | if (title == "") { |
| 242 | 393 | title = "Choose Directory"; | |
| 243 | int result = editDialog->exec(); | 394 | } |
| 244 | if (result == QDialog::Accepted) { | 395 | QString displayAsString = item.property("displayAs").toString(); |
| 245 | int e = -1; | 396 | QRegExp displayAs = QRegExp(displayAsString != "" ? jsRegExp2QtRegExp(displayAsString) : "^(.*)$"); |
| 246 | int d = -1; | 397 | QString validateAsString = item.property("validateAs").toString(); |
| 247 | for (int i = 0; i < form.property("length").toInt32(); ++i) { | 398 | QRegExp validateAs = QRegExp(validateAsString != "" ? jsRegExp2QtRegExp(validateAsString) : ".*"); |
| 248 | QScriptValue item = form.property(i); | 399 | QString errorMessage = item.property("errorMessage").toString(); |
| 249 | QScriptValue value = item.property("value"); | 400 | if (errorMessage == "") { |
| 250 | 401 | errorMessage = "Invalid directory"; | |
| 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 | } | ||
| 279 | } | 402 | } |
| 280 | } | ||
| 281 | |||
| 282 | delete editDialog; | ||
| 283 | 403 | ||
| 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 | } | ||
| 285 | } | 438 | } |
| 286 | 439 | ||
| 287 | return false; | 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; | ||
| 288 | } | 449 | } |
| 289 | 450 | ||
| 290 | /// Display a prompt with a text box | 451 | /// Display a prompt with a text box |