2010-06-09 16:13:47 +02:00
/**************************************************************************
* *
* * This file is part of Qt Creator
* *
* * Copyright ( c ) 2009 Nokia Corporation and / or its subsidiary ( - ies ) .
* *
2011-04-13 08:42:33 +02:00
* * Contact : Nokia Corporation ( info @ qt . nokia . com )
2010-06-09 16:13:47 +02:00
* *
* *
* * GNU Lesser General Public License Usage
* *
2011-04-13 08:42:33 +02:00
* * This file may be used under the terms of the GNU Lesser General Public
* * License version 2.1 as published by the Free Software Foundation and
* * appearing in the file LICENSE . LGPL included in the packaging of this file .
* * Please review the following information to ensure the GNU Lesser General
* * Public License version 2.1 requirements will be met :
* * http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
2010-06-09 16:13:47 +02:00
* *
2010-12-17 16:01:08 +01:00
* * In addition , as a special exception , Nokia gives you certain additional
2011-04-13 08:42:33 +02:00
* * rights . These rights are described in the Nokia Qt LGPL Exception
2010-12-17 16:01:08 +01:00
* * version 1.1 , included in the file LGPL_EXCEPTION . txt in this package .
* *
2011-04-13 08:42:33 +02:00
* * Other Usage
* *
* * Alternatively , this file may be used in accordance with the terms and
* * conditions contained in a signed written agreement between you and Nokia .
* *
2010-12-17 16:01:08 +01:00
* * If you have questions regarding the use of this file , please contact
2011-05-06 15:05:37 +02:00
* * Nokia at info @ qt . nokia . com .
2010-06-09 16:13:47 +02:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "qmlengine.h"
2010-08-13 14:18:10 +02:00
# include "qmladapter.h"
2010-06-09 16:13:47 +02:00
2011-01-10 10:14:23 +01:00
# include "debuggerstartparameters.h"
2010-09-28 17:26:27 +02:00
# include "debuggeractions.h"
2010-06-16 11:08:54 +02:00
# include "debuggerconstants.h"
2010-11-10 16:33:11 +01:00
# include "debuggercore.h"
2010-06-09 16:13:47 +02:00
# include "debuggerdialogs.h"
2010-12-02 17:43:14 +01:00
# include "debuggermainwindow.h"
2010-11-10 16:33:11 +01:00
# include "debuggerrunner.h"
2010-06-16 11:08:54 +02:00
# include "debuggerstringutils.h"
2011-02-11 15:00:13 +01:00
# include "debuggertooltipmanager.h"
2010-06-16 11:08:54 +02:00
2010-06-09 16:13:47 +02:00
# include "breakhandler.h"
# include "moduleshandler.h"
# include "registerhandler.h"
# include "stackhandler.h"
# include "watchhandler.h"
# include "watchutils.h"
2010-08-13 14:18:10 +02:00
# include <extensionsystem/pluginmanager.h>
2010-09-13 13:30:35 +02:00
# include <projectexplorer/applicationlauncher.h>
2010-07-01 11:48:43 +02:00
2010-09-23 10:35:23 +02:00
# include <utils/environment.h>
2010-06-09 16:13:47 +02:00
# include <utils/qtcassert.h>
2011-02-25 11:57:34 +01:00
# include <utils/fileinprojectfinder.h>
2010-06-09 16:13:47 +02:00
2011-02-21 17:01:40 +01:00
# include <coreplugin/icore.h>
2011-02-16 14:35:26 +01:00
# include <coreplugin/helpmanager.h>
2010-06-09 16:13:47 +02:00
# include <QtCore/QDateTime>
# include <QtCore/QDebug>
# include <QtCore/QDir>
# include <QtCore/QFileInfo>
# include <QtCore/QTimer>
# include <QtGui/QAction>
# include <QtGui/QApplication>
# include <QtGui/QMainWindow>
# include <QtGui/QMessageBox>
# include <QtGui/QToolTip>
2010-07-23 18:40:12 +02:00
# include <QtGui/QTextDocument>
2010-06-09 16:13:47 +02:00
# include <QtNetwork/QTcpSocket>
2010-07-01 11:48:43 +02:00
# include <QtNetwork/QHostAddress>
2010-06-09 16:13:47 +02:00
# define DEBUG_QML 1
# if DEBUG_QML
# define SDEBUG(s) qDebug() << s
# else
# define SDEBUG(s)
# endif
# define XSDEBUG(s) qDebug() << s
2011-01-12 14:26:50 +01:00
using namespace ProjectExplorer ;
2010-06-09 16:13:47 +02:00
namespace Debugger {
namespace Internal {
2010-10-28 12:18:38 +02:00
struct JSAgentBreakpointData
{
QByteArray functionName ;
2011-02-25 11:57:34 +01:00
QByteArray fileUrl ;
qint32 lineNumber ;
} ;
struct JSAgentStackData
{
QByteArray functionName ;
QByteArray fileUrl ;
2010-10-28 12:18:38 +02:00
qint32 lineNumber ;
} ;
uint qHash ( const JSAgentBreakpointData & b )
{
2011-02-25 11:57:34 +01:00
return b . lineNumber ^ qHash ( b . fileUrl ) ;
2010-10-28 12:18:38 +02:00
}
QDataStream & operator < < ( QDataStream & s , const JSAgentBreakpointData & data )
{
2011-02-25 11:57:34 +01:00
return s < < data . functionName < < data . fileUrl < < data . lineNumber ;
}
QDataStream & operator < < ( QDataStream & s , const JSAgentStackData & data )
{
return s < < data . functionName < < data . fileUrl < < data . lineNumber ;
2010-10-28 12:18:38 +02:00
}
QDataStream & operator > > ( QDataStream & s , JSAgentBreakpointData & data )
{
2011-02-25 11:57:34 +01:00
return s > > data . functionName > > data . fileUrl > > data . lineNumber ;
}
QDataStream & operator > > ( QDataStream & s , JSAgentStackData & data )
{
return s > > data . functionName > > data . fileUrl > > data . lineNumber ;
2010-10-28 12:18:38 +02:00
}
bool operator = = ( const JSAgentBreakpointData & b1 , const JSAgentBreakpointData & b2 )
{
2011-02-25 11:57:34 +01:00
return b1 . lineNumber = = b2 . lineNumber & & b1 . fileUrl = = b2 . fileUrl ;
2010-10-28 12:18:38 +02:00
}
typedef QSet < JSAgentBreakpointData > JSAgentBreakpoints ;
2011-02-25 11:57:34 +01:00
typedef QList < JSAgentStackData > JSAgentStackFrames ;
2010-10-28 12:18:38 +02:00
2010-11-08 14:18:37 +01:00
static QDataStream & operator > > ( QDataStream & s , WatchData & data )
2010-07-22 13:00:26 +02:00
{
data = WatchData ( ) ;
2010-10-27 16:56:04 +02:00
QByteArray name ;
QByteArray value ;
QByteArray type ;
bool hasChildren = false ;
s > > data . exp > > name > > value > > type > > hasChildren > > data . id ;
data . name = QString : : fromUtf8 ( name ) ;
data . setType ( type , false ) ;
data . setValue ( QString : : fromUtf8 ( value ) ) ;
2010-07-22 13:00:26 +02:00
data . setHasChildren ( hasChildren ) ;
2010-07-22 14:58:37 +02:00
data . setAllUnneeded ( ) ;
2010-07-22 13:00:26 +02:00
return s ;
}
2010-11-22 10:20:31 +01:00
class QmlEnginePrivate
{
2010-11-15 17:09:28 +01:00
public :
2010-09-13 13:30:35 +02:00
explicit QmlEnginePrivate ( QmlEngine * q ) ;
2010-11-15 17:09:28 +01:00
private :
2010-12-03 12:07:32 +01:00
friend class QmlEngine ;
2010-09-13 13:30:35 +02:00
int m_ping ;
2011-01-12 14:26:50 +01:00
QmlAdapter m_adapter ;
ApplicationLauncher m_applicationLauncher ;
2011-02-25 11:57:34 +01:00
Utils : : FileInProjectFinder fileFinder ;
2010-09-13 13:30:35 +02:00
} ;
2010-11-22 10:20:31 +01:00
QmlEnginePrivate : : QmlEnginePrivate ( QmlEngine * q )
2011-01-12 14:26:50 +01:00
: m_ping ( 0 ) , m_adapter ( q )
2010-11-22 10:20:31 +01:00
{ }
2010-09-13 13:30:35 +02:00
2010-06-09 16:13:47 +02:00
///////////////////////////////////////////////////////////////////////
//
// QmlEngine
//
///////////////////////////////////////////////////////////////////////
2011-01-12 12:10:12 +01:00
QmlEngine : : QmlEngine ( const DebuggerStartParameters & startParameters ,
DebuggerEngine * masterEngine )
: DebuggerEngine ( startParameters , masterEngine ) ,
d ( new QmlEnginePrivate ( this ) )
2010-06-09 16:13:47 +02:00
{
2010-08-24 15:35:46 +02:00
setObjectName ( QLatin1String ( " QmlEngine " ) ) ;
2010-06-09 16:13:47 +02:00
}
QmlEngine : : ~ QmlEngine ( )
2011-07-06 19:07:38 +02:00
{
delete d ;
}
2010-08-18 13:54:12 +02:00
2010-07-09 17:07:59 +02:00
void QmlEngine : : setupInferior ( )
2010-06-09 16:13:47 +02:00
{
2010-07-09 17:07:59 +02:00
QTC_ASSERT ( state ( ) = = InferiorSetupRequested , qDebug ( ) < < state ( ) ) ;
2010-08-13 14:18:10 +02:00
2010-09-16 17:08:07 +02:00
if ( startParameters ( ) . startMode = = AttachToRemote ) {
2011-02-11 16:02:41 +01:00
emit requestRemoteSetup ( ) ;
2010-09-16 17:08:07 +02:00
} else {
2011-01-12 14:26:50 +01:00
connect ( & d - > m_applicationLauncher ,
SIGNAL ( processExited ( int ) ) ,
SLOT ( disconnected ( ) ) ) ;
connect ( & d - > m_applicationLauncher ,
2011-04-15 12:59:44 +02:00
SIGNAL ( appendMessage ( QString , Utils : : OutputFormat ) ) ,
SLOT ( appendMessage ( QString , Utils : : OutputFormat ) ) ) ;
2011-01-12 14:26:50 +01:00
connect ( & d - > m_applicationLauncher ,
SIGNAL ( bringToForegroundRequested ( qint64 ) ) ,
runControl ( ) ,
2011-01-14 14:25:02 +01:00
SLOT ( bringApplicationToForeground ( qint64 ) ) ) ;
2010-09-16 17:08:07 +02:00
d - > m_applicationLauncher . setEnvironment ( startParameters ( ) . environment ) ;
d - > m_applicationLauncher . setWorkingDirectory ( startParameters ( ) . workingDirectory ) ;
notifyInferiorSetupOk ( ) ;
}
2010-07-09 17:07:59 +02:00
}
2010-07-05 11:28:38 +02:00
2011-04-15 12:59:44 +02:00
void QmlEngine : : appendMessage ( const QString & msg , Utils : : OutputFormat /* format */ )
2010-12-03 16:18:50 +01:00
{
2011-02-21 17:01:40 +01:00
showMessage ( msg , AppOutput ) ; // FIXME: Redirect to RunControl
2010-12-03 16:18:50 +01:00
}
2010-08-13 14:18:10 +02:00
void QmlEngine : : connectionEstablished ( )
{
attemptBreakpointSynchronization ( ) ;
2010-11-10 11:39:01 +01:00
ExtensionSystem : : PluginManager * pluginManager =
ExtensionSystem : : PluginManager : : instance ( ) ;
2011-01-12 14:26:50 +01:00
pluginManager - > addObject ( & d - > m_adapter ) ;
2010-09-08 16:44:42 +02:00
pluginManager - > addObject ( this ) ;
2010-08-13 14:18:10 +02:00
2010-11-10 11:39:01 +01:00
showMessage ( tr ( " QML Debugger connected. " ) , StatusBar ) ;
2010-08-13 14:18:10 +02:00
2011-04-21 12:25:06 +02:00
if ( ! watchHandler ( ) - > watcherNames ( ) . isEmpty ( ) ) {
synchronizeWatchers ( ) ;
}
connect ( watchersModel ( ) , SIGNAL ( layoutChanged ( ) ) , this , SLOT ( synchronizeWatchers ( ) ) ) ;
2011-02-23 16:09:56 +01:00
2010-08-13 14:18:10 +02:00
notifyEngineRunAndInferiorRunOk ( ) ;
2010-11-15 17:09:28 +01:00
2010-08-13 14:18:10 +02:00
}
void QmlEngine : : connectionStartupFailed ( )
{
2011-02-24 10:03:44 +01:00
Core : : ICore * const core = Core : : ICore : : instance ( ) ;
QMessageBox * infoBox = new QMessageBox ( core - > mainWindow ( ) ) ;
infoBox - > setIcon ( QMessageBox : : Critical ) ;
infoBox - > setWindowTitle ( tr ( " Qt Creator " ) ) ;
infoBox - > setText ( tr ( " Could not connect to the in-process QML debugger. \n "
" Do you want to retry? " ) ) ;
infoBox - > setStandardButtons ( QMessageBox : : Retry | QMessageBox : : Cancel | QMessageBox : : Help ) ;
infoBox - > setDefaultButton ( QMessageBox : : Retry ) ;
infoBox - > setModal ( true ) ;
connect ( infoBox , SIGNAL ( finished ( int ) ) ,
this , SLOT ( retryMessageBoxFinished ( int ) ) ) ;
infoBox - > show ( ) ;
}
void QmlEngine : : retryMessageBoxFinished ( int result )
{
switch ( result ) {
2011-02-16 14:35:26 +01:00
case QMessageBox : : Retry : {
d - > m_adapter . beginConnection ( ) ;
break ;
}
case QMessageBox : : Help : {
Core : : HelpManager * helpManager = Core : : HelpManager : : instance ( ) ;
helpManager - > handleHelpRequest ( " qthelp://com.nokia.qtcreator/doc/creator-debugging-qml.html " ) ;
2011-02-24 10:03:44 +01:00
// fall through
2011-02-16 14:35:26 +01:00
}
default :
notifyEngineRunFailed ( ) ;
2011-02-16 14:37:37 +01:00
break ;
2011-02-16 14:35:26 +01:00
}
2010-08-13 14:18:10 +02:00
}
2010-08-27 13:11:55 +02:00
void QmlEngine : : connectionError ( QAbstractSocket : : SocketError socketError )
2010-08-13 14:18:10 +02:00
{
2011-01-12 14:26:50 +01:00
if ( socketError = = QAbstractSocket : : RemoteHostClosedError )
2010-11-10 11:39:01 +01:00
showMessage ( tr ( " QML Debugger: Remote host closed connection. " ) , StatusBar ) ;
2010-08-13 14:18:10 +02:00
}
2010-09-30 14:05:20 +02:00
void QmlEngine : : serviceConnectionError ( const QString & serviceName )
{
2010-11-10 11:39:01 +01:00
showMessage ( tr ( " QML Debugger: Could not connect to service '%1'. " )
. arg ( serviceName ) , StatusBar ) ;
2010-09-30 14:05:20 +02:00
}
2011-01-24 16:58:35 +01:00
bool QmlEngine : : canDisplayTooltip ( ) const
{
return state ( ) = = InferiorRunOk | | state ( ) = = InferiorStopOk ;
}
2011-02-21 17:01:40 +01:00
void QmlEngine : : filterApplicationMessage ( const QString & msg , int /*channel*/ )
{
2011-03-02 12:01:34 +01:00
static const QString qddserver = QLatin1String ( " QDeclarativeDebugServer: " ) ;
2011-05-11 12:48:14 +02:00
static const QString cannotRetrieveDebuggingOutput = ApplicationLauncher : : msgWinCannotRetrieveDebuggingOutput ( ) ;
2011-02-21 17:01:40 +01:00
2011-03-01 16:45:41 +01:00
const int index = msg . indexOf ( qddserver ) ;
2011-02-21 17:01:40 +01:00
if ( index ! = - 1 ) {
QString status = msg ;
status . remove ( 0 , index + qddserver . length ( ) ) ; // chop of 'QDeclarativeDebugServer: '
2011-03-23 16:02:22 +00:00
static QString waitingForConnection = QLatin1String ( " Waiting for connection " ) ;
static QString unableToListen = QLatin1String ( " Unable to listen " ) ;
static QString debuggingNotEnabled = QLatin1String ( " Ignoring \" -qmljsdebugger= " ) ;
2011-04-21 15:59:05 +02:00
static QString debuggingNotEnabled2 = QLatin1String ( " Ignoring \" -qmljsdebugger= " ) ; // There is (was?) a bug in one of the error strings - safest to handle both
2011-02-21 17:01:40 +01:00
static QString connectionEstablished = QLatin1String ( " Connection established " ) ;
QString errorMessage ;
if ( status . startsWith ( waitingForConnection ) ) {
d - > m_adapter . beginConnection ( ) ;
} else if ( status . startsWith ( unableToListen ) ) {
2011-02-24 10:03:44 +01:00
//: Error message shown after 'Could not connect ... debugger:"
2011-02-21 17:01:40 +01:00
errorMessage = tr ( " The port seems to be in use. " ) ;
2011-04-21 15:59:05 +02:00
} else if ( status . startsWith ( debuggingNotEnabled ) | | status . startsWith ( debuggingNotEnabled2 ) ) {
2011-02-24 10:03:44 +01:00
//: Error message shown after 'Could not connect ... debugger:"
errorMessage = tr ( " The application is not set up for QML/JS debugging. " ) ;
2011-02-21 17:01:40 +01:00
} else if ( status . startsWith ( connectionEstablished ) ) {
// nothing to do
} else {
qWarning ( ) < < " Unknown QDeclarativeDebugServer status message: " < < status ;
}
if ( ! errorMessage . isEmpty ( ) ) {
notifyEngineRunFailed ( ) ;
Core : : ICore * const core = Core : : ICore : : instance ( ) ;
QMessageBox * infoBox = new QMessageBox ( core - > mainWindow ( ) ) ;
infoBox - > setIcon ( QMessageBox : : Critical ) ;
infoBox - > setWindowTitle ( tr ( " Qt Creator " ) ) ;
2011-03-02 12:01:34 +01:00
//: %1 is detailed error message
infoBox - > setText ( tr ( " Could not connect to the in-process QML debugger: \n %1 " )
2011-02-21 17:01:40 +01:00
. arg ( errorMessage ) ) ;
infoBox - > setStandardButtons ( QMessageBox : : Ok | QMessageBox : : Help ) ;
infoBox - > setDefaultButton ( QMessageBox : : Ok ) ;
infoBox - > setModal ( true ) ;
connect ( infoBox , SIGNAL ( finished ( int ) ) ,
2011-02-24 10:03:44 +01:00
this , SLOT ( wrongSetupMessageBoxFinished ( int ) ) ) ;
2011-02-21 17:01:40 +01:00
infoBox - > show ( ) ;
}
2011-03-02 12:01:34 +01:00
} else if ( msg . contains ( cannotRetrieveDebuggingOutput ) ) {
2011-02-21 17:01:40 +01:00
// we won't get debugging output, so just try to connect ...
d - > m_adapter . beginConnection ( ) ;
}
}
void QmlEngine : : showMessage ( const QString & msg , int channel , int timeout ) const
{
if ( channel = = AppOutput | | channel = = AppError ) {
const_cast < QmlEngine * > ( this ) - > filterApplicationMessage ( msg , channel ) ;
}
DebuggerEngine : : showMessage ( msg , channel , timeout ) ;
}
2011-02-28 10:58:21 +01:00
bool QmlEngine : : acceptsWatchesWhileRunning ( ) const
{
return true ;
}
2010-11-15 17:09:28 +01:00
void QmlEngine : : closeConnection ( )
{
2011-04-21 12:25:06 +02:00
disconnect ( watchersModel ( ) , SIGNAL ( layoutChanged ( ) ) , this , SLOT ( synchronizeWatchers ( ) ) ) ;
2011-02-08 16:10:28 +01:00
disconnect ( & d - > m_adapter , SIGNAL ( connectionStartupFailed ( ) ) ,
this , SLOT ( connectionStartupFailed ( ) ) ) ;
d - > m_adapter . closeConnection ( ) ;
2011-01-12 14:26:50 +01:00
ExtensionSystem : : PluginManager * pluginManager =
ExtensionSystem : : PluginManager : : instance ( ) ;
2010-11-15 17:09:28 +01:00
2011-02-08 16:10:28 +01:00
if ( pluginManager - > allObjects ( ) . contains ( this ) ) {
2011-01-12 14:26:50 +01:00
pluginManager - > removeObject ( & d - > m_adapter ) ;
2010-11-15 17:09:28 +01:00
pluginManager - > removeObject ( this ) ;
}
}
2010-07-09 17:07:59 +02:00
void QmlEngine : : runEngine ( )
{
QTC_ASSERT ( state ( ) = = EngineRunRequested , qDebug ( ) < < state ( ) ) ;
2010-08-13 14:18:10 +02:00
2011-04-21 15:59:05 +02:00
if ( ! isSlaveEngine ( ) & & startParameters ( ) . startMode ! = AttachToRemote )
2010-11-15 17:09:28 +01:00
startApplicationLauncher ( ) ;
}
void QmlEngine : : startApplicationLauncher ( )
{
if ( ! d - > m_applicationLauncher . isRunning ( ) ) {
2011-03-30 13:14:30 +02:00
appendMessage ( tr ( " Starting %1 %2 " ) . arg (
QDir : : toNativeSeparators ( startParameters ( ) . executable ) ,
startParameters ( ) . processArgs )
+ QLatin1Char ( ' \n ' )
2011-04-15 12:59:44 +02:00
, Utils : : NormalMessageFormat ) ;
2011-01-12 14:26:50 +01:00
d - > m_applicationLauncher . start ( ApplicationLauncher : : Gui ,
2010-08-18 13:54:12 +02:00
startParameters ( ) . executable ,
startParameters ( ) . processArgs ) ;
}
2010-11-15 17:09:28 +01:00
}
2010-08-13 14:18:10 +02:00
2010-11-15 17:09:28 +01:00
void QmlEngine : : stopApplicationLauncher ( )
{
if ( d - > m_applicationLauncher . isRunning ( ) ) {
disconnect ( & d - > m_applicationLauncher , SIGNAL ( processExited ( int ) ) , this , SLOT ( disconnected ( ) ) ) ;
d - > m_applicationLauncher . stop ( ) ;
}
2010-08-18 13:54:12 +02:00
}
2011-02-11 16:02:41 +01:00
void QmlEngine : : handleRemoteSetupDone ( int gdbServerPort , int qmlPort )
2010-09-16 17:08:07 +02:00
{
2011-02-11 16:02:41 +01:00
Q_UNUSED ( gdbServerPort ) ;
if ( qmlPort ! = - 1 )
startParameters ( ) . qmlServerPort = qmlPort ;
2010-09-16 17:08:07 +02:00
notifyInferiorSetupOk ( ) ;
}
void QmlEngine : : handleRemoteSetupFailed ( const QString & message )
{
QMessageBox : : critical ( 0 , tr ( " Failed to start application " ) ,
tr ( " Application startup failed: %1 " ) . arg ( message ) ) ;
notifyInferiorSetupFailed ( ) ;
}
2010-07-09 17:07:59 +02:00
void QmlEngine : : shutdownInferior ( )
2010-06-09 16:13:47 +02:00
{
2010-11-15 17:09:28 +01:00
if ( isSlaveEngine ( ) ) {
resetLocation ( ) ;
2010-08-13 14:18:10 +02:00
}
2010-11-15 17:09:28 +01:00
stopApplicationLauncher ( ) ;
2010-07-09 17:07:59 +02:00
notifyInferiorShutdownOk ( ) ;
}
void QmlEngine : : shutdownEngine ( )
{
2010-11-15 17:09:28 +01:00
closeConnection ( ) ;
2010-08-13 14:18:10 +02:00
2010-11-15 17:09:28 +01:00
// double check (ill engine?):
stopApplicationLauncher ( ) ;
2010-08-13 14:18:10 +02:00
2010-08-10 14:42:44 +02:00
notifyEngineShutdownOk ( ) ;
2010-11-15 17:09:28 +01:00
if ( ! isSlaveEngine ( ) )
showMessage ( QString ( ) , StatusBar ) ;
2010-06-09 16:13:47 +02:00
}
2010-07-08 18:10:50 +02:00
void QmlEngine : : setupEngine ( )
2010-06-09 16:13:47 +02:00
{
2011-02-08 16:17:13 +01:00
d - > m_ping = 0 ;
2011-01-12 14:26:50 +01:00
connect ( & d - > m_adapter , SIGNAL ( connectionError ( QAbstractSocket : : SocketError ) ) ,
2010-10-27 15:23:30 +02:00
SLOT ( connectionError ( QAbstractSocket : : SocketError ) ) ) ;
2011-01-12 14:26:50 +01:00
connect ( & d - > m_adapter , SIGNAL ( serviceConnectionError ( QString ) ) ,
2010-10-27 15:23:30 +02:00
SLOT ( serviceConnectionError ( QString ) ) ) ;
2011-01-12 14:26:50 +01:00
connect ( & d - > m_adapter , SIGNAL ( connected ( ) ) ,
2010-10-27 15:23:30 +02:00
SLOT ( connectionEstablished ( ) ) ) ;
2011-01-12 14:26:50 +01:00
connect ( & d - > m_adapter , SIGNAL ( connectionStartupFailed ( ) ) ,
2010-10-27 15:23:30 +02:00
SLOT ( connectionStartupFailed ( ) ) ) ;
2010-08-13 14:18:10 +02:00
2010-07-09 08:48:33 +02:00
notifyEngineSetupOk ( ) ;
2010-07-01 11:48:43 +02:00
}
2010-06-09 16:13:47 +02:00
void QmlEngine : : continueInferior ( )
{
2010-07-13 08:41:27 +02:00
QTC_ASSERT ( state ( ) = = InferiorStopOk , qDebug ( ) < < state ( ) ) ;
2010-06-25 14:08:53 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " CONTINUE " ;
rs < < cmd ;
logMessage ( LogSend , cmd ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
2010-07-22 15:31:11 +02:00
resetLocation ( ) ;
2010-07-13 08:41:27 +02:00
notifyInferiorRunRequested ( ) ;
notifyInferiorRunOk ( ) ;
2010-06-09 16:13:47 +02:00
}
void QmlEngine : : interruptInferior ( )
{
2010-06-25 14:08:53 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " INTERRUPT " ;
rs < < cmd ;
logMessage ( LogSend , cmd ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
2010-08-04 17:13:17 +02:00
notifyInferiorStopOk ( ) ;
2010-06-09 16:13:47 +02:00
}
void QmlEngine : : executeStep ( )
{
2010-06-25 14:08:53 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " STEPINTO " ;
rs < < cmd ;
logMessage ( LogSend , cmd ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
2011-05-16 17:06:52 +02:00
resetLocation ( ) ;
2010-07-13 08:41:27 +02:00
notifyInferiorRunRequested ( ) ;
notifyInferiorRunOk ( ) ;
2010-06-09 16:13:47 +02:00
}
void QmlEngine : : executeStepI ( )
{
2010-06-25 14:08:53 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " STEPINTO " ;
rs < < cmd ;
logMessage ( LogSend , cmd ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
2011-05-16 17:06:52 +02:00
resetLocation ( ) ;
2010-07-13 08:41:27 +02:00
notifyInferiorRunRequested ( ) ;
notifyInferiorRunOk ( ) ;
2010-06-09 16:13:47 +02:00
}
void QmlEngine : : executeStepOut ( )
{
2010-06-25 14:08:53 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " STEPOUT " ;
rs < < cmd ;
logMessage ( LogSend , cmd ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
2011-05-16 17:06:52 +02:00
resetLocation ( ) ;
2010-07-13 08:41:27 +02:00
notifyInferiorRunRequested ( ) ;
notifyInferiorRunOk ( ) ;
2010-06-09 16:13:47 +02:00
}
void QmlEngine : : executeNext ( )
{
2010-06-25 14:08:53 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " STEPOVER " ;
rs < < cmd ;
logMessage ( LogSend , cmd ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
2011-05-16 17:06:52 +02:00
resetLocation ( ) ;
2010-07-13 08:41:27 +02:00
notifyInferiorRunRequested ( ) ;
notifyInferiorRunOk ( ) ;
2010-06-09 16:13:47 +02:00
}
void QmlEngine : : executeNextI ( )
{
2010-06-25 14:08:53 +02:00
SDEBUG ( " QmlEngine::executeNextI() " ) ;
2010-06-09 16:13:47 +02:00
}
2011-02-23 10:16:11 +01:00
void QmlEngine : : executeRunToLine ( const ContextData & data )
2010-06-09 16:13:47 +02:00
{
2011-02-23 10:16:11 +01:00
Q_UNUSED ( data )
2010-06-09 16:13:47 +02:00
SDEBUG ( " FIXME: QmlEngine::executeRunToLine() " ) ;
}
void QmlEngine : : executeRunToFunction ( const QString & functionName )
{
Q_UNUSED ( functionName )
XSDEBUG ( " FIXME: QmlEngine::executeRunToFunction() " ) ;
}
2011-02-23 10:16:11 +01:00
void QmlEngine : : executeJumpToLine ( const ContextData & data )
2010-06-09 16:13:47 +02:00
{
2011-02-23 10:16:11 +01:00
Q_UNUSED ( data )
2010-06-09 16:13:47 +02:00
XSDEBUG ( " FIXME: QmlEngine::executeJumpToLine() " ) ;
}
void QmlEngine : : activateFrame ( int index )
{
2010-07-22 15:22:46 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " ACTIVATE_FRAME " ;
rs < < cmd
< < index ;
logMessage ( LogSend , QString ( " %1 %2 " ) . arg ( QString ( cmd ) , QString : : number ( index ) ) ) ;
2010-07-22 15:22:46 +02:00
sendMessage ( reply ) ;
2010-12-16 19:06:33 +01:00
gotoLocation ( stackHandler ( ) - > frames ( ) . value ( index ) ) ;
2010-06-09 16:13:47 +02:00
}
void QmlEngine : : selectThread ( int index )
{
Q_UNUSED ( index )
}
void QmlEngine : : attemptBreakpointSynchronization ( )
{
2010-11-10 16:33:11 +01:00
BreakHandler * handler = breakHandler ( ) ;
2010-11-23 16:12:16 +01:00
2011-06-24 16:25:30 +02:00
foreach ( BreakpointModelId id , handler - > unclaimedBreakpointIds ( ) ) {
2010-11-23 16:12:16 +01:00
// Take ownership of the breakpoint. Requests insertion.
if ( acceptsBreakpoint ( id ) )
handler - > setEngine ( id , this ) ;
}
2010-11-10 16:33:11 +01:00
JSAgentBreakpoints breakpoints ;
2011-06-24 16:25:30 +02:00
foreach ( BreakpointModelId id , handler - > engineBreakpointIds ( this ) ) {
2010-11-30 11:35:17 +01:00
if ( handler - > state ( id ) = = BreakpointRemoveRequested ) {
handler - > notifyBreakpointRemoveProceeding ( id ) ;
handler - > notifyBreakpointRemoveOk ( id ) ;
} else {
if ( handler - > state ( id ) = = BreakpointInsertRequested ) {
handler - > notifyBreakpointInsertProceeding ( id ) ;
}
JSAgentBreakpointData bp ;
2011-02-25 11:57:34 +01:00
bp . fileUrl = QUrl : : fromLocalFile ( handler - > fileName ( id ) ) . toString ( ) . toUtf8 ( ) ;
2010-11-30 11:35:17 +01:00
bp . lineNumber = handler - > lineNumber ( id ) ;
bp . functionName = handler - > functionName ( id ) . toUtf8 ( ) ;
breakpoints . insert ( bp ) ;
if ( handler - > state ( id ) = = BreakpointInsertProceeding ) {
handler - > notifyBreakpointInsertOk ( id ) ;
}
}
2010-06-25 14:08:53 +02:00
}
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " BREAKPOINTS " ;
rs < < cmd
< < breakpoints ;
QStringList breakPointsStr ;
foreach ( const JSAgentBreakpointData & bp , breakpoints ) {
breakPointsStr < < QString ( " ('%1' '%2' %3) " ) . arg ( QString ( bp . functionName ) ,
2011-02-25 11:57:34 +01:00
QString ( bp . fileUrl ) , QString : : number ( bp . lineNumber ) ) ;
2010-12-17 10:18:34 +01:00
}
logMessage ( LogSend , QString ( " %1 [%2] " ) . arg ( QString ( cmd ) , breakPointsStr . join ( " , " ) ) ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
2010-06-09 16:13:47 +02:00
}
2011-06-24 16:25:30 +02:00
bool QmlEngine : : acceptsBreakpoint ( BreakpointModelId id ) const
2010-10-05 11:01:14 +02:00
{
2010-11-26 13:06:03 +01:00
return ! DebuggerEngine : : isCppBreakpoint ( breakHandler ( ) - > breakpointData ( id ) ) ;
2010-10-05 11:01:14 +02:00
}
2010-06-09 16:13:47 +02:00
void QmlEngine : : loadSymbols ( const QString & moduleName )
{
Q_UNUSED ( moduleName )
}
void QmlEngine : : loadAllSymbols ( )
{
}
void QmlEngine : : reloadModules ( )
{
}
void QmlEngine : : requestModuleSymbols ( const QString & moduleName )
{
Q_UNUSED ( moduleName )
}
//////////////////////////////////////////////////////////////////////
//
// Tooltip specific stuff
//
//////////////////////////////////////////////////////////////////////
2011-02-17 10:08:57 +01:00
bool QmlEngine : : setToolTipExpression ( const QPoint & mousePos ,
2011-02-11 15:00:13 +01:00
TextEditor : : ITextEditor * editor , const DebuggerToolTipContext & ctx )
2010-06-09 16:13:47 +02:00
{
2010-10-27 15:23:30 +02:00
// This is processed by QML inspector, which has dependencies to
// the qml js editor. Makes life easier.
2011-02-11 15:00:13 +01:00
emit tooltipRequested ( mousePos , editor , ctx . position ) ;
2011-02-17 10:08:57 +01:00
return true ;
2010-06-09 16:13:47 +02:00
}
//////////////////////////////////////////////////////////////////////
//
// Watch specific stuff
//
//////////////////////////////////////////////////////////////////////
2010-11-10 16:33:11 +01:00
void QmlEngine : : assignValueInDebugger ( const WatchData * ,
2010-10-27 15:23:30 +02:00
const QString & expression , const QVariant & valueV )
2010-06-09 16:13:47 +02:00
{
2010-07-22 19:06:26 +02:00
QRegExp inObject ( " @([0-9a-fA-F]+) - > ( . + ) " ) ;
if ( inObject . exactMatch ( expression ) ) {
bool ok = false ;
quint64 objectId = inObject . cap ( 1 ) . toULongLong ( & ok , 16 ) ;
QString property = inObject . cap ( 2 ) ;
if ( ok & & objectId > 0 & & ! property . isEmpty ( ) ) {
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " SET_PROPERTY " ;
rs < < cmd ;
2010-09-23 13:22:08 +02:00
rs < < expression . toUtf8 ( ) < < objectId < < property < < valueV . toString ( ) ;
2010-12-17 10:18:34 +01:00
logMessage ( LogSend , QString ( " %1 %2 %3 %4 %5 " ) . arg (
QString ( cmd ) , QString : : number ( objectId ) , QString ( property ) ,
valueV . toString ( ) ) ) ;
2010-07-22 19:06:26 +02:00
sendMessage ( reply ) ;
}
}
2010-06-09 16:13:47 +02:00
}
2010-11-10 16:33:11 +01:00
void QmlEngine : : updateWatchData ( const WatchData & data ,
const WatchUpdateFlags & )
2010-06-09 16:13:47 +02:00
{
2010-07-22 15:32:39 +02:00
// qDebug() << "UPDATE WATCH DATA" << data.toString();
2010-06-16 11:08:54 +02:00
//watchHandler()->rebuildModel();
2010-06-09 16:13:47 +02:00
showStatusMessage ( tr ( " Stopped. " ) , 5000 ) ;
2010-06-25 14:08:53 +02:00
2010-07-22 14:58:37 +02:00
if ( ! data . name . isEmpty ( ) & & data . isValueNeeded ( ) ) {
2010-06-25 14:08:53 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " EXEC " ;
rs < < cmd ;
2010-06-25 14:08:53 +02:00
rs < < data . iname < < data . name ;
2010-12-17 10:18:34 +01:00
logMessage ( LogSend , QString ( " %1 %2 %3 " ) . arg ( QString ( cmd ) , QString ( data . iname ) ,
QString ( data . name ) ) ) ;
2010-06-25 14:08:53 +02:00
sendMessage ( reply ) ;
}
2010-08-11 10:46:45 +02:00
if ( ! data . name . isEmpty ( ) & & data . isChildrenNeeded ( )
2011-02-23 16:09:56 +01:00
& & watchHandler ( ) - > isExpandedIName ( data . iname ) ) {
2010-10-15 13:00:14 +02:00
expandObject ( data . iname , data . id ) ;
2011-02-23 16:09:56 +01:00
}
synchronizeWatchers ( ) ;
2010-07-22 14:58:37 +02:00
2011-02-23 16:09:56 +01:00
if ( ! data . isSomethingNeeded ( ) )
watchHandler ( ) - > insertData ( data ) ;
}
void QmlEngine : : synchronizeWatchers ( )
{
2011-04-21 12:25:06 +02:00
// send watchers list
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
QByteArray cmd = " WATCH_EXPRESSIONS " ;
rs < < cmd ;
rs < < watchHandler ( ) - > watchedExpressions ( ) ;
logMessage ( LogSend , QString ( " %1 %2 " ) . arg (
QString ( cmd ) , watchHandler ( ) - > watchedExpressions ( ) . join ( " , " ) ) ) ;
sendMessage ( reply ) ;
2010-06-09 16:13:47 +02:00
}
2010-12-17 10:18:34 +01:00
void QmlEngine : : expandObject ( const QByteArray & iname , quint64 objectId )
2010-07-22 14:58:37 +02:00
{
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " EXPAND " ;
rs < < cmd ;
2010-07-22 14:58:37 +02:00
rs < < iname < < objectId ;
2010-12-17 10:18:34 +01:00
logMessage ( LogSend , QString ( " %1 %2 %3 " ) . arg ( QString ( cmd ) , QString ( iname ) ,
QString : : number ( objectId ) ) ) ;
2010-07-22 14:58:37 +02:00
sendMessage ( reply ) ;
}
2010-07-23 11:30:07 +02:00
void QmlEngine : : sendPing ( )
{
2010-09-13 13:30:35 +02:00
d - > m_ping + + ;
2010-07-23 11:30:07 +02:00
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " PING " ;
rs < < cmd ;
2010-09-13 13:30:35 +02:00
rs < < d - > m_ping ;
2010-12-17 10:18:34 +01:00
logMessage ( LogSend , QString ( " %1 %2 " ) . arg ( QString ( cmd ) , QString : : number ( d - > m_ping ) ) ) ;
2010-07-23 11:30:07 +02:00
sendMessage ( reply ) ;
}
2010-07-16 11:44:29 +02:00
unsigned QmlEngine : : debuggerCapabilities ( ) const
{
return AddWatcherCapability ;
/*ReverseSteppingCapability | SnapshotCapability
| AutoDerefPointersCapability | DisassemblerCapability
| RegisterCapability | ShowMemoryCapability
| JumpToLineCapability | ReloadModuleCapability
| ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability
| ReturnFromFunctionCapability
| CreateFullBacktraceCapability
| WatchpointCapability
| AddWatcherCapability ; */
2010-06-25 14:08:53 +02:00
}
2011-07-19 17:48:57 +02:00
QString QmlEngine : : toFileInProject ( const QUrl & fileUrl )
2011-02-25 11:57:34 +01:00
{
2011-04-26 09:46:05 +02:00
if ( d - > fileFinder . projectDirectory ( ) . isEmpty ( ) ) {
d - > fileFinder . setProjectDirectory ( startParameters ( ) . projectSourceDirectory ) ;
d - > fileFinder . setProjectFiles ( startParameters ( ) . projectSourceFiles ) ;
2011-02-25 11:57:34 +01:00
}
2011-07-19 17:48:57 +02:00
return d - > fileFinder . findFile ( fileUrl ) ;
2011-02-25 11:57:34 +01:00
}
2010-06-25 14:08:53 +02:00
void QmlEngine : : messageReceived ( const QByteArray & message )
{
QByteArray rwData = message ;
QDataStream stream ( & rwData , QIODevice : : ReadOnly ) ;
QByteArray command ;
stream > > command ;
2010-07-02 17:03:25 +02:00
if ( command = = " STOPPED " ) {
2011-01-19 18:53:04 +01:00
//qDebug() << command << this << state();
2011-01-14 18:47:44 +01:00
if ( state ( ) = = InferiorRunOk )
2010-08-18 13:54:12 +02:00
notifyInferiorSpontaneousStop ( ) ;
2010-07-02 17:03:25 +02:00
2011-01-14 18:50:33 +01:00
QString logString = QString : : fromLatin1 ( command ) ;
2010-12-17 10:18:34 +01:00
2011-02-25 11:57:34 +01:00
JSAgentStackFrames stackFrames ;
2010-11-10 16:33:11 +01:00
QList < WatchData > watches ;
QList < WatchData > locals ;
2010-10-27 17:36:39 +02:00
stream > > stackFrames > > watches > > locals ;
2010-06-25 14:08:53 +02:00
2011-02-14 16:36:05 +01:00
logString + = QString : : fromLatin1 ( " (%1 stack frames) (%2 watches) (%3 locals) " ) .
arg ( stackFrames . size ( ) ) . arg ( watches . size ( ) ) . arg ( locals . size ( ) ) ;
2010-12-17 10:18:34 +01:00
2011-02-25 11:57:34 +01:00
StackFrames ideStackFrames ;
for ( int i = 0 ; i ! = stackFrames . size ( ) ; + + i ) {
StackFrame frame ;
frame . line = stackFrames . at ( i ) . lineNumber ;
frame . function = stackFrames . at ( i ) . functionName ;
2011-07-19 17:48:57 +02:00
frame . file = toFileInProject ( QUrl ( stackFrames . at ( i ) . fileUrl ) ) ;
2011-02-25 11:57:34 +01:00
frame . usable = QFileInfo ( frame . file ) . isReadable ( ) ;
frame . level = i + 1 ;
ideStackFrames < < frame ;
}
2010-06-25 14:08:53 +02:00
2011-02-25 11:57:34 +01:00
if ( ideStackFrames . size ( ) & & ideStackFrames . back ( ) . function = = " <global> " )
ideStackFrames . takeLast ( ) ;
stackHandler ( ) - > setFrames ( ideStackFrames ) ;
2010-06-25 14:08:53 +02:00
watchHandler ( ) - > beginCycle ( ) ;
2010-07-23 11:30:07 +02:00
bool needPing = false ;
2010-06-25 14:08:53 +02:00
2010-11-10 16:33:11 +01:00
foreach ( WatchData data , watches ) {
2010-06-25 14:08:53 +02:00
data . iname = watchHandler ( ) - > watcherName ( data . exp ) ;
2010-07-22 13:00:26 +02:00
watchHandler ( ) - > insertData ( data ) ;
2010-07-22 14:58:37 +02:00
2010-07-23 11:30:07 +02:00
if ( watchHandler ( ) - > expandedINames ( ) . contains ( data . iname ) ) {
needPing = true ;
2010-10-15 13:00:14 +02:00
expandObject ( data . iname , data . id ) ;
2010-07-23 11:30:07 +02:00
}
2010-06-25 14:08:53 +02:00
}
2010-11-10 16:33:11 +01:00
foreach ( WatchData data , locals ) {
2010-07-22 13:00:26 +02:00
data . iname = " local. " + data . exp ;
watchHandler ( ) - > insertData ( data ) ;
2010-07-22 14:58:37 +02:00
2010-07-23 11:30:07 +02:00
if ( watchHandler ( ) - > expandedINames ( ) . contains ( data . iname ) ) {
needPing = true ;
2010-10-15 13:00:14 +02:00
expandObject ( data . iname , data . id ) ;
2010-07-23 11:30:07 +02:00
}
2010-07-05 11:28:38 +02:00
}
2011-02-25 11:57:34 +01:00
if ( needPing ) {
2010-07-23 11:30:07 +02:00
sendPing ( ) ;
2011-02-25 11:57:34 +01:00
} else {
2010-07-23 11:30:07 +02:00
watchHandler ( ) - > endCycle ( ) ;
2011-02-25 11:57:34 +01:00
}
2010-07-16 11:44:29 +02:00
2010-08-18 13:54:12 +02:00
bool becauseOfException ;
stream > > becauseOfException ;
2010-12-17 10:18:34 +01:00
logString + = becauseOfException ? " exception " : " no_exception " ;
2010-08-18 13:54:12 +02:00
if ( becauseOfException ) {
2010-07-23 18:40:12 +02:00
QString error ;
stream > > error ;
2011-03-02 12:01:34 +01:00
logString + = QLatin1Char ( ' ' ) ;
logString + = error ;
2010-12-17 10:18:34 +01:00
logMessage ( LogReceive , logString ) ;
2011-01-19 19:16:34 +01:00
QString msg = stackFrames . isEmpty ( )
2011-03-02 12:01:34 +01:00
? tr ( " <p>An uncaught exception occurred:</p><p>%1</p> " )
2011-01-19 19:16:34 +01:00
. arg ( Qt : : escape ( error ) )
2011-03-02 12:01:34 +01:00
: tr ( " <p>An uncaught exception occurred in <i>%1</i>:</p><p>%2</p> " )
2011-02-25 11:57:34 +01:00
. arg ( stackFrames . value ( 0 ) . fileUrl , Qt : : escape ( error ) ) ;
2010-07-23 18:40:12 +02:00
showMessageBox ( QMessageBox : : Information , tr ( " Uncaught Exception " ) , msg ) ;
2010-10-04 14:23:20 +02:00
} else {
//
// Make breakpoint non-pending
//
QString file ;
2010-10-28 12:18:38 +02:00
QString function ;
2010-10-04 14:23:20 +02:00
int line = - 1 ;
2011-02-25 11:57:34 +01:00
if ( ! ideStackFrames . isEmpty ( ) ) {
file = ideStackFrames . at ( 0 ) . file ;
line = ideStackFrames . at ( 0 ) . line ;
function = ideStackFrames . at ( 0 ) . function ;
2010-10-04 14:23:20 +02:00
}
2010-07-23 18:40:12 +02:00
2010-11-10 16:33:11 +01:00
BreakHandler * handler = breakHandler ( ) ;
2011-06-24 16:25:30 +02:00
foreach ( BreakpointModelId id , handler - > engineBreakpointIds ( this ) ) {
2010-11-10 16:33:11 +01:00
QString processedFilename = handler - > fileName ( id ) ;
if ( processedFilename = = file & & handler - > lineNumber ( id ) = = line ) {
2010-11-30 11:35:17 +01:00
QTC_ASSERT ( handler - > state ( id ) = = BreakpointInserted , /**/ ) ;
2010-11-10 16:33:11 +01:00
BreakpointResponse br = handler - > response ( id ) ;
2010-11-15 17:04:29 +01:00
br . fileName = file ;
br . lineNumber = line ;
br . functionName = function ;
2010-11-10 16:33:11 +01:00
handler - > setResponse ( id , br ) ;
2010-10-04 14:23:20 +02:00
}
}
2010-12-17 10:18:34 +01:00
logMessage ( LogReceive , logString ) ;
2010-10-04 14:23:20 +02:00
}
2011-01-19 18:53:04 +01:00
2011-02-25 11:57:34 +01:00
if ( ! ideStackFrames . isEmpty ( ) )
gotoLocation ( ideStackFrames . value ( 0 ) ) ;
2011-01-19 18:53:04 +01:00
2010-06-25 14:08:53 +02:00
} else if ( command = = " RESULT " ) {
2010-11-10 16:33:11 +01:00
WatchData data ;
2010-07-22 13:00:26 +02:00
QByteArray iname ;
stream > > iname > > data ;
2010-12-17 10:18:34 +01:00
logMessage ( LogReceive , QString ( " %1 %2 %3 " ) . arg ( QString ( command ) ,
QString ( iname ) , QString ( data . value ) ) ) ;
2010-07-22 13:00:26 +02:00
data . iname = iname ;
2010-08-26 16:02:41 +02:00
if ( iname . startsWith ( " watch. " ) ) {
watchHandler ( ) - > insertData ( data ) ;
} else if ( iname = = " console " ) {
2010-11-10 11:39:01 +01:00
showMessage ( data . value , ScriptConsoleOutput ) ;
2010-08-26 16:02:41 +02:00
} else {
qWarning ( ) < < " QmlEngine: Unexcpected result: " < < iname < < data . value ;
}
2010-07-22 14:58:37 +02:00
} else if ( command = = " EXPANDED " ) {
2010-11-10 16:33:11 +01:00
QList < WatchData > result ;
2010-07-22 14:58:37 +02:00
QByteArray iname ;
stream > > iname > > result ;
2010-12-17 10:18:34 +01:00
logMessage ( LogReceive , QString ( " %1 %2 (%3 x watchdata) " ) . arg (
QString ( command ) , QString ( iname ) , QString : : number ( result . size ( ) ) ) ) ;
2010-07-23 11:30:07 +02:00
bool needPing = false ;
2010-11-10 16:33:11 +01:00
foreach ( WatchData data , result ) {
2010-07-22 14:58:37 +02:00
data . iname = iname + ' . ' + data . exp ;
watchHandler ( ) - > insertData ( data ) ;
2010-07-23 11:30:07 +02:00
if ( watchHandler ( ) - > expandedINames ( ) . contains ( data . iname ) ) {
needPing = true ;
2010-10-15 13:00:14 +02:00
expandObject ( data . iname , data . id ) ;
2010-07-23 11:30:07 +02:00
}
2010-07-22 14:58:37 +02:00
}
2010-07-23 11:30:07 +02:00
if ( needPing )
sendPing ( ) ;
2010-07-22 15:22:46 +02:00
} else if ( command = = " LOCALS " ) {
2010-11-10 16:33:11 +01:00
QList < WatchData > locals ;
2011-04-20 16:47:47 +02:00
QList < WatchData > watches ;
2010-07-22 15:22:46 +02:00
int frameId ;
stream > > frameId > > locals ;
2011-04-20 16:47:47 +02:00
if ( ! stream . atEnd ( ) ) { // compatibility with jsdebuggeragent from 2.1, 2.2
stream > > watches ;
}
2010-12-17 10:18:34 +01:00
2011-04-20 16:47:47 +02:00
logMessage ( LogReceive , QString ( " %1 %2 (%3 x locals) (%4 x watchdata) " ) . arg (
2010-12-17 10:18:34 +01:00
QString ( command ) , QString : : number ( frameId ) ,
2011-04-20 16:47:47 +02:00
QString : : number ( locals . size ( ) ) ,
QString : : number ( watches . size ( ) ) ) ) ;
2010-07-22 15:22:46 +02:00
watchHandler ( ) - > beginCycle ( ) ;
2010-07-23 11:30:07 +02:00
bool needPing = false ;
2011-04-20 16:47:47 +02:00
foreach ( WatchData data , watches ) {
data . iname = watchHandler ( ) - > watcherName ( data . exp ) ;
watchHandler ( ) - > insertData ( data ) ;
if ( watchHandler ( ) - > expandedINames ( ) . contains ( data . iname ) ) {
needPing = true ;
expandObject ( data . iname , data . id ) ;
}
}
2010-11-10 16:33:11 +01:00
foreach ( WatchData data , locals ) {
2010-07-22 15:22:46 +02:00
data . iname = " local. " + data . exp ;
watchHandler ( ) - > insertData ( data ) ;
2010-07-23 11:30:07 +02:00
if ( watchHandler ( ) - > expandedINames ( ) . contains ( data . iname ) ) {
needPing = true ;
2010-10-15 13:00:14 +02:00
expandObject ( data . iname , data . id ) ;
2010-07-23 11:30:07 +02:00
}
2010-07-22 15:22:46 +02:00
}
2010-07-23 11:30:07 +02:00
if ( needPing )
sendPing ( ) ;
else
watchHandler ( ) - > endCycle ( ) ;
} else if ( command = = " PONG " ) {
int ping ;
stream > > ping ;
2010-12-17 10:18:34 +01:00
logMessage ( LogReceive , QString ( " %1 %2 " ) . arg ( QString ( command ) , QString : : number ( ping ) ) ) ;
2010-09-13 13:30:35 +02:00
if ( ping = = d - > m_ping )
2010-07-23 11:30:07 +02:00
watchHandler ( ) - > endCycle ( ) ;
2010-06-25 14:08:53 +02:00
} else {
qDebug ( ) < < Q_FUNC_INFO < < " Unknown command: " < < command ;
2010-12-17 10:18:34 +01:00
logMessage ( LogReceive , QString ( " %1 UNKNOWN COMMAND!! " ) . arg ( QString ( command ) ) ) ;
2010-06-25 14:08:53 +02:00
}
}
2010-08-10 14:42:44 +02:00
void QmlEngine : : disconnected ( )
{
2010-11-10 11:39:01 +01:00
showMessage ( tr ( " QML Debugger disconnected. " ) , StatusBar ) ;
2010-08-10 14:42:44 +02:00
notifyInferiorExited ( ) ;
}
2011-02-24 10:03:44 +01:00
void QmlEngine : : wrongSetupMessageBoxFinished ( int result )
2011-02-21 17:01:40 +01:00
{
if ( result = = QMessageBox : : Help ) {
Core : : HelpManager * helpManager = Core : : HelpManager : : instance ( ) ;
helpManager - > handleHelpRequest (
QLatin1String ( " qthelp://com.nokia.qtcreator/doc/creator-debugging-qml.html " ) ) ;
}
}
2010-08-26 16:02:41 +02:00
void QmlEngine : : executeDebuggerCommand ( const QString & command )
{
QByteArray reply ;
QDataStream rs ( & reply , QIODevice : : WriteOnly ) ;
2010-12-17 10:18:34 +01:00
QByteArray cmd = " EXEC " ;
QByteArray console = " console " ;
rs < < cmd < < console < < command ;
logMessage ( LogSend , QString ( " %1 %2 %3 " ) . arg ( QString ( cmd ) , QString ( console ) ,
QString ( command ) ) ) ;
2010-08-26 16:02:41 +02:00
sendMessage ( reply ) ;
}
2010-09-08 13:31:12 +02:00
QString QmlEngine : : qmlImportPath ( ) const
{
2010-10-19 11:14:03 +02:00
return startParameters ( ) . environment . value ( " QML_IMPORT_PATH " ) ;
2010-09-08 13:31:12 +02:00
}
2010-12-17 10:18:34 +01:00
void QmlEngine : : logMessage ( LogDirection direction , const QString & message )
{
QString msg = " JSDebugger " ;
if ( direction = = LogSend ) {
msg + = " sending " ;
} else {
msg + = " receiving " ;
}
msg + = message ;
showMessage ( msg , LogDebug ) ;
}
2011-02-21 17:01:40 +01:00
QmlEngine * createQmlEngine ( const DebuggerStartParameters & sp ,
2011-01-12 12:10:12 +01:00
DebuggerEngine * masterEngine )
{
return new QmlEngine ( sp , masterEngine ) ;
}
2010-12-03 12:07:32 +01:00
} // namespace Internal
2010-06-09 16:13:47 +02:00
} // namespace Debugger
2010-07-01 11:48:43 +02:00