473 namespace { |
475 namespace { |
474 |
476 |
475 class InitModelJob : public QScriptDebuggerCommandSchedulerJob |
477 class InitModelJob : public QScriptDebuggerCommandSchedulerJob |
476 { |
478 { |
477 public: |
479 public: |
478 InitModelJob(QScriptDebuggerLocalsModelPrivate *model, |
480 InitModelJob(QScriptDebuggerLocalsModel *model, |
479 int frameIndex, |
481 int frameIndex, |
480 QScriptDebuggerCommandSchedulerInterface *scheduler) |
482 QScriptDebuggerCommandSchedulerInterface *scheduler) |
481 : QScriptDebuggerCommandSchedulerJob(scheduler), |
483 : QScriptDebuggerCommandSchedulerJob(scheduler), |
482 m_model(model), m_frameIndex(frameIndex), m_state(0) |
484 m_model(model), m_frameIndex(frameIndex), m_state(0) |
483 { } |
485 { } |
484 |
486 |
485 void start() |
487 void start() |
486 { |
488 { |
|
489 if (!m_model) { |
|
490 // Model has been deleted. |
|
491 finish(); |
|
492 return; |
|
493 } |
487 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
494 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
488 frontend.scheduleGetScopeChain(m_frameIndex); |
495 frontend.scheduleGetScopeChain(m_frameIndex); |
489 } |
496 } |
490 |
497 |
491 void handleResponse(const QScriptDebuggerResponse &response, |
498 void handleResponse(const QScriptDebuggerResponse &response, |
492 int) |
499 int) |
493 { |
500 { |
|
501 if (!m_model) { |
|
502 // Model has been deleted. |
|
503 finish(); |
|
504 return; |
|
505 } |
494 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
506 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
|
507 QScriptDebuggerLocalsModelPrivate *model_d = QScriptDebuggerLocalsModelPrivate::get(m_model); |
495 switch (m_state) { |
508 switch (m_state) { |
496 case 0: { |
509 case 0: { |
497 QScriptDebuggerValueList scopeChain = response.resultAsScriptValueList(); |
510 QScriptDebuggerValueList scopeChain = response.resultAsScriptValueList(); |
498 for (int i = 0; i < scopeChain.size(); ++i) { |
511 for (int i = 0; i < scopeChain.size(); ++i) { |
499 const QScriptDebuggerValue &scopeObject = scopeChain.at(i); |
512 const QScriptDebuggerValue &scopeObject = scopeChain.at(i); |
500 QString name = QString::fromLatin1("Scope"); |
513 QString name = QString::fromLatin1("Scope"); |
501 if (i > 0) |
514 if (i > 0) |
502 name.append(QString::fromLatin1(" (%0)").arg(i)); |
515 name.append(QString::fromLatin1(" (%0)").arg(i)); |
503 QModelIndex index = m_model->addTopLevelObject(name, scopeObject); |
516 QModelIndex index = model_d->addTopLevelObject(name, scopeObject); |
504 if (i == 0) |
517 if (i == 0) |
505 m_model->emitScopeObjectAvailable(index); |
518 model_d->emitScopeObjectAvailable(index); |
506 } |
519 } |
507 frontend.scheduleGetThisObject(m_frameIndex); |
520 frontend.scheduleGetThisObject(m_frameIndex); |
508 ++m_state; |
521 ++m_state; |
509 } break; |
522 } break; |
510 case 1: { |
523 case 1: { |
511 QScriptDebuggerValue thisObject = response.resultAsScriptValue(); |
524 QScriptDebuggerValue thisObject = response.resultAsScriptValue(); |
512 m_model->addTopLevelObject(QLatin1String("this"), thisObject); |
525 model_d->addTopLevelObject(QLatin1String("this"), thisObject); |
513 finish(); |
526 finish(); |
514 } break; |
527 } break; |
515 } |
528 } |
516 } |
529 } |
517 |
530 |
518 private: |
531 private: |
519 QScriptDebuggerLocalsModelPrivate *m_model; |
532 QPointer<QScriptDebuggerLocalsModel> m_model; |
520 int m_frameIndex; |
533 int m_frameIndex; |
521 int m_state; |
534 int m_state; |
522 }; |
535 }; |
523 |
536 |
524 } // namespace |
537 } // namespace |
525 |
538 |
526 void QScriptDebuggerLocalsModel::init(int frameIndex) |
539 void QScriptDebuggerLocalsModel::init(int frameIndex) |
527 { |
540 { |
528 Q_D(QScriptDebuggerLocalsModel); |
541 Q_D(QScriptDebuggerLocalsModel); |
529 d->frameIndex = frameIndex; |
542 d->frameIndex = frameIndex; |
530 QScriptDebuggerJob *job = new InitModelJob(d, frameIndex, d->commandScheduler); |
543 QScriptDebuggerJob *job = new InitModelJob(this, frameIndex, d->commandScheduler); |
531 d->jobScheduler->scheduleJob(job); |
544 d->jobScheduler->scheduleJob(job); |
532 } |
545 } |
533 |
546 |
534 namespace { |
547 namespace { |
535 |
548 |
536 class SyncModelJob : public QScriptDebuggerCommandSchedulerJob |
549 class SyncModelJob : public QScriptDebuggerCommandSchedulerJob |
537 { |
550 { |
538 public: |
551 public: |
539 SyncModelJob(QScriptDebuggerLocalsModelPrivate *model, |
552 SyncModelJob(QScriptDebuggerLocalsModel *model, |
540 int frameIndex, |
553 int frameIndex, |
541 QScriptDebuggerCommandSchedulerInterface *scheduler) |
554 QScriptDebuggerCommandSchedulerInterface *scheduler) |
542 : QScriptDebuggerCommandSchedulerJob(scheduler), |
555 : QScriptDebuggerCommandSchedulerJob(scheduler), |
543 m_model(model), m_frameIndex(frameIndex), m_state(0) |
556 m_model(model), m_frameIndex(frameIndex), m_state(0) |
544 { } |
557 { } |
545 |
558 |
546 void start() |
559 void start() |
547 { |
560 { |
|
561 if (!m_model) { |
|
562 // Model has been deleted. |
|
563 finish(); |
|
564 return; |
|
565 } |
548 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
566 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
549 frontend.scheduleGetScopeChain(m_frameIndex); |
567 frontend.scheduleGetScopeChain(m_frameIndex); |
550 } |
568 } |
551 |
569 |
552 void handleResponse(const QScriptDebuggerResponse &response, |
570 void handleResponse(const QScriptDebuggerResponse &response, |
553 int) |
571 int) |
554 { |
572 { |
|
573 if (!m_model) { |
|
574 // Model has been deleted. |
|
575 finish(); |
|
576 return; |
|
577 } |
555 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
578 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); |
556 switch (m_state) { |
579 switch (m_state) { |
557 case 0: { |
580 case 0: { |
558 QScriptDebuggerValueList scopeChain = response.resultAsScriptValueList(); |
581 QScriptDebuggerValueList scopeChain = response.resultAsScriptValueList(); |
559 m_topLevelObjects << scopeChain; |
582 m_topLevelObjects << scopeChain; |
560 frontend.scheduleGetThisObject(m_frameIndex); |
583 frontend.scheduleGetThisObject(m_frameIndex); |
561 ++m_state; |
584 ++m_state; |
562 } break; |
585 } break; |
563 case 1: { |
586 case 1: { |
|
587 QScriptDebuggerLocalsModelPrivate *model_d = QScriptDebuggerLocalsModelPrivate::get(m_model); |
564 QScriptDebuggerValue thisObject = response.resultAsScriptValue(); |
588 QScriptDebuggerValue thisObject = response.resultAsScriptValue(); |
565 m_topLevelObjects.append(thisObject); |
589 m_topLevelObjects.append(thisObject); |
566 bool equal = (m_topLevelObjects.size() == m_model->invisibleRootNode->children.size()); |
590 bool equal = (m_topLevelObjects.size() == model_d->invisibleRootNode->children.size()); |
567 for (int i = 0; equal && (i < m_topLevelObjects.size()); ++i) { |
591 for (int i = 0; equal && (i < m_topLevelObjects.size()); ++i) { |
568 const QScriptDebuggerValue &object = m_topLevelObjects.at(i); |
592 const QScriptDebuggerValue &object = m_topLevelObjects.at(i); |
569 equal = (object == m_model->invisibleRootNode->children.at(i)->property.value()); |
593 equal = (object == model_d->invisibleRootNode->children.at(i)->property.value()); |
570 } |
594 } |
571 if (!equal) { |
595 if (!equal) { |
572 // the scope chain and/or this-object changed, so invalidate the model. |
596 // the scope chain and/or this-object changed, so invalidate the model. |
573 // we could try to be more clever, i.e. figure out |
597 // we could try to be more clever, i.e. figure out |
574 // exactly which objects were popped/pushed |
598 // exactly which objects were popped/pushed |
575 m_model->removeTopLevelNodes(); |
599 model_d->removeTopLevelNodes(); |
576 for (int j = 0; j < m_topLevelObjects.size(); ++j) { |
600 for (int j = 0; j < m_topLevelObjects.size(); ++j) { |
577 const QScriptDebuggerValue &object = m_topLevelObjects.at(j); |
601 const QScriptDebuggerValue &object = m_topLevelObjects.at(j); |
578 QString name; |
602 QString name; |
579 if (j == m_topLevelObjects.size()-1) { |
603 if (j == m_topLevelObjects.size()-1) { |
580 name = QString::fromLatin1("this"); |
604 name = QString::fromLatin1("this"); |
581 } else { |
605 } else { |
582 name = QString::fromLatin1("Scope"); |
606 name = QString::fromLatin1("Scope"); |
583 if (j > 0) |
607 if (j > 0) |
584 name.append(QString::fromLatin1(" (%0)").arg(j)); |
608 name.append(QString::fromLatin1(" (%0)").arg(j)); |
585 } |
609 } |
586 QModelIndex index = m_model->addTopLevelObject(name, object); |
610 QModelIndex index = model_d->addTopLevelObject(name, object); |
587 if (j == 0) |
611 if (j == 0) |
588 m_model->emitScopeObjectAvailable(index); |
612 model_d->emitScopeObjectAvailable(index); |
589 } |
613 } |
590 } else { |
614 } else { |
591 m_model->syncTopLevelNodes(); |
615 model_d->syncTopLevelNodes(); |
592 } |
616 } |
593 finish(); |
617 finish(); |
594 } break; |
618 } break; |
595 } |
619 } |
596 } |
620 } |
597 |
621 |
598 private: |
622 private: |
599 QScriptDebuggerLocalsModelPrivate *m_model; |
623 QPointer<QScriptDebuggerLocalsModel> m_model; |
600 int m_frameIndex; |
624 int m_frameIndex; |
601 int m_state; |
625 int m_state; |
602 QScriptDebuggerValueList m_topLevelObjects; |
626 QScriptDebuggerValueList m_topLevelObjects; |
603 }; |
627 }; |
604 |
628 |