src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    52 
    52 
    53 #include "private/qabstractitemmodel_p.h"
    53 #include "private/qabstractitemmodel_p.h"
    54 
    54 
    55 #include <QtCore/qdebug.h>
    55 #include <QtCore/qdebug.h>
    56 #include <QtCore/qcoreapplication.h>
    56 #include <QtCore/qcoreapplication.h>
       
    57 #include <QtCore/qpointer.h>
    57 #include <QtGui/qbrush.h>
    58 #include <QtGui/qbrush.h>
    58 #include <QtGui/qfont.h>
    59 #include <QtGui/qfont.h>
    59 
    60 
    60 Q_DECLARE_METATYPE(QScriptDebuggerObjectSnapshotDelta)
    61 Q_DECLARE_METATYPE(QScriptDebuggerObjectSnapshotDelta)
    61 
    62 
   368 
   369 
   369     void start()
   370     void start()
   370     {
   371     {
   371         if (!m_index.isValid()) {
   372         if (!m_index.isValid()) {
   372             // nothing to do, the node has been removed
   373             // nothing to do, the node has been removed
       
   374             finish();
   373             return;
   375             return;
   374         }
   376         }
   375         QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
   377         QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
   376         frontend.scheduleNewScriptObjectSnapshot();
   378         frontend.scheduleNewScriptObjectSnapshot();
   377     }
   379     }
   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 
   606 
   630 
   607 void QScriptDebuggerLocalsModel::sync(int frameIndex)
   631 void QScriptDebuggerLocalsModel::sync(int frameIndex)
   608 {
   632 {
   609     Q_D(QScriptDebuggerLocalsModel);
   633     Q_D(QScriptDebuggerLocalsModel);
   610     d->frameIndex = frameIndex;
   634     d->frameIndex = frameIndex;
   611     QScriptDebuggerJob *job = new SyncModelJob(d, frameIndex, d->commandScheduler);
   635     QScriptDebuggerJob *job = new SyncModelJob(this, frameIndex, d->commandScheduler);
   612     d->jobScheduler->scheduleJob(job);
   636     d->jobScheduler->scheduleJob(job);
   613 }
   637 }
   614 
   638 
   615 namespace {
   639 namespace {
   616 
   640 
   634 
   658 
   635     void start()
   659     void start()
   636     {
   660     {
   637         if (!m_index.isValid()) {
   661         if (!m_index.isValid()) {
   638             // nothing to do, the node has been removed
   662             // nothing to do, the node has been removed
       
   663             finish();
   639             return;
   664             return;
   640         }
   665         }
   641         QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
   666         QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
   642         QScriptDebuggerLocalsModelNode *node = model()->nodeFromIndex(m_index);
   667         QScriptDebuggerLocalsModelNode *node = model()->nodeFromIndex(m_index);
   643         frontend.scheduleScriptObjectSnapshotCapture(node->snapshotId, node->property.value());
   668         frontend.scheduleScriptObjectSnapshotCapture(node->snapshotId, node->property.value());