diff options
Diffstat (limited to 'src/scripttools/debugging')
196 files changed, 27880 insertions, 0 deletions
diff --git a/src/scripttools/debugging/debugging.pri b/src/scripttools/debugging/debugging.pri new file mode 100644 index 0000000..fa39e83 --- /dev/null +++ b/src/scripttools/debugging/debugging.pri @@ -0,0 +1,157 @@ +RESOURCES += $$PWD/scripttools_debugging.qrc + +SOURCES += \ + $$PWD/qscriptdebuggervalue.cpp \ + $$PWD/qscriptdebuggervalueproperty.cpp \ + $$PWD/qscriptdebuggercommand.cpp \ + $$PWD/qscriptdebuggerresponse.cpp \ + $$PWD/qscriptdebuggerevent.cpp \ + $$PWD/qscriptdebuggercommandexecutor.cpp \ + $$PWD/qscriptdebuggercommandschedulerfrontend.cpp \ + $$PWD/qscriptdebuggerbackend.cpp \ + $$PWD/qscriptdebuggeragent.cpp \ + $$PWD/qscriptdebuggerfrontend.cpp \ + $$PWD/qscriptstdmessagehandler.cpp \ + $$PWD/qscriptenginedebuggerfrontend.cpp \ + $$PWD/qscriptdebuggerjob.cpp \ + $$PWD/qscriptdebuggercommandschedulerjob.cpp \ + $$PWD/qscriptvalueproperty.cpp \ + $$PWD/qscriptobjectsnapshot.cpp \ + $$PWD/qscriptscriptdata.cpp \ + $$PWD/qscriptxmlparser.cpp \ + $$PWD/qscriptbreakpointdata.cpp \ + $$PWD/qscriptdebugger.cpp \ + $$PWD/qscriptdebuggerconsole.cpp \ + $$PWD/qscriptdebuggerconsolecommand.cpp \ + $$PWD/qscriptdebuggerconsolecommandjob.cpp \ + $$PWD/qscriptdebuggerconsolecommandgroupdata.cpp \ + $$PWD/qscriptdebuggerconsolecommandmanager.cpp \ + $$PWD/qscriptcompletiontaskinterface.cpp \ + $$PWD/qscriptcompletiontask.cpp \ + $$PWD/qscriptdebuggerconsoleglobalobject.cpp \ + $$PWD/qscriptdebuggerscriptedconsolecommand.cpp + +HEADERS += \ + $$PWD/qscriptdebuggervalue_p.h \ + $$PWD/qscriptdebuggervalueproperty_p.h \ + $$PWD/qscriptdebuggerobjectsnapshotdelta_p.h \ + $$PWD/qscriptdebuggercommand_p.h \ + $$PWD/qscriptdebuggercommandschedulerinterface_p.h \ + $$PWD/qscriptdebuggercommandschedulerfrontend_p.h \ + $$PWD/qscriptdebuggerresponse_p.h \ + $$PWD/qscriptdebuggerresponsehandlerinterface_p.h \ + $$PWD/qscriptdebuggerevent_p.h \ + $$PWD/qscriptdebuggercommandexecutor_p.h \ + $$PWD/qscriptdebuggerbackend_p_p.h \ + $$PWD/qscriptdebuggerbackend_p.h \ + $$PWD/qscriptdebuggeragent_p_p.h \ + $$PWD/qscriptdebuggeragent_p.h \ + $$PWD/qscriptdebuggerfrontend_p_p.h \ + $$PWD/qscriptdebuggerfrontend_p.h \ + $$PWD/qscriptmessagehandlerinterface_p.h \ + $$PWD/qscriptstdmessagehandler_p.h \ + $$PWD/qscriptenginedebuggerfrontend_p.h \ + $$PWD/qscriptdebuggerjob_p_p.h \ + $$PWD/qscriptdebuggerjob_p.h \ + $$PWD/qscriptdebuggercommandschedulerjob_p_p.h \ + $$PWD/qscriptdebuggercommandschedulerjob_p.h \ + $$PWD/qscriptdebuggerjobschedulerinterface_p.h \ + $$PWD/qscriptdebuggereventhandlerinterface_p.h \ + $$PWD/qscriptvalueproperty_p.h \ + $$PWD/qscriptobjectsnapshot_p.h \ + $$PWD/qscriptscriptdata_p.h \ + $$PWD/qscriptxmlparser_p.h \ + $$PWD/qscriptbreakpointdata_p.h \ + $$PWD/qscriptdebugger_p.h \ + $$PWD/qscriptdebuggerconsole_p.h \ + $$PWD/qscriptdebuggerconsolecommand_p_p.h \ + $$PWD/qscriptdebuggerconsolecommand_p.h \ + $$PWD/qscriptdebuggerconsolecommandjob_p_p.h \ + $$PWD/qscriptdebuggerconsolecommandjob_p.h \ + $$PWD/qscriptdebuggerconsolecommandgroupdata_p.h \ + $$PWD/qscriptdebuggerconsolecommandmanager_p.h \ + $$PWD/qscriptdebuggerconsolehistorianinterface_p.h \ + $$PWD/qscriptcompletionproviderinterface_p.h \ + $$PWD/qscriptcompletiontaskinterface_p_p.h \ + $$PWD/qscriptcompletiontaskinterface_p.h \ + $$PWD/qscriptcompletiontask_p.h \ + $$PWD/qscripttooltipproviderinterface_p.h \ + $$PWD/qscriptdebuggerconsoleglobalobject_p.h \ + $$PWD/qscriptdebuggerscriptedconsolecommand_p.h + +SOURCES += \ + $$PWD/qscriptedit.cpp \ + $$PWD/qscriptsyntaxhighlighter.cpp + +HEADERS += \ + $$PWD/qscriptedit_p.h \ + $$PWD/qscriptsyntaxhighlighter_p.h + +SOURCES += \ + $$PWD/qscriptdebuggerconsolewidgetinterface.cpp \ + $$PWD/qscriptdebuggerconsolewidget.cpp \ + $$PWD/qscriptdebuggerstackwidgetinterface.cpp \ + $$PWD/qscriptdebuggerstackwidget.cpp \ + $$PWD/qscriptdebuggerstackmodel.cpp \ + $$PWD/qscriptdebuggerscriptswidgetinterface.cpp \ + $$PWD/qscriptdebuggerscriptswidget.cpp \ + $$PWD/qscriptdebuggerscriptsmodel.cpp \ + $$PWD/qscriptdebuggerlocalswidgetinterface.cpp \ + $$PWD/qscriptdebuggerlocalswidget.cpp \ + $$PWD/qscriptdebuggerlocalsmodel.cpp \ + $$PWD/qscriptdebuggercodewidgetinterface.cpp \ + $$PWD/qscriptdebuggercodewidget.cpp \ + $$PWD/qscriptdebuggercodeviewinterface.cpp \ + $$PWD/qscriptdebuggercodeview.cpp \ + $$PWD/qscriptdebuggercodefinderwidgetinterface.cpp \ + $$PWD/qscriptdebuggercodefinderwidget.cpp \ + $$PWD/qscriptdebugoutputwidgetinterface.cpp \ + $$PWD/qscriptdebugoutputwidget.cpp \ + $$PWD/qscriptbreakpointswidgetinterface.cpp \ + $$PWD/qscriptbreakpointswidget.cpp \ + $$PWD/qscriptbreakpointsmodel.cpp \ + $$PWD/qscripterrorlogwidgetinterface.cpp \ + $$PWD/qscripterrorlogwidget.cpp + +HEADERS += \ + $$PWD/qscriptdebuggerconsolewidgetinterface_p_p.h \ + $$PWD/qscriptdebuggerconsolewidgetinterface_p.h \ + $$PWD/qscriptdebuggerconsolewidget_p.h \ + $$PWD/qscriptdebuggerstackwidgetinterface_p_p.h \ + $$PWD/qscriptdebuggerstackwidgetinterface_p.h \ + $$PWD/qscriptdebuggerstackwidget_p.h \ + $$PWD/qscriptdebuggerstackmodel_p.h \ + $$PWD/qscriptdebuggerscriptswidgetinterface_p_p.h \ + $$PWD/qscriptdebuggerscriptswidgetinterface_p.h \ + $$PWD/qscriptdebuggerscriptswidget_p.h \ + $$PWD/qscriptdebuggerscriptsmodel_p.h \ + $$PWD/qscriptdebuggerlocalswidgetinterface_p_p.h \ + $$PWD/qscriptdebuggerlocalswidgetinterface_p.h \ + $$PWD/qscriptdebuggerlocalswidget_p.h \ + $$PWD/qscriptdebuggerlocalsmodel_p.h \ + $$PWD/qscriptdebuggercodewidgetinterface_p_p.h \ + $$PWD/qscriptdebuggercodewidgetinterface_p.h \ + $$PWD/qscriptdebuggercodewidget_p.h \ + $$PWD/qscriptdebuggercodeviewinterface_p_p.h \ + $$PWD/qscriptdebuggercodeviewinterface_p.h \ + $$PWD/qscriptdebuggercodeview_p.h \ + $$PWD/qscriptdebuggercodefinderwidgetinterface_p_p.h \ + $$PWD/qscriptdebuggercodefinderwidgetinterface_p.h \ + $$PWD/qscriptdebuggercodefinderwidget_p.h \ + $$PWD/qscriptdebugoutputwidgetinterface_p_p.h \ + $$PWD/qscriptdebugoutputwidgetinterface_p.h \ + $$PWD/qscriptdebugoutputwidget_p.h \ + $$PWD/qscriptbreakpointswidgetinterface_p_p.h \ + $$PWD/qscriptbreakpointswidgetinterface_p.h \ + $$PWD/qscriptbreakpointswidget_p.h \ + $$PWD/qscriptbreakpointsmodel_p.h \ + $$PWD/qscripterrorlogwidgetinterface_p_p.h \ + $$PWD/qscripterrorlogwidgetinterface_p.h \ + $$PWD/qscripterrorlogwidget_p.h \ + $$PWD/qscriptdebuggerwidgetfactoryinterface_p.h + +SOURCES += \ + $$PWD/qscriptenginedebugger.cpp + +HEADERS += \ + $$PWD/qscriptenginedebugger.h diff --git a/src/scripttools/debugging/images/breakpoint.png b/src/scripttools/debugging/images/breakpoint.png Binary files differnew file mode 100644 index 0000000..21c4376 --- /dev/null +++ b/src/scripttools/debugging/images/breakpoint.png diff --git a/src/scripttools/debugging/images/breakpoint.svg b/src/scripttools/debugging/images/breakpoint.svg new file mode 100644 index 0000000..e8d63cc --- /dev/null +++ b/src/scripttools/debugging/images/breakpoint.svg @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="14" + height="14" + id="svg2270" + sodipodi:version="0.32" + inkscape:version="0.45.1" + version="1.0" + sodipodi:docbase="D:\depot\research\main\editor\images" + sodipodi:docname="breakpoint.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs2272"> + <linearGradient + id="linearGradient7029"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop7031" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop7033" /> + </linearGradient> + <linearGradient + id="linearGradient17794"> + <stop + style="stop-color:#f18383;stop-opacity:1;" + offset="0" + id="stop17798" /> + <stop + id="stop8006" + offset="0.3807947" + style="stop-color:#ed6767;stop-opacity:1;" /> + <stop + style="stop-color:#e62323;stop-opacity:1;" + offset="1" + id="stop17796" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient17794" + id="linearGradient24732" + gradientUnits="userSpaceOnUse" + x1="472.42236" + y1="436.79602" + x2="461.39169" + y2="424.95065" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient17794" + id="linearGradient2438" + gradientUnits="userSpaceOnUse" + x1="472.42236" + y1="436.79602" + x2="461.39169" + y2="424.95065" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient17794" + id="radialGradient6052" + cx="466.73566" + cy="431.19708" + fx="466.73566" + fy="431.19708" + r="9.3095722" + gradientTransform="matrix(1,0,0,1.0057859,0,-2.4948735)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7029" + id="linearGradient7035" + x1="6.75" + y1="0.5" + x2="6.75" + y2="12.5" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="32" + inkscape:cx="8.6877264" + inkscape:cy="6.3888789" + inkscape:document-units="px" + inkscape:current-layer="g25843" + width="14px" + height="14px" + inkscape:window-width="1280" + inkscape:window-height="998" + inkscape:window-x="0" + inkscape:window-y="0" + showgrid="true" + gridspacingx="0.5px" + gridspacingy="0.5px" + gridempspacing="2" + inkscape:grid-points="true" /> + <metadata + id="metadata2275"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g25843" + transform="matrix(0.7931251,0,0,0.7931251,-372.13374,-408.22195)"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient6052);fill-opacity:1.0;stroke:#c80000;stroke-width:1.43637741;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path22737" + sodipodi:cx="466.73566" + sodipodi:cy="431.19708" + sodipodi:rx="8.5913839" + sodipodi:ry="8.6452484" + d="M 475.32704 431.19708 A 8.5913839 8.6452484 0 1 1 458.14427,431.19708 A 8.5913839 8.6452484 0 1 1 475.32704 431.19708 z" + transform="matrix(0.8805346,0,0,0.8750503,66.41784,145.57686)" /> + <path + sodipodi:type="arc" + style="opacity:1;fill:url(#linearGradient7035);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path6058" + sodipodi:cx="6.75" + sodipodi:cy="6.5" + sodipodi:rx="5.75" + sodipodi:ry="6" + d="M 12.5 6.5 A 5.75 6 0 1 1 1,6.5 A 5.75 6 0 1 1 12.5 6.5 z" + transform="matrix(0.9867408,0,0,0.6304178,470.73423,515.01579)" /> + </g> + </g> +</svg> diff --git a/src/scripttools/debugging/images/d_breakpoint.png b/src/scripttools/debugging/images/d_breakpoint.png Binary files differnew file mode 100644 index 0000000..867b30d --- /dev/null +++ b/src/scripttools/debugging/images/d_breakpoint.png diff --git a/src/scripttools/debugging/images/d_breakpoint.svg b/src/scripttools/debugging/images/d_breakpoint.svg new file mode 100644 index 0000000..f303b34 --- /dev/null +++ b/src/scripttools/debugging/images/d_breakpoint.svg @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="14" + height="14" + id="svg2270" + sodipodi:version="0.32" + inkscape:version="0.45.1" + version="1.0" + sodipodi:docbase="D:\depot\research\main\editor\images" + sodipodi:docname="breakpoint.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs2272"> + <linearGradient + id="linearGradient7029"> + <stop + style="stop-color:#cfcfcf;stop-opacity:1;" + offset="0" + id="stop7031" /> + <stop + style="stop-color:#cfcfcf;stop-opacity:0;" + offset="1" + id="stop7033" /> + </linearGradient> + <linearGradient + id="linearGradient17794"> + <stop + style="stop-color:#917373;stop-opacity:1;" + offset="0" + id="stop17798" /> + <stop + id="stop8006" + offset="0.3807947" + style="stop-color:#8d5757;stop-opacity:1;" /> + <stop + style="stop-color:#862323;stop-opacity:1;" + offset="1" + id="stop17796" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient17794" + id="linearGradient24732" + gradientUnits="userSpaceOnUse" + x1="472.42236" + y1="436.79602" + x2="461.39169" + y2="424.95065" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient17794" + id="linearGradient2438" + gradientUnits="userSpaceOnUse" + x1="472.42236" + y1="436.79602" + x2="461.39169" + y2="424.95065" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient17794" + id="radialGradient6052" + cx="466.73566" + cy="431.19708" + fx="466.73566" + fy="431.19708" + r="9.3095722" + gradientTransform="matrix(1,0,0,1.0057859,0,-2.4948735)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7029" + id="linearGradient7035" + x1="6.75" + y1="0.5" + x2="6.75" + y2="12.5" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="32" + inkscape:cx="8.6877264" + inkscape:cy="6.3888789" + inkscape:document-units="px" + inkscape:current-layer="g25843" + width="14px" + height="14px" + inkscape:window-width="1280" + inkscape:window-height="998" + inkscape:window-x="0" + inkscape:window-y="0" + showgrid="true" + gridspacingx="0.5px" + gridspacingy="0.5px" + gridempspacing="2" + inkscape:grid-points="true" /> + <metadata + id="metadata2275"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g25843" + transform="matrix(0.7931251,0,0,0.7931251,-372.13374,-408.22195)"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient6052);fill-opacity:1.0;stroke:#872727;stroke-width:1.43637741;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path22737" + sodipodi:cx="466.73566" + sodipodi:cy="431.19708" + sodipodi:rx="8.5913839" + sodipodi:ry="8.6452484" + d="M 475.32704 431.19708 A 8.5913839 8.6452484 0 1 1 458.14427,431.19708 A 8.5913839 8.6452484 0 1 1 475.32704 431.19708 z" + transform="matrix(0.8805346,0,0,0.8750503,66.41784,145.57686)" /> + <path + sodipodi:type="arc" + style="opacity:1;fill:url(#linearGradient7035);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path6058" + sodipodi:cx="6.75" + sodipodi:cy="6.5" + sodipodi:rx="5.75" + sodipodi:ry="6" + d="M 12.5 6.5 A 5.75 6 0 1 1 1,6.5 A 5.75 6 0 1 1 12.5 6.5 z" + transform="matrix(0.9867408,0,0,0.6304178,470.73423,515.01579)" /> + </g> + </g> +</svg> diff --git a/src/scripttools/debugging/images/d_interrupt.png b/src/scripttools/debugging/images/d_interrupt.png Binary files differnew file mode 100644 index 0000000..e5b3af0 --- /dev/null +++ b/src/scripttools/debugging/images/d_interrupt.png diff --git a/src/scripttools/debugging/images/d_play.png b/src/scripttools/debugging/images/d_play.png Binary files differnew file mode 100644 index 0000000..7ef9667 --- /dev/null +++ b/src/scripttools/debugging/images/d_play.png diff --git a/src/scripttools/debugging/images/delete.png b/src/scripttools/debugging/images/delete.png Binary files differnew file mode 100644 index 0000000..9f0491d --- /dev/null +++ b/src/scripttools/debugging/images/delete.png diff --git a/src/scripttools/debugging/images/find.png b/src/scripttools/debugging/images/find.png Binary files differnew file mode 100644 index 0000000..3f369fd --- /dev/null +++ b/src/scripttools/debugging/images/find.png diff --git a/src/scripttools/debugging/images/interrupt.png b/src/scripttools/debugging/images/interrupt.png Binary files differnew file mode 100644 index 0000000..c5f396e --- /dev/null +++ b/src/scripttools/debugging/images/interrupt.png diff --git a/src/scripttools/debugging/images/location.png b/src/scripttools/debugging/images/location.png Binary files differnew file mode 100644 index 0000000..6c4a4bf --- /dev/null +++ b/src/scripttools/debugging/images/location.png diff --git a/src/scripttools/debugging/images/location.svg b/src/scripttools/debugging/images/location.svg new file mode 100644 index 0000000..afb7005 --- /dev/null +++ b/src/scripttools/debugging/images/location.svg @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="14" + height="14" + id="svg2243" + sodipodi:version="0.32" + inkscape:version="0.45.1" + version="1.0" + sodipodi:docbase="c:\depot\research\main\editor\images" + sodipodi:docname="location.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs2245"> + <linearGradient + id="linearGradient3134"> + <stop + style="stop-color:#dcdc23;stop-opacity:1;" + offset="0" + id="stop3136" /> + <stop + id="stop5080" + offset="0.64285713" + style="stop-color:#e5d044;stop-opacity:1;" /> + <stop + style="stop-color:#b89354;stop-opacity:1;" + offset="1" + id="stop3138" /> + </linearGradient> + <linearGradient + id="linearGradient3137"> + <stop + style="stop-color:#ffffff;stop-opacity:0.86274511;" + offset="0" + id="stop3139" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop3141" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3137" + id="linearGradient3143" + x1="6.5" + y1="3" + x2="6.515625" + y2="12.180227" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3134" + id="linearGradient3140" + x1="6.5" + y1="3.015625" + x2="6.484375" + y2="11.984375" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="64" + inkscape:cx="8.3920091" + inkscape:cy="7.4257237" + inkscape:document-units="px" + inkscape:current-layer="layer1" + width="14px" + height="14px" + showborder="true" + inkscape:window-width="1600" + inkscape:window-height="1174" + inkscape:window-x="0" + inkscape:window-y="0" + gridempspacing="2" + showgrid="true" + inkscape:grid-points="true" + gridspacingx="0.5px" + gridspacingy="0.5px" /> + <metadata + id="metadata2248"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:url(#linearGradient3140);fill-opacity:1.0;fill-rule:evenodd;stroke:#b18b1b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 6.5,3 L 6.5,5.5 L 0.5,5.5 L 0.5,9.5 L 6.5,9.5 L 6.5,12 L 13.125,7.5 L 6.5,3 z " + id="path2216" + sodipodi:nodetypes="cccccccc" /> + <path + style="fill:url(#linearGradient3143);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:1" + d="M 6.5,3 L 6.5,5.5 L 0.5,5.5 L 0.5,7.5 C 7,6.5 7.5,9.5 13,7.5 L 6.5,3 z " + id="path5066" + sodipodi:nodetypes="cccccc" /> + </g> +</svg> diff --git a/src/scripttools/debugging/images/mac/closetab.png b/src/scripttools/debugging/images/mac/closetab.png Binary files differnew file mode 100644 index 0000000..ab9d669 --- /dev/null +++ b/src/scripttools/debugging/images/mac/closetab.png diff --git a/src/scripttools/debugging/images/mac/next.png b/src/scripttools/debugging/images/mac/next.png Binary files differnew file mode 100644 index 0000000..a585cab --- /dev/null +++ b/src/scripttools/debugging/images/mac/next.png diff --git a/src/scripttools/debugging/images/mac/plus.png b/src/scripttools/debugging/images/mac/plus.png Binary files differnew file mode 100644 index 0000000..1ee4542 --- /dev/null +++ b/src/scripttools/debugging/images/mac/plus.png diff --git a/src/scripttools/debugging/images/mac/previous.png b/src/scripttools/debugging/images/mac/previous.png Binary files differnew file mode 100644 index 0000000..612fb34 --- /dev/null +++ b/src/scripttools/debugging/images/mac/previous.png diff --git a/src/scripttools/debugging/images/new.png b/src/scripttools/debugging/images/new.png Binary files differnew file mode 100644 index 0000000..9520080 --- /dev/null +++ b/src/scripttools/debugging/images/new.png diff --git a/src/scripttools/debugging/images/play.png b/src/scripttools/debugging/images/play.png Binary files differnew file mode 100644 index 0000000..5880175 --- /dev/null +++ b/src/scripttools/debugging/images/play.png diff --git a/src/scripttools/debugging/images/reload.png b/src/scripttools/debugging/images/reload.png Binary files differnew file mode 100644 index 0000000..18c752e --- /dev/null +++ b/src/scripttools/debugging/images/reload.png diff --git a/src/scripttools/debugging/images/return.png b/src/scripttools/debugging/images/return.png Binary files differnew file mode 100644 index 0000000..9db255a --- /dev/null +++ b/src/scripttools/debugging/images/return.png diff --git a/src/scripttools/debugging/images/runtocursor.png b/src/scripttools/debugging/images/runtocursor.png Binary files differnew file mode 100644 index 0000000..0d92dd5 --- /dev/null +++ b/src/scripttools/debugging/images/runtocursor.png diff --git a/src/scripttools/debugging/images/runtonewscript.png b/src/scripttools/debugging/images/runtonewscript.png Binary files differnew file mode 100644 index 0000000..fb5fe5a --- /dev/null +++ b/src/scripttools/debugging/images/runtonewscript.png diff --git a/src/scripttools/debugging/images/stepinto.png b/src/scripttools/debugging/images/stepinto.png Binary files differnew file mode 100644 index 0000000..de4baa1 --- /dev/null +++ b/src/scripttools/debugging/images/stepinto.png diff --git a/src/scripttools/debugging/images/stepout.png b/src/scripttools/debugging/images/stepout.png Binary files differnew file mode 100644 index 0000000..f49dcbf --- /dev/null +++ b/src/scripttools/debugging/images/stepout.png diff --git a/src/scripttools/debugging/images/stepover.png b/src/scripttools/debugging/images/stepover.png Binary files differnew file mode 100644 index 0000000..0a2d6ec --- /dev/null +++ b/src/scripttools/debugging/images/stepover.png diff --git a/src/scripttools/debugging/images/win/closetab.png b/src/scripttools/debugging/images/win/closetab.png Binary files differnew file mode 100644 index 0000000..ef9e020 --- /dev/null +++ b/src/scripttools/debugging/images/win/closetab.png diff --git a/src/scripttools/debugging/images/win/next.png b/src/scripttools/debugging/images/win/next.png Binary files differnew file mode 100644 index 0000000..8df4127 --- /dev/null +++ b/src/scripttools/debugging/images/win/next.png diff --git a/src/scripttools/debugging/images/win/plus.png b/src/scripttools/debugging/images/win/plus.png Binary files differnew file mode 100644 index 0000000..ecf0589 --- /dev/null +++ b/src/scripttools/debugging/images/win/plus.png diff --git a/src/scripttools/debugging/images/win/previous.png b/src/scripttools/debugging/images/win/previous.png Binary files differnew file mode 100644 index 0000000..0780bc2 --- /dev/null +++ b/src/scripttools/debugging/images/win/previous.png diff --git a/src/scripttools/debugging/images/wrap.png b/src/scripttools/debugging/images/wrap.png Binary files differnew file mode 100644 index 0000000..90f18d9 --- /dev/null +++ b/src/scripttools/debugging/images/wrap.png diff --git a/src/scripttools/debugging/qscriptbreakpointdata.cpp b/src/scripttools/debugging/qscriptbreakpointdata.cpp new file mode 100644 index 0000000..9762ca4 --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointdata.cpp @@ -0,0 +1,393 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptbreakpointdata_p.h" + +#include <QtCore/qdatastream.h> +#include <QtCore/qstring.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptBreakpointData + \internal + + \brief The QScriptBreakpointData class contains data associated with a breakpoint. +*/ + +class QScriptBreakpointDataPrivate +{ +public: + QScriptBreakpointDataPrivate(); + ~QScriptBreakpointDataPrivate(); + + void init(int ln); + + qint64 scriptId; + QString fileName; + int lineNumber; + bool enabled; + bool singleShot; + int ignoreCount; + QString condition; + QVariant data; + int hitCount; +}; + +QScriptBreakpointDataPrivate::QScriptBreakpointDataPrivate() +{ +} + +QScriptBreakpointDataPrivate::~QScriptBreakpointDataPrivate() +{ +} + +void QScriptBreakpointDataPrivate::init(int ln) +{ + scriptId = -1; + lineNumber = ln; + enabled = true; + singleShot = false; + ignoreCount = 0; + hitCount = 0; +} + +/*! + Constructs an empty QScriptBreakpointData. +*/ +QScriptBreakpointData::QScriptBreakpointData() + : d_ptr(new QScriptBreakpointDataPrivate) +{ + d_ptr->init(/*lineNumber=*/-1); +} + +/*! + Constructs a QScriptBreakpointData with the given \a lineNumber. +*/ +QScriptBreakpointData::QScriptBreakpointData(qint64 scriptId, int lineNumber) + : d_ptr(new QScriptBreakpointDataPrivate) +{ + d_ptr->init(lineNumber); + d_ptr->scriptId = scriptId; +} + +/*! + Constructs a QScriptBreakpointData with the given \a lineNumber. +*/ +QScriptBreakpointData::QScriptBreakpointData(const QString &fileName, int lineNumber) + : d_ptr(new QScriptBreakpointDataPrivate) +{ + d_ptr->init(lineNumber); + d_ptr->fileName = fileName; +} + +/*! + Constructs a QScriptBreakpointData that is a copy of \a other. +*/ +QScriptBreakpointData::QScriptBreakpointData(const QScriptBreakpointData &other) + : d_ptr(new QScriptBreakpointDataPrivate) +{ + Q_ASSERT(other.d_ptr != 0); + *d_ptr = *other.d_ptr; +} + +/*! + Destroys this QScriptBreakpointData. +*/ +QScriptBreakpointData::~QScriptBreakpointData() +{ + delete d_ptr; +} + +/*! + Assigns \a other to this QScriptBreakpointData. +*/ +QScriptBreakpointData &QScriptBreakpointData::operator=(const QScriptBreakpointData &other) +{ + Q_ASSERT(d_ptr != 0); + Q_ASSERT(other.d_ptr != 0); + *d_ptr = *other.d_ptr; + return *this; +} + +qint64 QScriptBreakpointData::scriptId() const +{ + Q_D(const QScriptBreakpointData); + return d->scriptId; +} + +void QScriptBreakpointData::setScriptId(qint64 id) +{ + Q_D(QScriptBreakpointData); + d->scriptId = id; +} + +QString QScriptBreakpointData::fileName() const +{ + Q_D(const QScriptBreakpointData); + return d->fileName; +} + +void QScriptBreakpointData::setFileName(const QString &fileName) +{ + Q_D(QScriptBreakpointData); + d->fileName = fileName; +} + +/*! + Returns the breakpoint line number. +*/ +int QScriptBreakpointData::lineNumber() const +{ + Q_D(const QScriptBreakpointData); + return d->lineNumber; +} + +/*! + Sets the breakpoint line number to \a lineNumber. +*/ +void QScriptBreakpointData::setLineNumber(int lineNumber) +{ + Q_D(QScriptBreakpointData); + d->lineNumber = lineNumber; +} + +/*! + Returns true if the breakpoint is enabled, false otherwise. +*/ +bool QScriptBreakpointData::isEnabled() const +{ + Q_D(const QScriptBreakpointData); + return d->enabled; +} + +/*! + Sets the \a enabled state of the breakpoint. +*/ +void QScriptBreakpointData::setEnabled(bool enabled) +{ + Q_D(QScriptBreakpointData); + d->enabled = enabled; +} + +/*! + Returns true if the breakpoint is single-shot, false otherwise. +*/ +bool QScriptBreakpointData::isSingleShot() const +{ + Q_D(const QScriptBreakpointData); + return d->singleShot; +} + +/*! + Sets the \a singleShot state of the breakpoint. +*/ +void QScriptBreakpointData::setSingleShot(bool singleShot) +{ + Q_D(QScriptBreakpointData); + d->singleShot = singleShot; +} + +/*! + Returns the ignore count of the breakpoint. +*/ +int QScriptBreakpointData::ignoreCount() const +{ + Q_D(const QScriptBreakpointData); + return d->ignoreCount; +} + +/*! + Sets the ignore \a count of the breakpoint. +*/ +void QScriptBreakpointData::setIgnoreCount(int count) +{ + Q_D(QScriptBreakpointData); + d->ignoreCount = count; +} + +/*! + If the ignore count is 0, this function increments the hit count and + returns true. Otherwise, it decrements the ignore count and returns + false. +*/ +bool QScriptBreakpointData::hit() +{ + Q_D(QScriptBreakpointData); + if (d->ignoreCount == 0) { + ++d->hitCount; + return true; + } + --d->ignoreCount; + return false; +} + +/*! + Returns the hit count of the breakpoint (the number of times the + breakpoint has been triggered). +*/ +int QScriptBreakpointData::hitCount() const +{ + Q_D(const QScriptBreakpointData); + return d->hitCount; +} + +/*! + Returns the condition of the breakpoint. +*/ +QString QScriptBreakpointData::condition() const +{ + Q_D(const QScriptBreakpointData); + return d->condition; +} + +/*! + Sets the \a condition of the breakpoint. +*/ +void QScriptBreakpointData::setCondition(const QString &condition) +{ + Q_D(QScriptBreakpointData); + d->condition = condition; +} + +/*! + Returns custom data associated with the breakpoint. +*/ +QVariant QScriptBreakpointData::data() const +{ + Q_D(const QScriptBreakpointData); + return d->data; +} + +/*! + Sets custom \a data associated with the breakpoint. +*/ +void QScriptBreakpointData::setData(const QVariant &data) +{ + Q_D(QScriptBreakpointData); + d->data = data; +} + +bool QScriptBreakpointData::isValid() const +{ + Q_D(const QScriptBreakpointData); + return (((d->scriptId != -1) || !d->fileName.isEmpty()) + && (d->lineNumber != -1)); +} + +/*! + Returns true if this QScriptBreakpointData is equal to the \a other + data, otherwise returns false. +*/ +bool QScriptBreakpointData::operator==(const QScriptBreakpointData &other) const +{ + Q_D(const QScriptBreakpointData); + const QScriptBreakpointDataPrivate *od = other.d_func(); + if (d == od) + return true; + if (!d || !od) + return false; + return ((d->scriptId == od->scriptId) + && (d->fileName == od->fileName) + && (d->lineNumber == od->lineNumber) + && (d->enabled == od->enabled) + && (d->singleShot == od->singleShot) + && (d->condition == od->condition) + && (d->ignoreCount == od->ignoreCount) + && (d->data == od->data) + && (d->hitCount == od->hitCount)); +} + +/*! + Returns true if this QScriptBreakpointData is not equal to the \a + other data, otherwise returns false. +*/ +bool QScriptBreakpointData::operator!=(const QScriptBreakpointData &other) const +{ + return !(*this == other); +} + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QScriptBreakpointData &data) + \relates QScriptBreakpointData + + Writes the given \a data to the specified \a stream. +*/ +QDataStream &operator<<(QDataStream &out, const QScriptBreakpointData &data) +{ + const QScriptBreakpointDataPrivate *d = data.d_ptr; + out << d->scriptId; + out << d->fileName; + out << d->lineNumber; + out << d->enabled; + out << d->singleShot; + out << d->ignoreCount; + out << d->condition; + out << d->data; + out << d->hitCount; + return out; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QScriptBreakpointData &data) + \relates QScriptBreakpointData + + Reads a QScriptBreakpointData from the specified \a stream into the + given \a data. +*/ +QDataStream &operator>>(QDataStream &in, QScriptBreakpointData &data) +{ + QScriptBreakpointDataPrivate *d = data.d_ptr; + in >> d->scriptId; + in >> d->fileName; + in >> d->lineNumber; + in >> d->enabled; + in >> d->singleShot; + in >> d->ignoreCount; + in >> d->condition; + in >> d->data; + in >> d->hitCount; + return in; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptbreakpointdata_p.h b/src/scripttools/debugging/qscriptbreakpointdata_p.h new file mode 100644 index 0000000..c1ff033 --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointdata_p.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTBREAKPOINTDATA_P_H +#define QSCRIPTBREAKPOINTDATA_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qmap.h> + +QT_BEGIN_NAMESPACE + +class QDataStream; +class QVariant; + +class QScriptBreakpointDataPrivate; +class Q_AUTOTEST_EXPORT QScriptBreakpointData +{ +public: + friend Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptBreakpointData &); + friend Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptBreakpointData &); + + QScriptBreakpointData(); + QScriptBreakpointData(qint64 scriptId, int lineNumber); + QScriptBreakpointData(const QString &fileName, int lineNumber); + QScriptBreakpointData(const QScriptBreakpointData &other); + ~QScriptBreakpointData(); + QScriptBreakpointData &operator=(const QScriptBreakpointData &other); + + bool isValid() const; + + // location + qint64 scriptId() const; + void setScriptId(qint64 id); + + QString fileName() const; + void setFileName(const QString &fileName); + + int lineNumber() const; + void setLineNumber(int lineNumber); + + // data + bool isEnabled() const; + void setEnabled(bool enabled); + + bool isSingleShot() const; + void setSingleShot(bool singleShot); + + int ignoreCount() const; + void setIgnoreCount(int count); + + QString condition() const; + void setCondition(const QString &condition); + + QVariant data() const; + void setData(const QVariant &data); + + bool hit(); + + // statistics + int hitCount() const; + + + bool operator==(const QScriptBreakpointData &other) const; + bool operator!=(const QScriptBreakpointData &other) const; + +private: + QScriptBreakpointDataPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptBreakpointData) +}; + +typedef QMap<int, QScriptBreakpointData> QScriptBreakpointMap; + +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptBreakpointData &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptBreakpointData &); + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptbreakpointsmodel.cpp b/src/scripttools/debugging/qscriptbreakpointsmodel.cpp new file mode 100644 index 0000000..aea38aa --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointsmodel.cpp @@ -0,0 +1,497 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptbreakpointsmodel_p.h" +#include "qscriptdebuggerjobschedulerinterface_p.h" +#include "qscriptdebuggercommandschedulerjob_p.h" +#include "qscriptdebuggercommandschedulerfrontend_p.h" + +#include "private/qabstractitemmodel_p.h" + +#include <QtCore/qpair.h> +#include <QtGui/qicon.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptBreakpointsModel + \internal +*/ + +class QScriptBreakpointsModelPrivate + : public QAbstractItemModelPrivate +{ + Q_DECLARE_PUBLIC(QScriptBreakpointsModel) +public: + QScriptBreakpointsModelPrivate(); + ~QScriptBreakpointsModelPrivate(); + + QScriptDebuggerJobSchedulerInterface *jobScheduler; + QScriptDebuggerCommandSchedulerInterface *commandScheduler; + QList<QPair<int, QScriptBreakpointData> > breakpoints; +}; + +QScriptBreakpointsModelPrivate::QScriptBreakpointsModelPrivate() +{ +} + +QScriptBreakpointsModelPrivate::~QScriptBreakpointsModelPrivate() +{ +} + +QScriptBreakpointsModel::QScriptBreakpointsModel( + QScriptDebuggerJobSchedulerInterface *jobScheduler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler, + QObject *parent) + : QAbstractItemModel(*new QScriptBreakpointsModelPrivate, parent) +{ + Q_D(QScriptBreakpointsModel); + d->jobScheduler = jobScheduler; + d->commandScheduler = commandScheduler; +} + +QScriptBreakpointsModel::~QScriptBreakpointsModel() +{ +} + +namespace +{ + +class SetBreakpointJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SetBreakpointJob(const QScriptBreakpointData &data, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_data(data) + { } + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleSetBreakpoint(m_data); + } + + void handleResponse(const QScriptDebuggerResponse &, int) + { + finish(); + } + +private: + QScriptBreakpointData m_data; +}; + +} // namespace + +/*! + Sets a breakpoint defined by the given \a data. + A new row will be inserted into the model if the breakpoint could be + successfully set. +*/ +void QScriptBreakpointsModel::setBreakpoint(const QScriptBreakpointData &data) +{ + Q_D(QScriptBreakpointsModel); + QScriptDebuggerJob *job = new SetBreakpointJob(data, d->commandScheduler); + d->jobScheduler->scheduleJob(job); +} + +namespace +{ + +class SetBreakpointDataJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SetBreakpointDataJob(int id, const QScriptBreakpointData &data, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_id(id), m_data(data) + { } + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleSetBreakpointData(m_id, m_data); + } + + void handleResponse(const QScriptDebuggerResponse &, int) + { + finish(); + } + +private: + int m_id; + QScriptBreakpointData m_data; +}; + +} // namespace + +/*! + Sets the \a data associated with the breakpoint identified by \a id. + A dataChanged() signal will be emitted if the breakpoint data could + be successfully changed. +*/ +void QScriptBreakpointsModel::setBreakpointData(int id, const QScriptBreakpointData &data) +{ + Q_D(QScriptBreakpointsModel); + QScriptDebuggerJob *job = new SetBreakpointDataJob(id, data, d->commandScheduler); + d->jobScheduler->scheduleJob(job); +} + +namespace +{ + +class DeleteBreakpointJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + DeleteBreakpointJob(int id, QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_id(id) + { } + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleDeleteBreakpoint(m_id); + } + + void handleResponse(const QScriptDebuggerResponse &, int) + { + finish(); + } + +private: + int m_id; +}; + +} // namespace + +/*! + Deletes the breakpoint with the given \a id. + The corresponding row in the model will be removed if the breakpoint + was successfully deleted. +*/ +void QScriptBreakpointsModel::deleteBreakpoint(int id) +{ + Q_D(QScriptBreakpointsModel); + QScriptDebuggerJob *job = new DeleteBreakpointJob(id, d->commandScheduler); + d->jobScheduler->scheduleJob(job); +} + +/*! + Adds a breakpoint to the model. This function does not actually set + a breakpoint (i.e. it doesn't communicate with the debugger). +*/ +void QScriptBreakpointsModel::addBreakpoint(int id, const QScriptBreakpointData &data) +{ + Q_D(QScriptBreakpointsModel); + int rowIndex = d->breakpoints.size(); + beginInsertRows(QModelIndex(), rowIndex, rowIndex); + d->breakpoints.append(qMakePair(id, data)); + endInsertRows(); +} + +/*! + Modify the \a data of breakpoint \a id. +*/ +void QScriptBreakpointsModel::modifyBreakpoint(int id, const QScriptBreakpointData &data) +{ + Q_D(QScriptBreakpointsModel); + for (int i = 0; i < d->breakpoints.size(); ++i) { + if (d->breakpoints.at(i).first == id) { + d->breakpoints[i] = qMakePair(id, data); + emit dataChanged(createIndex(i, 0), createIndex(i, columnCount()-1)); + break; + } + } +} + +/*! + Remove the breakpoint identified by \a id from the model. This + function does not delete the breakpoint (i.e. it doesn't communicate + with the debugger). +*/ +void QScriptBreakpointsModel::removeBreakpoint(int id) +{ + Q_D(QScriptBreakpointsModel); + for (int i = 0; i < d->breakpoints.size(); ++i) { + if (d->breakpoints.at(i).first == id) { + beginRemoveRows(QModelIndex(), i, i); + d->breakpoints.removeAt(i); + endRemoveRows(); + break; + } + } +} + +/*! + Returns the id of the breakpoint at the given \a row. +*/ +int QScriptBreakpointsModel::breakpointIdAt(int row) const +{ + Q_D(const QScriptBreakpointsModel); + return d->breakpoints.at(row).first; +} + +/*! + Returns the data for the breakpoint at the given \a row. +*/ +QScriptBreakpointData QScriptBreakpointsModel::breakpointDataAt(int row) const +{ + Q_D(const QScriptBreakpointsModel); + return d->breakpoints.at(row).second; +} + +QScriptBreakpointData QScriptBreakpointsModel::breakpointData(int id) const +{ + Q_D(const QScriptBreakpointsModel); + for (int i = 0; i < d->breakpoints.size(); ++i) { + if (d->breakpoints.at(i).first == id) + return d->breakpoints.at(i).second; + } + return QScriptBreakpointData(); +} + +/*! + Tries to find a breakpoint with the given \a scriptId and \a + lineNumber. Returns the id of the first breakpoint that matches, or + -1 if no such breakpoint is found. +*/ +int QScriptBreakpointsModel::resolveBreakpoint(qint64 scriptId, int lineNumber) const +{ + Q_D(const QScriptBreakpointsModel); + for (int i = 0; i < d->breakpoints.size(); ++i) { + if ((d->breakpoints.at(i).second.scriptId() == scriptId) + && (d->breakpoints.at(i).second.lineNumber() == lineNumber)) { + return d->breakpoints.at(i).first; + } + } + return -1; +} + +int QScriptBreakpointsModel::resolveBreakpoint(const QString &fileName, int lineNumber) const +{ + Q_D(const QScriptBreakpointsModel); + for (int i = 0; i < d->breakpoints.size(); ++i) { + if ((d->breakpoints.at(i).second.fileName() == fileName) + && (d->breakpoints.at(i).second.lineNumber() == lineNumber)) { + return d->breakpoints.at(i).first; + } + } + return -1; +} + +/*! + \reimp +*/ +QModelIndex QScriptBreakpointsModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_D(const QScriptBreakpointsModel); + if (parent.isValid()) + return QModelIndex(); + if ((row < 0) || (row >= d->breakpoints.size())) + return QModelIndex(); + if ((column < 0) || (column >= columnCount())) + return QModelIndex(); + return createIndex(row, column); +} + +/*! + \reimp +*/ +QModelIndex QScriptBreakpointsModel::parent(const QModelIndex &) const +{ + return QModelIndex(); +} + +/*! + \reimp +*/ +int QScriptBreakpointsModel::columnCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return 6; + return 0; +} + +/*! + \reimp +*/ +int QScriptBreakpointsModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const QScriptBreakpointsModel); + if (!parent.isValid()) + return d->breakpoints.size(); + return 0; +} + +/*! + \reimp +*/ +QVariant QScriptBreakpointsModel::data(const QModelIndex &index, int role) const +{ + Q_D(const QScriptBreakpointsModel); + if (!index.isValid() || (index.row() >= d->breakpoints.size())) + return QVariant(); + const QPair<int, QScriptBreakpointData> &item = d->breakpoints.at(index.row()); + if (role == Qt::DisplayRole) { + if (index.column() == 0) + return item.first; + else if (index.column() == 1) { + QString loc = item.second.fileName(); + if (loc.isEmpty()) + loc = QString::fromLatin1("<anonymous script, id=%0>").arg(item.second.scriptId()); + loc.append(QString::fromLatin1(":%0").arg(item.second.lineNumber())); + return loc; + } else if (index.column() == 2) { + if (!item.second.condition().isEmpty()) + return item.second.condition(); + } else if (index.column() == 3) { + if (item.second.ignoreCount() != 0) + return item.second.ignoreCount(); + } else if (index.column() == 5) { + return item.second.hitCount(); + } + } else if (role == Qt::CheckStateRole) { + if (index.column() == 0) { + return item.second.isEnabled() ? Qt::Checked : Qt::Unchecked; + } else if (index.column() == 4) { + return item.second.isSingleShot() ? Qt::Checked : Qt::Unchecked; + } + } else if (role == Qt::EditRole) { + if (index.column() == 2) + return item.second.condition(); + else if (index.column() == 3) + return item.second.ignoreCount(); + } + return QVariant(); +} + +/*! + \reimp +*/ +bool QScriptBreakpointsModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_D(QScriptBreakpointsModel); + if (!index.isValid() || (index.row() >= d->breakpoints.size())) + return false; + const QPair<int, QScriptBreakpointData> &item = d->breakpoints.at(index.row()); + QScriptBreakpointData modifiedData; + int col = index.column(); + if ((col == 0) || (col == 4)) { + if (role == Qt::CheckStateRole) { + modifiedData = item.second; + if (col == 0) + modifiedData.setEnabled(value.toInt() == Qt::Checked); + else + modifiedData.setSingleShot(value.toInt() == Qt::Checked); + } + } else if (col == 2) { + if (role == Qt::EditRole) { + modifiedData = item.second; + modifiedData.setCondition(value.toString()); + } + } else if (col == 3) { + if (role == Qt::EditRole) { + modifiedData = item.second; + modifiedData.setIgnoreCount(value.toInt()); + } + } + if (!modifiedData.isValid()) + return false; + QScriptDebuggerJob *job = new SetBreakpointDataJob(item.first, modifiedData, d->commandScheduler); + d->jobScheduler->scheduleJob(job); + return true; +} + +/*! + \reimp +*/ +QVariant QScriptBreakpointsModel::headerData(int section, Qt::Orientation orient, int role) const +{ + if (orient == Qt::Horizontal) { + if (role == Qt::DisplayRole) { + if (section == 0) + return QObject::tr("ID"); + else if (section == 1) + return QObject::tr("Location"); + else if (section == 2) + return QObject::tr("Condition"); + else if (section == 3) + return QObject::tr("Ignore-count"); + else if (section == 4) + return QObject::tr("Single-shot"); + else if (section == 5) + return QObject::tr("Hit-count"); + } + } + return QVariant(); +} + +/*! + \reimp +*/ +Qt::ItemFlags QScriptBreakpointsModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + Qt::ItemFlags ret = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + switch (index.column()) { + case 0: + ret |= Qt::ItemIsUserCheckable; + break; + case 1: + break; + case 2: + ret |= Qt::ItemIsEditable; + break; + case 3: + ret |= Qt::ItemIsEditable; + break; + case 4: + ret |= Qt::ItemIsUserCheckable; + break; + } + return ret; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptbreakpointsmodel_p.h b/src/scripttools/debugging/qscriptbreakpointsmodel_p.h new file mode 100644 index 0000000..7bdc696 --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointsmodel_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTBREAKPOINTSMODEL_P_H +#define QSCRIPTBREAKPOINTSMODEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qabstractitemmodel.h> + +#include "qscriptbreakpointdata_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerJobSchedulerInterface; +class QScriptDebuggerCommandSchedulerInterface; + +class QScriptBreakpointsModelPrivate; +class Q_AUTOTEST_EXPORT QScriptBreakpointsModel + : public QAbstractItemModel +{ + Q_OBJECT +public: + QScriptBreakpointsModel(QScriptDebuggerJobSchedulerInterface *jobScheduler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler, + QObject *parent = 0); + ~QScriptBreakpointsModel(); + + void setBreakpoint(const QScriptBreakpointData &data); + void setBreakpointData(int id, const QScriptBreakpointData &data); + void deleteBreakpoint(int id); + + void addBreakpoint(int id, const QScriptBreakpointData &data); + void modifyBreakpoint(int id, const QScriptBreakpointData &data); + void removeBreakpoint(int id); + + int breakpointIdAt(int row) const; + QScriptBreakpointData breakpointDataAt(int row) const; + QScriptBreakpointData breakpointData(int id) const; + + int resolveBreakpoint(qint64 scriptId, int lineNumber) const; + int resolveBreakpoint(const QString &fileName, int lineNumber) const; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation, int role = Qt::DisplayRole) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + +private: + Q_DECLARE_PRIVATE(QScriptBreakpointsModel) + Q_DISABLE_COPY(QScriptBreakpointsModel) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptbreakpointswidget.cpp b/src/scripttools/debugging/qscriptbreakpointswidget.cpp new file mode 100644 index 0000000..aea1fe7 --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointswidget.cpp @@ -0,0 +1,393 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptbreakpointswidget_p.h" +#include "qscriptbreakpointswidgetinterface_p_p.h" +#include "qscriptbreakpointsmodel_p.h" +#include "qscriptdebuggerscriptsmodel_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qaction.h> +#include <QtGui/qcompleter.h> +#include <QtGui/qheaderview.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qmessagebox.h> +#include <QtGui/qtoolbar.h> +#include <QtGui/qtoolbutton.h> +#include <QtGui/qtreeview.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qstyleditemdelegate.h> +#include <QtGui/qevent.h> +#include <QtScript/qscriptengine.h> + +QT_BEGIN_NAMESPACE + +class QScriptNewBreakpointWidget : public QWidget +{ + Q_OBJECT +public: + QScriptNewBreakpointWidget(QWidget *parent = 0) + : QWidget(parent) { + QString system = QLatin1String("win"); + QHBoxLayout *hboxLayout = new QHBoxLayout(this); +#ifdef Q_OS_MAC + system = QLatin1String("mac"); +#else + hboxLayout->setSpacing(6); + hboxLayout->setMargin(0); +#endif + + toolClose = new QToolButton(this); + toolClose->setIcon(QIcon(QString::fromUtf8(":/qt/scripttools/debugging/images/%1/closetab.png").arg(system))); + toolClose->setAutoRaise(true); + toolClose->setText(QObject::tr("Close")); + hboxLayout->addWidget(toolClose); + + fileNameEdit = new QLineEdit(); + setFocusProxy(fileNameEdit); + QRegExp locationRegExp(QString::fromLatin1(".+:[0-9]+")); + QRegExpValidator *validator = new QRegExpValidator(locationRegExp, fileNameEdit); + fileNameEdit->setValidator(validator); + hboxLayout->addWidget(fileNameEdit); + + toolOk = new QToolButton(this); + toolOk->setIcon(QIcon(QString::fromUtf8(":/qt/scripttools/debugging/images/%1/plus.png").arg(system))); + toolOk->setAutoRaise(true); + toolOk->setEnabled(false); + hboxLayout->addWidget(toolOk); + + QObject::connect(toolClose, SIGNAL(clicked()), this, SLOT(hide())); + QObject::connect(toolOk, SIGNAL(clicked()), this, SLOT(onOkClicked())); + QObject::connect(fileNameEdit, SIGNAL(textChanged(QString)), + this, SLOT(onTextChanged())); + QObject::connect(fileNameEdit, SIGNAL(returnPressed()), + this, SLOT(onOkClicked())); + } + + void setCompleter(QCompleter *comp) + { fileNameEdit->setCompleter(comp); } + +Q_SIGNALS: + void newBreakpointRequest(const QString &fileName, int lineNumber); + +protected: + void keyPressEvent(QKeyEvent *e) + { + if (e->key() == Qt::Key_Escape) + hide(); + else + QWidget::keyPressEvent(e); + } + +private Q_SLOTS: + void onOkClicked() + { + QString location = fileNameEdit->text(); + fileNameEdit->clear(); + QString fileName = location.left(location.lastIndexOf(QLatin1Char(':'))); + int lineNumber = location.mid(fileName.length()+1).toInt(); + emit newBreakpointRequest(fileName, lineNumber); + } + + void onTextChanged() + { + toolOk->setEnabled(fileNameEdit->hasAcceptableInput()); + } + +private: + QLineEdit *fileNameEdit; + QToolButton *toolClose; + QToolButton *toolOk; +}; + + + +class QScriptBreakpointsWidgetPrivate + : public QScriptBreakpointsWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptBreakpointsWidget) +public: + QScriptBreakpointsWidgetPrivate(); + ~QScriptBreakpointsWidgetPrivate(); + + void _q_newBreakpoint(); + void _q_deleteBreakpoint(); + void _q_onCurrentChanged(const QModelIndex &index); + void _q_onNewBreakpointRequest(const QString &fileName, int lineNumber); + + static QPixmap pixmap(const QString &path) + { + static QString prefix = QString::fromLatin1(":/qt/scripttools/debugging/images/"); + return QPixmap(prefix + path); + } + + QTreeView *view; + QScriptNewBreakpointWidget *newBreakpointWidget; + QAction *deleteBreakpointAction; + QScriptDebuggerScriptsModel *scriptsModel; +}; + +QScriptBreakpointsWidgetPrivate::QScriptBreakpointsWidgetPrivate() +{ +} + +QScriptBreakpointsWidgetPrivate::~QScriptBreakpointsWidgetPrivate() +{ +} + +void QScriptBreakpointsWidgetPrivate::_q_newBreakpoint() +{ + newBreakpointWidget->show(); + newBreakpointWidget->setFocus(Qt::OtherFocusReason); +} + +void QScriptBreakpointsWidgetPrivate::_q_deleteBreakpoint() +{ + Q_Q(QScriptBreakpointsWidget); + QModelIndex index = view->currentIndex(); + if (index.isValid()) { + int id = q->breakpointsModel()->breakpointIdAt(index.row()); + q->breakpointsModel()->deleteBreakpoint(id); + } +} + +void QScriptBreakpointsWidgetPrivate::_q_onCurrentChanged(const QModelIndex &index) +{ + deleteBreakpointAction->setEnabled(index.isValid()); +} + +void QScriptBreakpointsWidgetPrivate::_q_onNewBreakpointRequest(const QString &fileName, int lineNumber) +{ + QScriptBreakpointData data(fileName, lineNumber); + q_func()->breakpointsModel()->setBreakpoint(data); +} + +class QScriptBreakpointsItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + QScriptBreakpointsItemDelegate(QObject *parent = 0) + : QStyledItemDelegate(parent) {} + + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const + { + QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index); + if (index.column() == 2) { + // condition + QLineEdit *le = qobject_cast<QLineEdit*>(editor); + if (le) { + QObject::connect(le, SIGNAL(textEdited(QString)), + this, SLOT(validateInput(QString))); + } + } + return editor; + } + + bool eventFilter(QObject *editor, QEvent *event) + { +#if QT_VERSION >= 0x040500 + if (QLineEdit *le = qobject_cast<QLineEdit*>(editor)) { + if (event->type() == QEvent::KeyPress) { + int key = static_cast<QKeyEvent*>(event)->key(); + if ((key == Qt::Key_Enter) || (key == Qt::Key_Return)) { + if (QScriptEngine::checkSyntax(le->text()).state() != QScriptSyntaxCheckResult::Valid) { + // ignore when script contains syntax error + return true; + } + } + } + } +#endif + return QStyledItemDelegate::eventFilter(editor, event); + } + + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const + { +#if QT_VERSION >= 0x040500 + if (index.column() == 2) { + // check that the syntax is OK + QString condition = qobject_cast<QLineEdit*>(editor)->text(); + if (QScriptEngine::checkSyntax(condition).state() != QScriptSyntaxCheckResult::Valid) + return; + } +#endif + QStyledItemDelegate::setModelData(editor, model, index); + } + +private Q_SLOTS: + void validateInput(const QString &text) + { + QWidget *editor = qobject_cast<QWidget*>(sender()); + QPalette pal = editor->palette(); + QColor col; +#if QT_VERSION >= 0x040500 + bool ok = (QScriptEngine::checkSyntax(text).state() == QScriptSyntaxCheckResult::Valid); +#else + bool ok = true; +#endif + if (ok) { + col = Qt::white; + } else { + QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax( + text + QLatin1Char('\n')); + if (result.state() == QScriptSyntaxCheckResult::Intermediate) + col = QColor(255, 240, 192); + else + col = QColor(255, 102, 102); + } + pal.setColor(QPalette::Active, QPalette::Base, col); + editor->setPalette(pal); + } +}; + +QScriptBreakpointsWidget::QScriptBreakpointsWidget(QWidget *parent) + : QScriptBreakpointsWidgetInterface(*new QScriptBreakpointsWidgetPrivate, parent, 0) +{ + Q_D(QScriptBreakpointsWidget); + d->view = new QTreeView(); +// d->view->setEditTriggers(QAbstractItemView::NoEditTriggers); + d->view->setEditTriggers(QAbstractItemView::AllEditTriggers); +// d->view->setAlternatingRowColors(true); + d->view->setRootIsDecorated(false); + d->view->setSelectionBehavior(QAbstractItemView::SelectRows); +// d->view->header()->hide(); +// d->view->header()->setDefaultAlignment(Qt::AlignLeft); +// d->view->header()->setResizeMode(QHeaderView::ResizeToContents); + d->view->setItemDelegate(new QScriptBreakpointsItemDelegate(this)); + + d->newBreakpointWidget = new QScriptNewBreakpointWidget(); + d->newBreakpointWidget->hide(); + QObject::connect(d->newBreakpointWidget, SIGNAL(newBreakpointRequest(QString,int)), + this, SLOT(_q_onNewBreakpointRequest(QString,int))); + + QIcon newBreakpointIcon; + newBreakpointIcon.addPixmap(d->pixmap(QString::fromLatin1("new.png")), QIcon::Normal); + QAction *newBreakpointAction = new QAction(newBreakpointIcon, QObject::tr("New"), this); + QObject::connect(newBreakpointAction, SIGNAL(triggered()), + this, SLOT(_q_newBreakpoint())); + + QIcon deleteBreakpointIcon; + deleteBreakpointIcon.addPixmap(d->pixmap(QString::fromLatin1("delete.png")), QIcon::Normal); + d->deleteBreakpointAction = new QAction(deleteBreakpointIcon, QObject::tr("Delete"), this); + d->deleteBreakpointAction->setEnabled(false); + QObject::connect(d->deleteBreakpointAction, SIGNAL(triggered()), + this, SLOT(_q_deleteBreakpoint())); + + QToolBar *toolBar = new QToolBar(); + toolBar->addAction(newBreakpointAction); + toolBar->addAction(d->deleteBreakpointAction); + + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->addWidget(toolBar); + vbox->addWidget(d->newBreakpointWidget); + vbox->addWidget(d->view); +} + +QScriptBreakpointsWidget::~QScriptBreakpointsWidget() +{ +} + +/*! + \reimp +*/ +QScriptBreakpointsModel *QScriptBreakpointsWidget::breakpointsModel() const +{ + Q_D(const QScriptBreakpointsWidget); + return qobject_cast<QScriptBreakpointsModel*>(d->view->model()); +} + +/*! + \reimp +*/ +void QScriptBreakpointsWidget::setBreakpointsModel(QScriptBreakpointsModel *model) +{ + Q_D(QScriptBreakpointsWidget); + d->view->setModel(model); + d->view->header()->resizeSection(0, 50); + QObject::connect(d->view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(_q_onCurrentChanged(QModelIndex))); +} + +/*! + \reimp +*/ +QScriptDebuggerScriptsModel *QScriptBreakpointsWidget::scriptsModel() const +{ + Q_D(const QScriptBreakpointsWidget); + return d->scriptsModel; +} + +/*! + \reimp +*/ +void QScriptBreakpointsWidget::setScriptsModel(QScriptDebuggerScriptsModel *model) +{ + Q_D(QScriptBreakpointsWidget); + d->scriptsModel = model; + QCompleter *completer = new QCompleter(model, this); + completer->setCompletionRole(Qt::DisplayRole); + d->newBreakpointWidget->setCompleter(completer); +} + +/*! + \reimp +*/ +void QScriptBreakpointsWidget::keyPressEvent(QKeyEvent *e) +{ + Q_D(QScriptBreakpointsWidget); + if (e->key() == Qt::Key_Delete) { + QModelIndex index = d->view->currentIndex(); + if (!index.isValid()) + return; + int id = breakpointsModel()->breakpointIdAt(index.row()); + breakpointsModel()->deleteBreakpoint(id); + } +} + +QT_END_NAMESPACE + +#include "qscriptbreakpointswidget.moc" + +#include "moc_qscriptbreakpointswidget_p.cpp" diff --git a/src/scripttools/debugging/qscriptbreakpointswidget_p.h b/src/scripttools/debugging/qscriptbreakpointswidget_p.h new file mode 100644 index 0000000..458883e --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointswidget_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTBREAKPOINTSWIDGET_P_H +#define QSCRIPTBREAKPOINTSWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptbreakpointswidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptBreakpointsWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptBreakpointsWidget: + public QScriptBreakpointsWidgetInterface +{ + Q_OBJECT +public: + QScriptBreakpointsWidget(QWidget *parent = 0); + ~QScriptBreakpointsWidget(); + + QScriptBreakpointsModel *breakpointsModel() const; + void setBreakpointsModel(QScriptBreakpointsModel *model); + + QScriptDebuggerScriptsModel *scriptsModel() const; + void setScriptsModel(QScriptDebuggerScriptsModel *model); + +protected: + void keyPressEvent(QKeyEvent *e); + +private: + Q_PRIVATE_SLOT(d_func(), void _q_newBreakpoint()) + Q_PRIVATE_SLOT(d_func(), void _q_deleteBreakpoint()) + Q_PRIVATE_SLOT(d_func(), void _q_onCurrentChanged(const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void _q_onNewBreakpointRequest(const QString &, int)) + + Q_DECLARE_PRIVATE(QScriptBreakpointsWidget) + Q_DISABLE_COPY(QScriptBreakpointsWidget) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptbreakpointswidgetinterface.cpp b/src/scripttools/debugging/qscriptbreakpointswidgetinterface.cpp new file mode 100644 index 0000000..6f23e01 --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointswidgetinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptbreakpointswidgetinterface_p.h" +#include "qscriptbreakpointswidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptBreakpointsWidgetInterfacePrivate::QScriptBreakpointsWidgetInterfacePrivate() +{ +} + +QScriptBreakpointsWidgetInterfacePrivate::~QScriptBreakpointsWidgetInterfacePrivate() +{ +} + +QScriptBreakpointsWidgetInterface::~QScriptBreakpointsWidgetInterface() +{ +} + +QScriptBreakpointsWidgetInterface::QScriptBreakpointsWidgetInterface( + QScriptBreakpointsWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptbreakpointswidgetinterface_p.h b/src/scripttools/debugging/qscriptbreakpointswidgetinterface_p.h new file mode 100644 index 0000000..c86f3e8 --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointswidgetinterface_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTBREAKPOINTSWIDGETINTERFACE_P_H +#define QSCRIPTBREAKPOINTSWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +QT_BEGIN_NAMESPACE + +class QScriptBreakpointsModel; +class QScriptDebuggerScriptsModel; + +class QScriptBreakpointsWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptBreakpointsWidgetInterface: + public QWidget +{ + Q_OBJECT +public: + ~QScriptBreakpointsWidgetInterface(); + + virtual QScriptBreakpointsModel *breakpointsModel() const = 0; + virtual void setBreakpointsModel(QScriptBreakpointsModel *model) = 0; + + virtual QScriptDebuggerScriptsModel *scriptsModel() const = 0; + virtual void setScriptsModel(QScriptDebuggerScriptsModel *model) = 0; + +Q_SIGNALS: + void currentScriptChanged(qint64 scriptId); + +protected: + QScriptBreakpointsWidgetInterface( + QScriptBreakpointsWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptBreakpointsWidgetInterface) + Q_DISABLE_COPY(QScriptBreakpointsWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptbreakpointswidgetinterface_p_p.h b/src/scripttools/debugging/qscriptbreakpointswidgetinterface_p_p.h new file mode 100644 index 0000000..f25afcb --- /dev/null +++ b/src/scripttools/debugging/qscriptbreakpointswidgetinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTBREAKPOINTSWIDGETINTERFACE_P_P_H +#define QSCRIPTBREAKPOINTSWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptBreakpointsWidgetInterface; +class QScriptBreakpointsWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptBreakpointsWidgetInterface) +public: + QScriptBreakpointsWidgetInterfacePrivate(); + ~QScriptBreakpointsWidgetInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptcompletionproviderinterface_p.h b/src/scripttools/debugging/qscriptcompletionproviderinterface_p.h new file mode 100644 index 0000000..db2077f --- /dev/null +++ b/src/scripttools/debugging/qscriptcompletionproviderinterface_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTCOMPLETIONPROVIDERINTERFACE_P_H +#define QSCRIPTCOMPLETIONPROVIDERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptCompletionTaskInterface; + +class Q_AUTOTEST_EXPORT QScriptCompletionProviderInterface +{ +public: + enum Option { + ConsoleCommandCompletion = 1 + }; + + virtual ~QScriptCompletionProviderInterface() {} + + virtual QScriptCompletionTaskInterface *createCompletionTask( + const QString &contents, int cursorPosition, + int frameIndex, int options) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptcompletiontask.cpp b/src/scripttools/debugging/qscriptcompletiontask.cpp new file mode 100644 index 0000000..3767505 --- /dev/null +++ b/src/scripttools/debugging/qscriptcompletiontask.cpp @@ -0,0 +1,305 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptcompletiontask_p.h" +#include "qscriptcompletiontaskinterface_p_p.h" +#include "qscriptdebuggerconsole_p.h" +#include "qscriptdebuggerconsolecommand_p.h" +#include "qscriptdebuggerconsolecommandmanager_p.h" + +#include "qscriptenginedebuggerfrontend_p.h" // ### kill +#include "qscriptdebuggerbackend_p.h" // ### kill +#include <QtScript/qscriptcontext.h> +#include <QtScript/qscriptvalue.h> +#include <QtScript/qscriptvalueiterator.h> + +#include "private/qobject_p.h" + +#include <QtCore/qset.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QScriptCompletionTaskPrivate + : public QScriptCompletionTaskInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptCompletionTask) +public: + QScriptCompletionTaskPrivate(); + ~QScriptCompletionTaskPrivate(); + + void completeScriptExpression(); + + QString contents; + int cursorPosition; + int frameIndex; + QScriptDebuggerFrontend *frontend; + QScriptDebuggerConsole *console; +}; + +QScriptCompletionTaskPrivate::QScriptCompletionTaskPrivate() +{ +} + +QScriptCompletionTaskPrivate::~QScriptCompletionTaskPrivate() +{ +} + +QScriptCompletionTask::QScriptCompletionTask( + const QString &contents, int cursorPosition, + int frameIndex, QScriptDebuggerFrontend *frontend, + QScriptDebuggerConsole *console, + QObject *parent) + : QScriptCompletionTaskInterface( + *new QScriptCompletionTaskPrivate, parent) +{ + Q_D(QScriptCompletionTask); + d->contents = contents; + d->cursorPosition = cursorPosition; + if ((frameIndex == -1) && console) + d->frameIndex = console->currentFrameIndex(); + else + d->frameIndex = frameIndex; + d->frontend = frontend; + d->console = console; +} + +QScriptCompletionTask::~QScriptCompletionTask() +{ +} + +namespace { + +static bool isIdentChar(const QChar &ch) +{ + static QChar underscore = QLatin1Char('_'); + return ch.isLetter() || (ch == underscore); +} + +static bool isPrefixOf(const QString &prefix, const QString &what) +{ + return ((what.length() > prefix.length()) + && what.startsWith(prefix)); +} + +} // namespace + +void QScriptCompletionTaskPrivate::completeScriptExpression() +{ + int pos = cursorPosition; + if ((pos > 0) && contents.at(pos-1).isNumber()) { + // completion of numbers is pointless + return; + } + + while ((pos > 0) && isIdentChar(contents.at(pos-1))) + --pos; + int pos2 = cursorPosition; + while ((pos2 < contents.size()-1) && isIdentChar(contents.at(pos2+1))) + ++pos2; + QString ident = contents.mid(pos, pos2 - pos + 1); + position = pos; + + QStringList path; + path.append(ident); + while ((pos > 0) && (contents.at(pos-1) == QLatin1Char('.'))) { + --pos; + pos2 = pos; + while ((pos > 0) && isIdentChar(contents.at(pos-1))) + --pos; + path.prepend(contents.mid(pos, pos2 - pos)); + } + + // ### super-cheating for now; have to use the async API + QScriptEngineDebuggerFrontend *edf = static_cast<QScriptEngineDebuggerFrontend*>(frontend); + QScriptDebuggerBackend *backend = edf->backend(); + QScriptContext *ctx = backend->context(frameIndex); + QScriptValueList objects; + QString prefix = path.last(); + QSet<QString> matches; + if (path.size() > 1) { + const QString &topLevelIdent = path.at(0); + QScriptValue obj; + if (topLevelIdent == QString::fromLatin1("this")) { + obj = ctx->thisObject(); + } else { + QScriptValueList scopeChain; +#if QT_VERSION >= 0x040500 + scopeChain = ctx->scopeChain(); +#else + scopeChain.append(ctx->activationObject()); +#endif + for (int i = 0; i < scopeChain.size(); ++i) { + QScriptValue oo = scopeChain.at(i).property(topLevelIdent); + if (oo.isObject()) { + obj = oo; + break; + } + } + } + for (int i = 1; obj.isObject() && (i < path.size()-1); ++i) + obj = obj.property(path.at(i)); + if (obj.isValid()) + objects.append(obj); + } else { +#if QT_VERSION >= 0x040500 + objects << ctx->scopeChain(); +#else + objects.append(ctx->activationObject()); +#endif + QStringList keywords; + keywords.append(QString::fromLatin1("this")); + keywords.append(QString::fromLatin1("true")); + keywords.append(QString::fromLatin1("false")); + keywords.append(QString::fromLatin1("null")); + for (int i = 0; i < keywords.size(); ++i) { + const QString &kwd = keywords.at(i); + if (isPrefixOf(prefix, kwd)) + matches.insert(kwd); + } + } + + for (int i = 0; i < objects.size(); ++i) { + QScriptValue obj = objects.at(i); + while (obj.isObject()) { + QScriptValueIterator it(obj); + while (it.hasNext()) { + it.next(); + QString propertyName = it.name(); + if (isPrefixOf(prefix, propertyName)) + matches.insert(propertyName); + } + obj = obj.prototype(); + } + } + results = matches.toList(); + qStableSort(results); + + length = prefix.length(); + type = QScriptCompletionTask::ScriptIdentifierCompletion; +} + +void QScriptCompletionTask::start() +{ + Q_D(QScriptCompletionTask); + d->type = NoCompletion; + // see if we're typing a command + // ### don't hardcode the command prefix + QRegExp cmdRx(QString::fromLatin1("^\\s*\\.([a-zA-Z]*)")); + int cmdIndex = cmdRx.indexIn(d->contents); + if ((cmdIndex != -1) && d->console) { + int len = cmdRx.matchedLength(); + QString prefix = cmdRx.capturedTexts().at(1); + if ((d->cursorPosition >= cmdIndex) && (d->cursorPosition <= (cmdIndex+len))) { + // editing command --> get command completions + d->results = d->console->commandManager()->completions(prefix); + qStableSort(d->results); + d->position = cmdRx.pos(1); + d->length = prefix.length(); + d->type = CommandNameCompletion; + d->appendix = QString::fromLatin1(" "); + emit finished(); + } else { + QScriptDebuggerConsoleCommand *cmd = d->console->commandManager()->findCommand(prefix); + if (!cmd) { + emit finished(); + return; + } + // editing an argument + int argNum = 0; + QString arg; + int pos = cmdIndex + len; + while (pos < d->contents.size()) { + while ((pos < d->contents.size()) && d->contents.at(pos).isSpace()) + ++pos; + if (pos < d->contents.size()) { + int pos2 = pos + 1; + while ((pos2 < d->contents.size()) && !d->contents.at(pos2).isSpace()) + ++pos2; + if ((d->cursorPosition >= pos) && (d->cursorPosition <= pos2)) { + arg = d->contents.mid(pos, pos2 - pos); + break; + } + pos = pos2; + ++argNum; + } + } + QString argType = cmd->argumentTypes().value(argNum); + if (!argType.isEmpty()) { + if (argType == QString::fromLatin1("command-or-group-name")) { + d->results = d->console->commandManager()->completions(arg); + } else if (argType == QString::fromLatin1("script-filename")) { + // ### super-cheating for now; have to use the async API + QScriptEngineDebuggerFrontend *edf = static_cast<QScriptEngineDebuggerFrontend*>(d->frontend); + QScriptDebuggerBackend *backend = edf->backend(); + QScriptScriptMap scripts = backend->scripts(); + QScriptScriptMap::const_iterator it; + for (it = scripts.constBegin(); it != scripts.constEnd(); ++it) { + QString fileName = it.value().fileName(); + if (isPrefixOf(arg, fileName)) + d->results.append(fileName); + } + } else if (argType == QString::fromLatin1("subcommand-name")) { + for (int i = 0; i < cmd->subCommands().size(); ++i) { + QString name = cmd->subCommands().at(i); + if (isPrefixOf(arg, name)) + d->results.append(name); + } + } else if (argType == QString::fromLatin1("script")) { + d->completeScriptExpression(); + } + if ((d->type == NoCompletion) && !d->results.isEmpty()) { + qStableSort(d->results); + d->position = pos; + d->length = arg.length(); + d->type = CommandArgumentCompletion; + } + } + emit finished(); + } + } else { + // assume it's an eval expression + d->completeScriptExpression(); + emit finished(); + } +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptcompletiontask_p.h b/src/scripttools/debugging/qscriptcompletiontask_p.h new file mode 100644 index 0000000..dd82250 --- /dev/null +++ b/src/scripttools/debugging/qscriptcompletiontask_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTCOMPLETIONTASK_P_H +#define QSCRIPTCOMPLETIONTASK_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptcompletiontaskinterface_p.h" + +#include <QtCore/qlist.h> +#include <QtCore/qmap.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerFrontend; +class QScriptDebuggerConsole; + +class QScriptCompletionTaskPrivate; +class Q_AUTOTEST_EXPORT QScriptCompletionTask + : public QScriptCompletionTaskInterface +{ + Q_OBJECT +public: + QScriptCompletionTask( + const QString &contents, int cursorPosition, + int frameIndex, + QScriptDebuggerFrontend *frontend, + QScriptDebuggerConsole *console, + QObject *parent = 0); + ~QScriptCompletionTask(); + + void start(); + +private: + Q_DECLARE_PRIVATE(QScriptCompletionTask) + Q_DISABLE_COPY(QScriptCompletionTask) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptcompletiontaskinterface.cpp b/src/scripttools/debugging/qscriptcompletiontaskinterface.cpp new file mode 100644 index 0000000..8757fe1 --- /dev/null +++ b/src/scripttools/debugging/qscriptcompletiontaskinterface.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptcompletiontaskinterface_p.h" +#include "qscriptcompletiontaskinterface_p_p.h" + +#include "private/qobject_p.h" + +QT_BEGIN_NAMESPACE + +QScriptCompletionTaskInterfacePrivate::QScriptCompletionTaskInterfacePrivate() +{ + type = QScriptCompletionTaskInterface::NoCompletion; +} + +QScriptCompletionTaskInterfacePrivate::~QScriptCompletionTaskInterfacePrivate() +{ +} + +QScriptCompletionTaskInterface::~QScriptCompletionTaskInterface() +{ +} + +QScriptCompletionTaskInterface::QScriptCompletionTaskInterface( + QScriptCompletionTaskInterfacePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} + +QScriptCompletionTaskInterface::CompletionType QScriptCompletionTaskInterface::completionType() const +{ + Q_D(const QScriptCompletionTaskInterface); + return static_cast<QScriptCompletionTaskInterface::CompletionType>(d->type); +} + +int QScriptCompletionTaskInterface::resultCount() const +{ + Q_D(const QScriptCompletionTaskInterface); + return d->results.size(); +} + +QString QScriptCompletionTaskInterface::resultAt(int index) const +{ + Q_D(const QScriptCompletionTaskInterface); + return d->results.value(index); +} + +void QScriptCompletionTaskInterface::addResult(const QString &result) +{ + Q_D(QScriptCompletionTaskInterface); + d->results.append(result); +} + +int QScriptCompletionTaskInterface::position() const +{ + Q_D(const QScriptCompletionTaskInterface); + return d->position; +} + +int QScriptCompletionTaskInterface::length() const +{ + Q_D(const QScriptCompletionTaskInterface); + return d->length; +} + +QString QScriptCompletionTaskInterface::appendix() const +{ + Q_D(const QScriptCompletionTaskInterface); + return d->appendix; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptcompletiontaskinterface_p.h b/src/scripttools/debugging/qscriptcompletiontaskinterface_p.h new file mode 100644 index 0000000..acd24d1 --- /dev/null +++ b/src/scripttools/debugging/qscriptcompletiontaskinterface_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTCOMPLETIONTASKINTERFACE_P_H +#define QSCRIPTCOMPLETIONTASKINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> + +QT_BEGIN_NAMESPACE + +class QString; + +class QScriptCompletionTaskInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptCompletionTaskInterface + : public QObject +{ + Q_OBJECT +public: + enum CompletionType { + NoCompletion, + CommandNameCompletion, + CommandArgumentCompletion, + ScriptIdentifierCompletion + }; + + ~QScriptCompletionTaskInterface(); + + virtual void start() = 0; + + CompletionType completionType() const; + + int resultCount() const; + QString resultAt(int index) const; + + int position() const; + int length() const; + + QString appendix() const; + +protected: + void addResult(const QString &result); + +Q_SIGNALS: + void finished(); + +protected: + QScriptCompletionTaskInterface( + QScriptCompletionTaskInterfacePrivate &dd, QObject *parent); + +private: + Q_DECLARE_PRIVATE(QScriptCompletionTaskInterface) + Q_DISABLE_COPY(QScriptCompletionTaskInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptcompletiontaskinterface_p_p.h b/src/scripttools/debugging/qscriptcompletiontaskinterface_p_p.h new file mode 100644 index 0000000..c9e93d3 --- /dev/null +++ b/src/scripttools/debugging/qscriptcompletiontaskinterface_p_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTCOMPLETIONTASKINTERFACE_P_P_H +#define QSCRIPTCOMPLETIONTASKINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qobject_p.h> + +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> + +QT_BEGIN_NAMESPACE + +class QScriptCompletionTaskInterface; +class QScriptCompletionTaskInterfacePrivate + : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QScriptCompletionTaskInterface) +public: + QScriptCompletionTaskInterfacePrivate(); + virtual ~QScriptCompletionTaskInterfacePrivate(); + + int type; + QStringList results; + int position; + int length; + QString appendix; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebugger.cpp b/src/scripttools/debugging/qscriptdebugger.cpp new file mode 100644 index 0000000..5a356ae --- /dev/null +++ b/src/scripttools/debugging/qscriptdebugger.cpp @@ -0,0 +1,1828 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebugger_p.h" +#include "qscriptdebuggerconsole_p.h" +#include "qscriptdebuggerconsolecommandmanager_p.h" +#include "qscriptdebuggerconsolecommandjob_p.h" +#include "qscriptstdmessagehandler_p.h" +#include "qscriptdebuggerfrontend_p.h" +#include "qscriptdebuggereventhandlerinterface_p.h" +#include "qscriptdebuggerresponsehandlerinterface_p.h" +#include "qscriptdebuggerjobschedulerinterface_p.h" +#include "qscriptdebuggerconsolewidgetinterface_p.h" +#include "qscriptcompletionproviderinterface_p.h" +#include "qscriptcompletiontask_p.h" +#include "qscripttooltipproviderinterface_p.h" +#include "qscriptdebuggerstackwidgetinterface_p.h" +#include "qscriptdebuggerstackmodel_p.h" +#include "qscriptdebuggerscriptswidgetinterface_p.h" +#include "qscriptdebuggerscriptsmodel_p.h" +#include "qscriptdebuggerlocalswidgetinterface_p.h" +#include "qscriptdebuggerlocalsmodel_p.h" +#include "qscriptdebuggercodewidgetinterface_p.h" +#include "qscriptdebuggercodeviewinterface_p.h" +#include "qscriptdebuggercodefinderwidgetinterface_p.h" +#include "qscriptbreakpointswidgetinterface_p.h" +#include "qscriptbreakpointsmodel_p.h" +#include "qscriptdebugoutputwidgetinterface_p.h" +#include "qscripterrorlogwidgetinterface_p.h" +#include "qscriptdebuggerwidgetfactoryinterface_p.h" +#include "qscriptdebuggerevent_p.h" +#include "qscriptdebuggervalue_p.h" +#include "qscriptdebuggerresponse_p.h" +#include "qscriptdebuggercommand_p.h" +#include "qscriptdebuggercommandschedulerfrontend_p.h" +#include "qscriptdebuggercommandschedulerjob_p.h" +#include "qscriptdebuggerjob_p_p.h" +#include "qscriptxmlparser_p.h" + +#include "qscriptenginedebuggerfrontend_p.h" +#include "qscriptdebuggerbackend_p.h" +#include <QtScript/qscriptengine.h> + +#include "private/qobject_p.h" + +#include <QtScript/qscriptcontext.h> +#include <QtScript/qscriptcontextinfo.h> + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qdebug.h> + +#include <QtGui/qaction.h> +#include <QtGui/qevent.h> +#include <QtGui/qicon.h> +#include <QtGui/qinputdialog.h> + +QT_BEGIN_NAMESPACE +typedef QPair<QList<qint64>, QList<qint64> > QScriptScriptsDelta; +typedef QPair<QList<qint64>, QList<qint64> > QScriptContextsDelta; +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QScriptScriptsDelta) + +QT_BEGIN_NAMESPACE + +Q_SCRIPT_EXPORT QString qt_scriptToXml(const QString &program, int lineNumber = 1); + +namespace { + +static int scriptDebuggerCount = 0; +static bool eventCallbackRegistered = false; +static bool widgetInPaintEvent = false; + +static bool scriptDebuggerEventCallback(void **data) +{ + QEvent *event = reinterpret_cast<QEvent*>(data[1]); + if (event->type() == QEvent::Paint) { + QObject *receiver = reinterpret_cast<QObject*>(data[0]); + bool was = widgetInPaintEvent; + widgetInPaintEvent = true; + QCoreApplication::instance()->notify(receiver, event); + widgetInPaintEvent = was; + bool *result = reinterpret_cast<bool*>(data[2]); + *result = true; + return true; + } + return false; +} + +} + +/*! + \since 4.5 + \class QScriptDebugger + \internal + + \brief The QScriptDebugger class provides a Qt Script debugger. + + \ingroup scripttools + \mainclass +*/ + +class QScriptDebuggerPrivate + : public QObjectPrivate, + public QScriptDebuggerCommandSchedulerInterface, + public QScriptDebuggerJobSchedulerInterface, + public QScriptDebuggerEventHandlerInterface, + public QScriptDebuggerResponseHandlerInterface, + public QScriptCompletionProviderInterface, + public QScriptToolTipProviderInterface +{ + Q_DECLARE_PUBLIC(QScriptDebugger) +public: + QScriptDebuggerPrivate(); + ~QScriptDebuggerPrivate(); + + int scheduleJob(QScriptDebuggerJob *job); + void finishJob(QScriptDebuggerJob *job); + void hibernateUntilEvaluateFinished(QScriptDebuggerJob *job); + + void maybeStartNewJob(); + + int scheduleCommand(const QScriptDebuggerCommand &command, + QScriptDebuggerResponseHandlerInterface *responseHandler); + + void handleResponse( + const QScriptDebuggerResponse &response, int commandId); + bool debuggerEvent(const QScriptDebuggerEvent &event); + + QScriptCompletionTaskInterface *createCompletionTask( + const QString &contents, int cursorPosition, int frameIndex, int options); + + QString toolTip(int frameIndex, int lineNumber, + const QStringList &path); + + static QPixmap pixmap(const QString &path); + + void startInteraction(QScriptDebuggerEvent::Type type, + qint64 scriptId, int lineNumber); + void sync(); + void loadLocals(int frameIndex); + QScriptDebuggerLocalsModel *createLocalsModel(); + void selectScriptForFrame(int frameIndex); + void emitStoppedSignal(); + + void maybeDelete(QWidget *widget); + + // private slots + void _q_onLineEntered(const QString &contents); + void _q_onCurrentFrameChanged(int frameIndex); + void _q_onCurrentScriptChanged(qint64 scriptId); + void _q_onScriptLocationSelected(int lineNumber); + void _q_interrupt(); + void _q_continue(); + void _q_stepInto(); + void _q_stepOver(); + void _q_stepOut(); + void _q_runToCursor(); + void _q_runToNewScript(); + void _q_toggleBreakpoint(); + void _q_clearDebugOutput(); + void _q_clearErrorLog(); + void _q_clearConsole(); + void _q_findInScript(); + void _q_findNextInScript(); + void _q_findPreviousInScript(); + void _q_onFindCodeRequest(const QString &, int); + void _q_goToLine(); + + void executeConsoleCommand(const QString &command); + void findCode(const QString &exp, int options); + + QScriptDebuggerFrontend *frontend; + + bool interactive; + QScriptDebuggerConsole *console; + + int nextJobId; + QList<QScriptDebuggerJob*> pendingJobs; + QList<int> pendingJobIds; + QScriptDebuggerJob *activeJob; + bool activeJobHibernating; + QHash<int, QScriptDebuggerCommand> watchedCommands; + QHash<int, QScriptDebuggerResponseHandlerInterface*> responseHandlers; + + QScriptDebuggerConsoleWidgetInterface *consoleWidget; + QScriptDebuggerStackWidgetInterface *stackWidget; + QScriptDebuggerStackModel *stackModel; + QScriptDebuggerScriptsWidgetInterface *scriptsWidget; + QScriptDebuggerScriptsModel *scriptsModel; + QScriptDebuggerLocalsWidgetInterface *localsWidget; + QHash<int, QScriptDebuggerLocalsModel*> localsModels; + QScriptDebuggerCodeWidgetInterface *codeWidget; + QScriptDebuggerCodeFinderWidgetInterface *codeFinderWidget; + QScriptBreakpointsWidgetInterface *breakpointsWidget; + QScriptBreakpointsModel *breakpointsModel; + QScriptDebugOutputWidgetInterface *debugOutputWidget; + QScriptErrorLogWidgetInterface *errorLogWidget; + QScriptDebuggerWidgetFactoryInterface *widgetFactory; + + QAction *interruptAction; + QAction *continueAction; + QAction *stepIntoAction; + QAction *stepOverAction; + QAction *stepOutAction; + QAction *runToCursorAction; + QAction *runToNewScriptAction; + + QAction *toggleBreakpointAction; + + QAction *clearDebugOutputAction; + QAction *clearErrorLogAction; + QAction *clearConsoleAction; + + QAction *findInScriptAction; + QAction *findNextInScriptAction; + QAction *findPreviousInScriptAction; + QAction *goToLineAction; + + int updatesEnabledTimerId; +}; + +QScriptDebuggerPrivate::QScriptDebuggerPrivate() +{ + frontend = 0; + activeJob = 0; + activeJobHibernating = false; + nextJobId = 0; + interactive = false; + + console = new QScriptDebuggerConsole(); + QString scriptsPath = QLatin1String(":/qt/scripttools/debugging/scripts/commands"); + QScriptStdMessageHandler tmp; + console->loadScriptedCommands(scriptsPath, &tmp); + + consoleWidget = 0; + stackWidget = 0; + stackModel = 0; + scriptsWidget = 0; + scriptsModel = 0; + localsWidget = 0; + codeWidget = 0; + codeFinderWidget = 0; + breakpointsWidget = 0; + breakpointsModel = 0; + debugOutputWidget = 0; + errorLogWidget = 0; + widgetFactory = 0; + + interruptAction = 0; + continueAction = 0; + stepIntoAction = 0; + stepOverAction = 0; + stepOutAction = 0; + runToCursorAction = 0; + runToNewScriptAction = 0; + + toggleBreakpointAction = 0; + + clearErrorLogAction = 0; + clearDebugOutputAction = 0; + clearConsoleAction = 0; + + findInScriptAction = 0; + findNextInScriptAction = 0; + findPreviousInScriptAction = 0; + goToLineAction = 0; + + updatesEnabledTimerId = -1; +} + +QScriptDebuggerPrivate::~QScriptDebuggerPrivate() +{ + delete console; + qDeleteAll(pendingJobs); + delete activeJob; + maybeDelete(consoleWidget); + maybeDelete(stackWidget); + maybeDelete(scriptsWidget); + maybeDelete(localsWidget); + maybeDelete(codeWidget); + maybeDelete(codeFinderWidget); + maybeDelete(breakpointsWidget); + maybeDelete(debugOutputWidget); + maybeDelete(errorLogWidget); +} + +void QScriptDebuggerPrivate::maybeDelete(QWidget *widget) +{ + if (widget && !widget->parent()) + delete widget; +} + +QPixmap QScriptDebuggerPrivate::pixmap(const QString &path) +{ + static QString prefix = QString::fromLatin1(":/qt/scripttools/debugging/images/"); + return QPixmap(prefix + path); +} + +/*! + \reimp +*/ +int QScriptDebuggerPrivate::scheduleJob(QScriptDebuggerJob *job) +{ + QScriptDebuggerJobPrivate *priv = QScriptDebuggerJobPrivate::get(job); + Q_ASSERT(priv->jobScheduler == 0); + priv->jobScheduler = this; + int id = nextJobId; + pendingJobs.append(job); + pendingJobIds.append(id); + maybeStartNewJob(); + return id; +} + +/*! + \reimp +*/ +void QScriptDebuggerPrivate::finishJob(QScriptDebuggerJob *job) +{ + Q_UNUSED(job); + Q_ASSERT(activeJob == job); + delete activeJob; + activeJob = 0; + activeJobHibernating = false; + maybeStartNewJob(); +} + +/*! + \reimp +*/ +void QScriptDebuggerPrivate::hibernateUntilEvaluateFinished(QScriptDebuggerJob *job) +{ + Q_UNUSED(job); + Q_ASSERT(activeJob == job); + activeJobHibernating = true; +} + +/*! + Starts a new job if appropriate. +*/ +void QScriptDebuggerPrivate::maybeStartNewJob() +{ + if (activeJob || pendingJobs.isEmpty()) + return; + activeJob = pendingJobs.takeFirst(); + activeJob->start(); +} + +/*! + \reimp +*/ +int QScriptDebuggerPrivate::scheduleCommand( + const QScriptDebuggerCommand &command, + QScriptDebuggerResponseHandlerInterface *responseHandler) +{ + if (!frontend) + return -1; + int id = frontend->scheduleCommand(command, this); + if (responseHandler && (responseHandler != this)) + responseHandlers.insert(id, responseHandler); + if ((command.type() == QScriptDebuggerCommand::SetBreakpoint) + || (command.type() == QScriptDebuggerCommand::SetBreakpointData) + || (command.type() == QScriptDebuggerCommand::DeleteBreakpoint)) { + // need to watch this command and update the breakpoints model afterwards + watchedCommands.insert(id, command); + } + return id; +} + +/*! + \reimp +*/ +void QScriptDebuggerPrivate::handleResponse( + const QScriptDebuggerResponse &response, int commandId) +{ + Q_Q(QScriptDebugger); + if (watchedCommands.contains(commandId)) { + QScriptDebuggerCommand command = watchedCommands.take(commandId); + if (response.error() == QScriptDebuggerResponse::NoError) { + if (!breakpointsModel) + breakpointsModel = new QScriptBreakpointsModel(this, this, q); + switch (command.type()) { + case QScriptDebuggerCommand::SetBreakpoint: { + int breakpointId = response.resultAsInt(); + QScriptBreakpointData data = command.breakpointData(); + breakpointsModel->addBreakpoint(breakpointId, data); + } break; + case QScriptDebuggerCommand::SetBreakpointData: { + int breakpointId = command.breakpointId(); + QScriptBreakpointData data = command.breakpointData(); + breakpointsModel->modifyBreakpoint(breakpointId, data); + } break; + case QScriptDebuggerCommand::DeleteBreakpoint: { + int breakpointId = command.breakpointId(); + breakpointsModel->removeBreakpoint(breakpointId); + } break; + default: + Q_ASSERT(false); + } + } + } else if (response.async()) { + interactive = false; + // disable/invalidate/enable stuff + if (continueAction) + continueAction->setEnabled(false); + if (stepIntoAction) + stepIntoAction->setEnabled(false); + if (stepOverAction) + stepOverAction->setEnabled(false); + if (stepOutAction) + stepOutAction->setEnabled(false); + if (runToCursorAction) + runToCursorAction->setEnabled(false); + if (runToNewScriptAction) + runToNewScriptAction->setEnabled(false); + if (interruptAction) + interruptAction->setEnabled(true); + + // the timer is to avoid flicker when stepping + if (stackWidget) { + stackWidget->setUpdatesEnabled(false); + stackWidget->setEnabled(false); + if (updatesEnabledTimerId == -1) + updatesEnabledTimerId = q->startTimer(75); + } + if (localsWidget) { + localsWidget->setUpdatesEnabled(false); + localsWidget->setEnabled(false); + if (updatesEnabledTimerId == -1) + updatesEnabledTimerId = q->startTimer(75); + } + if (codeWidget) + codeWidget->invalidateExecutionLineNumbers(); + + emit q->started(); + } + + QScriptDebuggerResponseHandlerInterface *realHandler = responseHandlers.take(commandId); + if (realHandler) + realHandler->handleResponse(response, commandId); +} + +/*! + \reimp + + Handles a debugger event from the frontend. +*/ +bool QScriptDebuggerPrivate::debuggerEvent(const QScriptDebuggerEvent &event) +{ + Q_Q(QScriptDebugger); + switch (event.type()) { + case QScriptDebuggerEvent::None: + case QScriptDebuggerEvent::UserEvent: + case QScriptDebuggerEvent::MaxUserEvent: + Q_ASSERT(false); + break; + + case QScriptDebuggerEvent::Trace: + if (!debugOutputWidget && widgetFactory) + q->setDebugOutputWidget(widgetFactory->createDebugOutputWidget()); + if (debugOutputWidget) + debugOutputWidget->message(QtDebugMsg, event.message()); + return true; // trace doesn't stall execution + + case QScriptDebuggerEvent::SteppingFinished: { + if (!consoleWidget && widgetFactory) + q->setConsoleWidget(widgetFactory->createConsoleWidget()); + if (consoleWidget) { + QString msg = event.message(); + if (!msg.isEmpty()) + consoleWidget->message(QtDebugMsg, msg); + } + } break; + + case QScriptDebuggerEvent::Interrupted: + case QScriptDebuggerEvent::LocationReached: + break; + + case QScriptDebuggerEvent::Breakpoint: { + int bpId = event.breakpointId(); + if (!consoleWidget && widgetFactory) + q->setConsoleWidget(widgetFactory->createConsoleWidget()); + if (consoleWidget) { + consoleWidget->message(QtDebugMsg, + QString::fromLatin1("Breakpoint %0 at %1, line %2.") + .arg(bpId).arg(event.fileName()) + .arg(event.lineNumber())); + } + if (breakpointsModel->breakpointData(bpId).isSingleShot()) + breakpointsModel->removeBreakpoint(bpId); + } break; + + case QScriptDebuggerEvent::Exception: { + if (event.hasExceptionHandler()) { + // Let the exception be handled like normal. + // We may want to add a "Break on all exceptions" option + // to be able to customize this behavior. + return true; + } + if (!consoleWidget && widgetFactory) + q->setConsoleWidget(widgetFactory->createConsoleWidget()); + if (!errorLogWidget && widgetFactory) + q->setErrorLogWidget(widgetFactory->createErrorLogWidget()); + if (consoleWidget || errorLogWidget) { + QString fn = event.fileName(); + if (fn.isEmpty()) { + if (event.scriptId() != -1) + fn = QString::fromLatin1("<anonymous script, id=%0>").arg(event.scriptId()); + else + fn = QString::fromLatin1("<native>"); + } + QString msg = QString::fromLatin1("Uncaught exception at %0:%1: %2").arg(fn) + .arg(event.lineNumber()).arg(event.message()); + if (consoleWidget) + consoleWidget->message(QtCriticalMsg, msg); + if (errorLogWidget) + errorLogWidget->message(QtCriticalMsg, msg); + } + } break; + + case QScriptDebuggerEvent::InlineEvalFinished: { + QScriptDebuggerValue result = event.scriptValue(); + Q_ASSERT(console != 0); + int action = console->evaluateAction(); + console->setEvaluateAction(0); + switch (action) { + case 0: { // eval command + if (activeJob) { + if (activeJobHibernating) { + activeJobHibernating = false; + activeJob->evaluateFinished(result); + } + } else if (consoleWidget) { + // ### if the result is an object, need to do a tostring job on it +// messageHandler->message(QtDebugMsg, result.toString()); + if (result.type() != QScriptDebuggerValue::UndefinedValue) + consoleWidget->message(QtDebugMsg, event.message()); + } + } break; + case 1: { // return command + QScriptDebuggerCommandSchedulerFrontend frontend(this, this); + frontend.scheduleForceReturn(console->currentFrameIndex(), result); + } return false; + } + if (!event.isNestedEvaluate()) { + // in the case when evaluate() was called while the + // engine was not running, we don't want to enter interactive mode + return true; + } + } break; + + case QScriptDebuggerEvent::DebuggerInvocationRequest: { + if (!consoleWidget && widgetFactory) + q->setConsoleWidget(widgetFactory->createConsoleWidget()); + if (consoleWidget) { + QString fn = event.fileName(); + if (fn.isEmpty()) + fn = QString::fromLatin1("<anonymous script, id=%0>").arg(event.scriptId()); + consoleWidget->message(QtDebugMsg, + QString::fromLatin1("Debugger invoked from %1, line %2.") + .arg(fn).arg(event.lineNumber())); + } + } break; + + case QScriptDebuggerEvent::ForcedReturn: { + } break; + + } + + if (widgetInPaintEvent) { + QString msg = QString::fromLatin1("Suspending evaluation in paintEvent() is not supported; resuming."); + if (!consoleWidget && widgetFactory) + q->setConsoleWidget(widgetFactory->createConsoleWidget()); + if (!errorLogWidget && widgetFactory) + q->setErrorLogWidget(widgetFactory->createErrorLogWidget()); + if (consoleWidget) + consoleWidget->message(QtWarningMsg, msg); + if (errorLogWidget) + errorLogWidget->message(QtCriticalMsg, msg); + return true; + } + + if (activeJobHibernating) { + // evaluate() did not finish normally (e.g. due to a breakpoint), + // so cancel the job that's waiting for it + delete activeJob; + activeJob = 0; + activeJobHibernating = false; + } + + startInteraction(event.type(), event.scriptId(), event.lineNumber()); + return !interactive; +} + +/*! + \reimp +*/ +QString QScriptDebuggerPrivate::toolTip(int frameIndex, int lineNumber, + const QStringList &path) +{ + if (frameIndex == -1) { + if (stackWidget) + frameIndex = stackWidget->currentFrameIndex(); + else + frameIndex = console->currentFrameIndex(); + } + // ### cheating for now, need to use async API + QScriptEngineDebuggerFrontend *edf = static_cast<QScriptEngineDebuggerFrontend*>(frontend); + QScriptDebuggerBackend *backend = edf->backend(); + QScriptContext *ctx = backend->context(frameIndex); + if (!ctx || path.isEmpty()) + return QString(); + QScriptContextInfo ctxInfo(ctx); + if (ctx->callee().isValid() + && ((lineNumber < ctxInfo.functionStartLineNumber()) + || (lineNumber > ctxInfo.functionEndLineNumber()))) { + return QString(); + } + QScriptValueList objects; + int pathIndex = 0; + if (path.at(0) == QLatin1String("this")) { + objects.append(ctx->thisObject()); + ++pathIndex; + } else { +#if QT_VERSION >= 0x040500 + objects << ctx->scopeChain(); +#else + objects.append(ctx->activationObject()); +#endif + } + for (int i = 0; i < objects.size(); ++i) { + QScriptValue val = objects.at(i); + for (int j = pathIndex; val.isValid() && (j < path.size()); ++j) { + val = val.property(path.at(j)); + } + if (val.isValid()) { + bool hadException = (ctx->state() == QScriptContext::ExceptionState); + QString str = val.toString(); + if (!hadException && backend->engine()->hasUncaughtException()) + backend->engine()->clearExceptions(); + return str; + } + } + return QString(); +} + +/*! + \reimp +*/ +QScriptCompletionTaskInterface *QScriptDebuggerPrivate::createCompletionTask( + const QString &contents, int cursorPosition, int frameIndex, int options) +{ + return new QScriptCompletionTask( + contents, cursorPosition, frameIndex, frontend, + (options & QScriptCompletionProviderInterface::ConsoleCommandCompletion) ? console : 0); +} + +/*! + Slot called when a line has been entered in the console widget. +*/ +void QScriptDebuggerPrivate::_q_onLineEntered(const QString &contents) +{ + QScriptDebuggerConsoleCommandJob *commandJob; + commandJob = console->consumeInput(contents, consoleWidget, this); + if (commandJob != 0) { + scheduleJob(commandJob); + consoleWidget->setLineContinuationMode(false); + } else if (console->hasIncompleteInput()) { + consoleWidget->setLineContinuationMode(true); + } +} + +/*! + Slot called when the current index has changed in the stack widget. +*/ +void QScriptDebuggerPrivate::_q_onCurrentFrameChanged(int frameIndex) +{ + loadLocals(frameIndex); + selectScriptForFrame(frameIndex); +} + +/*! + Slot called when the current script has changed in the scripts widget. +*/ +void QScriptDebuggerPrivate::_q_onCurrentScriptChanged(qint64 scriptId) +{ + if (codeWidget && (codeWidget->currentScriptId() != scriptId)) { + codeWidget->setCurrentScript(scriptId); + QScriptDebuggerCodeViewInterface *view = codeWidget->currentView(); + if (view) + view->setExecutionLineNumber(-1, /*error=*/false); + } +} + +void QScriptDebuggerPrivate::_q_onScriptLocationSelected(int lineNumber) +{ + QScriptDebuggerCodeViewInterface *view = codeWidget->currentView(); + if (!view) + return; + view->gotoLine(lineNumber); +} + +void QScriptDebuggerPrivate::_q_interrupt() +{ + executeConsoleCommand(QString::fromLatin1("interrupt")); +} + +void QScriptDebuggerPrivate::_q_continue() +{ + executeConsoleCommand(QString::fromLatin1("continue")); +} + +void QScriptDebuggerPrivate::_q_stepInto() +{ + executeConsoleCommand(QString::fromLatin1("step")); +} + +void QScriptDebuggerPrivate::_q_stepOver() +{ + executeConsoleCommand(QString::fromLatin1("next")); +} + +void QScriptDebuggerPrivate::_q_stepOut() +{ + executeConsoleCommand(QString::fromLatin1("finish")); +} + +void QScriptDebuggerPrivate::_q_runToCursor() +{ + qint64 scriptId = codeWidget->currentScriptId(); + int lineNumber = codeWidget->currentView()->cursorLineNumber(); + QScriptDebuggerCommandSchedulerFrontend frontend(this, this); + frontend.scheduleRunToLocation(scriptId, lineNumber); +} + +void QScriptDebuggerPrivate::_q_runToNewScript() +{ + QScriptDebuggerCommandSchedulerFrontend frontend(this, this); + frontend.scheduleRunToLocation(QString(), -1); +} + +void QScriptDebuggerPrivate::_q_toggleBreakpoint() +{ + Q_ASSERT(codeWidget != 0); + QScriptDebuggerCodeViewInterface *view = codeWidget->currentView(); + if (!view) + return; + qint64 scriptId = codeWidget->currentScriptId(); + int lineNumber = view->cursorLineNumber(); + Q_ASSERT(breakpointsModel != 0); + int bpId = breakpointsModel->resolveBreakpoint(scriptId, lineNumber); + if (bpId != -1) { + breakpointsModel->deleteBreakpoint(bpId); + } else { + QScriptBreakpointData data(scriptId, lineNumber); + if (scriptsModel) + data.setFileName(scriptsModel->scriptData(scriptId).fileName()); + breakpointsModel->setBreakpoint(data); + } +} + +void QScriptDebuggerPrivate::_q_clearDebugOutput() +{ + if (debugOutputWidget) + debugOutputWidget->clear(); +} + +void QScriptDebuggerPrivate::_q_clearErrorLog() +{ + if (errorLogWidget) + errorLogWidget->clear(); +} + +void QScriptDebuggerPrivate::_q_clearConsole() +{ + if (consoleWidget) + consoleWidget->clear(); +} + +void QScriptDebuggerPrivate::executeConsoleCommand(const QString &command) +{ + QString tmp = console->incompleteInput(); + console->setIncompleteInput(QString()); + QScriptDebuggerJob *job = console->consumeInput(console->commandPrefix() + command, debugOutputWidget, this); + console->setIncompleteInput(tmp); + if (job != 0) { + scheduleJob(job); + // once to send the command... + QCoreApplication::processEvents(); + // ... and once to receive the response + QCoreApplication::processEvents(); + } +} + +void QScriptDebuggerPrivate::_q_findInScript() +{ + if (!codeFinderWidget && widgetFactory) + q_func()->setCodeFinderWidget(widgetFactory->createCodeFinderWidget()); + if (codeFinderWidget) { + codeFinderWidget->show(); + codeFinderWidget->setFocus(Qt::OtherFocusReason); + } +} + +void QScriptDebuggerPrivate::_q_findNextInScript() +{ + findCode(codeFinderWidget->text(), codeFinderWidget->findOptions()); +} + +void QScriptDebuggerPrivate::_q_findPreviousInScript() +{ + int options = codeFinderWidget->findOptions(); + options |= QTextDocument::FindBackward; + findCode(codeFinderWidget->text(), options); +} + +void QScriptDebuggerPrivate::_q_onFindCodeRequest( + const QString &exp, int options) +{ + findCode(exp, options); + if (findNextInScriptAction) + findNextInScriptAction->setEnabled(!exp.isEmpty()); + if (findPreviousInScriptAction) + findPreviousInScriptAction->setEnabled(!exp.isEmpty()); +} + +void QScriptDebuggerPrivate::findCode(const QString &exp, int options) +{ + QScriptDebuggerCodeViewInterface *view = codeWidget->currentView(); + if (!view) + return; + int result = view->find(exp, options); + codeFinderWidget->setOK(((result & 0x1) != 0) || exp.isEmpty()); + codeFinderWidget->setWrapped((result & 0x2) != 0); +} + +void QScriptDebuggerPrivate::_q_goToLine() +{ + QScriptDebuggerCodeViewInterface *view = codeWidget->currentView(); + if (!view) + return; + bool ok = false; + int lineNumber = QInputDialog::getInteger(0, QObject::tr("Go to Line"), + QObject::tr("Line:"), + view->cursorLineNumber(), + 1, INT_MAX, 1, &ok); + if (ok) + view->gotoLine(lineNumber); +} + +class QScriptDebuggerShowLineJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + QScriptDebuggerShowLineJob(qint64 scriptId, int lineNumber, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_scriptId(scriptId), m_lineNumber(lineNumber), + m_messageHandler(messageHandler) {} + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetScriptData(m_scriptId); + } + void handleResponse(const QScriptDebuggerResponse &response, int /*commandId*/) + { + QScriptScriptData data = response.resultAsScriptData(); + QString line = data.lines(m_lineNumber, 1).value(0); + m_messageHandler->message(QtDebugMsg, QString::fromLatin1("%0\t%1") + .arg(m_lineNumber).arg(line)); + finish(); + } + +private: + qint64 m_scriptId; + int m_lineNumber; + QScriptMessageHandlerInterface *m_messageHandler; +}; + +namespace { + +class SyncStackJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SyncStackJob(QScriptDebuggerPrivate *debugger) + : QScriptDebuggerCommandSchedulerJob(debugger), + m_debugger(debugger), m_index(0) {} + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetContextInfo(m_index); // ### getContextInfos() + } + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + if (response.error() != QScriptDebuggerResponse::InvalidContextIndex) { + m_infos.append(response.resultAsContextInfo()); + frontend.scheduleGetContextInfo(++m_index); + } else { + m_debugger->stackModel->setContextInfos(m_infos); + if (m_debugger->stackWidget->currentFrameIndex() == -1) + m_debugger->stackWidget->setCurrentFrameIndex(0); + m_debugger->stackWidget->setUpdatesEnabled(true); + m_debugger->stackWidget->setEnabled(true); + finish(); + } + } + +private: + QScriptDebuggerPrivate *m_debugger; + int m_index; + QList<QScriptContextInfo> m_infos; +}; + +class SyncScriptsJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SyncScriptsJob(QScriptDebuggerPrivate *debugger) + : QScriptDebuggerCommandSchedulerJob(debugger), + m_debugger(debugger), m_index(-1) {} + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleScriptsCheckpoint(); + } + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + if (m_index == -1) { + QScriptScriptsDelta delta; + delta = qvariant_cast<QScriptScriptsDelta>(response.result()); + + const QList<qint64> &removed = delta.second; + for (int i = 0; i < removed.size(); ++i) + m_debugger->scriptsModel->removeScript(removed.at(i)); + + m_added = delta.first; + if (!m_added.isEmpty()) { + frontend.scheduleGetScriptData(m_added.at(++m_index)); + } else { + m_debugger->scriptsModel->commit(); + finish(); + } + } else { + QScriptScriptData data = response.resultAsScriptData(); + qint64 scriptId = m_added.at(m_index); + m_debugger->scriptsModel->addScript(scriptId, data); + +#if QT_VERSION >= 0x040500 + // ### could be slow, might want to do this in a separate thread + QString xml = qt_scriptToXml(data.contents(), data.baseLineNumber()); + QScriptXmlParser::Result extraInfo = QScriptXmlParser::parse(xml); + m_debugger->scriptsModel->addExtraScriptInfo( + scriptId, extraInfo.functionsInfo, extraInfo.executableLineNumbers); +#endif + + if (++m_index < m_added.size()) + frontend.scheduleGetScriptData(m_added.at(m_index)); + else { + m_debugger->scriptsModel->commit(); + finish(); + } + } + } + +private: + QScriptDebuggerPrivate *m_debugger; + int m_index; + QList<qint64> m_added; +}; + +class SyncBreakpointsJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SyncBreakpointsJob(QScriptDebuggerPrivate *debugger) + : QScriptDebuggerCommandSchedulerJob(debugger), + m_debugger(debugger) {} + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetBreakpoints(); + } + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptBreakpointMap breakpoints = response.resultAsBreakpoints(); + QScriptBreakpointMap::const_iterator it; + for (it = breakpoints.constBegin(); it != breakpoints.constEnd(); ++it) { + int id = it.key(); + QScriptBreakpointData newData = it.value(); + QScriptBreakpointData existingData = m_debugger->breakpointsModel->breakpointData(id); + if (existingData.isValid() && (existingData != newData)) + m_debugger->breakpointsModel->modifyBreakpoint(id, newData); + } + finish(); + } + +private: + QScriptDebuggerPrivate *m_debugger; + int m_index; + QList<QScriptContextInfo> m_infos; +}; + +class SyncLocalsJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SyncLocalsJob(QScriptDebuggerPrivate *debugger) + : QScriptDebuggerCommandSchedulerJob(debugger), + m_debugger(debugger) {} + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleContextsCheckpoint(); + } + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptContextsDelta delta = qvariant_cast<QScriptContextsDelta>(response.result()); + for (int i = 0; i < delta.first.size(); ++i) { + QScriptDebuggerLocalsModel *model = m_debugger->localsModels.take(delta.first.at(i)); + delete model; + } + finish(); + } + +private: + QScriptDebuggerPrivate *m_debugger; +}; + +class LoadLocalsJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + LoadLocalsJob(QScriptDebuggerPrivate *debugger, int frameIndex) + : QScriptDebuggerCommandSchedulerJob(debugger), + m_debugger(debugger), m_frameIndex(frameIndex), m_state(0) {} + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetContextId(m_frameIndex); + } + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + qint64 contextId = response.resultAsLongLong(); + QScriptDebuggerLocalsModel *model = m_debugger->localsModels.value(contextId); + if (model) { + model->sync(m_frameIndex); + } else { + model = m_debugger->createLocalsModel(); + m_debugger->localsModels.insert(contextId, model); + model->init(m_frameIndex); + } + if (m_debugger->localsWidget) { + if (m_debugger->localsWidget->localsModel() != model) // ### bug in qtreeview + m_debugger->localsWidget->setLocalsModel(model); + m_debugger->localsWidget->setUpdatesEnabled(true); + m_debugger->localsWidget->setEnabled(true); + } + finish(); + } + +private: + QScriptDebuggerPrivate *m_debugger; + int m_frameIndex; + int m_state; +}; + +class EmitStoppedSignalJob : public QScriptDebuggerJob +{ +public: + EmitStoppedSignalJob(QScriptDebuggerPrivate *debugger) + : m_debugger(debugger) {} + + void start() + { + m_debugger->emitStoppedSignal(); + finish(); + } + +private: + QScriptDebuggerPrivate *m_debugger; +}; + +} // namespace + +void QScriptDebuggerPrivate::startInteraction(QScriptDebuggerEvent::Type type, + qint64 scriptId, int lineNumber) +{ + Q_Q(QScriptDebugger); + if (type != QScriptDebuggerEvent::InlineEvalFinished) { + if (stackWidget) + stackWidget->setCurrentFrameIndex(0); + console->setCurrentFrameIndex(0); + console->setCurrentScriptId(scriptId); + console->setCurrentLineNumber(lineNumber); + } + + if ((scriptId != -1) && consoleWidget) { + QScriptDebuggerJob *job = new QScriptDebuggerShowLineJob(scriptId, lineNumber, consoleWidget, this); + scheduleJob(job); + } + + sync(); + + if (!interactive) { + interactive = true; + if (updatesEnabledTimerId != -1) { + q->killTimer(updatesEnabledTimerId); + updatesEnabledTimerId = -1; + } + console->bumpSessionId(); + scheduleJob(new EmitStoppedSignalJob(this)); + } + + if (consoleWidget) + consoleWidget->activateWindow(); + else if (codeWidget) + codeWidget->activateWindow(); + + if (continueAction) + continueAction->setEnabled(true); + if (stepIntoAction) + stepIntoAction->setEnabled(true); + if (stepOverAction) + stepOverAction->setEnabled(true); + if (stepOutAction) + stepOutAction->setEnabled(true); + if (runToCursorAction) + runToCursorAction->setEnabled(true); + if (runToNewScriptAction) + runToNewScriptAction->setEnabled(true); + if (interruptAction) + interruptAction->setEnabled(false); + + bool hasScript = (codeWidget != 0); + if (findInScriptAction) + findInScriptAction->setEnabled(hasScript); + if (toggleBreakpointAction) + toggleBreakpointAction->setEnabled(hasScript); + if (goToLineAction) + goToLineAction->setEnabled(hasScript); +} + +void QScriptDebuggerPrivate::sync() +{ + if (localsWidget) { + QScriptDebuggerJob *job = new SyncLocalsJob(this); + scheduleJob(job); + } + if (scriptsModel) { + QScriptDebuggerJob *job = new SyncScriptsJob(this); + scheduleJob(job); + } + if (stackModel) { + QScriptDebuggerJob *job = new SyncStackJob(this); + scheduleJob(job); + } + if (breakpointsModel) { + // need to sync because the ignore-count could have changed + QScriptDebuggerJob *job = new SyncBreakpointsJob(this); + scheduleJob(job); + } + + if (stackWidget && (stackWidget->currentFrameIndex() != -1)) { + int index = stackWidget->currentFrameIndex(); + loadLocals(index); + selectScriptForFrame(index); + } else if (codeWidget && (console->currentFrameIndex() != -1)) { + selectScriptForFrame(console->currentFrameIndex()); + } +} + +void QScriptDebuggerPrivate::loadLocals(int frameIndex) +{ + LoadLocalsJob *job = new LoadLocalsJob(this, frameIndex); + scheduleJob(job); +} + +QScriptDebuggerLocalsModel *QScriptDebuggerPrivate::createLocalsModel() +{ + return new QScriptDebuggerLocalsModel(this, this, q_func()); +} + +namespace { + +class ShowFrameCodeJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + ShowFrameCodeJob(QScriptDebuggerPrivate *debugger, int frameIndex) + : QScriptDebuggerCommandSchedulerJob(debugger), + m_debugger(debugger), m_frameIndex(frameIndex) {} + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetContextInfo(m_frameIndex); + } + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + if (m_info.isNull()) { + m_info = response.resultAsContextInfo(); + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetContextState(m_frameIndex); + } else { + int contextState = response.resultAsInt(); + bool error = (contextState == QScriptContext::ExceptionState); + if (m_debugger->scriptsWidget) { + m_debugger->scriptsWidget->setCurrentScript(m_info.scriptId()); + } + if (m_debugger->codeWidget) { + m_debugger->codeWidget->setCurrentScript(m_info.scriptId()); + QScriptDebuggerCodeViewInterface *view = m_debugger->codeWidget->currentView(); + if (view) + view->setExecutionLineNumber(m_info.lineNumber(), error); + } + finish(); + } + } + +private: + QScriptDebuggerPrivate *m_debugger; + int m_frameIndex; + QScriptContextInfo m_info; +}; + +} // namespace + +void QScriptDebuggerPrivate::selectScriptForFrame(int frameIndex) +{ + QScriptDebuggerJob *job = new ShowFrameCodeJob(this, frameIndex); + scheduleJob(job); +} + +void QScriptDebuggerPrivate::emitStoppedSignal() +{ + emit q_func()->stopped(); +} + +/*! + Constructs a new QScriptDebugger object. +*/ +QScriptDebugger::QScriptDebugger(QObject *parent) + : QObject(*new QScriptDebuggerPrivate, parent) +{ + ++scriptDebuggerCount; +} + +/*! + Destroys this QScriptDebugger. +*/ +QScriptDebugger::~QScriptDebugger() +{ + --scriptDebuggerCount; + if ((scriptDebuggerCount == 0) && eventCallbackRegistered) { + eventCallbackRegistered = false; + QInternal::unregisterCallback(QInternal::EventNotifyCallback, + scriptDebuggerEventCallback); + } +} + +/*! + \internal +*/ +QScriptDebugger::QScriptDebugger(QScriptDebuggerPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} + +QScriptDebuggerFrontend *QScriptDebugger::frontend() const +{ + Q_D(const QScriptDebugger); + return d->frontend; +} + +void QScriptDebugger::setFrontend(QScriptDebuggerFrontend *frontend) +{ + Q_D(QScriptDebugger); + if (d->frontend) + d->frontend->setEventHandler(0); + d->frontend = frontend; + if (frontend) { + frontend->setEventHandler(d); + if (!eventCallbackRegistered) { + eventCallbackRegistered = true; + QInternal::registerCallback(QInternal::EventNotifyCallback, + scriptDebuggerEventCallback); + } + } +} + +QScriptDebuggerConsoleWidgetInterface *QScriptDebugger::consoleWidget() const +{ + Q_D(const QScriptDebugger); + return d->consoleWidget; +} + +void QScriptDebugger::setConsoleWidget(QScriptDebuggerConsoleWidgetInterface *consoleWidget) +{ + Q_D(QScriptDebugger); + if (d->consoleWidget) { + QObject::disconnect(d->consoleWidget, 0, this, 0); + } + d->consoleWidget = consoleWidget; + if (consoleWidget) { + consoleWidget->setCommandHistorian(d->console); + consoleWidget->setCompletionProvider(d); + QObject::connect(consoleWidget, SIGNAL(lineEntered(QString)), + this, SLOT(_q_onLineEntered(QString))); + + d->console->showDebuggerInfoMessage(consoleWidget); + } +} + +QScriptDebuggerStackWidgetInterface *QScriptDebugger::stackWidget() const +{ + Q_D(const QScriptDebugger); + return d->stackWidget; +} + +void QScriptDebugger::setStackWidget(QScriptDebuggerStackWidgetInterface *stackWidget) +{ + Q_D(QScriptDebugger); + if (d->stackWidget) { + QObject::disconnect(d->stackWidget, 0, this, 0); + } + d->stackWidget = stackWidget; + if (stackWidget) { + if (!d->stackModel) { + d->stackModel = new QScriptDebuggerStackModel(this); + if (d->interactive) + d->scheduleJob(new SyncStackJob(d)); + } + stackWidget->setStackModel(d->stackModel); + QObject::connect(stackWidget, SIGNAL(currentFrameChanged(int)), + this, SLOT(_q_onCurrentFrameChanged(int))); + } +} + +QScriptDebuggerScriptsWidgetInterface *QScriptDebugger::scriptsWidget() const +{ + Q_D(const QScriptDebugger); + return d->scriptsWidget; +} + +void QScriptDebugger::setScriptsWidget(QScriptDebuggerScriptsWidgetInterface *scriptsWidget) +{ + Q_D(QScriptDebugger); + if (d->scriptsWidget) { + QObject::disconnect(d->scriptsWidget, 0, this, 0); + } + d->scriptsWidget = scriptsWidget; + if (scriptsWidget) { + if (!d->scriptsModel) { + d->scriptsModel = new QScriptDebuggerScriptsModel(this); + if (d->interactive) + d->scheduleJob(new SyncScriptsJob(d)); + } + scriptsWidget->setScriptsModel(d->scriptsModel); + QObject::connect(scriptsWidget, SIGNAL(currentScriptChanged(qint64)), + this, SLOT(_q_onCurrentScriptChanged(qint64))); + QObject::connect(d->scriptsWidget, SIGNAL(scriptLocationSelected(int)), + this, SLOT(_q_onScriptLocationSelected(int))); + } +} + +QScriptDebuggerLocalsWidgetInterface *QScriptDebugger::localsWidget() const +{ + Q_D(const QScriptDebugger); + return d->localsWidget; +} + +void QScriptDebugger::setLocalsWidget(QScriptDebuggerLocalsWidgetInterface *localsWidget) +{ + Q_D(QScriptDebugger); + if (d->localsWidget) { + // ### d->localsWidget->setLocalsModel(0); + } + localsWidget->setCompletionProvider(d); + d->localsWidget = localsWidget; +} + +QScriptDebuggerCodeWidgetInterface *QScriptDebugger::codeWidget() const +{ + Q_D(const QScriptDebugger); + return d->codeWidget; +} + +void QScriptDebugger::setCodeWidget(QScriptDebuggerCodeWidgetInterface *codeWidget) +{ + Q_D(QScriptDebugger); + if (d->codeWidget) { + d->codeWidget->removeEventFilter(this); + } + d->codeWidget = codeWidget; + if (codeWidget) { + if (!d->scriptsModel) { + d->scriptsModel = new QScriptDebuggerScriptsModel(this); + if (d->interactive) + d->scheduleJob(new SyncScriptsJob(d)); + } + codeWidget->setScriptsModel(d->scriptsModel); + if (!d->breakpointsModel) { + d->breakpointsModel = new QScriptBreakpointsModel(d, d, this); + if (d->interactive) + d->scheduleJob(new SyncBreakpointsJob(d)); + } + codeWidget->setBreakpointsModel(d->breakpointsModel); + codeWidget->setToolTipProvider(d); + codeWidget->installEventFilter(this); + } + bool hasScript = (codeWidget != 0) && (codeWidget->currentView() != 0); + if (d->findInScriptAction) + d->findInScriptAction->setEnabled(hasScript && (d->codeFinderWidget != 0)); + if (d->goToLineAction) + d->goToLineAction->setEnabled(hasScript); + if (d->toggleBreakpointAction) + d->toggleBreakpointAction->setEnabled(hasScript); +} + +QScriptDebuggerCodeFinderWidgetInterface *QScriptDebugger::codeFinderWidget() const +{ + Q_D(const QScriptDebugger); + return d->codeFinderWidget; +} + +void QScriptDebugger::setCodeFinderWidget(QScriptDebuggerCodeFinderWidgetInterface *codeFinderWidget) +{ + Q_D(QScriptDebugger); + if (d->codeFinderWidget) { + QObject::disconnect(d->codeFinderWidget, 0, this, 0); + } + d->codeFinderWidget = codeFinderWidget; + if (codeFinderWidget) { + QObject::connect(codeFinderWidget, SIGNAL(findRequest(QString,int)), + this, SLOT(_q_onFindCodeRequest(QString,int))); + } + if (d->findInScriptAction) { + d->findInScriptAction->setEnabled( + (codeFinderWidget != 0) + && (d->codeWidget != 0) + && (d->codeWidget->currentView() != 0)); + } +} + +QScriptDebugOutputWidgetInterface *QScriptDebugger::debugOutputWidget() const +{ + Q_D(const QScriptDebugger); + return d->debugOutputWidget; +} + +void QScriptDebugger::setDebugOutputWidget(QScriptDebugOutputWidgetInterface *debugOutputWidget) +{ + Q_D(QScriptDebugger); + d->debugOutputWidget = debugOutputWidget; +} + +QScriptBreakpointsWidgetInterface *QScriptDebugger::breakpointsWidget() const +{ + Q_D(const QScriptDebugger); + return d->breakpointsWidget; +} + +void QScriptDebugger::setBreakpointsWidget(QScriptBreakpointsWidgetInterface *breakpointsWidget) +{ + Q_D(QScriptDebugger); + if (d->breakpointsWidget) { + // ### invalidate + } + d->breakpointsWidget = breakpointsWidget; + if (breakpointsWidget) { + if (!d->breakpointsModel) { + d->breakpointsModel = new QScriptBreakpointsModel(d, d, this); + if (d->interactive) + d->scheduleJob(new SyncBreakpointsJob(d)); + } + d->breakpointsWidget->setBreakpointsModel(d->breakpointsModel); + d->breakpointsWidget->setScriptsModel(d->scriptsModel); + } +} + +QScriptErrorLogWidgetInterface *QScriptDebugger::errorLogWidget() const +{ + Q_D(const QScriptDebugger); + return d->errorLogWidget; +} + +void QScriptDebugger::setErrorLogWidget(QScriptErrorLogWidgetInterface *errorLogWidget) +{ + Q_D(QScriptDebugger); + d->errorLogWidget = errorLogWidget; +} + +QScriptDebuggerWidgetFactoryInterface *QScriptDebugger::widgetFactory() const +{ + Q_D(const QScriptDebugger); + return d->widgetFactory; +} + +void QScriptDebugger::setWidgetFactory(QScriptDebuggerWidgetFactoryInterface *factory) +{ + Q_D(QScriptDebugger); + d->widgetFactory = factory; +} + +QAction *QScriptDebugger::interruptAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->interruptAction) { + QIcon interruptIcon; + interruptIcon.addPixmap(d->pixmap(QString::fromLatin1("interrupt.png")), QIcon::Normal); + interruptIcon.addPixmap(d->pixmap(QString::fromLatin1("d_interrupt.png")), QIcon::Disabled); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->interruptAction = new QAction(interruptIcon, QObject::tr("Interrupt"), parent); + d->interruptAction->setEnabled(!d->interactive); + d->interruptAction->setShortcut(QObject::tr("Shift+F5")); + QObject::connect(d->interruptAction, SIGNAL(triggered()), + that, SLOT(_q_interrupt())); + } + return d->interruptAction; +} + +QAction *QScriptDebugger::continueAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->continueAction) { + QIcon continueIcon; + continueIcon.addPixmap(d->pixmap(QString::fromLatin1("play.png")), QIcon::Normal); + continueIcon.addPixmap(d->pixmap(QString::fromLatin1("d_play.png")), QIcon::Disabled); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->continueAction = new QAction(continueIcon, QObject::tr("Continue"), parent); + d->continueAction->setEnabled(d->interactive); + d->continueAction->setShortcut(QObject::tr("F5")); + QObject::connect(d->continueAction, SIGNAL(triggered()), + that, SLOT(_q_continue())); + } + return d->continueAction; +} + +QAction *QScriptDebugger::stepIntoAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->stepIntoAction) { + QIcon stepIntoIcon; + stepIntoIcon.addPixmap(d->pixmap(QString::fromLatin1("stepinto.png")), QIcon::Normal); + stepIntoIcon.addPixmap(d->pixmap(QString::fromLatin1("d_stepinto.png")), QIcon::Disabled); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->stepIntoAction = new QAction(stepIntoIcon, QObject::tr("Step Into"), parent); + d->stepIntoAction->setEnabled(d->interactive); + d->stepIntoAction->setShortcut(QObject::tr("F11")); + QObject::connect(d->stepIntoAction, SIGNAL(triggered()), + that, SLOT(_q_stepInto())); + } + return d->stepIntoAction; +} + +QAction *QScriptDebugger::stepOverAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->stepOverAction) { + QIcon stepOverIcon; + stepOverIcon.addPixmap(d->pixmap(QString::fromLatin1("stepover.png")), QIcon::Normal); + stepOverIcon.addPixmap(d->pixmap(QString::fromLatin1("d_stepover.png")), QIcon::Disabled); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->stepOverAction = new QAction(stepOverIcon, QObject::tr("Step Over"), parent); + d->stepOverAction->setEnabled(d->interactive); + d->stepOverAction->setShortcut(QObject::tr("F10")); + QObject::connect(d->stepOverAction, SIGNAL(triggered()), + that, SLOT(_q_stepOver())); + } + return d->stepOverAction; +} + +QAction *QScriptDebugger::stepOutAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->stepOutAction) { + QIcon stepOutIcon; + stepOutIcon.addPixmap(d->pixmap(QString::fromLatin1("stepout.png")), QIcon::Normal); + stepOutIcon.addPixmap(d->pixmap(QString::fromLatin1("d_stepout.png")), QIcon::Disabled); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->stepOutAction = new QAction(stepOutIcon, QObject::tr("Step Out"), parent); + d->stepOutAction->setEnabled(d->interactive); + d->stepOutAction->setShortcut(QObject::tr("Shift+F11")); + QObject::connect(d->stepOutAction, SIGNAL(triggered()), + that, SLOT(_q_stepOut())); + } + return d->stepOutAction; +} + +QAction *QScriptDebugger::runToCursorAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->runToCursorAction) { + QIcon runToCursorIcon; + runToCursorIcon.addPixmap(d->pixmap(QString::fromLatin1("runtocursor.png")), QIcon::Normal); + runToCursorIcon.addPixmap(d->pixmap(QString::fromLatin1("d_runtocursor.png")), QIcon::Disabled); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->runToCursorAction = new QAction(runToCursorIcon, QObject::tr("Run to Cursor"), parent); + d->runToCursorAction->setEnabled(d->interactive); + d->runToCursorAction->setShortcut(QObject::tr("Ctrl+F10")); + QObject::connect(d->runToCursorAction, SIGNAL(triggered()), + that, SLOT(_q_runToCursor())); + } + return d->runToCursorAction; +} + +QAction *QScriptDebugger::runToNewScriptAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->runToNewScriptAction) { + QIcon runToNewScriptIcon; + runToNewScriptIcon.addPixmap(d->pixmap(QString::fromLatin1("runtonewscript.png")), QIcon::Normal); + runToNewScriptIcon.addPixmap(d->pixmap(QString::fromLatin1("d_breakonscriptload.png")), QIcon::Disabled); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->runToNewScriptAction = new QAction(runToNewScriptIcon, + QObject::tr("Run to New Script"), parent); + d->runToNewScriptAction->setEnabled(d->interactive); + QObject::connect(d->runToNewScriptAction, SIGNAL(triggered()), + that, SLOT(_q_runToNewScript())); + } + return d->runToNewScriptAction; +} + +QAction *QScriptDebugger::toggleBreakpointAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->toggleBreakpointAction) { + QIcon toggleBreakpointIcon; + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->toggleBreakpointAction = new QAction(toggleBreakpointIcon, + QObject::tr("Toggle Breakpoint"), parent); + d->toggleBreakpointAction->setShortcut(QObject::tr("F9")); + d->toggleBreakpointAction->setEnabled((d->codeWidget != 0) && (d->codeWidget->currentView() != 0)); + QObject::connect(d->toggleBreakpointAction, SIGNAL(triggered()), + that, SLOT(_q_toggleBreakpoint())); + } + return d->toggleBreakpointAction; +} + +QAction *QScriptDebugger::clearDebugOutputAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->clearDebugOutputAction) { + QIcon clearDebugOutputIcon; + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->clearDebugOutputAction = new QAction(clearDebugOutputIcon, QObject::tr("Clear Debug Output"), parent); + QObject::connect(d->clearDebugOutputAction, SIGNAL(triggered()), + that, SLOT(_q_clearDebugOutput())); + } + return d->clearDebugOutputAction; +} + +QAction *QScriptDebugger::clearErrorLogAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->clearErrorLogAction) { + QIcon clearErrorLogIcon; + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->clearErrorLogAction = new QAction(clearErrorLogIcon, QObject::tr("Clear Error Log"), parent); + QObject::connect(d->clearErrorLogAction, SIGNAL(triggered()), + that, SLOT(_q_clearErrorLog())); + } + return d->clearErrorLogAction; +} + +QAction *QScriptDebugger::clearConsoleAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->clearConsoleAction) { + QIcon clearConsoleIcon; + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->clearConsoleAction = new QAction(clearConsoleIcon, QObject::tr("Clear Console"), parent); + QObject::connect(d->clearConsoleAction, SIGNAL(triggered()), + that, SLOT(_q_clearConsole())); + } + return d->clearConsoleAction; +} + +QAction *QScriptDebugger::findInScriptAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->findInScriptAction) { + QIcon findInScriptIcon; + findInScriptIcon.addPixmap(d->pixmap(QString::fromLatin1("find.png")), QIcon::Normal); + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->findInScriptAction = new QAction(findInScriptIcon, QObject::tr("&Find in Script..."), parent); + d->findInScriptAction->setShortcut(QObject::tr("Ctrl+F")); + d->findInScriptAction->setEnabled( + (d->codeFinderWidget != 0) + && (d->codeWidget != 0) + && (d->codeWidget->currentView() != 0)); + QObject::connect(d->findInScriptAction, SIGNAL(triggered()), + that, SLOT(_q_findInScript())); + } + return d->findInScriptAction; +} + +QAction *QScriptDebugger::findNextInScriptAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->findNextInScriptAction) { + QIcon findNextInScriptIcon; + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->findNextInScriptAction = new QAction(findNextInScriptIcon, QObject::tr("Find &Next"), parent); + d->findNextInScriptAction->setEnabled(d->codeFinderWidget && !d->codeFinderWidget->text().isEmpty()); + d->findNextInScriptAction->setShortcut(QObject::tr("F3")); + QObject::connect(d->findNextInScriptAction, SIGNAL(triggered()), + that, SLOT(_q_findNextInScript())); + } + return d->findNextInScriptAction; +} + +QAction *QScriptDebugger::findPreviousInScriptAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->findPreviousInScriptAction) { + QIcon findPreviousInScriptIcon; + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->findPreviousInScriptAction = new QAction(findPreviousInScriptIcon, QObject::tr("Find &Previous"), parent); + d->findPreviousInScriptAction->setEnabled(d->codeFinderWidget && !d->codeFinderWidget->text().isEmpty()); + d->findPreviousInScriptAction->setShortcut(QObject::tr("Shift+F3")); + QObject::connect(d->findPreviousInScriptAction, SIGNAL(triggered()), + that, SLOT(_q_findPreviousInScript())); + } + return d->findPreviousInScriptAction; +} + +QAction *QScriptDebugger::goToLineAction(QObject *parent) const +{ + Q_D(const QScriptDebugger); + if (!d->goToLineAction) { + QIcon goToLineIcon; + QScriptDebugger *that = const_cast<QScriptDebugger*>(this); + that->d_func()->goToLineAction = new QAction(goToLineIcon, QObject::tr("Go to Line"), parent); + d->goToLineAction->setShortcut(QObject::tr("Ctrl+G")); + d->goToLineAction->setEnabled((d->codeWidget != 0) && (d->codeWidget->currentView() != 0)); + QObject::connect(d->goToLineAction, SIGNAL(triggered()), + that, SLOT(_q_goToLine())); + } + return d->goToLineAction; +} + +/*! + \reimp +*/ +bool QScriptDebugger::eventFilter(QObject *watched, QEvent *e) +{ + Q_D(QScriptDebugger); + if (watched == d->codeWidget) { + if (e->type() == QEvent::KeyPress) { + d->_q_findInScript(); + d->codeFinderWidget->setText(static_cast<QKeyEvent*>(e)->text()); + return true; + } + } + return false; +} + +/*! + \reimp +*/ +void QScriptDebugger::timerEvent(QTimerEvent *e) +{ + Q_D(QScriptDebugger); + if (e->timerId() == d->updatesEnabledTimerId) { + killTimer(d->updatesEnabledTimerId); + d->updatesEnabledTimerId = -1; + if (d->stackWidget) + d->stackWidget->setUpdatesEnabled(true); + if (d->localsWidget) + d->localsWidget->setUpdatesEnabled(true); + } else { + QObject::timerEvent(e); + } +} + +QT_END_NAMESPACE + +#include "moc_qscriptdebugger_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebugger_p.h b/src/scripttools/debugging/qscriptdebugger_p.h new file mode 100644 index 0000000..8f14f4d --- /dev/null +++ b/src/scripttools/debugging/qscriptdebugger_p.h @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGER_P_H +#define QSCRIPTDEBUGGER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerFrontend; +class QScriptDebuggerConsoleWidgetInterface; +class QScriptDebuggerScriptsWidgetInterface; +class QScriptDebuggerCodeWidgetInterface; +class QScriptDebuggerCodeFinderWidgetInterface; +class QScriptBreakpointsWidgetInterface; +class QScriptDebuggerStackWidgetInterface; +class QScriptDebuggerLocalsWidgetInterface; +class QScriptDebugOutputWidgetInterface; +class QScriptErrorLogWidgetInterface; +class QScriptDebuggerWidgetFactoryInterface; +class QAction; +class QEvent; + +class QScriptDebuggerPrivate; +class Q_AUTOTEST_EXPORT QScriptDebugger : public QObject +{ + Q_OBJECT +public: + QScriptDebugger(QObject *parent = 0); + ~QScriptDebugger(); + + QScriptDebuggerFrontend *frontend() const; + void setFrontend(QScriptDebuggerFrontend *frontend); + + QScriptDebuggerConsoleWidgetInterface *consoleWidget() const; + void setConsoleWidget(QScriptDebuggerConsoleWidgetInterface *consoleWidget); + + QScriptDebuggerScriptsWidgetInterface *scriptsWidget() const; + void setScriptsWidget(QScriptDebuggerScriptsWidgetInterface *scriptsWidget); + + QScriptDebuggerCodeWidgetInterface *codeWidget() const; + void setCodeWidget(QScriptDebuggerCodeWidgetInterface *codeWidget); + + QScriptDebuggerCodeFinderWidgetInterface *codeFinderWidget() const; + void setCodeFinderWidget(QScriptDebuggerCodeFinderWidgetInterface *codeFinderWidget); + + QScriptDebuggerStackWidgetInterface *stackWidget() const; + void setStackWidget(QScriptDebuggerStackWidgetInterface *stackWidget); + + QScriptDebuggerLocalsWidgetInterface *localsWidget() const; + void setLocalsWidget(QScriptDebuggerLocalsWidgetInterface *localsWidget); + + QScriptBreakpointsWidgetInterface *breakpointsWidget() const; + void setBreakpointsWidget(QScriptBreakpointsWidgetInterface *breakpointsWidget); + + QScriptDebugOutputWidgetInterface *debugOutputWidget() const; + void setDebugOutputWidget(QScriptDebugOutputWidgetInterface *debugOutputWidget); + + QScriptErrorLogWidgetInterface *errorLogWidget() const; + void setErrorLogWidget(QScriptErrorLogWidgetInterface *errorLogWidget); + + QScriptDebuggerWidgetFactoryInterface *widgetFactory() const; + void setWidgetFactory(QScriptDebuggerWidgetFactoryInterface *factory); + + QAction *interruptAction(QObject *parent) const; + QAction *continueAction(QObject *parent) const; + QAction *stepIntoAction(QObject *parent) const; + QAction *stepOverAction(QObject *parent) const; + QAction *stepOutAction(QObject *parent) const; + QAction *runToCursorAction(QObject *parent) const; + QAction *runToNewScriptAction(QObject *parent) const; + + QAction *toggleBreakpointAction(QObject *parent) const; + + QAction *findInScriptAction(QObject *parent) const; + QAction *findNextInScriptAction(QObject *parent) const; + QAction *findPreviousInScriptAction(QObject *parent) const; + QAction *goToLineAction(QObject *parent) const; + + QAction *clearDebugOutputAction(QObject *parent) const; + QAction *clearConsoleAction(QObject *parent) const; + QAction *clearErrorLogAction(QObject *parent) const; + + bool eventFilter(QObject *, QEvent *e); + +Q_SIGNALS: + void stopped() const; + void started() const; + +protected: + void timerEvent(QTimerEvent *e); + +protected: + QScriptDebugger(QScriptDebuggerPrivate &dd, QObject *parent); + +private: + Q_DECLARE_PRIVATE(QScriptDebugger) + Q_DISABLE_COPY(QScriptDebugger) + + Q_PRIVATE_SLOT(d_func(), void _q_onLineEntered(const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_onCurrentFrameChanged(int)) + Q_PRIVATE_SLOT(d_func(), void _q_onCurrentScriptChanged(qint64)) + Q_PRIVATE_SLOT(d_func(), void _q_onScriptLocationSelected(int)) + + Q_PRIVATE_SLOT(d_func(), void _q_interrupt()) + Q_PRIVATE_SLOT(d_func(), void _q_continue()) + Q_PRIVATE_SLOT(d_func(), void _q_stepInto()) + Q_PRIVATE_SLOT(d_func(), void _q_stepOver()) + Q_PRIVATE_SLOT(d_func(), void _q_stepOut()) + Q_PRIVATE_SLOT(d_func(), void _q_runToCursor()) + Q_PRIVATE_SLOT(d_func(), void _q_runToNewScript()) + + Q_PRIVATE_SLOT(d_func(), void _q_toggleBreakpoint()) + + Q_PRIVATE_SLOT(d_func(), void _q_clearDebugOutput()) + Q_PRIVATE_SLOT(d_func(), void _q_clearErrorLog()) + Q_PRIVATE_SLOT(d_func(), void _q_clearConsole()) + + Q_PRIVATE_SLOT(d_func(), void _q_findInScript()) + Q_PRIVATE_SLOT(d_func(), void _q_findNextInScript()) + Q_PRIVATE_SLOT(d_func(), void _q_findPreviousInScript()) + Q_PRIVATE_SLOT(d_func(), void _q_onFindCodeRequest(const QString &, int)) + Q_PRIVATE_SLOT(d_func(), void _q_goToLine()) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggeragent.cpp b/src/scripttools/debugging/qscriptdebuggeragent.cpp new file mode 100644 index 0000000..fcba033 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggeragent.cpp @@ -0,0 +1,748 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggeragent_p.h" +#include "qscriptdebuggeragent_p_p.h" +#include "qscriptdebuggerbackend_p_p.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qset.h> +#include <QtScript/qscriptengine.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerAgent + \internal + + This class implements a state machine that uses the low-level events + reported by the QScriptEngineAgent interface to implement debugging- + specific functionality such as stepping and breakpoints. It is used + internally by the QScriptDebuggerBackend class. +*/ + +QScriptDebuggerAgentPrivate::QScriptDebuggerAgentPrivate() +{ + state = NoState; + nextBreakpointId = 1; + nextContextId = 0; + statementCounter = 0; +} + +QScriptDebuggerAgentPrivate::~QScriptDebuggerAgentPrivate() +{ +} + +QScriptDebuggerAgentPrivate *QScriptDebuggerAgentPrivate::get( + QScriptDebuggerAgent *q) +{ + if (!q) + return 0; + return q->d_func(); +} + + +/*! + Constructs a new agent for the given \a engine. The agent will + report debugging-related events (e.g. step completion) to the given + \a backend. +*/ +QScriptDebuggerAgent::QScriptDebuggerAgent( + QScriptDebuggerBackendPrivate *backend, QScriptEngine *engine) +#if QT_VERSION >= 0x040500 + : QScriptEngineAgent(*new QScriptDebuggerAgentPrivate, engine) +#else + : QScriptEngineAgent(engine), d_ptr(new QScriptDebuggerAgentPrivate) +#endif +{ + Q_D(QScriptDebuggerAgent); +#if QT_VERSION < 0x040500 + d_ptr->q_ptr = this; +#endif + d->backend = backend; + + QScriptContext *ctx = engine->currentContext(); + while (ctx) { + d->scriptIdStack.append(QList<qint64>()); + d->contextIdStack.append(d->nextContextId); + ++d->nextContextId; + ctx = ctx->parentContext(); + } +} + +/*! + Destroys this QScriptDebuggerAgent. +*/ +QScriptDebuggerAgent::~QScriptDebuggerAgent() +{ + Q_D(QScriptDebuggerAgent); + if (d->backend) + d->backend->agentDestroyed(this); +#if QT_VERSION < 0x040500 + delete d_ptr; +#endif +} + +/*! + Instructs the agent to perform a "step into" operation. This + function returns immediately. The agent will report step completion + at a later time, i.e. when script statements are evaluted. +*/ +void QScriptDebuggerAgent::enterStepIntoMode(int count) +{ + Q_D(QScriptDebuggerAgent); + d->state = QScriptDebuggerAgentPrivate::SteppingIntoState; + d->stepCount = count; + d->stepResult = QScriptValue(); +} + +/*! + Instructs the agent to perform a "step over" operation. This + function returns immediately. The agent will report step completion + at a later time, i.e. when script statements are evaluted. +*/ +void QScriptDebuggerAgent::enterStepOverMode(int count) +{ + Q_D(QScriptDebuggerAgent); + d->state = QScriptDebuggerAgentPrivate::SteppingOverState; + if (engine()->isEvaluating()) + d->stepDepth = 0; + else + d->stepDepth = -1; + d->stepCount = count; + d->stepResult = QScriptValue(); +} + +/*! + Instructs the agent to perform a "step out" operation. This + function returns immediately. The agent will report step completion + at a later time, i.e. when script statements are evaluted. +*/ +void QScriptDebuggerAgent::enterStepOutMode() +{ + Q_D(QScriptDebuggerAgent); + d->state = QScriptDebuggerAgentPrivate::SteppingOutState; + if (engine()->isEvaluating()) + d->stepDepth = 0; + else + d->stepDepth = -1; +} + +/*! + Instructs the agent to continue evaluation. + This function returns immediately. +*/ +void QScriptDebuggerAgent::enterContinueMode() +{ + Q_D(QScriptDebuggerAgent); + d->state = QScriptDebuggerAgentPrivate::NoState; +} + +/*! + Instructs the agent to interrupt evaluation. + This function returns immediately. +*/ +void QScriptDebuggerAgent::enterInterruptMode() +{ + Q_D(QScriptDebuggerAgent); + d->state = QScriptDebuggerAgentPrivate::InterruptingState; +} + +/*! + Instructs the agent to continue evaluation until the location + described by \a fileName and \a lineNumber is reached. This + function returns immediately. +*/ +void QScriptDebuggerAgent::enterRunToLocationMode(const QString &fileName, int lineNumber) +{ + Q_D(QScriptDebuggerAgent); + d->targetFileName = fileName; + d->targetLineNumber = lineNumber; + d->targetScriptId = resolveScript(fileName); + d->state = QScriptDebuggerAgentPrivate::RunningToLocationState; +} + +/*! + Instructs the agent to continue evaluation until the location + described by \a scriptId and \a lineNumber is reached. This + function returns immediately. +*/ +void QScriptDebuggerAgent::enterRunToLocationMode(qint64 scriptId, int lineNumber) +{ + Q_D(QScriptDebuggerAgent); + d->targetScriptId = scriptId; + d->targetFileName = QString(); + d->targetLineNumber = lineNumber; + d->state = QScriptDebuggerAgentPrivate::RunningToLocationState; +} + +void QScriptDebuggerAgent::enterReturnByForceMode(int contextIndex, const QScriptValue &value) +{ + Q_D(QScriptDebuggerAgent); + d->returnCounter = contextIndex + 1; + d->returnValue = QScriptValue(); + d->state = QScriptDebuggerAgentPrivate::ReturningByForceState; + // throw an exception; we will catch it when the proper frame is popped + engine()->currentContext()->throwValue(value); +} + +/*! + Sets a breakpoint defined by the given \a data. + Returns an integer that uniquely identifies the new breakpoint, + or -1 if setting the breakpoint failed. +*/ +int QScriptDebuggerAgent::setBreakpoint(const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerAgent); + qint64 scriptId = data.scriptId(); + if (scriptId != -1) { + if (!d->scripts.contains(scriptId)) { + // that script has been unloaded, so invalidate the ID + scriptId = -1; + const_cast<QScriptBreakpointData&>(data).setScriptId(-1); + } else if (data.fileName().isEmpty()) { + QString fileName = d->scripts[scriptId].fileName(); + const_cast<QScriptBreakpointData&>(data).setFileName(fileName); + } + } + + int id = d->nextBreakpointId; + ++d->nextBreakpointId; + + if (scriptId != -1) { + d->resolvedBreakpoints[scriptId].append(id); + } else { + QString fileName = data.fileName(); + bool resolved = false; + QScriptScriptMap::const_iterator it; + for (it = d->scripts.constBegin(); it != d->scripts.constEnd(); ++it) { + if (it.value().fileName() == fileName) { + d->resolvedBreakpoints[it.key()].append(id); + resolved = true; + break; + } + } + if (!resolved) + d->unresolvedBreakpoints[fileName].append(id); + } + + d->breakpoints.insert(id, data); + + return id; +} + +/*! + Deletes the breakpoint with the given \a id. + Returns true if the breakpoint was deleted, false if + no such breakpoint exists. +*/ +bool QScriptDebuggerAgent::deleteBreakpoint(int id) +{ + Q_D(QScriptDebuggerAgent); + if (!d->breakpoints.contains(id)) + return false; + d->breakpoints.remove(id); + bool found = false; + { + QHash<qint64, QList<int> >::iterator it; + it = d->resolvedBreakpoints.begin(); + for ( ; !found && (it != d->resolvedBreakpoints.end()); ) { + QList<int> &lst = it.value(); + Q_ASSERT(!lst.isEmpty()); + for (int i = 0; i < lst.size(); ++i) { + if (lst.at(i) == id) { + lst.removeAt(i); + found = true; + break; + } + } + if (lst.isEmpty()) + it = d->resolvedBreakpoints.erase(it); + else + ++it; + } + } + if (!found) { + QHash<QString, QList<int> >::iterator it; + it = d->unresolvedBreakpoints.begin(); + for ( ; !found && (it != d->unresolvedBreakpoints.end()); ) { + QList<int> &lst = it.value(); + Q_ASSERT(!lst.isEmpty()); + for (int i = 0; i < lst.size(); ++i) { + if (lst.at(i) == id) { + lst.removeAt(i); + found = true; + break; + } + } + if (lst.isEmpty()) + it = d->unresolvedBreakpoints.erase(it); + else + ++it; + } + } + return found; +} + +/*! + Deletes all breakpoints. +*/ +void QScriptDebuggerAgent::deleteAllBreakpoints() +{ + Q_D(QScriptDebuggerAgent); + d->breakpoints.clear(); + d->resolvedBreakpoints.clear(); + d->unresolvedBreakpoints.clear(); +} + +/*! + Returns the data associated with the breakpoint with the given \a + id. +*/ +QScriptBreakpointData QScriptDebuggerAgent::breakpointData(int id) const +{ + Q_D(const QScriptDebuggerAgent); + return d->breakpoints.value(id); +} + +/*! + Sets the data associated with the breakpoint with the given \a + id. +*/ +bool QScriptDebuggerAgent::setBreakpointData(int id, + const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerAgent); + if (!d->breakpoints.contains(id)) + return false; + d->breakpoints[id] = data; + return true; +} + +/*! + Returns all breakpoints. +*/ +QScriptBreakpointMap QScriptDebuggerAgent::breakpoints() const +{ + Q_D(const QScriptDebuggerAgent); + return d->breakpoints; +} + +/*! + Returns all scripts. +*/ +QScriptScriptMap QScriptDebuggerAgent::scripts() const +{ + Q_D(const QScriptDebuggerAgent); + return d->scripts; +} + +/*! + Returns the data associated with the script with the given \a id. +*/ +QScriptScriptData QScriptDebuggerAgent::scriptData(qint64 id) const +{ + Q_D(const QScriptDebuggerAgent); + return d->scripts.value(id); +} + +/*! + Checkpoints the current scripts. +*/ +void QScriptDebuggerAgent::scriptsCheckpoint() +{ + Q_D(QScriptDebuggerAgent); + d->previousCheckpointScripts = d->checkpointScripts; + d->checkpointScripts = d->scripts; +} + +/*! + Returns the difference between the current checkpoint and the + previous checkpoint. The first item in the pair is a list containing + the identifiers of the scripts that were added. The second item in + the pair is a list containing the identifiers of the scripts that + were removed. +*/ +QPair<QList<qint64>, QList<qint64> > QScriptDebuggerAgent::scriptsDelta() const +{ + Q_D(const QScriptDebuggerAgent); + QSet<qint64> prevSet = d->previousCheckpointScripts.keys().toSet(); + QSet<qint64> currSet = d->checkpointScripts.keys().toSet(); + QSet<qint64> addedScriptIds = currSet - prevSet; + QSet<qint64> removedScriptIds = prevSet - currSet; + return qMakePair(addedScriptIds.toList(), removedScriptIds.toList()); +} + +/*! + Returns the identifier of the script that has the given \a fileName, + or -1 if there is no such script. +*/ +qint64 QScriptDebuggerAgent::resolveScript(const QString &fileName) const +{ + Q_D(const QScriptDebuggerAgent); + QScriptScriptMap::const_iterator it; + for (it = d->scripts.constBegin(); it != d->scripts.constEnd(); ++it) { + if (it.value().fileName() == fileName) + return it.key(); + } + return -1; +} + +QList<qint64> QScriptDebuggerAgent::contextIds() const +{ + Q_D(const QScriptDebuggerAgent); + return d->contextIdStack; +} + +QPair<QList<qint64>, QList<qint64> > QScriptDebuggerAgent::contextsCheckpoint() +{ + Q_D(QScriptDebuggerAgent); + int i = d->checkpointContextIdStack.size() - 1; + int j = d->contextIdStack.size() - 1; + for ( ; (i >= 0) && (j >= 0); --i, --j) { + if (d->checkpointContextIdStack.at(i) != d->contextIdStack.at(j)) + break; + } + QList<qint64> removed = d->checkpointContextIdStack.mid(0, i+1); + QList<qint64> added = d->contextIdStack.mid(0, j+1); + d->checkpointContextIdStack = d->contextIdStack; + return qMakePair(removed, added); +} + +void QScriptDebuggerAgent::nullifyBackendPointer() +{ + Q_D(QScriptDebuggerAgent); + d->backend = 0; +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::scriptLoad(qint64 id, const QString &program, + const QString &fileName, int baseLineNumber) +{ + Q_D(QScriptDebuggerAgent); + QScriptScriptData data = QScriptScriptData(program, fileName, baseLineNumber); + d->scripts.insert(id, data); + + if ((d->state == QScriptDebuggerAgentPrivate::RunningToLocationState) + && (d->targetScriptId == -1) + && ((d->targetFileName == fileName) || d->targetFileName.isEmpty())) { + d->targetScriptId = id; + } + + if (!fileName.isEmpty()) { + QList<int> lst = d->unresolvedBreakpoints.take(fileName); + if (!lst.isEmpty()) + d->resolvedBreakpoints.insert(id, lst); + } +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::scriptUnload(qint64 id) +{ + Q_D(QScriptDebuggerAgent); + QScriptScriptData data = d->scripts.take(id); + QString fileName = data.fileName(); + + if ((d->state == QScriptDebuggerAgentPrivate::RunningToLocationState) + && (d->targetScriptId == id)) { + d->targetScriptId = -1; + d->targetFileName = fileName; + } + + if (!fileName.isEmpty()) { + QList<int> lst = d->resolvedBreakpoints.take(id); + if (!lst.isEmpty()) + d->unresolvedBreakpoints.insert(fileName, lst); + } +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::contextPush() +{ + Q_D(QScriptDebuggerAgent); + d->scriptIdStack.append(QList<qint64>()); + d->contextIdStack.prepend(d->nextContextId); + ++d->nextContextId; +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::contextPop() +{ + Q_D(QScriptDebuggerAgent); + d->scriptIdStack.removeLast(); + d->contextIdStack.removeFirst(); +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::functionEntry(qint64 scriptId) +{ + Q_D(QScriptDebuggerAgent); + QList<qint64> &ids = d->scriptIdStack.last(); + ids.append(scriptId); + if ((d->state == QScriptDebuggerAgentPrivate::SteppingOverState) + || (d->state == QScriptDebuggerAgentPrivate::SteppingOutState)) { + ++d->stepDepth; + } +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::functionExit(qint64 scriptId, + const QScriptValue &returnValue) +{ + Q_UNUSED(scriptId); + Q_D(QScriptDebuggerAgent); + QList<qint64> &ids = d->scriptIdStack.last(); + ids.removeLast(); + if (d->state == QScriptDebuggerAgentPrivate::SteppingOverState) { + --d->stepDepth; + } else if (d->state == QScriptDebuggerAgentPrivate::SteppingOutState) { + if (--d->stepDepth < 0) { + d->stepResult = returnValue; + d->state = QScriptDebuggerAgentPrivate::SteppedOutState; + } + } else if (d->state == QScriptDebuggerAgentPrivate::ReturningByForceState) { + if (--d->returnCounter == 0) { + d->returnValue = returnValue; + d->state = QScriptDebuggerAgentPrivate::ReturnedByForceState; + engine()->clearExceptions(); + } + } +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::positionChange(qint64 scriptId, + int lineNumber, int columnNumber) +{ + Q_D(QScriptDebuggerAgent); + if (engine()->processEventsInterval() == -1) { + // see if it's time to call processEvents() + if ((++d->statementCounter % 25000) == 0) { + if (!d->processEventsTimer.isNull()) { + if (d->processEventsTimer.elapsed() > 30) { + QCoreApplication::processEvents(); + d->processEventsTimer.restart(); + } + } else { + d->processEventsTimer.start(); + } + } + } + + // check breakpoints + { + QList<int> lst = d->resolvedBreakpoints.value(scriptId); + for (int i = 0; i < lst.size(); ++i) { + int id = lst.at(i); + QScriptBreakpointData &data = d->breakpoints[id]; + if (!data.isEnabled()) + continue; + if (data.lineNumber() != lineNumber) + continue; + if (!data.condition().isEmpty()) { + // ### careful, evaluate() can cause an exception + // ### disable callbacks in nested evaluate? + QScriptDebuggerAgentPrivate::State was = d->state; + d->state = QScriptDebuggerAgentPrivate::NoState; + QScriptValue ret = engine()->evaluate( + data.condition(), + QString::fromLatin1("Breakpoint %0 condition checker").arg(id)); + if (!ret.isError()) + d->state = was; + if (!ret.toBoolean()) + continue; + } + if (!data.hit()) + continue; + d->hitBreakpointId = id; + d->state = QScriptDebuggerAgentPrivate::BreakpointState; + } + } + + switch (d->state) { + case QScriptDebuggerAgentPrivate::NoState: + case QScriptDebuggerAgentPrivate::SteppingOutState: + case QScriptDebuggerAgentPrivate::ReturningByForceState: + // Do nothing + break; + + case QScriptDebuggerAgentPrivate::SteppingIntoState: + if (--d->stepCount == 0) { + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) + d->backend->stepped(scriptId, lineNumber, columnNumber, QScriptValue()); + } + break; + + case QScriptDebuggerAgentPrivate::SteppingOverState: + if ((d->stepDepth > 0) || (--d->stepCount != 0)) + break; + // fallthrough + case QScriptDebuggerAgentPrivate::SteppedOverState: + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) + d->backend->stepped(scriptId, lineNumber, columnNumber, d->stepResult); + break; + + case QScriptDebuggerAgentPrivate::SteppedOutState: + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) + d->backend->stepped(scriptId, lineNumber, columnNumber, d->stepResult); + break; + + case QScriptDebuggerAgentPrivate::RunningToLocationState: + if (((lineNumber == d->targetLineNumber) || (d->targetLineNumber == -1)) + && (scriptId == d->targetScriptId)) { + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) + d->backend->locationReached(scriptId, lineNumber, columnNumber); + } + break; + + case QScriptDebuggerAgentPrivate::InterruptingState: + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) + d->backend->interrupted(scriptId, lineNumber, columnNumber); + break; + + case QScriptDebuggerAgentPrivate::BreakpointState: + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) + d->backend->breakpoint(scriptId, lineNumber, columnNumber, d->hitBreakpointId); + if (d->breakpoints.value(d->hitBreakpointId).isSingleShot()) + deleteBreakpoint(d->hitBreakpointId); + break; + + case QScriptDebuggerAgentPrivate::ReturnedByForceState: + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) + d->backend->forcedReturn(scriptId, lineNumber, columnNumber, d->returnValue); + break; + + case QScriptDebuggerAgentPrivate::SteppedIntoState: + case QScriptDebuggerAgentPrivate::ReachedLocationState: + case QScriptDebuggerAgentPrivate::InterruptedState: +// ### deal with the case when code is evaluated while we're already paused +// Q_ASSERT(false); + break; + } +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::exceptionThrow(qint64 scriptId, + const QScriptValue &exception, + bool hasHandler) +{ + Q_D(QScriptDebuggerAgent); + if (d->state == QScriptDebuggerAgentPrivate::ReturningByForceState) { + // we threw this exception ourselves, so ignore it for now + // (see functionExit()). + return; + } + if (d->backend) + d->backend->exception(scriptId, exception, hasHandler); +} + +/*! + \reimp +*/ +void QScriptDebuggerAgent::exceptionCatch(qint64 scriptId, + const QScriptValue &exception) +{ + Q_UNUSED(scriptId); + Q_UNUSED(exception); +} + +/*! + \reimp +*/ +bool QScriptDebuggerAgent::supportsExtension(Extension extension) const +{ +#if QT_VERSION >= 0x040500 + return (extension == DebuggerInvocationRequest); +#else + Q_UNUSED(extension); + return false; +#endif +} + +/*! + \reimp +*/ +QVariant QScriptDebuggerAgent::extension(Extension extension, + const QVariant &argument) +{ + Q_UNUSED(extension); +#if QT_VERSION >= 0x040500 + Q_D(QScriptDebuggerAgent); + Q_ASSERT(extension == DebuggerInvocationRequest); + QVariantList lst = argument.toList(); + qint64 scriptId = lst.at(0).toLongLong(); + int lineNumber = lst.at(1).toInt(); + int columnNumber = lst.at(2).toInt(); + d->state = QScriptDebuggerAgentPrivate::NoState; + if (d->backend) { + d->backend->debuggerInvocationRequest( + scriptId, lineNumber, columnNumber); + } +#else + Q_UNUSED(argument); +#endif + return QVariant(); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggeragent_p.h b/src/scripttools/debugging/qscriptdebuggeragent_p.h new file mode 100644 index 0000000..556b17b --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggeragent_p.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERAGENT_P_H +#define QSCRIPTDEBUGGERAGENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtScript/qscriptengineagent.h> + +#include <QtCore/qpair.h> + +#include "qscriptbreakpointdata_p.h" +#include "qscriptscriptdata_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerBackendPrivate; + +class QScriptDebuggerAgentPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerAgent : public QScriptEngineAgent +{ +public: + QScriptDebuggerAgent(QScriptDebuggerBackendPrivate *backend, + QScriptEngine *engine); + ~QScriptDebuggerAgent(); + + void enterStepIntoMode(int count = 1); + void enterStepOverMode(int count = 1); + void enterStepOutMode(); + void enterContinueMode(); + void enterInterruptMode(); + void enterRunToLocationMode(const QString &fileName, int lineNumber); + void enterRunToLocationMode(qint64 scriptId, int lineNumber); + void enterReturnByForceMode(int contextIndex, const QScriptValue &value); + + int setBreakpoint(const QScriptBreakpointData &data); + bool deleteBreakpoint(int id); + void deleteAllBreakpoints(); + QScriptBreakpointData breakpointData(int id) const; + bool setBreakpointData(int id, const QScriptBreakpointData &data); + QScriptBreakpointMap breakpoints() const; + + QScriptScriptMap scripts() const; + QScriptScriptData scriptData(qint64 id) const; + void scriptsCheckpoint(); + QPair<QList<qint64>, QList<qint64> > scriptsDelta() const; + qint64 resolveScript(const QString &fileName) const; + + QList<qint64> contextIds() const; + QPair<QList<qint64>, QList<qint64> > contextsCheckpoint(); + + void nullifyBackendPointer(); + + // reimplemented + void scriptLoad(qint64 id, const QString &program, + const QString &fileName, int baseLineNumber); + void scriptUnload(qint64 id); + + void contextPush(); + void contextPop(); + + void functionEntry(qint64 scriptId); + void functionExit(qint64 scriptId, + const QScriptValue &returnValue); + + void positionChange(qint64 scriptId, + int lineNumber, int columnNumber); + + void exceptionThrow(qint64 scriptId, + const QScriptValue &exception, + bool hasHandler); + void exceptionCatch(qint64 scriptId, + const QScriptValue &exception); + + bool supportsExtension(Extension extension) const; + QVariant extension(Extension extension, + const QVariant &argument = QVariant()); + +private: +#if QT_VERSION < 0x040500 + QScriptDebuggerAgentPrivate *d_ptr; +#endif + Q_DECLARE_PRIVATE(QScriptDebuggerAgent) + Q_DISABLE_COPY(QScriptDebuggerAgent) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggeragent_p_p.h b/src/scripttools/debugging/qscriptdebuggeragent_p_p.h new file mode 100644 index 0000000..cf6fd1a --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggeragent_p_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERAGENT_P_P_H +#define QSCRIPTDEBUGGERAGENT_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qscriptengineagent_p.h> + +#include <QtScript/qscriptvalue.h> +#include <QtCore/qdatetime.h> +#include <QtCore/qhash.h> +#include <QtCore/qmap.h> +#include <QtCore/qlist.h> + +#include "qscriptscriptdata_p.h" +#include "qscriptbreakpointdata_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerAgent; +class QScriptDebuggerAgentPrivate +#if QT_VERSION >= 0x040500 + : public QScriptEngineAgentPrivate +#endif +{ + Q_DECLARE_PUBLIC(QScriptDebuggerAgent) +public: + enum State { + NoState, + SteppingIntoState, + SteppedIntoState, + SteppingOverState, + SteppedOverState, + SteppingOutState, + SteppedOutState, + RunningToLocationState, + ReachedLocationState, + InterruptingState, + InterruptedState, + BreakpointState, + ReturningByForceState, + ReturnedByForceState + }; + + QScriptDebuggerAgentPrivate(); + ~QScriptDebuggerAgentPrivate(); + + static QScriptDebuggerAgentPrivate *get(QScriptDebuggerAgent *); + + State state; + int stepDepth; + int stepCount; + int targetScriptId; + QString targetFileName; + int targetLineNumber; + QScriptValue stepResult; + int returnCounter; + QScriptValue returnValue; + + int nextBreakpointId; + QHash<qint64, QList<int> > resolvedBreakpoints; + QHash<QString, QList<int> > unresolvedBreakpoints; + QScriptBreakpointMap breakpoints; + int hitBreakpointId; + + QScriptScriptMap scripts; + QScriptScriptMap checkpointScripts; + QScriptScriptMap previousCheckpointScripts; + QList<QList<qint64> > scriptIdStack; + + QList<qint64> contextIdStack; + QList<qint64> checkpointContextIdStack; + qint64 nextContextId; + + QTime processEventsTimer; + int statementCounter; + + QScriptDebuggerBackendPrivate *backend; + +#if QT_VERSION < 0x040500 + QScriptDebuggerAgent *q_ptr; +#endif +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerbackend.cpp b/src/scripttools/debugging/qscriptdebuggerbackend.cpp new file mode 100644 index 0000000..24a3847 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerbackend.cpp @@ -0,0 +1,998 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerbackend_p.h" +#include "qscriptdebuggerbackend_p_p.h" +#include "qscriptdebuggeragent_p.h" +#include "qscriptdebuggercommandexecutor_p.h" +#include "qscriptdebuggerevent_p.h" +#include "qscriptdebuggervalue_p.h" +#include "qscriptscriptdata_p.h" +#include "qscriptbreakpointdata_p.h" +#include "qscriptobjectsnapshot_p.h" + +#include <QtScript/qscriptengine.h> +#include <QtScript/qscriptcontextinfo.h> +#include <QtScript/qscriptvalueiterator.h> + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qdebug.h> + +Q_DECLARE_METATYPE(QScriptDebuggerValue) +Q_DECLARE_METATYPE(QScriptDebuggerBackendPrivate*) + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerBackend + \internal + + \brief The QScriptDebuggerBackend class is the base class of debugger back-ends. + + QScriptDebuggerBackend builds on the QScriptDebuggerAgent class. + + This class is usually used together with the QScriptDebuggerFrontend + class, in order to form a (front-end, back-end) pair. + + Call attachTo() to attach to a QScriptEngine object. Call detach() + to detach from the current engine. + + Call stepInto() to step into the next script statement; call stepOver() + to step over the next script statement; and call stepOut() to step out + of the currently executing script function. An event() will be generated + when the stepping is completed. + + Call runToLocation() to execute script statements until a certain + location has been reached. An event() will be generated when the location + has been reached. + + Call interruptEvaluation() to request that evaluation should be + interrupted. An event() will be generated upon the next script + statement that is reached. + + Call continueEvalution() to allow script evaluation to continue. + + Call setBreakpoint() to set a breakpoint. A breakpoint event() will + be generated when a breakpoint is hit. Call deleteBreakpoint() to + delete a breakpoint. Call modifyBreakpoint() to change the state of + an existing breakpoint. + + Call contextCount() to obtain the number of active contexts + (frames). Call context() to obtain a pointer to a QScriptContext. + + \section1 Subclassing + + When subclassing QScriptDebuggerBackend, you must implement the pure + virtual event() function. This function typically forwards the event + to a QScriptDebuggerFrontend object. For most type of events, + event() should block until the back-end is instructed to resume + execution (e.g. until continueEvalution() is called). You must + implement resume(), which is responsible for making event() return. + + \sa QScriptDebuggerFrontend, QScriptDebuggerEvent +*/ + +// helper class that's used to handle our custom Qt events +class QScriptDebuggerBackendEventReceiver : public QObject +{ +public: + QScriptDebuggerBackendEventReceiver(QScriptDebuggerBackendPrivate *backend, + QObject *parent = 0) + : QObject(parent), m_backend(backend) {} + ~QScriptDebuggerBackendEventReceiver() {} + + bool event(QEvent *e) + { + return m_backend->event(e); + } + +private: + QScriptDebuggerBackendPrivate *m_backend; +}; + + +QScriptDebuggerBackendPrivate::QScriptDebuggerBackendPrivate() +{ + eventReceiver = 0; + agent = 0; + commandExecutor = 0; + pendingEvaluateLineNumber = -1; + ignoreExceptions = false; + nextScriptValueIteratorId = 0; + nextScriptObjectSnapshotId = 0; +} + +QScriptDebuggerBackendPrivate::~QScriptDebuggerBackendPrivate() +{ + if (agent) + agent->nullifyBackendPointer(); + delete commandExecutor; + delete eventReceiver; + qDeleteAll(scriptValueIterators); + qDeleteAll(scriptObjectSnapshots); +} + +void QScriptDebuggerBackendPrivate::postEvent(QEvent *e) +{ + if (!eventReceiver) { + eventReceiver = new QScriptDebuggerBackendEventReceiver(this); + eventReceiver->moveToThread(agent->engine()->thread()); + } + QCoreApplication::postEvent(eventReceiver, e); +} + +bool QScriptDebuggerBackendPrivate::event(QEvent *e) +{ + if (e->type() == QEvent::User+1) { + QScriptDebuggerEventEvent *de = static_cast<QScriptDebuggerEventEvent*>(e); + q_func()->event(de->event()); + return true; + } + return false; +} + +void QScriptDebuggerBackendPrivate::agentDestroyed(QScriptDebuggerAgent *ag) +{ + // Since agents are owned by the script engine, this in practice means + // that the engine has been destroyed. Invalidate our pointer so we + // don't crash later. + if (agent == ag) + agent = 0; +} + +/*! + The agent calls this function when it has completed a step + operation. +*/ +void QScriptDebuggerBackendPrivate::stepped(qint64 scriptId, + int lineNumber, + int columnNumber, + const QScriptValue &result) +{ + Q_Q(QScriptDebuggerBackend); + QScriptDebuggerEvent e(QScriptDebuggerEvent::SteppingFinished, + scriptId, lineNumber, columnNumber); + e.setFileName(agent->scriptData(scriptId).fileName()); + QScriptDebuggerValue value(result); + e.setScriptValue(value); + if (!result.isUndefined()) + e.setMessage(result.toString()); // for convenience -- we always need it + q->event(e); +} + +/*! + The agent calls this function when it has run to a particular + location. +*/ +void QScriptDebuggerBackendPrivate::locationReached(qint64 scriptId, + int lineNumber, + int columnNumber) +{ + Q_Q(QScriptDebuggerBackend); + QScriptDebuggerEvent e(QScriptDebuggerEvent::LocationReached, + scriptId, lineNumber, columnNumber); + e.setFileName(agent->scriptData(scriptId).fileName()); + q->event(e); +} + +/*! + The agent calls this function when evaluation has been interrupted. +*/ +void QScriptDebuggerBackendPrivate::interrupted(qint64 scriptId, + int lineNumber, + int columnNumber) +{ + Q_Q(QScriptDebuggerBackend); + QScriptDebuggerEvent e(QScriptDebuggerEvent::Interrupted, + scriptId, lineNumber, columnNumber); + e.setFileName(agent->scriptData(scriptId).fileName()); + q->event(e); +} + +/*! + The agent calls this function when a breakpoint has been triggered. +*/ +void QScriptDebuggerBackendPrivate::breakpoint(qint64 scriptId, + int lineNumber, + int columnNumber, + int breakpointId) +{ + Q_Q(QScriptDebuggerBackend); + QScriptDebuggerEvent e(QScriptDebuggerEvent::Breakpoint, + scriptId, lineNumber, columnNumber); + e.setFileName(agent->scriptData(scriptId).fileName()); + e.setBreakpointId(breakpointId); + q->event(e); +} + +/*! + The agent calls this function when an uncaught exception has + occurred. +*/ +void QScriptDebuggerBackendPrivate::exception(qint64 scriptId, + const QScriptValue &exception, + bool hasHandler) +{ + Q_Q(QScriptDebuggerBackend); + if (ignoreExceptions) { + // don't care (it's caught by us) + return; + } + QScriptDebuggerEvent e(QScriptDebuggerEvent::Exception); + e.setScriptId(scriptId); + e.setFileName(agent->scriptData(scriptId).fileName()); + e.setMessage(exception.toString()); + e.setHasExceptionHandler(hasHandler); + int lineNumber = -1; + QString fileName; + if (exception.property(QLatin1String("lineNumber")).isNumber()) + lineNumber = exception.property(QLatin1String("lineNumber")).toInt32(); + if (exception.property(QLatin1String("fileName")).isString()) + fileName = exception.property(QLatin1String("fileName")).toString(); + if (lineNumber == -1) { + QScriptContextInfo info(q->engine()->currentContext()); + lineNumber = info.lineNumber(); + fileName = info.fileName(); + } + if (lineNumber != -1) + e.setLineNumber(lineNumber); + if (!fileName.isEmpty()) + e.setFileName(fileName); + QScriptDebuggerValue value(exception); + e.setScriptValue(value); + q->event(e); +} + +QScriptValue QScriptDebuggerBackendPrivate::trace(QScriptContext *context, + QScriptEngine *engine) +{ + QScriptValue data = context->callee().data(); + QScriptDebuggerBackendPrivate *self = qscriptvalue_cast<QScriptDebuggerBackendPrivate*>(data); + if (!self) + return engine->undefinedValue(); + QString str; + for (int i = 0; i < context->argumentCount(); ++i) { + if (i > 0) + str.append(QLatin1String(" ")); + str.append(context->argument(i).toString()); + } + QScriptDebuggerEvent e(QScriptDebuggerEvent::Trace); + e.setMessage(str); + self->q_func()->event(e); + return engine->undefinedValue(); +} + +QScriptValue QScriptDebuggerBackendPrivate::qsassert(QScriptContext *context, + QScriptEngine *engine) +{ + QScriptValue arg = context->argument(0); + if (arg.toBoolean()) + return arg; + QScriptContextInfo info(context->parentContext()); + QString msg; + QString fileName = info.fileName(); + if (fileName.isEmpty()) + fileName = QString::fromLatin1("<anonymous script, id=%0>").arg(info.scriptId()); + msg.append(fileName); + msg.append(QLatin1Char(':')); + msg.append(QString::number(info.lineNumber())); + msg.append(QString::fromLatin1(": Assertion failed")); + for (int i = 1; i < context->argumentCount(); ++i) { + if (i == 1) + msg.append(QLatin1Char(':')); + msg.append(QLatin1Char(' ')); + msg.append(context->argument(i).toString()); + } + QScriptValue err = context->throwError(msg); + err.setProperty(QString::fromLatin1("name"), QScriptValue(engine, QString::fromLatin1("AssertionError"))); + return err; +} + +QScriptValue QScriptDebuggerBackendPrivate::fileName(QScriptContext *context, + QScriptEngine *engine) +{ + QScriptContextInfo info(context->parentContext()); + QString fn = info.fileName(); + if (fn.isEmpty()) + return engine->undefinedValue(); + return QScriptValue(engine, fn); +} + +QScriptValue QScriptDebuggerBackendPrivate::lineNumber(QScriptContext *context, + QScriptEngine *engine) +{ + QScriptContextInfo info(context->parentContext()); + return QScriptValue(engine, info.lineNumber()); +} + +/*! + The agent calls this function when the engine has reached a + "debugger" statement. +*/ +void QScriptDebuggerBackendPrivate::debuggerInvocationRequest( + qint64 scriptId, int lineNumber, int columnNumber) +{ + Q_Q(QScriptDebuggerBackend); + QScriptDebuggerEvent e(QScriptDebuggerEvent::DebuggerInvocationRequest, + scriptId, lineNumber, columnNumber); + e.setFileName(agent->scriptData(scriptId).fileName()); + q->event(e); +} + +void QScriptDebuggerBackendPrivate::forcedReturn( + qint64 scriptId, int lineNumber, int columnNumber, + const QScriptValue &value) +{ + Q_Q(QScriptDebuggerBackend); + QScriptDebuggerEvent e(QScriptDebuggerEvent::ForcedReturn, + scriptId, lineNumber, columnNumber); + e.setFileName(agent->scriptData(scriptId).fileName()); + e.setScriptValue(QScriptDebuggerValue(value)); + q->event(e); +} + +/*! + Creates a QScriptDebuggerBackend object. +*/ +QScriptDebuggerBackend::QScriptDebuggerBackend() + : d_ptr(new QScriptDebuggerBackendPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this QScriptDebuggerBackend. +*/ +QScriptDebuggerBackend::~QScriptDebuggerBackend() +{ + detach(); + delete d_ptr; +} + +/*! + \internal +*/ +QScriptDebuggerBackend::QScriptDebuggerBackend(QScriptDebuggerBackendPrivate &dd) + : d_ptr(&dd) +{ + d_ptr->q_ptr = this; +} + +/*! + Attaches this backend to the given \a engine. + The backend automatically detaches from the old engine, if any. + + This function installs its own agent on the \a engine using + QScriptEngine::setAgent(); any existing agent will be replaced. + + \sa detach(). engine() +*/ +void QScriptDebuggerBackend::attachTo(QScriptEngine *engine) +{ + Q_D(QScriptDebuggerBackend); + detach(); + d->agent = new QScriptDebuggerAgent(d, engine); + QScriptValue global = engine->globalObject(); + global.setProperty(QString::fromLatin1("print"), traceFunction()); +// global.setProperty(QString::fromLatin1("qAssert"), assertFunction()); + global.setProperty(QString::fromLatin1("__FILE__"), fileNameFunction(), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter + | QScriptValue::ReadOnly); + global.setProperty(QString::fromLatin1("__LINE__"), lineNumberFunction(), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter + | QScriptValue::ReadOnly); + engine->setAgent(d->agent); +} + +/*! + Detaches this backend from the current script engine. + The backend's state (including breakpoints and information on loaded + scripts) will be invalidated. + + \sa attach() +*/ +void QScriptDebuggerBackend::detach() +{ + Q_D(QScriptDebuggerBackend); + if (!d->agent) + return; + QScriptEngine *eng = d->agent->engine(); + if (eng && eng->agent() == d->agent) { + eng->setAgent(0); + QScriptValue global = eng->globalObject(); + if (global.property(QString::fromLatin1("print")).strictlyEquals(traceFunction())) + global.setProperty(QString::fromLatin1("print"), QScriptValue()); +// global.setProperty(QString::fromLatin1("qAssert"), QScriptValue()); + if (global.property(QString::fromLatin1("__FILE__")).strictlyEquals(fileNameFunction())) + global.setProperty(QString::fromLatin1("__FILE__"), QScriptValue()); + if (global.property(QString::fromLatin1("__LINE__")).strictlyEquals(lineNumberFunction())) + global.setProperty(QString::fromLatin1("__LINE__"), QScriptValue()); + d->agent->nullifyBackendPointer(); + d->agent = 0; // agent is owned by engine + } + + d->pendingEvaluateLineNumber = -1; + d->ignoreExceptions = false; + d->nextScriptValueIteratorId = 0; + qDeleteAll(d->scriptValueIterators); + d->scriptValueIterators.clear(); + qDeleteAll(d->scriptObjectSnapshots); + d->scriptObjectSnapshots.clear(); +} + +/*! + Returns the script engine that this backend is attached to, or 0 if + the backend is not attached to an engine. + + \sa attachTo() +*/ +QScriptEngine *QScriptDebuggerBackend::engine() const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return 0; + return d->agent->engine(); +} + +/*! + Steps into the next script statement. + When stepping is complete, an event() will be generated. +*/ +void QScriptDebuggerBackend::stepInto(int count) +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) { + d->agent->enterStepIntoMode(count); + resume(); + } +} + +/*! + Steps over the next script statement. + When stepping is complete, an event() will be generated. +*/ +void QScriptDebuggerBackend::stepOver(int count) +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) { + d->agent->enterStepOverMode(count); + resume(); + } +} + +/*! + Steps out of the current script function. + When stepping is complete, an event() will be generated. +*/ +void QScriptDebuggerBackend::stepOut() +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) { + d->agent->enterStepOutMode(); + resume(); + } +} + +/*! + Continues script evaluation. Evaluation will proceed without + interruption until either 1) an uncaught exception occurs, 2) a + breakpoint is triggered, or 3) interruptEvaluation() is called. + In each case, a proper event() will be generated. +*/ +void QScriptDebuggerBackend::continueEvalution() +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) { + d->agent->enterContinueMode(); + resume(); + } +} + +/*! + Interrupts script evaluation. When the next script statement is + reached, an event() will be generated. +*/ +void QScriptDebuggerBackend::interruptEvaluation() +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) + d->agent->enterInterruptMode(); +} + +/*! + Continues evaluation until the location defined by the given \a + fileName and \a lineNumber is reached. When the location is reached, + an event() will be generated. +*/ +void QScriptDebuggerBackend::runToLocation(const QString &fileName, int lineNumber) +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) { + d->agent->enterRunToLocationMode(fileName, lineNumber); + resume(); + } +} + +/*! + Continues evaluation until the location defined by the given \a + scriptId and \a lineNumber is reached. When the location is reached, + an event() will be generated. +*/ +void QScriptDebuggerBackend::runToLocation(qint64 scriptId, int lineNumber) +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) { + d->agent->enterRunToLocationMode(scriptId, lineNumber); + resume(); + } +} + +void QScriptDebuggerBackend::returnToCaller(int contextIndex, const QScriptValue &value) +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) { + d->agent->enterReturnByForceMode(contextIndex, value); + resume(); + } +} + +/*! + Evaluates the given \a program. When evaluation is complete, an + event() is generated. +*/ +void QScriptDebuggerBackend::evaluate(int contextIndex, const QString &program, + const QString &fileName, int lineNumber) +{ + Q_D(QScriptDebuggerBackend); + d->pendingEvaluateContextIndex = contextIndex; + d->pendingEvaluateProgram = program; + d->pendingEvaluateFileName = fileName; + d->pendingEvaluateLineNumber = lineNumber; + if (!engine()->isEvaluating()) + doPendingEvaluate(/*postEvent=*/true); + else + resume(); +} + +/*! + Executes the pending evaluate, if any. +*/ +void QScriptDebuggerBackend::doPendingEvaluate(bool postEvent) +{ + Q_D(QScriptDebuggerBackend); + QString program = d->pendingEvaluateProgram; + if (program.isEmpty()) + return; + int contextIndex = d->pendingEvaluateContextIndex; + QScriptContext *ctx = context(contextIndex); + Q_ASSERT(ctx != 0); + QString fileName = d->pendingEvaluateFileName; + int lineNumber = d->pendingEvaluateLineNumber; + d->pendingEvaluateProgram = QString(); + d->pendingEvaluateFileName = QString(); + d->pendingEvaluateLineNumber = -1; + d->pendingEvaluateContextIndex = -1; + + // push a new context and initialize its scope chain etc. + { + QScriptContext *evalContext = engine()->pushContext(); +#if QT_VERSION >= 0x040500 + QScriptValueList scopeChain = ctx->scopeChain(); + if (scopeChain.isEmpty()) + scopeChain.append(engine()->globalObject()); + while (!scopeChain.isEmpty()) + evalContext->pushScope(scopeChain.takeLast()); +#endif + evalContext->setActivationObject(ctx->activationObject()); + evalContext->setThisObject(ctx->thisObject()); + } + + d->agent->enterContinueMode(); + // set a flag so that any exception that happens in + // the evaluate() is not sent to the debugger + d->ignoreExceptions = true; + bool hadException = engine()->hasUncaughtException(); + QScriptValue ret = engine()->evaluate(program, fileName, lineNumber); + d->ignoreExceptions = false; + if (!hadException && engine()->hasUncaughtException()) + engine()->clearExceptions(); + engine()->popContext(); + + QScriptDebuggerValue retret(ret); + QScriptDebuggerEvent e(QScriptDebuggerEvent::InlineEvalFinished); + e.setScriptValue(retret); + if (!ret.isUndefined()) + e.setMessage(ret.toString()); // for convenience -- we always need it + + e.setNestedEvaluate(engine()->isEvaluating()); + + if (postEvent) { + QScriptDebuggerEventEvent *de = new QScriptDebuggerEventEvent(e); + d->postEvent(de); + } else { + event(e); + } +} + +/*! + Sets a breakpoint defined by the given \a data, and returns a unique + identifier for the new breakpoint. + + If the conditions of the breakpoint is satisfied at some point + during script evaluation, a breakpoint event() will be generated. + + \sa deleteBreakpoint(), breakpoints() +*/ +int QScriptDebuggerBackend::setBreakpoint(const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerBackend); + if (!d->agent) + return -1; + if (!data.isValid()) + return -1; + return d->agent->setBreakpoint(data); +} + +/*! + Deletes the breakpoint identified by the given \a id. Returns true + if the breakpoint was deleted (i.e. the \a id was valid), otherwise + returns false. + + \sa setBreakpoint() +*/ +bool QScriptDebuggerBackend::deleteBreakpoint(int id) +{ + Q_D(QScriptDebuggerBackend); + if (!d->agent) + return false; + return d->agent->deleteBreakpoint(id); +} + +/*! + Deletes all breakpoints. +*/ +void QScriptDebuggerBackend::deleteAllBreakpoints() +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) + d->agent->deleteAllBreakpoints(); +} + +/*! + Returns the data associated with the breakpoint identified by the + given \a id. +*/ +QScriptBreakpointData QScriptDebuggerBackend::breakpointData(int id) const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return QScriptBreakpointData(); + return d->agent->breakpointData(id); +} + +/*! + Sets the \a data associated with the breakpoint identified by the + given \a id. +*/ +bool QScriptDebuggerBackend::setBreakpointData(int id, const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) + return d->agent->setBreakpointData(id, data); + return false; +} + +/*! + Returns this backend's breakpoints. + + \sa setBreakpoint() +*/ +QScriptBreakpointMap QScriptDebuggerBackend::breakpoints() const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return QScriptBreakpointMap(); + return d->agent->breakpoints(); +} + +/*! + Returns the scripts that this backend knows about. + + \sa scriptData() +*/ +QScriptScriptMap QScriptDebuggerBackend::scripts() const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return QScriptScriptMap(); + return d->agent->scripts(); +} + +/*! + Returns the data for the script identified by the given \a id. + + \sa scripts() +*/ +QScriptScriptData QScriptDebuggerBackend::scriptData(qint64 id) const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return QScriptScriptData(); + return d->agent->scriptData(id); +} + +/*! + Makes a checkpoint of the currently loaded scripts. + + \sa scriptsDelta() +*/ +void QScriptDebuggerBackend::scriptsCheckpoint() +{ + Q_D(QScriptDebuggerBackend); + if (d->agent) + d->agent->scriptsCheckpoint(); +} + +/*! + Returns the difference between the latest scripts checkpoint and the + previous checkpoint. The first item in the pair is a list + containing the identifiers of the scripts that were added. The + second item in the pair is a list containing the identifiers of the + scripts that were removed. + + \sa scriptsCheckpoint() +*/ +QScriptScriptsDelta QScriptDebuggerBackend::scriptsDelta() const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return QPair<QList<qint64>, QList<qint64> >(); + return d->agent->scriptsDelta(); +} + +qint64 QScriptDebuggerBackend::resolveScript(const QString &fileName) const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return -1; + return d->agent->resolveScript(fileName); +} + +/*! + Returns the number of contexts (frames). +*/ +int QScriptDebuggerBackend::contextCount() const +{ + if (!engine()) + return 0; + int count = 0; + QScriptContext *ctx = engine()->currentContext(); + while (ctx) { + ++count; + ctx = ctx->parentContext(); + } + return count; +} + +/*! + Returns the context for the frame with the given \a index. +*/ +QScriptContext *QScriptDebuggerBackend::context(int index) const +{ + if (index < 0) + return 0; + QScriptContext *ctx = engine()->currentContext(); + while (ctx) { + if (index == 0) + return ctx; + ctx = ctx->parentContext(); + --index; + } + return 0; +} + +/*! + Returns a backtrace of the current execution. +*/ +QStringList QScriptDebuggerBackend::backtrace() const +{ + if (!engine()) + return QStringList(); + return engine()->currentContext()->backtrace(); +} + +QList<qint64> QScriptDebuggerBackend::contextIds() const +{ + Q_D(const QScriptDebuggerBackend); + if (!d->agent) + return QList<qint64>(); + return d->agent->contextIds(); +} + +QScriptContextsDelta QScriptDebuggerBackend::contextsCheckpoint() +{ + Q_D(QScriptDebuggerBackend); + if (!d->agent) + return QScriptContextsDelta(); + return d->agent->contextsCheckpoint(); +} + +int QScriptDebuggerBackend::newScriptObjectSnapshot() +{ + Q_D(QScriptDebuggerBackend); + int id = d->nextScriptObjectSnapshotId; + ++d->nextScriptObjectSnapshotId; + d->scriptObjectSnapshots[id] = new QScriptObjectSnapshot(); + return id; +} + +QScriptObjectSnapshot *QScriptDebuggerBackend::scriptObjectSnapshot(int id) const +{ + Q_D(const QScriptDebuggerBackend); + return d->scriptObjectSnapshots.value(id); +} + +void QScriptDebuggerBackend::deleteScriptObjectSnapshot(int id) +{ + Q_D(QScriptDebuggerBackend); + QScriptObjectSnapshot *snap = d->scriptObjectSnapshots.take(id); + delete snap; +} + +int QScriptDebuggerBackend::newScriptValueIterator(const QScriptValue &object) +{ + Q_D(QScriptDebuggerBackend); + int id = d->nextScriptValueIteratorId; + ++d->nextScriptValueIteratorId; + d->scriptValueIterators[id] = new QScriptValueIterator(object); + return id; +} + +QScriptValueIterator *QScriptDebuggerBackend::scriptValueIterator(int id) const +{ + Q_D(const QScriptDebuggerBackend); + return d->scriptValueIterators.value(id); +} + +void QScriptDebuggerBackend::deleteScriptValueIterator(int id) +{ + Q_D(QScriptDebuggerBackend); + QScriptValueIterator *it = d->scriptValueIterators.take(id); + delete it; +} + +bool QScriptDebuggerBackend::ignoreExceptions() const +{ + Q_D(const QScriptDebuggerBackend); + return d->ignoreExceptions; +} + +void QScriptDebuggerBackend::setIgnoreExceptions(bool ignore) +{ + Q_D(QScriptDebuggerBackend); + d->ignoreExceptions = ignore; +} + +/*! + Returns a trace function. The trace function has similar semantics + to the built-in print() function; however, instead of writing text + to standard output, it generates a trace event containing the text. +*/ +QScriptValue QScriptDebuggerBackend::traceFunction() const +{ + Q_D(const QScriptDebuggerBackend); + if (!engine()) + return QScriptValue(); + QScriptValue fun = engine()->newFunction(QScriptDebuggerBackendPrivate::trace); + fun.setData(qScriptValueFromValue(engine(), const_cast<QScriptDebuggerBackendPrivate*>(d))); + return fun; +} + +QScriptValue QScriptDebuggerBackend::assertFunction() const +{ + if (!engine()) + return QScriptValue(); + QScriptValue fun = engine()->newFunction(QScriptDebuggerBackendPrivate::qsassert); + return fun; +} + +QScriptValue QScriptDebuggerBackend::fileNameFunction() const +{ + if (!engine()) + return QScriptValue(); + QScriptValue fun = engine()->newFunction(QScriptDebuggerBackendPrivate::fileName); + return fun; +} + +QScriptValue QScriptDebuggerBackend::lineNumberFunction() const +{ + if (!engine()) + return QScriptValue(); + QScriptValue fun = engine()->newFunction(QScriptDebuggerBackendPrivate::lineNumber); + return fun; +} + +QScriptDebuggerCommandExecutor *QScriptDebuggerBackend::commandExecutor() const +{ + Q_D(const QScriptDebuggerBackend); + if (d->commandExecutor) + return d->commandExecutor; + QScriptDebuggerBackendPrivate *dd = const_cast<QScriptDebuggerBackendPrivate*>(d); + dd->commandExecutor = new QScriptDebuggerCommandExecutor(); + return dd->commandExecutor; +} + +void QScriptDebuggerBackend::setCommandExecutor(QScriptDebuggerCommandExecutor *executor) +{ + Q_D(QScriptDebuggerBackend); + d->commandExecutor = executor; +} + +/*! + \fn void QScriptDebuggerBackend::resume() + + This function is called when control should be returned back to the + back-end, i.e. when script evaluation should be resumed after an + event has been delivered. + + Subclasses must reimplement this function to make event() return. + + \sa event() +*/ + +/*! + \fn void QScriptDebuggerBackend::event(const QScriptDebuggerEvent &event) + + This function is called when the back-end has generated the given \a event. + + Subclasses must reimplement this function to handle the + event. Typically the event is forwarded to a + QScriptDebuggerFrontend, which will in turn forward it to its + QScriptDebuggerClient. The client may then query the front-end for + information about the execution state, and call e.g. + continueEvalution() to resume execution. This function should block + until resume() is called. + + \sa resume() +*/ + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerbackend_p.h b/src/scripttools/debugging/qscriptdebuggerbackend_p.h new file mode 100644 index 0000000..6d593a6 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerbackend_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERBACKEND_P_H +#define QSCRIPTDEBUGGERBACKEND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qpair.h> + +#include "qscriptbreakpointdata_p.h" +#include "qscriptscriptdata_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptContext; +class QScriptEngine; +class QScriptDebuggerCommandExecutor; +class QScriptDebuggerEvent; +class QScriptValue; +class QScriptValueIterator; +class QScriptObjectSnapshot; +class QStringList; + +typedef QPair<QList<qint64>, QList<qint64> > QScriptScriptsDelta; +typedef QPair<QList<qint64>, QList<qint64> > QScriptContextsDelta; + +class QScriptDebuggerBackendPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerBackend +{ +public: + QScriptDebuggerBackend(); + virtual ~QScriptDebuggerBackend(); + + void attachTo(QScriptEngine *engine); + void detach(); + + QScriptEngine *engine() const; + + void stepInto(int count = 1); + void stepOver(int count = 1); + void stepOut(); + void continueEvalution(); + void interruptEvaluation(); + void runToLocation(const QString &fileName, int lineNumber); + void runToLocation(qint64 scriptId, int lineNumber); + void returnToCaller(int contextIndex, const QScriptValue &value); + void evaluate(int contextIndex, const QString &program, + const QString &fileName, int lineNumber); + + int setBreakpoint(const QScriptBreakpointData &data); + bool deleteBreakpoint(int id); + void deleteAllBreakpoints(); + QScriptBreakpointData breakpointData(int id) const; + bool setBreakpointData(int id, const QScriptBreakpointData &data); + QScriptBreakpointMap breakpoints() const; + + QScriptScriptMap scripts() const; + QScriptScriptData scriptData(qint64 id) const; + void scriptsCheckpoint(); + QScriptScriptsDelta scriptsDelta() const; + qint64 resolveScript(const QString &fileName) const; + + int contextCount() const; + QScriptContext *context(int index) const; + QStringList backtrace() const; + QList<qint64> contextIds() const; + QScriptContextsDelta contextsCheckpoint(); + + int newScriptObjectSnapshot(); + QScriptObjectSnapshot *scriptObjectSnapshot(int id) const; + void deleteScriptObjectSnapshot(int id); + + int newScriptValueIterator(const QScriptValue &object); + QScriptValueIterator *scriptValueIterator(int id) const; + void deleteScriptValueIterator(int id); + + QScriptValue traceFunction() const; + QScriptValue assertFunction() const; + QScriptValue fileNameFunction() const; + QScriptValue lineNumberFunction() const; + + void doPendingEvaluate(bool postEvent); + + bool ignoreExceptions() const; + void setIgnoreExceptions(bool ignore); + + QScriptDebuggerCommandExecutor *commandExecutor() const; + void setCommandExecutor(QScriptDebuggerCommandExecutor *executor); + + virtual void resume() = 0; + +protected: + virtual void event(const QScriptDebuggerEvent &event) = 0; + +protected: + QScriptDebuggerBackend(QScriptDebuggerBackendPrivate &dd); + QScriptDebuggerBackendPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerBackend) + Q_DISABLE_COPY(QScriptDebuggerBackend) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerbackend_p_p.h b/src/scripttools/debugging/qscriptdebuggerbackend_p_p.h new file mode 100644 index 0000000..98d9c85 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerbackend_p_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERBACKEND_P_P_H +#define QSCRIPTDEBUGGERBACKEND_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qhash.h> +#include <QtCore/qlist.h> + +#include "qscriptdebuggerbackend_p.h" + +QT_BEGIN_NAMESPACE + +class QEvent; +class QString; +class QScriptContext; +class QScriptEngine; +class QScriptValue; +class QScriptValueIterator; +class QScriptObjectSnapshot; +class QScriptDebuggerAgent; +class QScriptDebuggerCommandExecutor; + +class QScriptDebuggerBackend; +class Q_AUTOTEST_EXPORT QScriptDebuggerBackendPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerBackend) +public: + QScriptDebuggerBackendPrivate(); + virtual ~QScriptDebuggerBackendPrivate(); + + void postEvent(QEvent *e); + virtual bool event(QEvent *e); + + // events reported by agent + virtual void stepped(qint64 scriptId, int lineNumber, int columnNumber, + const QScriptValue &result); + virtual void locationReached(qint64 scriptId, int lineNumber, int columnNumber); + virtual void interrupted(qint64 scriptId, int lineNumber, int columnNumber); + virtual void breakpoint(qint64 scriptId, int lineNumber, int columnNumber, + int breakpointId); + virtual void exception(qint64 scriptId, const QScriptValue &exception, + bool hasHandler); + virtual void debuggerInvocationRequest(qint64 scriptId, int lineNumber, + int columnNumber); + virtual void forcedReturn(qint64 scriptId, int lineNumber, int columnNumber, + const QScriptValue &value); + + static QScriptValue trace(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue qsassert(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue fileName(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue lineNumber(QScriptContext *context, + QScriptEngine *engine); + + void agentDestroyed(QScriptDebuggerAgent *); + + QScriptDebuggerAgent *agent; + QScriptDebuggerCommandExecutor *commandExecutor; + + int pendingEvaluateContextIndex; + QString pendingEvaluateProgram; + QString pendingEvaluateFileName; + int pendingEvaluateLineNumber; + bool ignoreExceptions; + + int nextScriptValueIteratorId; + QMap<int, QScriptValueIterator*> scriptValueIterators; + + int nextScriptObjectSnapshotId; + QMap<int, QScriptObjectSnapshot*> scriptObjectSnapshots; + + QObject *eventReceiver; + + QScriptDebuggerBackend *q_ptr; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodefinderwidget.cpp b/src/scripttools/debugging/qscriptdebuggercodefinderwidget.cpp new file mode 100644 index 0000000..21f8b2c --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodefinderwidget.cpp @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercodefinderwidget_p.h" +#include "qscriptdebuggercodefinderwidgetinterface_p_p.h" + +#include <QtGui/qboxlayout.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qcheckbox.h> +#include <QtGui/qlabel.h> +#include <QtGui/qtoolbutton.h> +#include <QtGui/qevent.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeFinderWidgetPrivate + : public QScriptDebuggerCodeFinderWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerCodeFinderWidget) +public: + QScriptDebuggerCodeFinderWidgetPrivate(); + ~QScriptDebuggerCodeFinderWidgetPrivate(); + + // private slots + void _q_updateButtons(); + void _q_onTextChanged(const QString &); + void _q_next(); + void _q_previous(); + + int findOptions() const; + + QLineEdit *editFind; + QCheckBox *checkCase; + QLabel *labelWrapped; + QToolButton *toolNext; + QToolButton *toolClose; + QToolButton *toolPrevious; + QCheckBox *checkWholeWords; +}; + +QScriptDebuggerCodeFinderWidgetPrivate::QScriptDebuggerCodeFinderWidgetPrivate() +{ +} + +QScriptDebuggerCodeFinderWidgetPrivate::~QScriptDebuggerCodeFinderWidgetPrivate() +{ +} + +void QScriptDebuggerCodeFinderWidgetPrivate::_q_updateButtons() +{ + if (editFind->text().isEmpty()) { + toolPrevious->setEnabled(false); + toolNext->setEnabled(false); + } else { + toolPrevious->setEnabled(true); + toolNext->setEnabled(true); + } +} + +int QScriptDebuggerCodeFinderWidgetPrivate::findOptions() const +{ + int flags = 0; + if (checkCase->isChecked()) + flags |= QTextDocument::FindCaseSensitively; + if (checkWholeWords->isChecked()) + flags |= QTextDocument::FindWholeWords; + return flags; +} + +void QScriptDebuggerCodeFinderWidgetPrivate::_q_onTextChanged(const QString &text) +{ + emit q_func()->findRequest(text, findOptions() | 0x100); +} + +void QScriptDebuggerCodeFinderWidgetPrivate::_q_next() +{ + emit q_func()->findRequest(editFind->text(), findOptions()); +} + +void QScriptDebuggerCodeFinderWidgetPrivate::_q_previous() +{ + emit q_func()->findRequest(editFind->text(), findOptions() | QTextDocument::FindBackward); +} + +QScriptDebuggerCodeFinderWidget::QScriptDebuggerCodeFinderWidget(QWidget *parent) + : QScriptDebuggerCodeFinderWidgetInterface( + *new QScriptDebuggerCodeFinderWidgetPrivate, parent, 0) +{ + Q_D(QScriptDebuggerCodeFinderWidget); + QString system = QLatin1String("win"); + QHBoxLayout *hboxLayout = new QHBoxLayout(this); +#ifdef Q_OS_MAC + system = QLatin1String("mac"); +#else + hboxLayout->setSpacing(6); + hboxLayout->setMargin(0); +#endif + + d->toolClose = new QToolButton(this); + d->toolClose->setIcon(QIcon(QString::fromUtf8(":/qt/scripttools/debugging/images/%1/closetab.png").arg(system))); + d->toolClose->setAutoRaise(true); + d->toolClose->setText(QObject::tr("Close")); + hboxLayout->addWidget(d->toolClose); + + d->editFind = new QLineEdit(this); + d->editFind->setMinimumSize(QSize(150, 0)); + connect(d->editFind, SIGNAL(textChanged(const QString&)), + this, SLOT(_q_updateButtons())); + connect(d->editFind, SIGNAL(returnPressed()), + this, SLOT(_q_next())); + hboxLayout->addWidget(d->editFind); + + d->toolPrevious = new QToolButton(this); + d->toolPrevious->setAutoRaise(true); + d->toolPrevious->setText(tr("Previous")); + d->toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + d->toolPrevious->setIcon(QIcon(QString::fromUtf8(":/qt/scripttools/debugging/images/%1/previous.png").arg(system))); + hboxLayout->addWidget(d->toolPrevious); + + d->toolNext = new QToolButton(this); + d->toolNext->setAutoRaise(true); + d->toolNext->setText(tr("Next")); + d->toolNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + d->toolNext->setIcon(QIcon(QString::fromUtf8(":/qt/scripttools/debugging/images/%1/next.png").arg(system))); + hboxLayout->addWidget(d->toolNext); + + d->checkCase = new QCheckBox(tr("Case Sensitive"), this); + hboxLayout->addWidget(d->checkCase); + + d->checkWholeWords = new QCheckBox(tr("Whole words"), this); + hboxLayout->addWidget(d->checkWholeWords); + + d->labelWrapped = new QLabel(this); + d->labelWrapped->setMinimumSize(QSize(0, 20)); + d->labelWrapped->setMaximumSize(QSize(115, 20)); + d->labelWrapped->setTextFormat(Qt::RichText); + d->labelWrapped->setScaledContents(true); + d->labelWrapped->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); + d->labelWrapped->setText(tr("<img src=\":/qt/scripttools/debugging/images/wrap.png\"> Search wrapped")); + hboxLayout->addWidget(d->labelWrapped); + + QSpacerItem *spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + hboxLayout->addItem(spacerItem); + setMinimumWidth(minimumSizeHint().width()); + d->labelWrapped->hide(); + + d->_q_updateButtons(); + + setFocusProxy(d->editFind); + QObject::connect(d->toolClose, SIGNAL(clicked()), this, SLOT(hide())); + QObject::connect(d->editFind, SIGNAL(textChanged(QString)), + this, SLOT(_q_onTextChanged(QString))); + QObject::connect(d->toolNext, SIGNAL(clicked()), this, SLOT(_q_next())); + QObject::connect(d->toolPrevious, SIGNAL(clicked()), this, SLOT(_q_previous())); +} + +QScriptDebuggerCodeFinderWidget::~QScriptDebuggerCodeFinderWidget() +{ +} + +int QScriptDebuggerCodeFinderWidget::findOptions() const +{ + Q_D(const QScriptDebuggerCodeFinderWidget); + return d->findOptions(); +} + +QString QScriptDebuggerCodeFinderWidget::text() const +{ + Q_D(const QScriptDebuggerCodeFinderWidget); + return d->editFind->text(); +} + +void QScriptDebuggerCodeFinderWidget::setText(const QString &text) +{ + Q_D(const QScriptDebuggerCodeFinderWidget); + d->editFind->setText(text); +} + +void QScriptDebuggerCodeFinderWidget::setOK(bool ok) +{ + Q_D(QScriptDebuggerCodeFinderWidget); + QPalette p = d->editFind->palette(); + QColor c; + if (ok) + c = Qt::white; + else + c = QColor(255, 102, 102); + p.setColor(QPalette::Active, QPalette::Base, c); + d->editFind->setPalette(p); + if (!ok) + d->labelWrapped->hide(); +} + +void QScriptDebuggerCodeFinderWidget::setWrapped(bool wrapped) +{ + Q_D(QScriptDebuggerCodeFinderWidget); + d->labelWrapped->setVisible(wrapped); +} + +void QScriptDebuggerCodeFinderWidget::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Escape) + hide(); + else + QScriptDebuggerCodeFinderWidgetInterface::keyPressEvent(e); +} + +QT_END_NAMESPACE + +#include "moc_qscriptdebuggercodefinderwidget_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebuggercodefinderwidget_p.h b/src/scripttools/debugging/qscriptdebuggercodefinderwidget_p.h new file mode 100644 index 0000000..eb5b388 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodefinderwidget_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEFINDERWIDGET_P_H +#define QSCRIPTDEBUGGERCODEFINDERWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggercodefinderwidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeFinderWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCodeFinderWidget: + public QScriptDebuggerCodeFinderWidgetInterface +{ + Q_OBJECT +public: + QScriptDebuggerCodeFinderWidget(QWidget *parent = 0); + ~QScriptDebuggerCodeFinderWidget(); + + int findOptions() const; + + QString text() const; + void setText(const QString &text); + + void setOK(bool ok); + void setWrapped(bool wrapped); + +protected: + void keyPressEvent(QKeyEvent *e); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCodeFinderWidget) + Q_DISABLE_COPY(QScriptDebuggerCodeFinderWidget) + + Q_PRIVATE_SLOT(d_func(), void _q_updateButtons()) + Q_PRIVATE_SLOT(d_func(), void _q_onTextChanged(const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_next()) + Q_PRIVATE_SLOT(d_func(), void _q_previous()) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface.cpp b/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface.cpp new file mode 100644 index 0000000..3e602a6 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercodefinderwidgetinterface_p.h" +#include "qscriptdebuggercodefinderwidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerCodeFinderWidgetInterfacePrivate::QScriptDebuggerCodeFinderWidgetInterfacePrivate() +{ +} + +QScriptDebuggerCodeFinderWidgetInterfacePrivate::~QScriptDebuggerCodeFinderWidgetInterfacePrivate() +{ +} + +QScriptDebuggerCodeFinderWidgetInterface::~QScriptDebuggerCodeFinderWidgetInterface() +{ +} + +QScriptDebuggerCodeFinderWidgetInterface::QScriptDebuggerCodeFinderWidgetInterface( + QScriptDebuggerCodeFinderWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface_p.h b/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface_p.h new file mode 100644 index 0000000..0c20487 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEFINDERWIDGETINTERFACE_P_H +#define QSCRIPTDEBUGGERCODEFINDERWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +#include <QtGui/qtextdocument.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeFinderWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCodeFinderWidgetInterface: + public QWidget +{ + Q_OBJECT +public: + ~QScriptDebuggerCodeFinderWidgetInterface(); + + virtual int findOptions() const = 0; + + virtual QString text() const = 0; + virtual void setText(const QString &text) = 0; + + virtual void setOK(bool ok) = 0; + virtual void setWrapped(bool wrapped) = 0; + +Q_SIGNALS: + void findRequest(const QString &exp, int options); + +protected: + QScriptDebuggerCodeFinderWidgetInterface( + QScriptDebuggerCodeFinderWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCodeFinderWidgetInterface) + Q_DISABLE_COPY(QScriptDebuggerCodeFinderWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface_p_p.h b/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface_p_p.h new file mode 100644 index 0000000..e269384 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodefinderwidgetinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEFINDERWIDGETINTERFACE_P_P_H +#define QSCRIPTDEBUGGERCODEFINDERWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeFinderWidgetInterface; +class QScriptDebuggerCodeFinderWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerCodeFinderWidgetInterface) +public: + QScriptDebuggerCodeFinderWidgetInterfacePrivate(); + ~QScriptDebuggerCodeFinderWidgetInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodeview.cpp b/src/scripttools/debugging/qscriptdebuggercodeview.cpp new file mode 100644 index 0000000..bc493e0 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodeview.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercodeview_p.h" +#include "qscriptdebuggercodeviewinterface_p_p.h" + +#include "qscriptedit_p.h" + +#include <QtGui/qboxlayout.h> +#include <QtGui/qtextobject.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeViewPrivate + : public QScriptDebuggerCodeViewInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerCodeView) +public: + QScriptDebuggerCodeViewPrivate(); + ~QScriptDebuggerCodeViewPrivate(); + + QScriptEdit *editor; +}; + +QScriptDebuggerCodeViewPrivate::QScriptDebuggerCodeViewPrivate() +{ +} + +QScriptDebuggerCodeViewPrivate::~QScriptDebuggerCodeViewPrivate() +{ +} + +QScriptDebuggerCodeView::QScriptDebuggerCodeView(QWidget *parent) + : QScriptDebuggerCodeViewInterface(*new QScriptDebuggerCodeViewPrivate, parent, 0) +{ + Q_D(QScriptDebuggerCodeView); + d->editor = new QScriptEdit(); + d->editor->setReadOnly(true); + d->editor->setBackgroundVisible(false); + QObject::connect(d->editor, SIGNAL(breakpointToggleRequest(int,bool)), + this, SIGNAL(breakpointToggleRequest(int,bool))); + QObject::connect(d->editor, SIGNAL(breakpointEnableRequest(int,bool)), + this, SIGNAL(breakpointEnableRequest(int,bool))); + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->addWidget(d->editor); +} + +QScriptDebuggerCodeView::~QScriptDebuggerCodeView() +{ +} + +QString QScriptDebuggerCodeView::text() const +{ + Q_D(const QScriptDebuggerCodeView); + return d->editor->toPlainText(); +} + +void QScriptDebuggerCodeView::setText(const QString &text) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->setPlainText(text); +} + +int QScriptDebuggerCodeView::cursorLineNumber() const +{ + Q_D(const QScriptDebuggerCodeView); + return d->editor->currentLineNumber(); +} + +void QScriptDebuggerCodeView::gotoLine(int lineNumber) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->gotoLine(lineNumber); +} + +int QScriptDebuggerCodeView::find(const QString &exp, int options) +{ + Q_D(QScriptDebuggerCodeView); + QPlainTextEdit *ed = (QPlainTextEdit*)d->editor; + QTextCursor cursor = ed->textCursor(); + if (options & 0x100) { + // start searching from the beginning of selection + if (cursor.hasSelection()) { + int len = cursor.selectedText().length(); + cursor.clearSelection(); + cursor.setPosition(cursor.position() - len); + ed->setTextCursor(cursor); + } + options &= ~0x100; + } + int ret = 0; + if (ed->find(exp, QTextDocument::FindFlags(options))) { + ret |= 0x1; + } else { + QTextCursor curse = cursor; + curse.movePosition(QTextCursor::Start); + ed->setTextCursor(curse); + if (ed->find(exp, QTextDocument::FindFlags(options))) + ret |= 0x1 | 0x2; + else + ed->setTextCursor(cursor); + } + return ret; +} + +void QScriptDebuggerCodeView::setExecutionLineNumber(int lineNumber, bool error) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->setExecutionLineNumber(lineNumber, error); +} + +void QScriptDebuggerCodeView::setExecutableLineNumbers(const QSet<int> &lineNumbers) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->setExecutableLineNumbers(lineNumbers); +} + +int QScriptDebuggerCodeView::baseLineNumber() const +{ + Q_D(const QScriptDebuggerCodeView); + return d->editor->baseLineNumber(); +} + +void QScriptDebuggerCodeView::setBaseLineNumber(int lineNumber) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->setBaseLineNumber(lineNumber); +} + +void QScriptDebuggerCodeView::setBreakpoint(int lineNumber) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->setBreakpoint(lineNumber); +} + +void QScriptDebuggerCodeView::deleteBreakpoint(int lineNumber) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->deleteBreakpoint(lineNumber); +} + +void QScriptDebuggerCodeView::setBreakpointEnabled(int lineNumber, bool enable) +{ + Q_D(QScriptDebuggerCodeView); + d->editor->setBreakpointEnabled(lineNumber, enable); +} + +namespace { + +static bool isIdentChar(const QChar &ch) +{ + static QChar underscore = QLatin1Char('_'); + return ch.isLetter() || (ch == underscore); +} + +} // namespace + +/*! + \reimp +*/ +bool QScriptDebuggerCodeView::event(QEvent *e) +{ + Q_D(QScriptDebuggerCodeView); + if (e->type() == QEvent::ToolTip) { + if (d->editor->executionLineNumber() == -1) + return false; + QHelpEvent *he = static_cast<QHelpEvent*>(e); + QPoint pt = he->pos(); + pt.rx() -= d->editor->extraAreaWidth(); + pt.ry() -= 8; + QTextCursor cursor = d->editor->cursorForPosition(pt); + QTextBlock block = cursor.block(); + QString contents = block.text(); + if (contents.isEmpty()) + return false; + int linePosition = cursor.position() - block.position(); + linePosition -= 3; + if (linePosition < 0) + linePosition = 0; + + // ### generalize -- same as in completiontask + + int pos = linePosition; + if ((pos > 0) && contents.at(pos-1).isNumber()) { + // tooltips for numbers is pointless + return false; + } + + while ((pos > 0) && isIdentChar(contents.at(pos-1))) + --pos; + if ((pos > 0) && ((contents.at(pos-1) == QLatin1Char('\'')) + || (contents.at(pos-1) == QLatin1Char('\"')))) { + // ignore string literals + return false; + } + int pos2 = linePosition; + while ((pos2 < contents.size()-1) && isIdentChar(contents.at(pos2+1))) + ++pos2; + QString ident = contents.mid(pos, pos2 - pos + 1); + + QStringList path; + path.append(ident); + while ((pos > 0) && (contents.at(pos-1) == QLatin1Char('.'))) { + --pos; + pos2 = pos; + while ((pos > 0) && isIdentChar(contents.at(pos-1))) + --pos; + path.prepend(contents.mid(pos, pos2 - pos)); + } + + if (!path.isEmpty()) { + int lineNumber = cursor.blockNumber() + d->editor->baseLineNumber(); + emit toolTipRequest(he->globalPos(), lineNumber, path); + } + } + return false; +} + +QT_END_NAMESPACE + +#include "moc_qscriptdebuggercodeview_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebuggercodeview_p.h b/src/scripttools/debugging/qscriptdebuggercodeview_p.h new file mode 100644 index 0000000..a9cd615 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodeview_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEVIEW_P_H +#define QSCRIPTDEBUGGERCODEVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggercodeviewinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeViewPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCodeView: + public QScriptDebuggerCodeViewInterface +{ + Q_OBJECT +public: + QScriptDebuggerCodeView(QWidget *parent = 0); + ~QScriptDebuggerCodeView(); + + QString text() const; + void setText(const QString &text); + + int cursorLineNumber() const; + void gotoLine(int lineNumber); + + int find(const QString &exp, int options = 0); + + void setExecutionLineNumber(int lineNumber, bool error); + void setExecutableLineNumbers(const QSet<int> &lineNumbers); + + int baseLineNumber() const; + void setBaseLineNumber(int lineNumber); + + void setBreakpoint(int lineNumber); + void deleteBreakpoint(int lineNumber); + void setBreakpointEnabled(int lineNumber, bool enable); + + bool event(QEvent *e); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCodeView) + Q_DISABLE_COPY(QScriptDebuggerCodeView) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodeviewinterface.cpp b/src/scripttools/debugging/qscriptdebuggercodeviewinterface.cpp new file mode 100644 index 0000000..489fdfd --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodeviewinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercodeviewinterface_p.h" +#include "qscriptdebuggercodeviewinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerCodeViewInterfacePrivate::QScriptDebuggerCodeViewInterfacePrivate() +{ +} + +QScriptDebuggerCodeViewInterfacePrivate::~QScriptDebuggerCodeViewInterfacePrivate() +{ +} + +QScriptDebuggerCodeViewInterface::~QScriptDebuggerCodeViewInterface() +{ +} + +QScriptDebuggerCodeViewInterface::QScriptDebuggerCodeViewInterface( + QScriptDebuggerCodeViewInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggercodeviewinterface_p.h b/src/scripttools/debugging/qscriptdebuggercodeviewinterface_p.h new file mode 100644 index 0000000..ac67da8 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodeviewinterface_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEVIEWINTERFACE_P_H +#define QSCRIPTDEBUGGERCODEVIEWINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +QT_BEGIN_NAMESPACE + +class QPoint; +class QStringList; + +class QScriptDebuggerCodeViewInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCodeViewInterface: + public QWidget +{ + Q_OBJECT +public: + ~QScriptDebuggerCodeViewInterface(); + + virtual QString text() const = 0; + virtual void setText(const QString &text) = 0; + + virtual int cursorLineNumber() const = 0; + virtual void gotoLine(int lineNumber) = 0; + + virtual int find(const QString &exp, int options = 0) = 0; + + virtual void setExecutionLineNumber(int lineNumber, bool error) = 0; + virtual void setExecutableLineNumbers(const QSet<int> &lineNumbers) = 0; + + virtual int baseLineNumber() const = 0; + virtual void setBaseLineNumber(int lineNumber) = 0; + + virtual void setBreakpoint(int lineNumber) = 0; + virtual void deleteBreakpoint(int lineNumber) = 0; + virtual void setBreakpointEnabled(int lineNumber, bool enable) = 0; + +Q_SIGNALS: + void breakpointToggleRequest(int lineNumber, bool on); + void breakpointEnableRequest(int lineNumber, bool enable); + void toolTipRequest(const QPoint &pos, int lineNumber, const QStringList &path); + +protected: + QScriptDebuggerCodeViewInterface( + QScriptDebuggerCodeViewInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCodeViewInterface) + Q_DISABLE_COPY(QScriptDebuggerCodeViewInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodeviewinterface_p_p.h b/src/scripttools/debugging/qscriptdebuggercodeviewinterface_p_p.h new file mode 100644 index 0000000..55c7b58 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodeviewinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEVIEWINTERFACE_P_P_H +#define QSCRIPTDEBUGGERCODEVIEWINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeViewInterface; +class QScriptDebuggerCodeViewInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerCodeViewInterface) +public: + QScriptDebuggerCodeViewInterfacePrivate(); + ~QScriptDebuggerCodeViewInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodewidget.cpp b/src/scripttools/debugging/qscriptdebuggercodewidget.cpp new file mode 100644 index 0000000..14ce0fe --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodewidget.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercodewidget_p.h" +#include "qscriptdebuggercodewidgetinterface_p_p.h" +#include "qscriptdebuggercodeview_p.h" +#include "qscriptdebuggerscriptsmodel_p.h" +#include "qscriptbreakpointsmodel_p.h" +#include "qscripttooltipproviderinterface_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qstackedwidget.h> +#include <QtGui/qtooltip.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeWidgetPrivate + : public QScriptDebuggerCodeWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerCodeWidget) +public: + QScriptDebuggerCodeWidgetPrivate(); + ~QScriptDebuggerCodeWidgetPrivate(); + + qint64 scriptId(QScriptDebuggerCodeViewInterface *view) const; + + // private slots + void _q_onBreakpointToggleRequest(int lineNumber, bool on); + void _q_onBreakpointEnableRequest(int lineNumber, bool enable); + void _q_onBreakpointsAboutToBeRemoved(const QModelIndex&, int, int); + void _q_onBreakpointsInserted(const QModelIndex&, int, int); + void _q_onBreakpointsDataChanged(const QModelIndex &, const QModelIndex &); + void _q_onScriptsChanged(); + void _q_onToolTipRequest(const QPoint &pos, int lineNumber, const QStringList &path); + + QScriptDebuggerScriptsModel *scriptsModel; + QStackedWidget *viewStack; + QHash<qint64, QScriptDebuggerCodeViewInterface*> viewHash; + QScriptBreakpointsModel *breakpointsModel; + QScriptToolTipProviderInterface *toolTipProvider; +}; + +QScriptDebuggerCodeWidgetPrivate::QScriptDebuggerCodeWidgetPrivate() +{ + scriptsModel = 0; + breakpointsModel = 0; + toolTipProvider = 0; +} + +QScriptDebuggerCodeWidgetPrivate::~QScriptDebuggerCodeWidgetPrivate() +{ +} + +qint64 QScriptDebuggerCodeWidgetPrivate::scriptId(QScriptDebuggerCodeViewInterface *view) const +{ + if (!view) + return -1; + return viewHash.key(view); +} + +void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointToggleRequest(int lineNumber, bool on) +{ + QScriptDebuggerCodeViewInterface *view = qobject_cast<QScriptDebuggerCodeViewInterface*>(q_func()->sender()); + qint64 sid = scriptId(view); + Q_ASSERT(sid != -1); + if (on) { + QScriptBreakpointData data(sid, lineNumber); + data.setFileName(scriptsModel->scriptData(sid).fileName()); + breakpointsModel->setBreakpoint(data); + } else { + int bpid = breakpointsModel->resolveBreakpoint(sid, lineNumber); + if (bpid == -1) + bpid = breakpointsModel->resolveBreakpoint(scriptsModel->scriptData(sid).fileName(), lineNumber); + Q_ASSERT(bpid != -1); + breakpointsModel->deleteBreakpoint(bpid); + } +} + +void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointEnableRequest(int lineNumber, bool enable) +{ + QScriptDebuggerCodeViewInterface *view = qobject_cast<QScriptDebuggerCodeViewInterface*>(q_func()->sender()); + qint64 sid = scriptId(view); + int bpid = breakpointsModel->resolveBreakpoint(sid, lineNumber); + if (bpid == -1) + bpid = breakpointsModel->resolveBreakpoint(scriptsModel->scriptData(sid).fileName(), lineNumber); + Q_ASSERT(bpid != -1); + QScriptBreakpointData data = breakpointsModel->breakpointData(bpid); + data.setEnabled(enable); + breakpointsModel->setBreakpointData(bpid, data); +} + +void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointsAboutToBeRemoved( + const QModelIndex &, int first, int last) +{ + for (int i = first; i <= last; ++i) { + QScriptBreakpointData data = breakpointsModel->breakpointDataAt(i); + qint64 scriptId = data.scriptId(); + if (scriptId == -1) { + scriptId = scriptsModel->resolveScript(data.fileName()); + if (scriptId == -1) + continue; + } + QScriptDebuggerCodeViewInterface *view = viewHash.value(scriptId); + if (!view) + continue; + view->deleteBreakpoint(data.lineNumber()); + } +} + +void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointsInserted( + const QModelIndex &, int first, int last) +{ + for (int i = first; i <= last; ++i) { + QScriptBreakpointData data = breakpointsModel->breakpointDataAt(i); + qint64 scriptId = data.scriptId(); + if (scriptId == -1) { + scriptId = scriptsModel->resolveScript(data.fileName()); + if (scriptId == -1) + continue; + } + QScriptDebuggerCodeViewInterface *view = viewHash.value(scriptId); + if (!view) + continue; + view->setBreakpoint(data.lineNumber()); + } +} + +void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointsDataChanged( + const QModelIndex &tl, const QModelIndex &br) +{ + for (int i = tl.row(); i <= br.row(); ++i) { + QScriptBreakpointData data = breakpointsModel->breakpointDataAt(i); + qint64 scriptId = data.scriptId(); + if (scriptId == -1) { + scriptId = scriptsModel->resolveScript(data.fileName()); + if (scriptId == -1) + continue; + } + QScriptDebuggerCodeViewInterface *view = viewHash.value(scriptId); + if (!view) + continue; + view->setBreakpointEnabled(data.lineNumber(), data.isEnabled()); + } +} + +void QScriptDebuggerCodeWidgetPrivate::_q_onScriptsChanged() +{ + // kill editors for scripts that have been removed + QHash<qint64, QScriptDebuggerCodeViewInterface*>::iterator it; + for (it = viewHash.begin(); it != viewHash.end(); ) { + if (!scriptsModel->scriptData(it.key()).isValid()) { + it = viewHash.erase(it); + } else + ++it; + } +} + +void QScriptDebuggerCodeWidgetPrivate::_q_onToolTipRequest( + const QPoint &pos, int lineNumber, const QStringList &path) +{ + QString tip = toolTipProvider->toolTip(/*frameIndex=*/-1, lineNumber, path); + if (tip.indexOf(QLatin1Char('\n')) != -1) { + QStringList lines = tip.split(QLatin1Char('\n')); + int lineCount = lines.size(); + if (lineCount > 5) { + lines = lines.mid(0, 5); + lines.append(QString::fromLatin1("(... %0 more lines ...)").arg(lineCount - 5)); + } + tip = lines.join(QLatin1String("\n")); + } + QToolTip::showText(pos, tip); +} + +QScriptDebuggerCodeWidget::QScriptDebuggerCodeWidget(QWidget *parent) + : QScriptDebuggerCodeWidgetInterface(*new QScriptDebuggerCodeWidgetPrivate, parent, 0) +{ + Q_D(QScriptDebuggerCodeWidget); + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + d->viewStack = new QStackedWidget(); + vbox->addWidget(d->viewStack); +} + +QScriptDebuggerCodeWidget::~QScriptDebuggerCodeWidget() +{ +} + +QScriptDebuggerScriptsModel *QScriptDebuggerCodeWidget::scriptsModel() const +{ + Q_D(const QScriptDebuggerCodeWidget); + return d->scriptsModel; +} + +void QScriptDebuggerCodeWidget::setScriptsModel(QScriptDebuggerScriptsModel *model) +{ + Q_D(QScriptDebuggerCodeWidget); + d->scriptsModel = model; + QObject::connect(model, SIGNAL(layoutChanged()), + this, SLOT(_q_onScriptsChanged())); +} + +qint64 QScriptDebuggerCodeWidget::currentScriptId() const +{ + Q_D(const QScriptDebuggerCodeWidget); + return d->scriptId(currentView()); +} + +void QScriptDebuggerCodeWidget::setCurrentScript(qint64 scriptId) +{ + Q_D(QScriptDebuggerCodeWidget); + if (scriptId == -1) { + // ### show "native script" + return; + } + QScriptDebuggerCodeViewInterface *view = d->viewHash.value(scriptId); + if (!view) { + Q_ASSERT(d->scriptsModel != 0); + QScriptScriptData data = d->scriptsModel->scriptData(scriptId); + if (!data.isValid()) + return; + view = new QScriptDebuggerCodeView(); // ### use factory, so user can provide his own view + view->setBaseLineNumber(data.baseLineNumber()); + view->setText(data.contents()); + view->setExecutableLineNumbers(d->scriptsModel->executableLineNumbers(scriptId)); + QObject::connect(view, SIGNAL(breakpointToggleRequest(int,bool)), + this, SLOT(_q_onBreakpointToggleRequest(int,bool))); + QObject::connect(view, SIGNAL(breakpointEnableRequest(int,bool)), + this, SLOT(_q_onBreakpointEnableRequest(int,bool))); + QObject::connect(view, SIGNAL(toolTipRequest(QPoint,int,QStringList)), + this, SLOT(_q_onToolTipRequest(QPoint,int,QStringList))); + d->viewStack->addWidget(view); + d->viewHash.insert(scriptId, view); + } + d->viewStack->setCurrentWidget(view); +} + +void QScriptDebuggerCodeWidget::invalidateExecutionLineNumbers() +{ + Q_D(QScriptDebuggerCodeWidget); + QHash<qint64, QScriptDebuggerCodeViewInterface*>::const_iterator it; + for (it = d->viewHash.constBegin(); it != d->viewHash.constEnd(); ++it) + it.value()->setExecutionLineNumber(-1, /*error=*/false); +} + +QScriptBreakpointsModel *QScriptDebuggerCodeWidget::breakpointsModel() const +{ + Q_D(const QScriptDebuggerCodeWidget); + return d->breakpointsModel; +} + +void QScriptDebuggerCodeWidget::setBreakpointsModel(QScriptBreakpointsModel *model) +{ + Q_D(QScriptDebuggerCodeWidget); + d->breakpointsModel = model; + QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + this, SLOT(_q_onBreakpointsAboutToBeRemoved(QModelIndex,int,int))); + QObject::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(_q_onBreakpointsInserted(QModelIndex,int,int))); + QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), + this, SLOT(_q_onBreakpointsDataChanged(QModelIndex,QModelIndex))); +} + +void QScriptDebuggerCodeWidget::setToolTipProvider(QScriptToolTipProviderInterface *toolTipProvider) +{ + Q_D(QScriptDebuggerCodeWidget); + d->toolTipProvider = toolTipProvider; +} + +QScriptDebuggerCodeViewInterface *QScriptDebuggerCodeWidget::currentView() const +{ + Q_D(const QScriptDebuggerCodeWidget); + return qobject_cast<QScriptDebuggerCodeViewInterface*>(d->viewStack->currentWidget()); +} + +QT_END_NAMESPACE + +#include "moc_qscriptdebuggercodewidget_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebuggercodewidget_p.h b/src/scripttools/debugging/qscriptdebuggercodewidget_p.h new file mode 100644 index 0000000..bc01eb9 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodewidget_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEWIDGET_P_H +#define QSCRIPTDEBUGGERCODEWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggercodewidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCodeWidget: + public QScriptDebuggerCodeWidgetInterface +{ + Q_OBJECT +public: + QScriptDebuggerCodeWidget(QWidget *parent = 0); + ~QScriptDebuggerCodeWidget(); + + QScriptDebuggerScriptsModel *scriptsModel() const; + void setScriptsModel(QScriptDebuggerScriptsModel *model); + + void setToolTipProvider(QScriptToolTipProviderInterface *toolTipProvider); + + qint64 currentScriptId() const; + void setCurrentScript(qint64 scriptId); + + void invalidateExecutionLineNumbers(); + + QScriptBreakpointsModel *breakpointsModel() const; + void setBreakpointsModel(QScriptBreakpointsModel *model); + + QScriptDebuggerCodeViewInterface *currentView() const; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCodeWidget) + Q_DISABLE_COPY(QScriptDebuggerCodeWidget) + + Q_PRIVATE_SLOT(d_func(), void _q_onBreakpointToggleRequest(int,bool)) + Q_PRIVATE_SLOT(d_func(), void _q_onBreakpointEnableRequest(int,bool)) + Q_PRIVATE_SLOT(d_func(), void _q_onBreakpointsAboutToBeRemoved(const QModelIndex &,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_onBreakpointsInserted(const QModelIndex &,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_onBreakpointsDataChanged(const QModelIndex &, const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void _q_onScriptsChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_onToolTipRequest(const QPoint &, int, const QStringList &)) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodewidgetinterface.cpp b/src/scripttools/debugging/qscriptdebuggercodewidgetinterface.cpp new file mode 100644 index 0000000..573874e --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodewidgetinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercodewidgetinterface_p.h" +#include "qscriptdebuggercodewidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerCodeWidgetInterfacePrivate::QScriptDebuggerCodeWidgetInterfacePrivate() +{ +} + +QScriptDebuggerCodeWidgetInterfacePrivate::~QScriptDebuggerCodeWidgetInterfacePrivate() +{ +} + +QScriptDebuggerCodeWidgetInterface::~QScriptDebuggerCodeWidgetInterface() +{ +} + +QScriptDebuggerCodeWidgetInterface::QScriptDebuggerCodeWidgetInterface( + QScriptDebuggerCodeWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggercodewidgetinterface_p.h b/src/scripttools/debugging/qscriptdebuggercodewidgetinterface_p.h new file mode 100644 index 0000000..9fc39a7 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodewidgetinterface_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEWIDGETINTERFACE_P_H +#define QSCRIPTDEBUGGERCODEWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerScriptsModel; +class QScriptBreakpointsModel; +class QScriptToolTipProviderInterface; + +class QScriptDebuggerCodeViewInterface; + +class QScriptDebuggerCodeWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCodeWidgetInterface: + public QWidget +{ + Q_OBJECT +public: + ~QScriptDebuggerCodeWidgetInterface(); + + virtual QScriptDebuggerScriptsModel *scriptsModel() const = 0; + virtual void setScriptsModel(QScriptDebuggerScriptsModel *model) = 0; + + virtual QScriptBreakpointsModel *breakpointsModel() const = 0; + virtual void setBreakpointsModel(QScriptBreakpointsModel *model) = 0; + + virtual void setToolTipProvider(QScriptToolTipProviderInterface *toolTipProvider) = 0; + + virtual qint64 currentScriptId() const = 0; + virtual void setCurrentScript(qint64 scriptId) = 0; + + virtual void invalidateExecutionLineNumbers() = 0; + + virtual QScriptDebuggerCodeViewInterface *currentView() const = 0; + +protected: + QScriptDebuggerCodeWidgetInterface( + QScriptDebuggerCodeWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCodeWidgetInterface) + Q_DISABLE_COPY(QScriptDebuggerCodeWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercodewidgetinterface_p_p.h b/src/scripttools/debugging/qscriptdebuggercodewidgetinterface_p_p.h new file mode 100644 index 0000000..7f65c67 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercodewidgetinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCODEWIDGETINTERFACE_P_P_H +#define QSCRIPTDEBUGGERCODEWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCodeWidgetInterface; +class QScriptDebuggerCodeWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerCodeWidgetInterface) +public: + QScriptDebuggerCodeWidgetInterfacePrivate(); + ~QScriptDebuggerCodeWidgetInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercommand.cpp b/src/scripttools/debugging/qscriptdebuggercommand.cpp new file mode 100644 index 0000000..c40bfc4 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommand.cpp @@ -0,0 +1,690 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercommand_p.h" +#include "qscriptbreakpointdata_p.h" +#include "qscriptdebuggervalue_p.h" + +#include <QtCore/qhash.h> +#include <QtCore/qdatastream.h> + +Q_DECLARE_METATYPE(QScriptBreakpointData) +Q_DECLARE_METATYPE(QScriptDebuggerValue) + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerCommand + \internal + + \brief The QScriptDebuggerCommand class represents a command issued to a QScriptDebuggerFrontend. + + A debugger command is described by a command type and zero or more + attributes. Such commands are generated internally by the + QScriptDebuggerFrontend class (through the scheduleXXX commands). A + command is typically passed on to a QScriptDebuggerCommandExecutor + that applies the command to a QScriptDebuggerBackend. +*/ + +class QScriptDebuggerCommandPrivate +{ +public: + QScriptDebuggerCommandPrivate(); + ~QScriptDebuggerCommandPrivate(); + + QScriptDebuggerCommand::Type type; + QHash<QScriptDebuggerCommand::Attribute, QVariant> attributes; +}; + +QScriptDebuggerCommandPrivate::QScriptDebuggerCommandPrivate() + : type(QScriptDebuggerCommand::None) +{ +} + +QScriptDebuggerCommandPrivate::~QScriptDebuggerCommandPrivate() +{ +} + +/*! + Constructs a QScriptDebuggerCommand of type None. +*/ +QScriptDebuggerCommand::QScriptDebuggerCommand() + : d_ptr(new QScriptDebuggerCommandPrivate) +{ + d_ptr->type = None; +} + +/*! + Constructs a QScriptDebuggerCommand of the given \a type, with no + attributes defined. +*/ +QScriptDebuggerCommand::QScriptDebuggerCommand(Type type) + : d_ptr(new QScriptDebuggerCommandPrivate) +{ + d_ptr->type = type; +} + +/*! + Constructs a QScriptDebuggerCommand that is a copy of the \a other + command. +*/ +QScriptDebuggerCommand::QScriptDebuggerCommand(const QScriptDebuggerCommand &other) + : d_ptr(new QScriptDebuggerCommandPrivate) +{ + *d_ptr = *other.d_ptr; +} + +/*! + Destroys this QScriptDebuggerCommand. +*/ +QScriptDebuggerCommand::~QScriptDebuggerCommand() +{ + delete d_ptr; +} + +/*! + Assigns the \a other value to this QScriptDebuggerCommand. +*/ +QScriptDebuggerCommand &QScriptDebuggerCommand::operator=(const QScriptDebuggerCommand &other) +{ + *d_ptr = *other.d_ptr; + return *this; +} + +/*! + Returns the type of this command. +*/ +QScriptDebuggerCommand::Type QScriptDebuggerCommand::type() const +{ + Q_D(const QScriptDebuggerCommand); + return d->type; +} + +/*! + Returns the value of the given \a attribute, or \a defaultValue + if the attribute is not defined. +*/ +QVariant QScriptDebuggerCommand::attribute(Attribute attribute, + const QVariant &defaultValue) const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(attribute, defaultValue); +} + +/*! + Sets the \a value of the given \a attribute. +*/ +void QScriptDebuggerCommand::setAttribute(Attribute attribute, + const QVariant &value) +{ + Q_D(QScriptDebuggerCommand); + if (!value.isValid()) + d->attributes.remove(attribute); + else + d->attributes[attribute] = value; +} + +QHash<QScriptDebuggerCommand::Attribute, QVariant> QScriptDebuggerCommand::attributes() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes; +} + +/*! + Returns the FileName attribute of this command converted to a string. + This function is provided for convenience. + + \sa attribute() +*/ +QString QScriptDebuggerCommand::fileName() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(FileName).toString(); +} + +void QScriptDebuggerCommand::setFileName(const QString &fileName) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[FileName] = fileName; +} + +/*! + Returns the LineNumber attribute of this command converted to an int. + This function is provided for convenience. + + \sa attribute() +*/ +int QScriptDebuggerCommand::lineNumber() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(LineNumber, -1).toInt(); +} + +void QScriptDebuggerCommand::setLineNumber(int lineNumber) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[LineNumber] = lineNumber; +} + +/*! + Returns the ScriptID attribute of this command converted to a qint64. + This function is provided for convenience. + + \sa attribute() +*/ +qint64 QScriptDebuggerCommand::scriptId() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(ScriptID, -1).toLongLong(); +} + +void QScriptDebuggerCommand::setScriptId(qint64 id) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[ScriptID] = id; +} + +QString QScriptDebuggerCommand::program() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(Program).toString(); +} + +void QScriptDebuggerCommand::setProgram(const QString &program) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[Program] = program; +} + +int QScriptDebuggerCommand::breakpointId() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(BreakpointID, -1).toInt(); +} + +void QScriptDebuggerCommand::setBreakpointId(int id) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[BreakpointID] = id; +} + +QScriptBreakpointData QScriptDebuggerCommand::breakpointData() const +{ + Q_D(const QScriptDebuggerCommand); + return qvariant_cast<QScriptBreakpointData>(d->attributes.value(BreakpointData)); +} + +void QScriptDebuggerCommand::setBreakpointData(const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[BreakpointData] = qVariantFromValue(data); +} + +QScriptDebuggerValue QScriptDebuggerCommand::scriptValue() const +{ + Q_D(const QScriptDebuggerCommand); + return qvariant_cast<QScriptDebuggerValue>(d->attributes.value(ScriptValue)); +} + +void QScriptDebuggerCommand::setScriptValue(const QScriptDebuggerValue &value) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[ScriptValue] = qVariantFromValue(value); +} + +int QScriptDebuggerCommand::contextIndex() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(ContextIndex, -1).toInt(); +} + +void QScriptDebuggerCommand::setContextIndex(int index) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[ContextIndex] = index; +} + +int QScriptDebuggerCommand::iteratorId() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(IteratorID, -1).toInt(); +} + +void QScriptDebuggerCommand::setIteratorId(int id) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[IteratorID] = id; +} + +QString QScriptDebuggerCommand::name() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(Name).toString(); +} + +void QScriptDebuggerCommand::setName(const QString &name) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[Name] = name; +} + +QScriptDebuggerValue QScriptDebuggerCommand::subordinateScriptValue() const +{ + Q_D(const QScriptDebuggerCommand); + return qvariant_cast<QScriptDebuggerValue>(d->attributes.value(SubordinateScriptValue)); +} + +void QScriptDebuggerCommand::setSubordinateScriptValue(const QScriptDebuggerValue &value) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[SubordinateScriptValue] = qVariantFromValue(value); +} + +int QScriptDebuggerCommand::snapshotId() const +{ + Q_D(const QScriptDebuggerCommand); + return d->attributes.value(SnapshotID, -1).toInt(); +} + +void QScriptDebuggerCommand::setSnapshotId(int id) +{ + Q_D(QScriptDebuggerCommand); + d->attributes[SnapshotID] = id; +} + +/*! + Returns true if this QScriptDebuggerCommand is equal to the \a other + command, otherwise returns false. +*/ +bool QScriptDebuggerCommand::operator==(const QScriptDebuggerCommand &other) const +{ + Q_D(const QScriptDebuggerCommand); + const QScriptDebuggerCommandPrivate *od = other.d_func(); + if (d == od) + return true; + if (!d || !od) + return false; + return ((d->type == od->type) + && (d->attributes == od->attributes)); +} + +/*! + Returns true if this QScriptDebuggerCommand is not equal to the \a + other command, otherwise returns false. +*/ +bool QScriptDebuggerCommand::operator!=(const QScriptDebuggerCommand &other) const +{ + return !(*this == other); +} + +QScriptDebuggerCommand QScriptDebuggerCommand::interruptCommand() +{ + QScriptDebuggerCommand cmd(Interrupt); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::continueCommand() +{ + QScriptDebuggerCommand cmd(Continue); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::stepIntoCommand(int count) +{ + QScriptDebuggerCommand cmd(StepInto); + cmd.setAttribute(StepCount, count); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::stepOverCommand(int count) +{ + QScriptDebuggerCommand cmd(StepOver); + cmd.setAttribute(StepCount, count); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::stepOutCommand() +{ + QScriptDebuggerCommand cmd(StepOut); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::runToLocationCommand(const QString &fileName, int lineNumber) +{ + QScriptDebuggerCommand cmd(RunToLocation); + cmd.setFileName(fileName); + cmd.setLineNumber(lineNumber); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::runToLocationCommand(qint64 scriptId, int lineNumber) +{ + QScriptDebuggerCommand cmd(RunToLocationByID); + cmd.setScriptId(scriptId); + cmd.setLineNumber(lineNumber); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::forceReturnCommand(int contextIndex, const QScriptDebuggerValue &value) +{ + QScriptDebuggerCommand cmd(ForceReturn); + cmd.setContextIndex(contextIndex); + cmd.setScriptValue(value); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::resumeCommand() +{ + QScriptDebuggerCommand cmd(Resume); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::setBreakpointCommand(const QString &fileName, int lineNumber) +{ + QScriptDebuggerCommand cmd(SetBreakpoint); + cmd.setBreakpointData(QScriptBreakpointData(fileName, lineNumber)); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::setBreakpointCommand(const QScriptBreakpointData &data) +{ + QScriptDebuggerCommand cmd(SetBreakpoint); + cmd.setBreakpointData(data); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::deleteBreakpointCommand(int id) +{ + QScriptDebuggerCommand cmd(DeleteBreakpoint); + cmd.setBreakpointId(id); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::deleteAllBreakpointsCommand() +{ + QScriptDebuggerCommand cmd(DeleteAllBreakpoints); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getBreakpointsCommand() +{ + QScriptDebuggerCommand cmd(GetBreakpoints); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getBreakpointDataCommand(int id) +{ + QScriptDebuggerCommand cmd(GetBreakpointData); + cmd.setBreakpointId(id); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::setBreakpointDataCommand(int id, const QScriptBreakpointData &data) +{ + QScriptDebuggerCommand cmd(SetBreakpointData); + cmd.setBreakpointId(id); + cmd.setBreakpointData(data); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getScriptsCommand() +{ + QScriptDebuggerCommand cmd(GetScripts); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getScriptDataCommand(qint64 id) +{ + QScriptDebuggerCommand cmd(GetScriptData); + cmd.setScriptId(id); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::scriptsCheckpointCommand() +{ + QScriptDebuggerCommand cmd(ScriptsCheckpoint); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getScriptsDeltaCommand() +{ + QScriptDebuggerCommand cmd(GetScriptsDelta); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::resolveScriptCommand(const QString &fileName) +{ + QScriptDebuggerCommand cmd(ResolveScript); + cmd.setFileName(fileName); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getBacktraceCommand() +{ + QScriptDebuggerCommand cmd(GetBacktrace); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getContextCountCommand() +{ + QScriptDebuggerCommand cmd(GetContextCount); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getContextStateCommand(int contextIndex) +{ + QScriptDebuggerCommand cmd(GetContextState); + cmd.setContextIndex(contextIndex); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getContextInfoCommand(int contextIndex) +{ + QScriptDebuggerCommand cmd(GetContextInfo); + cmd.setContextIndex(contextIndex); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getContextIdCommand(int contextIndex) +{ + QScriptDebuggerCommand cmd(GetContextID); + cmd.setContextIndex(contextIndex); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getThisObjectCommand(int contextIndex) +{ + QScriptDebuggerCommand cmd(GetThisObject); + cmd.setContextIndex(contextIndex); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getActivationObjectCommand(int contextIndex) +{ + QScriptDebuggerCommand cmd(GetActivationObject); + cmd.setContextIndex(contextIndex); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getScopeChainCommand(int contextIndex) +{ + QScriptDebuggerCommand cmd(GetScopeChain); + cmd.setContextIndex(contextIndex); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::contextsCheckpoint() +{ + QScriptDebuggerCommand cmd(ContextsCheckpoint); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::newScriptObjectSnapshotCommand() +{ + QScriptDebuggerCommand cmd(NewScriptObjectSnapshot); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::scriptObjectSnapshotCaptureCommand(int id, const QScriptDebuggerValue &object) +{ + Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue); + QScriptDebuggerCommand cmd(ScriptObjectSnapshotCapture); + cmd.setSnapshotId(id); + cmd.setScriptValue(object); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::deleteScriptObjectSnapshotCommand(int id) +{ + QScriptDebuggerCommand cmd(DeleteScriptObjectSnapshot); + cmd.setSnapshotId(id); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::newScriptValueIteratorCommand(const QScriptDebuggerValue &object) +{ + QScriptDebuggerCommand cmd(NewScriptValueIterator); + Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue); + cmd.setScriptValue(object); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::getPropertiesByIteratorCommand(int id, int count) +{ + Q_UNUSED(count); + QScriptDebuggerCommand cmd(GetPropertiesByIterator); + cmd.setIteratorId(id); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::deleteScriptValueIteratorCommand(int id) +{ + QScriptDebuggerCommand cmd(DeleteScriptValueIterator); + cmd.setIteratorId(id); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::evaluateCommand( + int contextIndex, const QString &program, const QString &fileName, int lineNumber) +{ + QScriptDebuggerCommand cmd(Evaluate); + cmd.setContextIndex(contextIndex); + cmd.setProgram(program); + cmd.setFileName(fileName); + cmd.setLineNumber(lineNumber); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::scriptValueToStringCommand(const QScriptDebuggerValue &value) +{ + QScriptDebuggerCommand cmd(ScriptValueToString); + cmd.setScriptValue(value); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::setScriptValuePropertyCommand( + const QScriptDebuggerValue &object, const QString &name, + const QScriptDebuggerValue &value) +{ + QScriptDebuggerCommand cmd(SetScriptValueProperty); + cmd.setScriptValue(object); + cmd.setName(name); + cmd.setSubordinateScriptValue(value); + return cmd; +} + +QScriptDebuggerCommand QScriptDebuggerCommand::clearExceptionsCommand() +{ + QScriptDebuggerCommand cmd(ClearExceptions); + return cmd; +} + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QScriptDebuggerCommand &command) + \relates QScriptDebuggerCommand + + Writes the given \a command to the specified \a stream. +*/ +QDataStream &operator<<(QDataStream &out, const QScriptDebuggerCommand &command) +{ + const QScriptDebuggerCommandPrivate *d = command.d_ptr; + out << (quint32)d->type; + out << (qint32)d->attributes.size(); + QHash<QScriptDebuggerCommand::Attribute, QVariant>::const_iterator it; + for (it = d->attributes.constBegin(); it != d->attributes.constEnd(); ++it) { + out << (quint32)it.key(); + out << it.value(); + } + return out; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QScriptDebuggerCommand &command) + \relates QScriptDebuggerCommand + + Reads a QScriptDebuggerCommand from the specified \a stream into the + given \a command. +*/ +QDataStream &operator>>(QDataStream &in, QScriptDebuggerCommand &command) +{ + QScriptDebuggerCommandPrivate *d = command.d_ptr; + + quint32 type; + in >> type; + d->type = QScriptDebuggerCommand::Type(type); + + qint32 attribCount; + in >> attribCount; + QHash<QScriptDebuggerCommand::Attribute, QVariant> attribs; + for (qint32 i = 0; i < attribCount; ++i) { + quint32 key; + in >> key; + QVariant value; + in >> value; + attribs[QScriptDebuggerCommand::Attribute(key)] = value; + } + d->attributes = attribs; + + return in; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggercommand_p.h b/src/scripttools/debugging/qscriptdebuggercommand_p.h new file mode 100644 index 0000000..260e3ec --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommand_p.h @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCOMMAND_P_H +#define QSCRIPTDEBUGGERCOMMAND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qhash.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_NAMESPACE + +class QDataStream; +class QScriptBreakpointData; +class QScriptDebuggerValue; + +class QScriptDebuggerCommandPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCommand +{ +public: + friend Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerCommand &); + friend Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerCommand &); + + enum Type { + None, + + Interrupt, + Continue, + StepInto, + StepOver, + StepOut, + RunToLocation, + RunToLocationByID, + ForceReturn, + Resume, + + SetBreakpoint, + DeleteBreakpoint, + DeleteAllBreakpoints, + GetBreakpoints, + GetBreakpointData, + SetBreakpointData, + + GetScripts, + GetScriptData, + ScriptsCheckpoint, + GetScriptsDelta, + ResolveScript, + + GetBacktrace, + GetContextCount, + GetContextInfo, + GetContextState, + GetContextID, + GetThisObject, + GetActivationObject, + GetScopeChain, + ContextsCheckpoint, + + NewScriptObjectSnapshot, + ScriptObjectSnapshotCapture, + DeleteScriptObjectSnapshot, + + NewScriptValueIterator, + GetPropertiesByIterator, + DeleteScriptValueIterator, + + Evaluate, + + SetScriptValueProperty, + ScriptValueToString, + + ClearExceptions, + + UserCommand = 1000, + MaxUserCommand = 32767 + }; + + enum Attribute { + ScriptID, + FileName, + LineNumber, + Program, + BreakpointID, + BreakpointData, + ContextIndex, + ScriptValue, + StepCount, + IteratorID, + Name, + SubordinateScriptValue, + SnapshotID, + UserAttribute = 1000, + MaxUserAttribute = 32767 + }; + + QScriptDebuggerCommand(); + QScriptDebuggerCommand(Type type); + QScriptDebuggerCommand(const QScriptDebuggerCommand &other); + ~QScriptDebuggerCommand(); + + Type type() const; + + QVariant attribute(Attribute attribute, const QVariant &defaultValue = QVariant()) const; + void setAttribute(Attribute attribute, const QVariant &value); + QHash<Attribute, QVariant> attributes() const; + + QString fileName() const; + void setFileName(const QString &fileName); + + int lineNumber() const; + void setLineNumber(int lineNumber); + + qint64 scriptId() const; + void setScriptId(qint64 id); + + QString program() const; + void setProgram(const QString &program); + + int breakpointId() const; + void setBreakpointId(int id); + + QScriptBreakpointData breakpointData() const; + void setBreakpointData(const QScriptBreakpointData &data); + + QScriptDebuggerValue scriptValue() const; + void setScriptValue(const QScriptDebuggerValue &value); + + int contextIndex() const; + void setContextIndex(int index); + + int iteratorId() const; + void setIteratorId(int id); + + QString name() const; + void setName(const QString &name); + + QScriptDebuggerValue subordinateScriptValue() const; + void setSubordinateScriptValue(const QScriptDebuggerValue &value); + + int snapshotId() const; + void setSnapshotId(int id); + + QScriptDebuggerCommand &operator=(const QScriptDebuggerCommand &other); + + bool operator==(const QScriptDebuggerCommand &other) const; + bool operator!=(const QScriptDebuggerCommand &other) const; + + static QScriptDebuggerCommand interruptCommand(); + static QScriptDebuggerCommand continueCommand(); + static QScriptDebuggerCommand stepIntoCommand(int count = 1); + static QScriptDebuggerCommand stepOverCommand(int count = 1); + static QScriptDebuggerCommand stepOutCommand(); + static QScriptDebuggerCommand runToLocationCommand(const QString &fileName, int lineNumber); + static QScriptDebuggerCommand runToLocationCommand(qint64 scriptId, int lineNumber); + static QScriptDebuggerCommand forceReturnCommand(int contextIndex, const QScriptDebuggerValue &value); + static QScriptDebuggerCommand resumeCommand(); + + static QScriptDebuggerCommand setBreakpointCommand(const QString &fileName, int lineNumber); + static QScriptDebuggerCommand setBreakpointCommand(const QScriptBreakpointData &data); + static QScriptDebuggerCommand deleteBreakpointCommand(int id); + static QScriptDebuggerCommand deleteAllBreakpointsCommand(); + static QScriptDebuggerCommand getBreakpointsCommand(); + static QScriptDebuggerCommand getBreakpointDataCommand(int id); + static QScriptDebuggerCommand setBreakpointDataCommand(int id, const QScriptBreakpointData &data); + + static QScriptDebuggerCommand getScriptsCommand(); + static QScriptDebuggerCommand getScriptDataCommand(qint64 id); + static QScriptDebuggerCommand scriptsCheckpointCommand(); + static QScriptDebuggerCommand getScriptsDeltaCommand(); + static QScriptDebuggerCommand resolveScriptCommand(const QString &fileName); + + static QScriptDebuggerCommand getBacktraceCommand(); + static QScriptDebuggerCommand getContextCountCommand(); + static QScriptDebuggerCommand getContextStateCommand(int contextIndex); + static QScriptDebuggerCommand getContextInfoCommand(int contextIndex); + static QScriptDebuggerCommand getContextIdCommand(int contextIndex); + static QScriptDebuggerCommand getThisObjectCommand(int contextIndex); + static QScriptDebuggerCommand getActivationObjectCommand(int contextIndex); + static QScriptDebuggerCommand getScopeChainCommand(int contextIndex); + static QScriptDebuggerCommand contextsCheckpoint(); + + static QScriptDebuggerCommand newScriptObjectSnapshotCommand(); + static QScriptDebuggerCommand scriptObjectSnapshotCaptureCommand(int id, const QScriptDebuggerValue &object); + static QScriptDebuggerCommand deleteScriptObjectSnapshotCommand(int id); + + static QScriptDebuggerCommand newScriptValueIteratorCommand(const QScriptDebuggerValue &object); + static QScriptDebuggerCommand getPropertiesByIteratorCommand(int id, int count); + static QScriptDebuggerCommand deleteScriptValueIteratorCommand(int id); + + static QScriptDebuggerCommand evaluateCommand(int contextIndex, const QString &program, + const QString &fileName = QString(), + int lineNumber = 1); + + static QScriptDebuggerCommand setScriptValuePropertyCommand(const QScriptDebuggerValue &object, + const QString &name, + const QScriptDebuggerValue &value); + static QScriptDebuggerCommand scriptValueToStringCommand(const QScriptDebuggerValue &value); + + static QScriptDebuggerCommand clearExceptionsCommand(); + +private: + QScriptDebuggerCommandPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptDebuggerCommand) +}; + +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerCommand &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerCommand &); + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp new file mode 100644 index 0000000..e36386d --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp @@ -0,0 +1,423 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercommandexecutor_p.h" + +#include "qscriptdebuggerbackend_p.h" +#include "qscriptdebuggercommand_p.h" +#include "qscriptdebuggerresponse_p.h" +#include "qscriptdebuggervalue_p.h" +#include "qscriptdebuggervalueproperty_p.h" +#include "qscriptbreakpointdata_p.h" +#include "qscriptobjectsnapshot_p.h" +#include "qscriptdebuggerobjectsnapshotdelta_p.h" + +#include <QtCore/qstringlist.h> +#include <QtScript/qscriptengine.h> +#include <QtScript/qscriptcontextinfo.h> +#include <QtScript/qscriptvalueiterator.h> +#include <QtCore/qdebug.h> + +Q_DECLARE_METATYPE(QScriptScriptsDelta) +Q_DECLARE_METATYPE(QScriptDebuggerValueProperty) +Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList) +Q_DECLARE_METATYPE(QScriptDebuggerObjectSnapshotDelta) + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerCommandExecutor + \internal + + \brief The QScriptDebuggerCommandExecutor applies debugger commands to a back-end. + + The execute() function takes a command (typically produced by a + QScriptDebuggerFrontend) and applies it to a QScriptDebuggerBackend. + + \sa QScriptDebuggerCommmand +*/ + +class QScriptDebuggerCommandExecutorPrivate +{ +public: + QScriptDebuggerCommandExecutorPrivate(); + ~QScriptDebuggerCommandExecutorPrivate(); +}; + +QScriptDebuggerCommandExecutorPrivate::QScriptDebuggerCommandExecutorPrivate() +{ +} + +QScriptDebuggerCommandExecutorPrivate::~QScriptDebuggerCommandExecutorPrivate() +{ +} + +QScriptDebuggerCommandExecutor::QScriptDebuggerCommandExecutor() + : d_ptr(new QScriptDebuggerCommandExecutorPrivate()) +{ +} + +QScriptDebuggerCommandExecutor::~QScriptDebuggerCommandExecutor() +{ + delete d_ptr; +} + +/*! + Applies the given \a command to the given \a backend. +*/ +QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute( + QScriptDebuggerBackend *backend, + const QScriptDebuggerCommand &command) +{ + QScriptDebuggerResponse response; + switch (command.type()) { + case QScriptDebuggerCommand::None: + break; + + case QScriptDebuggerCommand::Interrupt: + backend->interruptEvaluation(); + break; + + case QScriptDebuggerCommand::Continue: + if (backend->engine()->isEvaluating()) { + backend->continueEvalution(); + response.setAsync(true); + } + break; + + case QScriptDebuggerCommand::StepInto: { + QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount); + int count = attr.isValid() ? attr.toInt() : 1; + backend->stepInto(count); + response.setAsync(true); + } break; + + case QScriptDebuggerCommand::StepOver: { + QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount); + int count = attr.isValid() ? attr.toInt() : 1; + backend->stepOver(count); + response.setAsync(true); + } break; + + case QScriptDebuggerCommand::StepOut: + backend->stepOut(); + response.setAsync(true); + break; + + case QScriptDebuggerCommand::RunToLocation: + backend->runToLocation(command.fileName(), command.lineNumber()); + response.setAsync(true); + break; + + case QScriptDebuggerCommand::RunToLocationByID: + backend->runToLocation(command.scriptId(), command.lineNumber()); + response.setAsync(true); + break; + + case QScriptDebuggerCommand::ForceReturn: { + int contextIndex = command.contextIndex(); + QScriptDebuggerValue value = command.scriptValue(); + QScriptEngine *engine = backend->engine(); + QScriptValue realValue = value.toScriptValue(engine); + backend->returnToCaller(contextIndex, realValue); + response.setAsync(true); + } break; + + case QScriptDebuggerCommand::Resume: + backend->resume(); + response.setAsync(true); + break; + + case QScriptDebuggerCommand::SetBreakpoint: { + QScriptBreakpointData data = command.breakpointData(); + if (!data.isValid()) + data = QScriptBreakpointData(command.fileName(), command.lineNumber()); + int id = backend->setBreakpoint(data); + response.setResult(id); + } break; + + case QScriptDebuggerCommand::DeleteBreakpoint: { + int id = command.breakpointId(); + if (!backend->deleteBreakpoint(id)) + response.setError(QScriptDebuggerResponse::InvalidBreakpointID); + } break; + + case QScriptDebuggerCommand::DeleteAllBreakpoints: + backend->deleteAllBreakpoints(); + break; + + case QScriptDebuggerCommand::GetBreakpoints: { + QScriptBreakpointMap bps = backend->breakpoints(); + if (!bps.isEmpty()) + response.setResult(bps); + } break; + + case QScriptDebuggerCommand::GetBreakpointData: { + int id = command.breakpointId(); + QScriptBreakpointData data = backend->breakpointData(id); + if (data.isValid()) + response.setResult(data); + else + response.setError(QScriptDebuggerResponse::InvalidBreakpointID); + } break; + + case QScriptDebuggerCommand::SetBreakpointData: { + int id = command.breakpointId(); + QScriptBreakpointData data = command.breakpointData(); + if (!backend->setBreakpointData(id, data)) + response.setError(QScriptDebuggerResponse::InvalidBreakpointID); + } break; + + case QScriptDebuggerCommand::GetScripts: { + QScriptScriptMap scripts = backend->scripts(); + if (!scripts.isEmpty()) + response.setResult(scripts); + } break; + + case QScriptDebuggerCommand::GetScriptData: { + qint64 id = command.scriptId(); + QScriptScriptData data = backend->scriptData(id); + if (data.isValid()) + response.setResult(data); + else + response.setError(QScriptDebuggerResponse::InvalidScriptID); + } break; + + case QScriptDebuggerCommand::ScriptsCheckpoint: + backend->scriptsCheckpoint(); + response.setResult(qVariantFromValue(backend->scriptsDelta())); + break; + + case QScriptDebuggerCommand::GetScriptsDelta: + response.setResult(qVariantFromValue(backend->scriptsDelta())); + break; + + case QScriptDebuggerCommand::ResolveScript: + response.setResult(backend->resolveScript(command.fileName())); + break; + + case QScriptDebuggerCommand::GetBacktrace: + response.setResult(backend->backtrace()); + break; + + case QScriptDebuggerCommand::GetContextCount: + response.setResult(backend->contextCount()); + break; + + case QScriptDebuggerCommand::GetContextState: { + QScriptContext *ctx = backend->context(command.contextIndex()); + if (ctx) + response.setResult(static_cast<int>(ctx->state())); + else + response.setError(QScriptDebuggerResponse::InvalidContextIndex); + } break; + + case QScriptDebuggerCommand::GetContextID: { + int idx = command.contextIndex(); + if ((idx >= 0) && (idx < backend->contextCount())) + response.setResult(backend->contextIds()[idx]); + else + response.setError(QScriptDebuggerResponse::InvalidContextIndex); + } break; + + case QScriptDebuggerCommand::GetContextInfo: { + QScriptContext *ctx = backend->context(command.contextIndex()); + if (ctx) + response.setResult(QScriptContextInfo(ctx)); + else + response.setError(QScriptDebuggerResponse::InvalidContextIndex); + } break; + + case QScriptDebuggerCommand::GetThisObject: { + QScriptContext *ctx = backend->context(command.contextIndex()); + if (ctx) + response.setResult(ctx->thisObject()); + else + response.setError(QScriptDebuggerResponse::InvalidContextIndex); + } break; + + case QScriptDebuggerCommand::GetActivationObject: { + QScriptContext *ctx = backend->context(command.contextIndex()); + if (ctx) + response.setResult(ctx->activationObject()); + else + response.setError(QScriptDebuggerResponse::InvalidContextIndex); + } break; + + case QScriptDebuggerCommand::GetScopeChain: { + QScriptContext *ctx = backend->context(command.contextIndex()); + if (ctx) { + QScriptDebuggerValueList dest; +#if QT_VERSION >= 0x040500 + QScriptValueList src = ctx->scopeChain(); + for (int i = 0; i < src.size(); ++i) + dest.append(src.at(i)); +#else + dest.append(ctx->activationObject()); +#endif + response.setResult(dest); + } else { + response.setError(QScriptDebuggerResponse::InvalidContextIndex); + } + } break; + + case QScriptDebuggerCommand::ContextsCheckpoint: { + response.setResult(qVariantFromValue(backend->contextsCheckpoint())); + } break; + + case QScriptDebuggerCommand::NewScriptObjectSnapshot: { + int id = backend->newScriptObjectSnapshot(); + response.setResult(id); + } break; + + case QScriptDebuggerCommand::ScriptObjectSnapshotCapture: { + int id = command.snapshotId(); + QScriptObjectSnapshot *snap = backend->scriptObjectSnapshot(id); + Q_ASSERT(snap != 0); + QScriptDebuggerValue object = command.scriptValue(); + Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue); + QScriptEngine *engine = backend->engine(); + QScriptValue realObject = object.toScriptValue(engine); + Q_ASSERT(realObject.isObject()); + QScriptObjectSnapshot::Delta delta = snap->capture(realObject); + QScriptDebuggerObjectSnapshotDelta result; + result.removedProperties = delta.removedProperties; + bool didIgnoreExceptions = backend->ignoreExceptions(); + backend->setIgnoreExceptions(true); + for (int i = 0; i < delta.changedProperties.size(); ++i) { + const QScriptValueProperty &src = delta.changedProperties.at(i); + bool hadException = engine->hasUncaughtException(); + QString str = src.value().toString(); + if (!hadException && engine->hasUncaughtException()) + engine->clearExceptions(); + QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags()); + result.changedProperties.append(dest); + } + for (int j = 0; j < delta.addedProperties.size(); ++j) { + const QScriptValueProperty &src = delta.addedProperties.at(j); + bool hadException = engine->hasUncaughtException(); + QString str = src.value().toString(); + if (!hadException && engine->hasUncaughtException()) + engine->clearExceptions(); + QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags()); + result.addedProperties.append(dest); + } + backend->setIgnoreExceptions(didIgnoreExceptions); + response.setResult(qVariantFromValue(result)); + } break; + + case QScriptDebuggerCommand::DeleteScriptObjectSnapshot: { + int id = command.snapshotId(); + backend->deleteScriptObjectSnapshot(id); + } break; + + case QScriptDebuggerCommand::NewScriptValueIterator: { + QScriptDebuggerValue object = command.scriptValue(); + Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue); + QScriptEngine *engine = backend->engine(); + QScriptValue realObject = object.toScriptValue(engine); + Q_ASSERT(realObject.isObject()); + int id = backend->newScriptValueIterator(realObject); + response.setResult(id); + } break; + + case QScriptDebuggerCommand::GetPropertiesByIterator: { + int id = command.iteratorId(); + int count = 1000; + QScriptValueIterator *it = backend->scriptValueIterator(id); + Q_ASSERT(it != 0); + QScriptDebuggerValuePropertyList props; + for (int i = 0; (i < count) && it->hasNext(); ++i) { + it->next(); + QString name = it->name(); + QScriptValue value = it->value(); + QString valueAsString = value.toString(); + QScriptValue::PropertyFlags flags = it->flags(); + QScriptDebuggerValueProperty prp(name, value, valueAsString, flags); + props.append(prp); + } + response.setResult(props); + } break; + + case QScriptDebuggerCommand::DeleteScriptValueIterator: { + int id = command.iteratorId(); + backend->deleteScriptValueIterator(id); + } break; + + case QScriptDebuggerCommand::Evaluate: { + int contextIndex = command.contextIndex(); + QString program = command.program(); + QString fileName = command.fileName(); + int lineNumber = command.lineNumber(); + backend->evaluate(contextIndex, program, fileName, lineNumber); + response.setAsync(true); + } break; + + case QScriptDebuggerCommand::ScriptValueToString: { + QScriptDebuggerValue value = command.scriptValue(); + QScriptEngine *engine = backend->engine(); + QScriptValue realValue = value.toScriptValue(engine); + response.setResult(realValue.toString()); + } break; + + case QScriptDebuggerCommand::SetScriptValueProperty: { + QScriptDebuggerValue object = command.scriptValue(); + QScriptEngine *engine = backend->engine(); + QScriptValue realObject = object.toScriptValue(engine); + QScriptDebuggerValue value = command.subordinateScriptValue(); + QScriptValue realValue = value.toScriptValue(engine); + QString name = command.name(); + realObject.setProperty(name, realValue); + } break; + + case QScriptDebuggerCommand::ClearExceptions: + backend->engine()->clearExceptions(); + break; + + case QScriptDebuggerCommand::UserCommand: + case QScriptDebuggerCommand::MaxUserCommand: + break; + } + return response; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor_p.h b/src/scripttools/debugging/qscriptdebuggercommandexecutor_p.h new file mode 100644 index 0000000..8fff5e5 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCOMMANDEXECUTOR_P_H +#define QSCRIPTDEBUGGERCOMMANDEXECUTOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerBackend; +class QScriptDebuggerCommand; +class QScriptDebuggerResponse; + +class QScriptDebuggerCommandExecutorPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCommandExecutor +{ +public: + QScriptDebuggerCommandExecutor(); + virtual ~QScriptDebuggerCommandExecutor(); + + virtual QScriptDebuggerResponse execute( + QScriptDebuggerBackend *backend, + const QScriptDebuggerCommand &command); + +protected: + QScriptDebuggerCommandExecutor(QScriptDebuggerCommandExecutorPrivate &dd); + QScriptDebuggerCommandExecutorPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCommandExecutor) + Q_DISABLE_COPY(QScriptDebuggerCommandExecutor) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend.cpp b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend.cpp new file mode 100644 index 0000000..1e20ab4 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend.cpp @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercommandschedulerfrontend_p.h" +#include "qscriptdebuggercommandschedulerinterface_p.h" +#include "qscriptdebuggercommand_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerCommandSchedulerFrontend::QScriptDebuggerCommandSchedulerFrontend( + QScriptDebuggerCommandSchedulerInterface *scheduler, + QScriptDebuggerResponseHandlerInterface *responseHandler) + : m_scheduler(scheduler), m_responseHandler(responseHandler) +{ +} + +QScriptDebuggerCommandSchedulerFrontend::~QScriptDebuggerCommandSchedulerFrontend() +{ +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleCommand(const QScriptDebuggerCommand &command) +{ + return m_scheduler->scheduleCommand(command, m_responseHandler); +} + +/*! + Instructs the front-end to break at the next script statement, and + returns a unique identifier associated with this command. + + When the next script statement is encountered, the client will be + notified, and the front-end will be ready to accept commands. + + \sa scheduleContinue() +*/ +int QScriptDebuggerCommandSchedulerFrontend::scheduleInterrupt() +{ + return scheduleCommand(QScriptDebuggerCommand::interruptCommand()); +} + +/*! + Instructs the front-end to continue evaluation, and returns a unique + identifier associated with this command. + + \sa scheduleBreak() +*/ +int QScriptDebuggerCommandSchedulerFrontend::scheduleContinue() +{ + return scheduleCommand(QScriptDebuggerCommand::continueCommand()); +} + +/*! + Instructs the front-end to step into the next script statement, and + returns a unique identifier associated with this command. + + Evaluation will automatically be continued, and the client()'s event() + function will be called when the statement has been stepped into. +*/ +int QScriptDebuggerCommandSchedulerFrontend::scheduleStepInto(int count) +{ + return scheduleCommand(QScriptDebuggerCommand::stepIntoCommand(count)); +} + +/*! + Instructs the front-end to step over the next script statement, and + returns a unique identifier associated with this command. + + Evaluation will automatically be continued, and the client()'s event() + function will be called when the statement has been stepped over. +*/ +int QScriptDebuggerCommandSchedulerFrontend::scheduleStepOver(int count) +{ + return scheduleCommand(QScriptDebuggerCommand::stepOverCommand(count)); +} + +/*! + Instructs the front-end to step out of the current script function, and + returns a unique identifier associated with this command. + + Evaluation will automatically be continued, and the client()'s + event() function will be called when the script function has been + stepped out of. +*/ +int QScriptDebuggerCommandSchedulerFrontend::scheduleStepOut() +{ + return scheduleCommand(QScriptDebuggerCommand::stepOutCommand()); +} + +/*! + Instructs the front-end to continue evaluation until the location + specified by the given \a fileName and \a lineNumber is reached. +*/ +int QScriptDebuggerCommandSchedulerFrontend::scheduleRunToLocation(const QString &fileName, int lineNumber) +{ + return scheduleCommand(QScriptDebuggerCommand::runToLocationCommand(fileName, lineNumber)); +} + +/*! + Instructs the front-end to continue evaluation until the location + specified by the given \a scriptId and \a lineNumber is reached. +*/ +int QScriptDebuggerCommandSchedulerFrontend::scheduleRunToLocation(qint64 scriptId, int lineNumber) +{ + return scheduleCommand(QScriptDebuggerCommand::runToLocationCommand(scriptId, lineNumber)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleForceReturn(int contextIndex, const QScriptDebuggerValue &value) +{ + return scheduleCommand(QScriptDebuggerCommand::forceReturnCommand(contextIndex, value)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleSetBreakpoint(const QString &fileName, int lineNumber) +{ + return scheduleCommand(QScriptDebuggerCommand::setBreakpointCommand(fileName, lineNumber)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleSetBreakpoint(const QScriptBreakpointData &data) +{ + return scheduleCommand(QScriptDebuggerCommand::setBreakpointCommand(data)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleDeleteBreakpoint(int id) +{ + return scheduleCommand(QScriptDebuggerCommand::deleteBreakpointCommand(id)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleDeleteAllBreakpoints() +{ + return scheduleCommand(QScriptDebuggerCommand::deleteAllBreakpointsCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetBreakpoints() +{ + return scheduleCommand(QScriptDebuggerCommand::getBreakpointsCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetBreakpointData(int id) +{ + return scheduleCommand(QScriptDebuggerCommand::getBreakpointDataCommand(id)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleSetBreakpointData(int id, const QScriptBreakpointData &data) +{ + return scheduleCommand(QScriptDebuggerCommand::setBreakpointDataCommand(id, data)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetScripts() +{ + return scheduleCommand(QScriptDebuggerCommand::getScriptsCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetScriptData(qint64 id) +{ + return scheduleCommand(QScriptDebuggerCommand::getScriptDataCommand(id)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleScriptsCheckpoint() +{ + return scheduleCommand(QScriptDebuggerCommand::scriptsCheckpointCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetScriptsDelta() +{ + return scheduleCommand(QScriptDebuggerCommand::getScriptsDeltaCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleResolveScript(const QString &fileName) +{ + return scheduleCommand(QScriptDebuggerCommand::resolveScriptCommand(fileName)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetBacktrace() +{ + return scheduleCommand(QScriptDebuggerCommand::getBacktraceCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetContextCount() +{ + return scheduleCommand(QScriptDebuggerCommand::getContextCountCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetContextState(int contextIndex) +{ + return scheduleCommand(QScriptDebuggerCommand::getContextStateCommand(contextIndex)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetContextInfo(int contextIndex) +{ + return scheduleCommand(QScriptDebuggerCommand::getContextInfoCommand(contextIndex)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetContextId(int contextIndex) +{ + return scheduleCommand(QScriptDebuggerCommand::getContextIdCommand(contextIndex)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetThisObject(int contextIndex) +{ + return scheduleCommand(QScriptDebuggerCommand::getThisObjectCommand(contextIndex)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetActivationObject(int contextIndex) +{ + return scheduleCommand(QScriptDebuggerCommand::getActivationObjectCommand(contextIndex)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetScopeChain(int contextIndex) +{ + return scheduleCommand(QScriptDebuggerCommand::getScopeChainCommand(contextIndex)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleContextsCheckpoint() +{ + return scheduleCommand(QScriptDebuggerCommand::contextsCheckpoint()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleEvaluate(int contextIndex, + const QString &program, + const QString &fileName, + int lineNumber) +{ + return scheduleCommand(QScriptDebuggerCommand::evaluateCommand(contextIndex, program, fileName, lineNumber)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleNewScriptValueIterator(const QScriptDebuggerValue &object) +{ + return scheduleCommand(QScriptDebuggerCommand::newScriptValueIteratorCommand(object)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleGetPropertiesByIterator(int id, int count) +{ + return scheduleCommand(QScriptDebuggerCommand::getPropertiesByIteratorCommand(id, count)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleDeleteScriptValueIterator(int id) +{ + return scheduleCommand(QScriptDebuggerCommand::deleteScriptValueIteratorCommand(id)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleScriptValueToString(const QScriptDebuggerValue &value) +{ + return scheduleCommand(QScriptDebuggerCommand::scriptValueToStringCommand(value)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleSetScriptValueProperty(const QScriptDebuggerValue &object, + const QString &name, + const QScriptDebuggerValue &value) +{ + return scheduleCommand(QScriptDebuggerCommand::setScriptValuePropertyCommand(object, name, value)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleClearExceptions() +{ + return scheduleCommand(QScriptDebuggerCommand::clearExceptionsCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleNewScriptObjectSnapshot() +{ + return scheduleCommand(QScriptDebuggerCommand::newScriptObjectSnapshotCommand()); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleScriptObjectSnapshotCapture(int id, const QScriptDebuggerValue &object) +{ + return scheduleCommand(QScriptDebuggerCommand::scriptObjectSnapshotCaptureCommand(id, object)); +} + +int QScriptDebuggerCommandSchedulerFrontend::scheduleDeleteScriptObjectSnapshot(int id) +{ + return scheduleCommand(QScriptDebuggerCommand::deleteScriptObjectSnapshotCommand(id)); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend_p.h b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend_p.h new file mode 100644 index 0000000..ed9cbf9 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerfrontend_p.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCOMMANDSCHEDULERFRONTEND_P_H +#define QSCRIPTDEBUGGERCOMMANDSCHEDULERFRONTEND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCommandSchedulerInterface; +class QScriptDebuggerResponseHandlerInterface; +class QScriptDebuggerCommand; +class QScriptDebuggerValue; +class QScriptBreakpointData; + +class Q_AUTOTEST_EXPORT QScriptDebuggerCommandSchedulerFrontend +{ +public: + QScriptDebuggerCommandSchedulerFrontend( + QScriptDebuggerCommandSchedulerInterface *scheduler, + QScriptDebuggerResponseHandlerInterface *responseHandler); + ~QScriptDebuggerCommandSchedulerFrontend(); + + // execution control + int scheduleInterrupt(); + int scheduleContinue(); + int scheduleStepInto(int count = 1); + int scheduleStepOver(int count = 1); + int scheduleStepOut(); + int scheduleRunToLocation(const QString &fileName, int lineNumber); + int scheduleRunToLocation(qint64 scriptId, int lineNumber); + int scheduleForceReturn(int contextIndex, const QScriptDebuggerValue &value); + + // breakpoints + int scheduleSetBreakpoint(const QString &fileName, int lineNumber); + int scheduleSetBreakpoint(const QScriptBreakpointData &data); + int scheduleDeleteBreakpoint(int id); + int scheduleDeleteAllBreakpoints(); + int scheduleGetBreakpoints(); + int scheduleGetBreakpointData(int id); + int scheduleSetBreakpointData(int id, const QScriptBreakpointData &data); + + // scripts + int scheduleGetScripts(); + int scheduleGetScriptData(qint64 id); + int scheduleScriptsCheckpoint(); + int scheduleGetScriptsDelta(); + int scheduleResolveScript(const QString &fileName); + + // stack + int scheduleGetBacktrace(); + int scheduleGetContextCount(); + int scheduleGetContextState(int contextIndex); + int scheduleGetContextInfo(int contextIndex); + int scheduleGetContextId(int contextIndex); + int scheduleGetThisObject(int contextIndex); + int scheduleGetActivationObject(int contextIndex); + int scheduleGetScopeChain(int contextIndex); + int scheduleContextsCheckpoint(); + + // iteration + int scheduleNewScriptValueIterator(const QScriptDebuggerValue &object); + int scheduleGetPropertiesByIterator(int id, int count); + int scheduleDeleteScriptValueIterator(int id); + + // evaluation + int scheduleEvaluate(int contextIndex, const QString &program, + const QString &fileName = QString(), + int lineNumber = 1); + + int scheduleScriptValueToString(const QScriptDebuggerValue &value); + int scheduleSetScriptValueProperty(const QScriptDebuggerValue &object, + const QString &name, + const QScriptDebuggerValue &value); + + int scheduleClearExceptions(); + + int scheduleNewScriptObjectSnapshot(); + int scheduleScriptObjectSnapshotCapture(int id, const QScriptDebuggerValue &object); + int scheduleDeleteScriptObjectSnapshot(int id); + +private: + int scheduleCommand(const QScriptDebuggerCommand &command); + + QScriptDebuggerCommandSchedulerInterface *m_scheduler; + QScriptDebuggerResponseHandlerInterface *m_responseHandler; + + Q_DISABLE_COPY(QScriptDebuggerCommandSchedulerFrontend) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerinterface_p.h b/src/scripttools/debugging/qscriptdebuggercommandschedulerinterface_p.h new file mode 100644 index 0000000..02a5097 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerinterface_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCOMMANDSCHEDULERINTERFACE_P_H +#define QSCRIPTDEBUGGERCOMMANDSCHEDULERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCommand; +class QScriptDebuggerResponseHandlerInterface; + +class Q_AUTOTEST_EXPORT QScriptDebuggerCommandSchedulerInterface +{ +public: + virtual ~QScriptDebuggerCommandSchedulerInterface() {} + + virtual int scheduleCommand( + const QScriptDebuggerCommand &command, + QScriptDebuggerResponseHandlerInterface *responseHandler) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerjob.cpp b/src/scripttools/debugging/qscriptdebuggercommandschedulerjob.cpp new file mode 100644 index 0000000..8421641 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerjob.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggercommandschedulerjob_p.h" +#include "qscriptdebuggercommandschedulerjob_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerCommandSchedulerJobPrivate::QScriptDebuggerCommandSchedulerJobPrivate() +{ +} + +QScriptDebuggerCommandSchedulerJobPrivate::~QScriptDebuggerCommandSchedulerJobPrivate() +{ +} + +QScriptDebuggerCommandSchedulerJob::QScriptDebuggerCommandSchedulerJob( + QScriptDebuggerCommandSchedulerInterface *commandScheduler) + : QScriptDebuggerJob(*new QScriptDebuggerCommandSchedulerJobPrivate) +{ + Q_D(QScriptDebuggerCommandSchedulerJob); + d->commandScheduler = commandScheduler; +} + +QScriptDebuggerCommandSchedulerJob::~QScriptDebuggerCommandSchedulerJob() +{ +} + +QScriptDebuggerCommandSchedulerJob::QScriptDebuggerCommandSchedulerJob( + QScriptDebuggerCommandSchedulerJobPrivate &dd, + QScriptDebuggerCommandSchedulerInterface *commandScheduler) + : QScriptDebuggerJob(dd) +{ + Q_D(QScriptDebuggerCommandSchedulerJob); + d->commandScheduler = commandScheduler; +} + +QScriptDebuggerCommandSchedulerInterface *QScriptDebuggerCommandSchedulerJob::commandScheduler() const +{ + Q_D(const QScriptDebuggerCommandSchedulerJob); + return d->commandScheduler; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerjob_p.h b/src/scripttools/debugging/qscriptdebuggercommandschedulerjob_p.h new file mode 100644 index 0000000..1d9ba63 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerjob_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCOMMANDSCHEDULERJOB_P_H +#define QSCRIPTDEBUGGERCOMMANDSCHEDULERJOB_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerjob_p.h" + +#include "qscriptdebuggerresponsehandlerinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCommandSchedulerInterface; + +class QScriptDebuggerCommandSchedulerJobPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerCommandSchedulerJob + : public QScriptDebuggerJob, + public QScriptDebuggerResponseHandlerInterface +{ +public: + QScriptDebuggerCommandSchedulerJob(QScriptDebuggerCommandSchedulerInterface *commandScheduler); + ~QScriptDebuggerCommandSchedulerJob(); + + QScriptDebuggerCommandSchedulerInterface *commandScheduler() const; + +protected: + QScriptDebuggerCommandSchedulerJob( + QScriptDebuggerCommandSchedulerJobPrivate &dd, + QScriptDebuggerCommandSchedulerInterface *commandScheduler); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerCommandSchedulerJob) + Q_DISABLE_COPY(QScriptDebuggerCommandSchedulerJob) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggercommandschedulerjob_p_p.h b/src/scripttools/debugging/qscriptdebuggercommandschedulerjob_p_p.h new file mode 100644 index 0000000..53f22e9 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggercommandschedulerjob_p_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCOMMANDSCHEDULERJOB_P_P_H +#define QSCRIPTDEBUGGERCOMMANDSCHEDULERJOB_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerjob_p_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCommandSchedulerInterface; + +class QScriptDebuggerCommandSchedulerJob; +class QScriptDebuggerCommandSchedulerJobPrivate + : public QScriptDebuggerJobPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerCommandSchedulerJob) +public: + QScriptDebuggerCommandSchedulerJobPrivate(); + ~QScriptDebuggerCommandSchedulerJobPrivate(); + + QScriptDebuggerCommandSchedulerInterface *commandScheduler; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsole.cpp b/src/scripttools/debugging/qscriptdebuggerconsole.cpp new file mode 100644 index 0000000..70bb8b1 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsole.cpp @@ -0,0 +1,387 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsole_p.h" +#include "qscriptdebuggerconsolecommandjob_p.h" +#include "qscriptdebuggerconsolecommandmanager_p.h" +#include "qscriptdebuggerscriptedconsolecommand_p.h" +#include "qscriptmessagehandlerinterface_p.h" + +#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qdebug.h> +#include <QtScript/qscriptengine.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerConsole + \internal + + \brief The QScriptDebuggerConsole class provides the core functionality of a debugger console. +*/ + +class QScriptDebuggerConsolePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerConsole) +public: + QScriptDebuggerConsolePrivate(QScriptDebuggerConsole*); + ~QScriptDebuggerConsolePrivate(); + + void loadScriptedCommands(const QString &scriptsPath, + QScriptMessageHandlerInterface *messageHandler); + QScriptDebuggerConsoleCommandJob *createJob( + const QString &command, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler); + + QScriptDebuggerConsoleCommandManager *commandManager; + QString commandPrefix; + QString input; + QStringList commandHistory; + int currentFrameIndex; + qint64 currentScriptId; + int currentLineNumber; + int evaluateAction; + qint64 sessionId; + + QScriptDebuggerConsole *q_ptr; +}; + +QScriptDebuggerConsolePrivate::QScriptDebuggerConsolePrivate(QScriptDebuggerConsole* parent) + : q_ptr(parent) +{ + sessionId = 0; + currentFrameIndex = 0; + currentScriptId = -1; + currentLineNumber = -1; + evaluateAction = 0; + commandPrefix = QLatin1String("."); + commandManager = new QScriptDebuggerConsoleCommandManager(); +} + +QScriptDebuggerConsolePrivate::~QScriptDebuggerConsolePrivate() +{ + delete commandManager; +} + +/*! + Loads command definitions from scripts located in the given \a scriptsPath. +*/ +void QScriptDebuggerConsolePrivate::loadScriptedCommands( + const QString &scriptsPath, + QScriptMessageHandlerInterface *messageHandler) +{ + QDir dir(scriptsPath); + QFileInfoList entries = dir.entryInfoList(QStringList() + << QLatin1String("*.qs")); + for (int i = 0; i < entries.size(); ++i) { + const QFileInfo &fi = entries.at(i); + QString fileName = fi.fileName(); + QFile file(scriptsPath + QLatin1Char('/') + fileName); + if (!file.open(QIODevice::ReadOnly)) + continue; + QTextStream stream(&file); + QString program = stream.readAll(); + QScriptDebuggerScriptedConsoleCommand *command; + command = QScriptDebuggerScriptedConsoleCommand::parse( + program, fileName, messageHandler); + if (!command) + continue; + commandManager->addCommand(command); + } +} + + +/*! + Creates a job that will execute the given debugger \a command. + Returns the new job, or 0 if the command is undefined. +*/ +QScriptDebuggerConsoleCommandJob *QScriptDebuggerConsolePrivate::createJob( + const QString &command, QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler) +{ + QString name; + int i = command.indexOf(QLatin1Char(' ')); + if (i == -1) { + name = command; + i = name.size(); + } else { + name = command.left(i); + } + if (name.isEmpty()) + return 0; + QScriptDebuggerConsoleCommand *cmd = commandManager->findCommand(name); + if (!cmd) { + // try to auto-complete + QStringList completions = commandManager->completions(name); + if (!completions.isEmpty()) { + if (completions.size() > 1) { + QString msg; + msg.append(QString::fromLatin1("Ambiguous command \"%0\": ") + .arg(name)); + for (int j = 0; j < completions.size(); ++j) { + if (j > 0) + msg.append(QString::fromLatin1(", ")); + msg.append(completions.at(j)); + } + msg.append(QString::fromLatin1(".")); + messageHandler->message(QtWarningMsg, msg); + return 0; + } + cmd = commandManager->findCommand(completions.at(0)); + Q_ASSERT(cmd != 0); + } + if (!cmd) { + messageHandler->message( + QtWarningMsg, + QString::fromLatin1("Undefined command \"%0\". Try \"help\".") + .arg(name)); + return 0; + } + } + QStringList args; + QString tmp = command.mid(i+1); + if (cmd->argumentTypes().contains(QString::fromLatin1("script"))) { + if (!tmp.isEmpty()) + args.append(tmp); + } else { + args = tmp.split(QLatin1Char(' '), QString::SkipEmptyParts); + } + return cmd->createJob(args, q_func(), messageHandler, commandScheduler); +} + +QScriptDebuggerConsole::QScriptDebuggerConsole() + : d_ptr(new QScriptDebuggerConsolePrivate(this)) +{ +} + +QScriptDebuggerConsole::~QScriptDebuggerConsole() +{ + delete d_ptr; +} + +void QScriptDebuggerConsole::loadScriptedCommands(const QString &scriptsPath, + QScriptMessageHandlerInterface *messageHandler) +{ + Q_D(QScriptDebuggerConsole); + d->loadScriptedCommands(scriptsPath, messageHandler); +} + +QScriptDebuggerConsoleCommandManager *QScriptDebuggerConsole::commandManager() const +{ + Q_D(const QScriptDebuggerConsole); + return d->commandManager; +} + +bool QScriptDebuggerConsole::hasIncompleteInput() const +{ + Q_D(const QScriptDebuggerConsole); + return !d->input.isEmpty(); +} + +QString QScriptDebuggerConsole::incompleteInput() const +{ + Q_D(const QScriptDebuggerConsole); + return d->input; +} + +void QScriptDebuggerConsole::setIncompleteInput(const QString &input) +{ + Q_D(QScriptDebuggerConsole); + d->input = input; +} + +QString QScriptDebuggerConsole::commandPrefix() const +{ + Q_D(const QScriptDebuggerConsole); + return d->commandPrefix; +} + +/*! + Consumes the given line of \a input. If the input starts with the + command prefix, it is regarded as a debugger command; otherwise the + input is evaluated as a plain script. +*/ +QScriptDebuggerConsoleCommandJob *QScriptDebuggerConsole::consumeInput( + const QString &input, QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler) +{ + Q_D(QScriptDebuggerConsole); + static const int maximumHistoryCount = 100; + QString cmd; + if (d->input.isEmpty() && input.isEmpty()) { + if (d->commandHistory.isEmpty()) + return 0; + cmd = d->commandHistory.first(); + } else { + cmd = input; + } + if (d->input.isEmpty() && cmd.startsWith(d->commandPrefix)) { + if (!input.isEmpty()) { + d->commandHistory.prepend(cmd); + if (d->commandHistory.size() > maximumHistoryCount) + d->commandHistory.removeLast(); + } + cmd.remove(0, d->commandPrefix.length()); + return d->createJob(cmd, messageHandler, commandScheduler); + } + d->input += cmd; + d->input += QLatin1Char('\n'); + QScriptSyntaxCheckResult check = QScriptEngine::checkSyntax(d->input); + if (check.state() == QScriptSyntaxCheckResult::Intermediate) + return false; + d->input.chop(1); // remove the last \n + cmd = QString(); + cmd.append(d->commandPrefix); + cmd.append(QString::fromLatin1("eval ")); + cmd.append(d->input); + d->commandHistory.prepend(cmd); + if (d->commandHistory.size() > maximumHistoryCount) + d->commandHistory.removeLast(); + d->input.clear(); + cmd.remove(0, d->commandPrefix.length()); + return d->createJob(cmd, messageHandler, commandScheduler); +} + +int QScriptDebuggerConsole::currentFrameIndex() const +{ + Q_D(const QScriptDebuggerConsole); + return d->currentFrameIndex; +} + +void QScriptDebuggerConsole::setCurrentFrameIndex(int index) +{ + Q_D(QScriptDebuggerConsole); + d->currentFrameIndex = index; +} + +qint64 QScriptDebuggerConsole::currentScriptId() const +{ + Q_D(const QScriptDebuggerConsole); + return d->currentScriptId; +} + +void QScriptDebuggerConsole::setCurrentScriptId(qint64 id) +{ + Q_D(QScriptDebuggerConsole); + d->currentScriptId = id; +} + +int QScriptDebuggerConsole::currentLineNumber() const +{ + Q_D(const QScriptDebuggerConsole); + return d->currentLineNumber; +} + +void QScriptDebuggerConsole::setCurrentLineNumber(int lineNumber) +{ + Q_D(QScriptDebuggerConsole); + d->currentLineNumber = lineNumber; +} + +int QScriptDebuggerConsole::evaluateAction() const +{ + Q_D(const QScriptDebuggerConsole); + return d->evaluateAction; +} + +void QScriptDebuggerConsole::setEvaluateAction(int action) +{ + Q_D(QScriptDebuggerConsole); + d->evaluateAction = action; +} + +qint64 QScriptDebuggerConsole::sessionId() const +{ + Q_D(const QScriptDebuggerConsole); + return d->sessionId; +} + +void QScriptDebuggerConsole::bumpSessionId() +{ + Q_D(QScriptDebuggerConsole); + ++d->sessionId; +} + +void QScriptDebuggerConsole::showDebuggerInfoMessage( + QScriptMessageHandlerInterface *messageHandler) +{ + messageHandler->message( + QtDebugMsg, + QString::fromLatin1( + "Welcome to the Qt Script debugger.\n" + "Debugger commands start with a . (period).\n" + "Any other input will be evaluated by the script interpreter.\n" + "Type \".help\" for help.\n")); +} + +/*! + \reimp +*/ +int QScriptDebuggerConsole::historyCount() const +{ + Q_D(const QScriptDebuggerConsole); + return d->commandHistory.size(); +} + +/*! + \reimp +*/ +QString QScriptDebuggerConsole::historyAt(int index) const +{ + Q_D(const QScriptDebuggerConsole); + return d->commandHistory.value(index); +} + +/*! + \reimp +*/ +void QScriptDebuggerConsole::changeHistoryAt(int index, const QString &newHistory) +{ + Q_D(QScriptDebuggerConsole); + d->commandHistory[index] = newHistory; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerconsole_p.h b/src/scripttools/debugging/qscriptdebuggerconsole_p.h new file mode 100644 index 0000000..b5ebf44 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsole_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLE_P_H +#define QSCRIPTDEBUGGERCONSOLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include "qscriptdebuggerconsolehistorianinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QString; +class QScriptDebuggerConsoleCommandJob; +class QScriptMessageHandlerInterface; +class QScriptDebuggerCommandSchedulerInterface; +class QScriptDebuggerConsoleCommandManager; + +class QScriptDebuggerConsolePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsole + : public QScriptDebuggerConsoleHistorianInterface +{ +public: + QScriptDebuggerConsole(); + ~QScriptDebuggerConsole(); + + void loadScriptedCommands(const QString &scriptsPath, + QScriptMessageHandlerInterface *messageHandler); + + void showDebuggerInfoMessage(QScriptMessageHandlerInterface *messageHandler); + + QScriptDebuggerConsoleCommandManager *commandManager() const; + + QScriptDebuggerConsoleCommandJob *consumeInput( + const QString &input, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler); + bool hasIncompleteInput() const; + QString incompleteInput() const; + void setIncompleteInput(const QString &input); + QString commandPrefix() const; + + int historyCount() const; + QString historyAt(int index) const; + void changeHistoryAt(int index, const QString &newHistory); + + int currentFrameIndex() const; + void setCurrentFrameIndex(int index); + + qint64 currentScriptId() const; + void setCurrentScriptId(qint64 id); + + int currentLineNumber() const; + void setCurrentLineNumber(int lineNumber); + + int evaluateAction() const; + void setEvaluateAction(int action); + + qint64 sessionId() const; + void bumpSessionId(); + +private: + QScriptDebuggerConsolePrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptDebuggerConsole) + Q_DISABLE_COPY(QScriptDebuggerConsole) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommand.cpp b/src/scripttools/debugging/qscriptdebuggerconsolecommand.cpp new file mode 100644 index 0000000..6cbf58c --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommand.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsolecommand_p.h" +#include "qscriptdebuggerconsolecommand_p_p.h" + +#include <QtCore/qstringlist.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerConsoleCommand + \internal + + \brief The QScriptDebuggerConsoleCommand class is the base class of console commands. + + \sa QScriptDebuggerConsoleCommandManager +*/ + +QScriptDebuggerConsoleCommandPrivate::QScriptDebuggerConsoleCommandPrivate() +{ +} + +QScriptDebuggerConsoleCommandPrivate::~QScriptDebuggerConsoleCommandPrivate() +{ +} + +QScriptDebuggerConsoleCommand::QScriptDebuggerConsoleCommand() + : d_ptr(new QScriptDebuggerConsoleCommandPrivate) +{ + d_ptr->q_ptr = this; +} + +QScriptDebuggerConsoleCommand::~QScriptDebuggerConsoleCommand() +{ + delete d_ptr; +} + +QScriptDebuggerConsoleCommand::QScriptDebuggerConsoleCommand(QScriptDebuggerConsoleCommandPrivate &dd) + : d_ptr(&dd) +{ + d_ptr->q_ptr = this; +} + +/*! + \fn QString QScriptDebuggerConsoleCommand::name() const + + Returns the name of this console command. +*/ + +/*! + \fn QString QScriptDebuggerConsoleCommand::group() const + + Returns the group that this console command belongs to. +*/ + +/*! + \fn QString QScriptDebuggerConsoleCommand::shortDescription() const + + Returns a short (one line) description of the command. +*/ + +/*! + \fn QString QScriptDebuggerConsoleCommand::longDescription() const + + Returns a detailed description of how to use the command. +*/ + +/*! + \fn QScriptDebuggerConsoleCommandJob *QScriptDebuggerConsoleCommand::createJob( + const QStringList &arguments, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *scheduler) = 0 + + Creates a job that will execute this command with the given \a + arguments. If the command cannot be executed (e.g. because one or + more arguments are invalid), a suitable error message should be + output to the \a messageHandler, and 0 should be returned. +*/ + +/*! + Returns a list of names of commands that may also be of interest to + users of this command. +*/ +QStringList QScriptDebuggerConsoleCommand::seeAlso() const +{ + return QStringList(); +} + +/*! + Returns a list of aliases for this command. +*/ +QStringList QScriptDebuggerConsoleCommand::aliases() const +{ + return QStringList(); +} + +QStringList QScriptDebuggerConsoleCommand::argumentTypes() const +{ + return QStringList(); +} + +QStringList QScriptDebuggerConsoleCommand::subCommands() const +{ + return QStringList(); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommand_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommand_p.h new file mode 100644 index 0000000..fbf285f --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommand_p.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLECOMMAND_P_H +#define QSCRIPTDEBUGGERCONSOLECOMMAND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qlist.h> + +QT_BEGIN_NAMESPACE + +class QString; +class QStringList; +class QScriptDebuggerConsole; +class QScriptDebuggerConsoleCommandJob; +class QScriptMessageHandlerInterface; +class QScriptDebuggerCommandSchedulerInterface; + +class QScriptDebuggerConsoleCommandPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleCommand +{ +public: + QScriptDebuggerConsoleCommand(); + virtual ~QScriptDebuggerConsoleCommand(); + + virtual QString name() const = 0; + virtual QString group() const = 0; + virtual QString shortDescription() const = 0; + virtual QString longDescription() const = 0; + virtual QStringList seeAlso() const; + virtual QStringList aliases() const; + + virtual QStringList argumentTypes() const; + + virtual QStringList subCommands() const; + virtual QScriptDebuggerConsoleCommandJob *createJob( + const QStringList &arguments, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *scheduler) = 0; + +protected: + QScriptDebuggerConsoleCommand(QScriptDebuggerConsoleCommandPrivate &dd); + QScriptDebuggerConsoleCommandPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerConsoleCommand) + Q_DISABLE_COPY(QScriptDebuggerConsoleCommand) +}; + +typedef QList<QScriptDebuggerConsoleCommand*> QScriptDebuggerConsoleCommandList; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommand_p_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommand_p_p.h new file mode 100644 index 0000000..3e1807a --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommand_p_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLECOMMAND_P_P_H +#define QSCRIPTDEBUGGERCONSOLECOMMAND_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsoleCommand; +class QScriptDebuggerConsoleCommandPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerConsoleCommand) +public: + QScriptDebuggerConsoleCommandPrivate(); + virtual ~QScriptDebuggerConsoleCommandPrivate(); + + QScriptDebuggerConsoleCommand *q_ptr; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata.cpp b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata.cpp new file mode 100644 index 0000000..9cfac97 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsolecommandgroupdata_p.h" + +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerConsoleCommandGroupData + \internal + + \brief The QScriptDebuggerConsoleCommandGroupData class holds data associated with a console command group. +*/ + +class QScriptDebuggerConsoleCommandGroupDataPrivate +{ +public: + QScriptDebuggerConsoleCommandGroupDataPrivate(); + ~QScriptDebuggerConsoleCommandGroupDataPrivate(); + + QString shortDescription; + QString longDescription; + + QBasicAtomicInt ref; +}; + +QScriptDebuggerConsoleCommandGroupDataPrivate::QScriptDebuggerConsoleCommandGroupDataPrivate() +{ + ref = 0; +} + +QScriptDebuggerConsoleCommandGroupDataPrivate::~QScriptDebuggerConsoleCommandGroupDataPrivate() +{ +} + +QScriptDebuggerConsoleCommandGroupData::QScriptDebuggerConsoleCommandGroupData() + : d_ptr(0) +{ +} + +QScriptDebuggerConsoleCommandGroupData::QScriptDebuggerConsoleCommandGroupData( + const QString &shortDescription, const QString &longDescription) + : d_ptr(new QScriptDebuggerConsoleCommandGroupDataPrivate) +{ + d_ptr->shortDescription = shortDescription; + d_ptr->longDescription = longDescription; + d_ptr->ref.ref(); +} + +QScriptDebuggerConsoleCommandGroupData::QScriptDebuggerConsoleCommandGroupData( + const QScriptDebuggerConsoleCommandGroupData &other) + : d_ptr(other.d_ptr) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +QScriptDebuggerConsoleCommandGroupData::~QScriptDebuggerConsoleCommandGroupData() +{ + if (d_ptr && !d_ptr->ref.deref()) { + delete d_ptr; + d_ptr = 0; + } +} + +QScriptDebuggerConsoleCommandGroupData &QScriptDebuggerConsoleCommandGroupData::operator=( + const QScriptDebuggerConsoleCommandGroupData &other) +{ + if (d_ptr == other.d_ptr) + return *this; + if (d_ptr && !d_ptr->ref.deref()) + delete d_ptr; + d_ptr = other.d_ptr; + if (d_ptr) + d_ptr->ref.ref(); + return *this; +} + +QString QScriptDebuggerConsoleCommandGroupData::shortDescription() const +{ + Q_D(const QScriptDebuggerConsoleCommandGroupData); + return d->shortDescription; +} + +QString QScriptDebuggerConsoleCommandGroupData::longDescription() const +{ + Q_D(const QScriptDebuggerConsoleCommandGroupData); + return d->longDescription; +} + +bool QScriptDebuggerConsoleCommandGroupData::isValid() const +{ + Q_D(const QScriptDebuggerConsoleCommandGroupData); + return (d != 0); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata_p.h new file mode 100644 index 0000000..c32277f --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLECOMMANDGROUPDATA_P_H +#define QSCRIPTDEBUGGERCONSOLECOMMANDGROUPDATA_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qmap.h> + +QT_BEGIN_NAMESPACE + +class QString; + +class QScriptDebuggerConsoleCommandGroupDataPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleCommandGroupData +{ +public: + QScriptDebuggerConsoleCommandGroupData(); + QScriptDebuggerConsoleCommandGroupData( + const QString &shortDescription, + const QString &longDescription); + QScriptDebuggerConsoleCommandGroupData( + const QScriptDebuggerConsoleCommandGroupData &other); + ~QScriptDebuggerConsoleCommandGroupData(); + + QString shortDescription() const; + QString longDescription() const; + + bool isValid() const; + + QScriptDebuggerConsoleCommandGroupData &operator=( + const QScriptDebuggerConsoleCommandGroupData &other); + +private: + QScriptDebuggerConsoleCommandGroupDataPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerConsoleCommandGroupData) +}; + +typedef QMap<QString, QScriptDebuggerConsoleCommandGroupData> QScriptDebuggerConsoleCommandGroupMap; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandjob.cpp b/src/scripttools/debugging/qscriptdebuggerconsolecommandjob.cpp new file mode 100644 index 0000000..69e8247 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandjob.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsolecommandjob_p.h" +#include "qscriptdebuggerconsolecommandjob_p_p.h" + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +QScriptDebuggerConsoleCommandJobPrivate::QScriptDebuggerConsoleCommandJobPrivate() +{ +} + +QScriptDebuggerConsoleCommandJobPrivate::~QScriptDebuggerConsoleCommandJobPrivate() +{ +} + +QScriptDebuggerConsoleCommandJob::QScriptDebuggerConsoleCommandJob( + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(*new QScriptDebuggerConsoleCommandJobPrivate, + scheduler) +{ + Q_D(QScriptDebuggerConsoleCommandJob); + d->console = console; + d->messageHandler = messageHandler; +} + +QScriptDebuggerConsoleCommandJob::~QScriptDebuggerConsoleCommandJob() +{ +} + +QScriptDebuggerConsoleCommandJob::QScriptDebuggerConsoleCommandJob( + QScriptDebuggerConsoleCommandJobPrivate &dd, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(dd, scheduler) +{ + Q_D(QScriptDebuggerConsoleCommandJob); + d->console = console; + d->messageHandler = messageHandler; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandjob_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommandjob_p.h new file mode 100644 index 0000000..8d3ddaa --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandjob_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLECOMMANDJOB_P_H +#define QSCRIPTDEBUGGERCONSOLECOMMANDJOB_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggercommandschedulerjob_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsole; +class QScriptMessageHandlerInterface; + +class QScriptDebuggerConsoleCommandJobPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleCommandJob + : public QScriptDebuggerCommandSchedulerJob +{ +public: + QScriptDebuggerConsoleCommandJob(QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *scheduler); + ~QScriptDebuggerConsoleCommandJob(); + +protected: + QScriptDebuggerConsoleCommandJob(QScriptDebuggerConsoleCommandJobPrivate &dd, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *scheduler); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerConsoleCommandJob) + Q_DISABLE_COPY(QScriptDebuggerConsoleCommandJob) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandjob_p_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommandjob_p_p.h new file mode 100644 index 0000000..ef52517 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandjob_p_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLECOMMANDJOB_P_P_H +#define QSCRIPTDEBUGGERCONSOLECOMMANDJOB_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggercommandschedulerjob_p_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsole; +class QScriptMessageHandlerInterface; + +class QScriptDebuggerConsoleCommandJob; +class QScriptDebuggerConsoleCommandJobPrivate + : public QScriptDebuggerCommandSchedulerJobPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerConsoleCommandJob) +public: + QScriptDebuggerConsoleCommandJobPrivate(); + ~QScriptDebuggerConsoleCommandJobPrivate(); + + QScriptDebuggerConsole *console; + QScriptMessageHandlerInterface *messageHandler; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager.cpp b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager.cpp new file mode 100644 index 0000000..ef9687e --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager.cpp @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsolecommandmanager_p.h" +#include "qscriptdebuggerconsolecommand_p.h" +#include "qscriptdebuggerconsolecommandgroupdata_p.h" + +#include <QtCore/qlist.h> +#include <QtCore/qstringlist.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerConsoleCommandManager + \internal + + \brief The QScriptDebuggerConsoleCommandManager manages a collection of console commands. + +*/ + +class QScriptDebuggerConsoleCommandManagerPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerConsoleCommandManager) +public: + QScriptDebuggerConsoleCommandManagerPrivate(); + ~QScriptDebuggerConsoleCommandManagerPrivate(); + + QList<QScriptDebuggerConsoleCommand*> commands; + QMap<QString, QScriptDebuggerConsoleCommandGroupData> groups; + + QScriptDebuggerConsoleCommandManager *q_ptr; +}; + +QScriptDebuggerConsoleCommandManagerPrivate::QScriptDebuggerConsoleCommandManagerPrivate() +{ + groups[QLatin1String("breakpoints")] = + QScriptDebuggerConsoleCommandGroupData(QLatin1String("Making program stop at certain points"), + QLatin1String("")); + groups[QLatin1String("files")] = + QScriptDebuggerConsoleCommandGroupData(QLatin1String("Examining files"), + QLatin1String("")); + groups[QLatin1String("stack")] = + QScriptDebuggerConsoleCommandGroupData(QLatin1String("Examining the stack"), + QLatin1String("")); + groups[QLatin1String("running")] = + QScriptDebuggerConsoleCommandGroupData(QLatin1String("Running the program"), + QLatin1String("")); + groups[QLatin1String("status")] = + QScriptDebuggerConsoleCommandGroupData(QLatin1String("Status inquiries"), + QLatin1String("")); + groups[QLatin1String("void")] = + QScriptDebuggerConsoleCommandGroupData(QLatin1String("No such group"), + QLatin1String("It's a secret to everyone")); +} + +QScriptDebuggerConsoleCommandManagerPrivate::~QScriptDebuggerConsoleCommandManagerPrivate() +{ + qDeleteAll(commands); +} + +QScriptDebuggerConsoleCommandManager::QScriptDebuggerConsoleCommandManager() + : d_ptr(new QScriptDebuggerConsoleCommandManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +QScriptDebuggerConsoleCommandManager::~QScriptDebuggerConsoleCommandManager() +{ + delete d_ptr; +} + +/*! + Adds the given \a command. + The manager takes ownership of the command. +*/ +void QScriptDebuggerConsoleCommandManager::addCommand(QScriptDebuggerConsoleCommand *command) +{ + Q_D(QScriptDebuggerConsoleCommandManager); + Q_ASSERT(command != 0); + if (command->name().isEmpty()) { + qWarning("addCommand(): nameless command ignored"); + return; + } + if (command->group().isEmpty()) { + qWarning("addCommand(): groupless command '%s' ignored", + qPrintable(command->name())); + return; + } + if (findCommand(command->name()) != 0) { + qWarning("addCommand(): duplicate command '%s' (group '%s') ignored", + qPrintable(command->name()), qPrintable(command->group())); + return; + } + if (!d->groups.contains(command->group())) { + qWarning("addCommand(): group '%s' for command '%s' is unknown!", + qPrintable(command->group()), qPrintable(command->name())); + } + d->commands.append(command); +} + +/*! + Registers a command group with the given \a name and \a data. +*/ +void QScriptDebuggerConsoleCommandManager::addCommandGroup( + const QString &name, const QScriptDebuggerConsoleCommandGroupData &data) +{ + Q_D(QScriptDebuggerConsoleCommandManager); + if (name.isEmpty()) { + qWarning("addCommandGroup(): nameless group ignored"); + return; + } + if (d->groups.contains(name)) { + qWarning("addCommandGroup(): group '%s' already defined", + qPrintable(name)); + return; + } + d->groups[name] = data; +} + +/*! + Returns the command with the given \a name if one exists, otherwise + returns 0. +*/ +QScriptDebuggerConsoleCommand *QScriptDebuggerConsoleCommandManager::findCommand(const QString &name) const +{ + Q_D(const QScriptDebuggerConsoleCommandManager); + for (int i = 0; i < d->commands.size(); ++i) { + QScriptDebuggerConsoleCommand *cmd = d->commands.at(i); + if (cmd->name() == name) + return cmd; + else if (cmd->aliases().contains(name)) + return cmd; + } + return 0; +} + +/*! + Returns the commands organized into groups. +*/ +QMap<QString, QList<QScriptDebuggerConsoleCommand*> > QScriptDebuggerConsoleCommandManager::commands() const +{ + Q_D(const QScriptDebuggerConsoleCommandManager); + QMap<QString, QList<QScriptDebuggerConsoleCommand*> > result; + for (int i = 0; i < d->commands.size(); ++i) { + QScriptDebuggerConsoleCommand *cmd = d->commands.at(i); + result[cmd->group()].append(cmd); + } + return result; +} + +/*! + Returns commands in the group of the given \a name. +*/ +QScriptDebuggerConsoleCommandList QScriptDebuggerConsoleCommandManager::commandsInGroup(const QString &name) const +{ + Q_D(const QScriptDebuggerConsoleCommandManager); + QScriptDebuggerConsoleCommandList result; + for (int i = 0; i < d->commands.size(); ++i) { + QScriptDebuggerConsoleCommand *cmd = d->commands.at(i); + if (cmd->group() == name) + result.append(cmd); + } + return result; +} + +/*! + Returns data associated with the group of the given \a name. +*/ +QScriptDebuggerConsoleCommandGroupData QScriptDebuggerConsoleCommandManager::commandGroupData(const QString &name) const +{ + Q_D(const QScriptDebuggerConsoleCommandManager); + return d->groups.value(name); +} + +/*! + Returns all command groups. +*/ +QMap<QString, QScriptDebuggerConsoleCommandGroupData> QScriptDebuggerConsoleCommandManager::commandGroups() const +{ + Q_D(const QScriptDebuggerConsoleCommandManager); + return d->groups; +} + +/*! + Returns the possible completions for the given \a prefix. +*/ +QStringList QScriptDebuggerConsoleCommandManager::completions(const QString &prefix) const +{ + Q_D(const QScriptDebuggerConsoleCommandManager); + QStringList result; + for (int i = 0; i < d->commands.size(); ++i) { + QScriptDebuggerConsoleCommand *cmd = d->commands.at(i); + QStringList names; + names.append(cmd->name()); +// names += cmd->aliases(); + for (int j = 0; j < names.size(); ++j) { + const QString &name = names.at(j); + if ((name.length() > prefix.length()) && name.startsWith(prefix)) + result.append(name); + } + } + qStableSort(result); + return result; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager_p.h new file mode 100644 index 0000000..b5c9842 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLECOMMANDMANAGER_P_H +#define QSCRIPTDEBUGGERCONSOLECOMMANDMANAGER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qmap.h> +#include <QtCore/qlist.h> + +#include "qscriptdebuggerconsolecommandgroupdata_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsoleCommand; +class QStringList; + +class QScriptDebuggerConsoleCommandManagerPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleCommandManager +{ +public: + QScriptDebuggerConsoleCommandManager(); + ~QScriptDebuggerConsoleCommandManager(); + + void addCommand(QScriptDebuggerConsoleCommand *command); + void addCommandGroup(const QString &name, + const QScriptDebuggerConsoleCommandGroupData &data); + + QScriptDebuggerConsoleCommand *findCommand(const QString &name) const; + QMap<QString, QList<QScriptDebuggerConsoleCommand*> > commands() const; + QList<QScriptDebuggerConsoleCommand*> commandsInGroup(const QString &name) const; + + QScriptDebuggerConsoleCommandGroupData commandGroupData(const QString &name) const; + QScriptDebuggerConsoleCommandGroupMap commandGroups() const; + + QStringList completions(const QString &prefix) const; + +private: + QScriptDebuggerConsoleCommandManagerPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptDebuggerConsoleCommandManager) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp b/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp new file mode 100644 index 0000000..0018b92 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp @@ -0,0 +1,465 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsoleglobalobject_p.h" +#include "qscriptdebuggercommandschedulerinterface_p.h" +#include "qscriptdebuggercommandschedulerfrontend_p.h" +#include "qscriptmessagehandlerinterface_p.h" +#include "qscriptdebuggerconsole_p.h" +#include "qscriptdebuggerconsolecommandmanager_p.h" + +#include <private/qobject_p.h> + +#include <QtScript/qscriptengine.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsoleGlobalObjectPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerConsoleGlobalObject) +public: + QScriptDebuggerConsoleGlobalObjectPrivate(); + ~QScriptDebuggerConsoleGlobalObjectPrivate(); + + QScriptDebuggerCommandSchedulerInterface *scheduler; + QScriptDebuggerResponseHandlerInterface *responseHandler; + QScriptMessageHandlerInterface *messageHandler; + QScriptDebuggerConsole *console; +}; + +QScriptDebuggerConsoleGlobalObjectPrivate::QScriptDebuggerConsoleGlobalObjectPrivate() +{ + scheduler = 0; + responseHandler = 0; + messageHandler = 0; + console = 0; +} + +QScriptDebuggerConsoleGlobalObjectPrivate::~QScriptDebuggerConsoleGlobalObjectPrivate() +{ +} + +QScriptDebuggerConsoleGlobalObject::QScriptDebuggerConsoleGlobalObject(QObject *parent) + : QObject(*new QScriptDebuggerConsoleGlobalObjectPrivate, parent) +{ +} + +QScriptDebuggerConsoleGlobalObject::~QScriptDebuggerConsoleGlobalObject() +{ +} + +QScriptDebuggerCommandSchedulerInterface *QScriptDebuggerConsoleGlobalObject::scheduler() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->scheduler; +} + +void QScriptDebuggerConsoleGlobalObject::setScheduler(QScriptDebuggerCommandSchedulerInterface *scheduler) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->scheduler = scheduler; +} + +QScriptDebuggerResponseHandlerInterface *QScriptDebuggerConsoleGlobalObject::responseHandler() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->responseHandler; +} + +void QScriptDebuggerConsoleGlobalObject::setResponseHandler( + QScriptDebuggerResponseHandlerInterface *responseHandler) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->responseHandler = responseHandler; +} + +QScriptMessageHandlerInterface *QScriptDebuggerConsoleGlobalObject::messageHandler() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->messageHandler; +} + +void QScriptDebuggerConsoleGlobalObject::setMessageHandler(QScriptMessageHandlerInterface *messageHandler) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->messageHandler = messageHandler; +} + +QScriptDebuggerConsole *QScriptDebuggerConsoleGlobalObject::console() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console; +} + +void QScriptDebuggerConsoleGlobalObject::setConsole(QScriptDebuggerConsole *console) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->console = console; +} + +// ### the scheduleXXX functions could take a callback function as argument (rather than using the +// global handleResponse() function) + +int QScriptDebuggerConsoleGlobalObject::scheduleInterrupt() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleInterrupt(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleContinue() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleContinue(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleStepInto(int count) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleStepInto(count); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleStepOver(int count) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleStepOver(count); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleStepOut() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleStepOut(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleRunToLocation(const QString &fileName, int lineNumber) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleRunToLocation(fileName, lineNumber); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleRunToLocation(qint64 scriptId, int lineNumber) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleRunToLocation(scriptId, lineNumber); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleForceReturn(int contextIndex, const QScriptDebuggerValue &value) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleForceReturn(contextIndex, value); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleSetBreakpoint(const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleSetBreakpoint(data); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleDeleteBreakpoint(int id) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleDeleteBreakpoint(id); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleDeleteAllBreakpoints() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleDeleteAllBreakpoints(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetBreakpoints() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetBreakpoints(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetBreakpointData(int id) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetBreakpointData(id); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleSetBreakpointData(int id, const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleSetBreakpointData(id, data); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetScripts() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetScripts(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetScriptData(qint64 id) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetScriptData(id); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleScriptsCheckpoint() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleScriptsCheckpoint(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetScriptsDelta() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetScriptsDelta(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleResolveScript(const QString &fileName) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleResolveScript(fileName); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetBacktrace() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetBacktrace(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetThisObject(int contextIndex) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetThisObject(contextIndex); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetActivationObject(int contextIndex) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetActivationObject(contextIndex); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetContextCount() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetContextCount(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetContextInfo(int contextIndex) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetContextInfo(contextIndex); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleNewScriptValueIterator(const QScriptDebuggerValue &object) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleNewScriptValueIterator(object); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleGetPropertiesByIterator(int id, int count) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleGetPropertiesByIterator(id, count); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleDeleteScriptValueIterator(int id) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleDeleteScriptValueIterator(id); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleEvaluate(int contextIndex, const QString &program, + const QString &fileName, + int lineNumber) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleEvaluate(contextIndex, program, fileName, lineNumber); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleScriptValueToString(const QScriptDebuggerValue &value) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleScriptValueToString(value); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleClearExceptions() +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + QScriptDebuggerCommandSchedulerFrontend frontend(d->scheduler, d->responseHandler); + return frontend.scheduleClearExceptions(); +} + +int QScriptDebuggerConsoleGlobalObject::scheduleCommand(const QScriptDebuggerCommand &command) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + return d->scheduler->scheduleCommand(command, d->responseHandler); +} + +void QScriptDebuggerConsoleGlobalObject::warning(const QString &text, + const QString &fileName, + int lineNumber, int columnNumber) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->messageHandler->message(QtWarningMsg, text, fileName, lineNumber, columnNumber); +} + +void QScriptDebuggerConsoleGlobalObject::message(const QString &text, + const QString &fileName, + int lineNumber, int columnNumber) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->messageHandler->message(QtDebugMsg, text, fileName, lineNumber, columnNumber); +} + +void QScriptDebuggerConsoleGlobalObject::error(const QString &text, + const QString &fileName, + int lineNumber, int columnNumber) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->messageHandler->message(QtCriticalMsg, text, fileName, lineNumber, columnNumber); +} + +int QScriptDebuggerConsoleGlobalObject::getCurrentFrameIndex() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->currentFrameIndex(); +} + +void QScriptDebuggerConsoleGlobalObject::setCurrentFrameIndex(int index) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->console->setCurrentFrameIndex(index); +} + +int QScriptDebuggerConsoleGlobalObject::getCurrentLineNumber() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->currentLineNumber(); +} + +void QScriptDebuggerConsoleGlobalObject::setCurrentLineNumber(int lineNumber) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->console->setCurrentLineNumber(lineNumber); +} + +qint64 QScriptDebuggerConsoleGlobalObject::getCurrentScriptId() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->currentScriptId(); +} + +void QScriptDebuggerConsoleGlobalObject::setCurrentScriptId(qint64 id) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->console->setCurrentScriptId(id); +} + +qint64 QScriptDebuggerConsoleGlobalObject::getSessionId() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->sessionId(); +} + +QScriptDebuggerConsoleCommandGroupMap QScriptDebuggerConsoleGlobalObject::getCommandGroups() const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->commandManager()->commandGroups(); +} + +QScriptDebuggerConsoleCommand *QScriptDebuggerConsoleGlobalObject::findCommand(const QString &name) const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->commandManager()->findCommand(name); +} + +QScriptDebuggerConsoleCommandList QScriptDebuggerConsoleGlobalObject::getCommandsInGroup(const QString &name) const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->commandManager()->commandsInGroup(name); +} + +QStringList QScriptDebuggerConsoleGlobalObject::getCommandCompletions(const QString &prefix) const +{ + Q_D(const QScriptDebuggerConsoleGlobalObject); + return d->console->commandManager()->completions(prefix); +} + +bool QScriptDebuggerConsoleGlobalObject::checkSyntax(const QString &program) +{ +#if QT_VERSION >= 0x040500 + return (QScriptEngine::checkSyntax(program).state() == QScriptSyntaxCheckResult::Valid); +#else + Q_UNUSED(program); + return true; +#endif +} + +void QScriptDebuggerConsoleGlobalObject::setEvaluateAction(int action) +{ + Q_D(QScriptDebuggerConsoleGlobalObject); + d->console->setEvaluateAction(action); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject_p.h b/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject_p.h new file mode 100644 index 0000000..b14e6c0 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject_p.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLEGLOBALOBJECT_P_H +#define QSCRIPTDEBUGGERCONSOLEGLOBALOBJECT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> + +#include <QtCore/qstringlist.h> + +#include "qscriptdebuggerconsolecommandgroupdata_p.h" +#include "qscriptdebuggerconsolecommand_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerCommandSchedulerInterface; +class QScriptMessageHandlerInterface; +class QScriptDebuggerResponseHandlerInterface; +class QScriptDebuggerConsole; +class QScriptDebuggerValue; +class QScriptDebuggerCommand; +class QScriptBreakpointData; + +class QScriptDebuggerConsoleGlobalObjectPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleGlobalObject + : public QObject +{ + Q_OBJECT +public: + QScriptDebuggerConsoleGlobalObject(QObject *parent = 0); + ~QScriptDebuggerConsoleGlobalObject(); + + QScriptDebuggerCommandSchedulerInterface *scheduler() const; + void setScheduler(QScriptDebuggerCommandSchedulerInterface *scheduler); + + QScriptDebuggerResponseHandlerInterface *responseHandler() const; + void setResponseHandler(QScriptDebuggerResponseHandlerInterface *responseHandler); + + QScriptMessageHandlerInterface *messageHandler() const; + void setMessageHandler(QScriptMessageHandlerInterface *messageHandler); + + QScriptDebuggerConsole *console() const; + void setConsole(QScriptDebuggerConsole *console); + +public Q_SLOTS: + // frontend + int scheduleInterrupt(); + int scheduleContinue(); + int scheduleStepInto(int count = 1); + int scheduleStepOver(int count = 1); + int scheduleStepOut(); + int scheduleRunToLocation(const QString &fileName, int lineNumber); + int scheduleRunToLocation(qint64 scriptId, int lineNumber); + int scheduleForceReturn(int contextIndex, const QScriptDebuggerValue &value); + + int scheduleSetBreakpoint(const QScriptBreakpointData &data); + int scheduleDeleteBreakpoint(int id); + int scheduleDeleteAllBreakpoints(); + int scheduleGetBreakpoints(); + int scheduleGetBreakpointData(int id); + int scheduleSetBreakpointData(int id, const QScriptBreakpointData &data); + + int scheduleGetScripts(); + int scheduleGetScriptData(qint64 id); + int scheduleScriptsCheckpoint(); + int scheduleGetScriptsDelta(); + int scheduleResolveScript(const QString &fileName); + + int scheduleGetBacktrace(); + int scheduleGetThisObject(int contextIndex); + int scheduleGetActivationObject(int contextIndex); + int scheduleGetContextCount(); + int scheduleGetContextInfo(int contextIndex); + + int scheduleNewScriptValueIterator(const QScriptDebuggerValue &object); + int scheduleGetPropertiesByIterator(int id, int count); + int scheduleDeleteScriptValueIterator(int id); + + int scheduleEvaluate(int contextIndex, const QString &program, + const QString &fileName = QString(), + int lineNumber = 1); + + int scheduleScriptValueToString(const QScriptDebuggerValue &value); + + int scheduleClearExceptions(); + + int scheduleCommand(const QScriptDebuggerCommand &command); + + // message handler + void message(const QString &text, const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1); + void warning(const QString &text, const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1); + void error(const QString &text, const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1); + + // console state + int getCurrentFrameIndex() const; + void setCurrentFrameIndex(int index); + qint64 getCurrentScriptId() const; + void setCurrentScriptId(qint64 id); + qint64 getSessionId() const; + int getCurrentLineNumber() const; + void setCurrentLineNumber(int lineNumber); + + // command introspection + QScriptDebuggerConsoleCommandGroupMap getCommandGroups() const; + QScriptDebuggerConsoleCommand *findCommand(const QString &command) const; + QScriptDebuggerConsoleCommandList getCommandsInGroup(const QString &name) const; + QStringList getCommandCompletions(const QString &prefix) const; + + bool checkSyntax(const QString &program); + + void setEvaluateAction(int action); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerConsoleGlobalObject) + Q_DISABLE_COPY(QScriptDebuggerConsoleGlobalObject) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolehistorianinterface_p.h b/src/scripttools/debugging/qscriptdebuggerconsolehistorianinterface_p.h new file mode 100644 index 0000000..6de0a98 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolehistorianinterface_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLEHISTORIANINTERFACE_P_H +#define QSCRIPTDEBUGGERCONSOLEHISTORIANINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QString; + +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleHistorianInterface +{ +public: + virtual ~QScriptDebuggerConsoleHistorianInterface() {} + + virtual int historyCount() const = 0; + virtual QString historyAt(int index) const = 0; + virtual void changeHistoryAt(int index, const QString &newHistory) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolewidget.cpp b/src/scripttools/debugging/qscriptdebuggerconsolewidget.cpp new file mode 100644 index 0000000..479487b --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolewidget.cpp @@ -0,0 +1,444 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsolewidget_p.h" +#include "qscriptdebuggerconsolewidgetinterface_p_p.h" +#include "qscriptdebuggerconsolehistorianinterface_p.h" +#include "qscriptcompletionproviderinterface_p.h" +#include "qscriptcompletiontaskinterface_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qplaintextedit.h> +#include <QtGui/qlabel.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qlistview.h> +#include <QtGui/qscrollbar.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qcompleter.h> + +QT_BEGIN_NAMESPACE + +namespace { + +class PromptLabel : public QLabel +{ +public: + PromptLabel(QWidget *parent = 0) + : QLabel(parent) + { + setFrameShape(QFrame::NoFrame); + setIndent(2); + setMargin(2); + setSizePolicy(QSizePolicy::Minimum, sizePolicy().verticalPolicy()); + setAlignment(Qt::AlignHCenter); +#ifndef QT_NO_STYLE_STYLESHEET + setStyleSheet(QLatin1String("background: white;")); +#endif + } + + QSize sizeHint() const { + QFontMetrics fm(font()); + return fm.size(0, text()) + QSize(8, 0); + } +}; + +class InputEdit : public QLineEdit +{ +public: + InputEdit(QWidget *parent = 0) + : QLineEdit(parent) + { + setFrame(false); + setSizePolicy(QSizePolicy::MinimumExpanding, sizePolicy().verticalPolicy()); + } +}; + +class CommandLine : public QWidget +{ + Q_OBJECT +public: + CommandLine(QWidget *parent = 0) + : QWidget(parent) + { + promptLabel = new PromptLabel(); + inputEdit = new InputEdit(); + QHBoxLayout *hbox = new QHBoxLayout(this); + hbox->setSpacing(0); + hbox->setMargin(0); + hbox->addWidget(promptLabel); + hbox->addWidget(inputEdit); + + QObject::connect(inputEdit, SIGNAL(returnPressed()), + this, SLOT(onReturnPressed())); + QObject::connect(inputEdit, SIGNAL(textEdited(QString)), + this, SIGNAL(lineEdited(QString))); + + setFocusProxy(inputEdit); + } + + QString prompt() const + { + return promptLabel->text(); + } + void setPrompt(const QString &prompt) + { + promptLabel->setText(prompt); + } + + QString input() const + { + return inputEdit->text(); + } + void setInput(const QString &input) + { + inputEdit->setText(input); + } + + int cursorPosition() const + { + return inputEdit->cursorPosition(); + } + void setCursorPosition(int position) + { + inputEdit->setCursorPosition(position); + } + + QWidget *editor() const + { + return inputEdit; + } + +Q_SIGNALS: + void lineEntered(const QString &contents); + void lineEdited(const QString &contents); + +private Q_SLOTS: + void onReturnPressed() + { + QString text = inputEdit->text(); + inputEdit->clear(); + emit lineEntered(text); + } + +private: + PromptLabel *promptLabel; + InputEdit *inputEdit; +}; + +class OutputEdit : public QPlainTextEdit +{ +public: + OutputEdit(QWidget *parent = 0) + : QPlainTextEdit(parent) + { + setFrameShape(QFrame::NoFrame); + setReadOnly(true); +// ### there's no context menu when the edit can't have focus, +// even though you can select text in it. +// setFocusPolicy(Qt::NoFocus); + setMaximumBlockCount(2500); + } + + void scrollToBottom() + { + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); + } + + int charactersPerLine() const + { + QFontMetrics fm(font()); + return width() / fm.maxWidth(); + } +}; + +} // namespace + +class QScriptDebuggerConsoleWidgetPrivate + : public QScriptDebuggerConsoleWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerConsoleWidget) +public: + QScriptDebuggerConsoleWidgetPrivate(); + ~QScriptDebuggerConsoleWidgetPrivate(); + + // private slots + void _q_onLineEntered(const QString &contents); + void _q_onLineEdited(const QString &contents); + void _q_onCompletionTaskFinished(); + + CommandLine *commandLine; + OutputEdit *outputEdit; + int historyIndex; + QString newInput; +}; + +QScriptDebuggerConsoleWidgetPrivate::QScriptDebuggerConsoleWidgetPrivate() +{ + historyIndex = -1; +} + +QScriptDebuggerConsoleWidgetPrivate::~QScriptDebuggerConsoleWidgetPrivate() +{ +} + +void QScriptDebuggerConsoleWidgetPrivate::_q_onLineEntered(const QString &contents) +{ + Q_Q(QScriptDebuggerConsoleWidget); + outputEdit->appendPlainText(QString::fromLatin1("%0 %1").arg(commandLine->prompt()).arg(contents)); + outputEdit->scrollToBottom(); + historyIndex = -1; + newInput.clear(); + emit q->lineEntered(contents); +} + +void QScriptDebuggerConsoleWidgetPrivate::_q_onLineEdited(const QString &contents) +{ + if (historyIndex != -1) { + // ### try to get the bash behavior... +#if 0 + historian->changeHistoryAt(historyIndex, contents); +#endif + } else { + newInput = contents; + } +} + +static bool lengthLessThan(const QString &s1, const QString &s2) +{ + return s1.length() < s2.length(); +} + +// input must be sorted by length already +static QString longestCommonPrefix(const QStringList &lst) +{ + QString result = lst.last(); + for (int i = lst.size() - 2; (i >= 0) && !result.isEmpty(); --i) { + const QString &s = lst.at(i); + int j = 0; + for ( ; (j < qMin(s.length(), result.length())) && (s.at(j) == result.at(j)); ++j) + ; + result = result.left(j); + } + return result; +} + +void QScriptDebuggerConsoleWidgetPrivate::_q_onCompletionTaskFinished() +{ + QScriptCompletionTaskInterface *task = 0; + task = qobject_cast<QScriptCompletionTaskInterface*>(q_func()->sender()); + if (task->resultCount() == 1) { + QString completion = task->resultAt(0); + completion.append(task->appendix()); + QString tmp = commandLine->input(); + tmp.remove(task->position(), task->length()); + tmp.insert(task->position(), completion); + commandLine->setInput(tmp); + } else if (task->resultCount() > 1) { + { + QStringList lst; + for (int i = 0; i < task->resultCount(); ++i) + lst.append(task->resultAt(i).mid(task->length())); + qSort(lst.begin(), lst.end(), lengthLessThan); + QString lcp = longestCommonPrefix(lst); + if (!lcp.isEmpty()) { + QString tmp = commandLine->input(); + tmp.insert(task->position() + task->length(), lcp); + commandLine->setInput(tmp); + } + } + + outputEdit->appendPlainText(QString::fromLatin1("%0 %1") + .arg(commandLine->prompt()).arg(commandLine->input())); + int maxLength = 0; + for (int i = 0; i < task->resultCount(); ++i) + maxLength = qMax(maxLength, task->resultAt(i).length()); + Q_ASSERT(maxLength > 0); + int tab = 8; + int columns = qMax(1, outputEdit->charactersPerLine() / (maxLength + tab)); + QString msg; + for (int i = 0; i < task->resultCount(); ++i) { + if (i != 0) { + if ((i % columns) == 0) { + outputEdit->appendPlainText(msg); + msg.clear(); + } else { + int pad = maxLength + tab - (msg.length() % (maxLength + tab)); + msg.append(QString(pad, QLatin1Char(' '))); + } + } + msg.append(task->resultAt(i)); + } + if (!msg.isEmpty()) + outputEdit->appendPlainText(msg); + outputEdit->scrollToBottom(); + } + task->deleteLater(); +} + +QScriptDebuggerConsoleWidget::QScriptDebuggerConsoleWidget(QWidget *parent) + : QScriptDebuggerConsoleWidgetInterface(*new QScriptDebuggerConsoleWidgetPrivate, parent, 0) +{ + Q_D(QScriptDebuggerConsoleWidget); + d->commandLine = new CommandLine(); + d->commandLine->setPrompt(QString::fromLatin1("qsdb>")); + d->outputEdit = new OutputEdit(); + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setSpacing(0); + vbox->setMargin(0); + vbox->addWidget(d->outputEdit); + vbox->addWidget(d->commandLine); + +#if 0 + QString sheet = QString::fromLatin1("background-color: black;" + "color: aquamarine;" + "font-size: 14px;" + "font-family: \"Monospace\""); +#endif +#ifndef QT_NO_STYLE_STYLESHEET + QString sheet = QString::fromLatin1("font-size: 14px; font-family: \"Monospace\";"); + setStyleSheet(sheet); +#endif + + QObject::connect(d->commandLine, SIGNAL(lineEntered(QString)), + this, SLOT(_q_onLineEntered(QString))); + QObject::connect(d->commandLine, SIGNAL(lineEdited(QString)), + this, SLOT(_q_onLineEdited(QString))); +} + +QScriptDebuggerConsoleWidget::~QScriptDebuggerConsoleWidget() +{ +} + +void QScriptDebuggerConsoleWidget::message( + QtMsgType type, const QString &text, const QString &fileName, + int lineNumber, int columnNumber, const QVariant &/*data*/) +{ + Q_D(QScriptDebuggerConsoleWidget); + QString msg; + if (!fileName.isEmpty() || (lineNumber != -1)) { + if (!fileName.isEmpty()) + msg.append(fileName); + else + msg.append(QLatin1String("<noname>")); + if (lineNumber != -1) { + msg.append(QLatin1Char(':')); + msg.append(QString::number(lineNumber)); + if (columnNumber != -1) { + msg.append(QLatin1Char(':')); + msg.append(QString::number(columnNumber)); + } + } + msg.append(QLatin1String(": ")); + } + msg.append(text); + QTextCharFormat oldFmt = d->outputEdit->currentCharFormat(); + QTextCharFormat fmt(oldFmt); + if (type == QtCriticalMsg) { + fmt.setForeground(Qt::red); + d->outputEdit->setCurrentCharFormat(fmt); + } + d->outputEdit->appendPlainText(msg); + d->outputEdit->setCurrentCharFormat(oldFmt); + d->outputEdit->scrollToBottom(); +} + +void QScriptDebuggerConsoleWidget::setLineContinuationMode(bool enabled) +{ + Q_D(QScriptDebuggerConsoleWidget); + QString prompt = enabled + ? QString::fromLatin1("....") + : QString::fromLatin1("qsdb>"); + d->commandLine->setPrompt(prompt); +} + +void QScriptDebuggerConsoleWidget::clear() +{ + Q_D(QScriptDebuggerConsoleWidget); + d->outputEdit->clear(); +} + +void QScriptDebuggerConsoleWidget::keyPressEvent(QKeyEvent *event) +{ + Q_D(QScriptDebuggerConsoleWidget); + if (event->key() == Qt::Key_Up) { + if (d->historyIndex+1 == d->historian->historyCount()) + return; + QString cmd = d->historian->historyAt(++d->historyIndex); + d->commandLine->setInput(cmd); + } else if (event->key() == Qt::Key_Down) { + if (d->historyIndex == -1) { + // nothing to do + } else if (d->historyIndex == 0) { + d->commandLine->setInput(d->newInput); + --d->historyIndex; + } else { + QString cmd = d->historian->historyAt(--d->historyIndex); + d->commandLine->setInput(cmd); + } + } else if (event->key() == Qt::Key_Tab) { + QScriptCompletionTaskInterface *task = 0; + task = d->completionProvider->createCompletionTask( + d->commandLine->input(), d->commandLine->cursorPosition(), + /*frameIndex=*/-1, // current frame + QScriptCompletionProviderInterface::ConsoleCommandCompletion); + QObject::connect(task, SIGNAL(finished()), + this, SLOT(_q_onCompletionTaskFinished())); + task->start(); + } else { + QScriptDebuggerConsoleWidgetInterface::keyPressEvent(event); + } +} + +bool QScriptDebuggerConsoleWidget::focusNextPrevChild(bool b) +{ + Q_D(QScriptDebuggerConsoleWidget); + if (d->outputEdit->hasFocus()) + return QScriptDebuggerConsoleWidgetInterface::focusNextPrevChild(b); + else + return false; +} + +QT_END_NAMESPACE + +#include "qscriptdebuggerconsolewidget.moc" + +#include "moc_qscriptdebuggerconsolewidget_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebuggerconsolewidget_p.h b/src/scripttools/debugging/qscriptdebuggerconsolewidget_p.h new file mode 100644 index 0000000..4fc1290 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolewidget_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLEWIDGET_P_H +#define QSCRIPTDEBUGGERCONSOLEWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerconsolewidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsoleWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleWidget: + public QScriptDebuggerConsoleWidgetInterface +{ + Q_OBJECT +public: + QScriptDebuggerConsoleWidget(QWidget *parent = 0); + ~QScriptDebuggerConsoleWidget(); + + void message(QtMsgType type, const QString &text, + const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1, + const QVariant &data = QVariant()); + + void setLineContinuationMode(bool enabled); + + void clear(); + +protected: + void keyPressEvent(QKeyEvent *event); + bool focusNextPrevChild(bool); + +protected: + QScriptDebuggerConsoleWidget( + QScriptDebuggerConsoleWidgetPrivate &dd, + QWidget *parent); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerConsoleWidget) + Q_DISABLE_COPY(QScriptDebuggerConsoleWidget) + + Q_PRIVATE_SLOT(d_func(), void _q_onLineEntered(const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_onLineEdited(const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_onCompletionTaskFinished()) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface.cpp b/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface.cpp new file mode 100644 index 0000000..071bae6 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerconsolewidgetinterface_p.h" +#include "qscriptdebuggerconsolewidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerConsoleWidgetInterfacePrivate::QScriptDebuggerConsoleWidgetInterfacePrivate() +{ + historian = 0; + completionProvider = 0; +} + +QScriptDebuggerConsoleWidgetInterfacePrivate::~QScriptDebuggerConsoleWidgetInterfacePrivate() +{ +} + +QScriptDebuggerConsoleWidgetInterface::~QScriptDebuggerConsoleWidgetInterface() +{ +} + +QScriptDebuggerConsoleWidgetInterface::QScriptDebuggerConsoleWidgetInterface( + QScriptDebuggerConsoleWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QScriptDebuggerConsoleHistorianInterface *QScriptDebuggerConsoleWidgetInterface::commandHistorian() const +{ + Q_D(const QScriptDebuggerConsoleWidgetInterface); + return d->historian; +} + +void QScriptDebuggerConsoleWidgetInterface::setCommandHistorian( + QScriptDebuggerConsoleHistorianInterface *historian) +{ + Q_D(QScriptDebuggerConsoleWidgetInterface); + d->historian = historian; +} + +QScriptCompletionProviderInterface *QScriptDebuggerConsoleWidgetInterface::completionProvider() const +{ + Q_D(const QScriptDebuggerConsoleWidgetInterface); + return d->completionProvider; +} + +void QScriptDebuggerConsoleWidgetInterface::setCompletionProvider( + QScriptCompletionProviderInterface *completionProvider) +{ + Q_D(QScriptDebuggerConsoleWidgetInterface); + d->completionProvider = completionProvider; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface_p.h b/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface_p.h new file mode 100644 index 0000000..6cfe8be --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLEWIDGETINTERFACE_P_H +#define QSCRIPTDEBUGGERCONSOLEWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +#include "qscriptmessagehandlerinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsoleHistorianInterface; +class QScriptCompletionProviderInterface; + +class QScriptDebuggerConsoleWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerConsoleWidgetInterface: + public QWidget, + public QScriptMessageHandlerInterface +{ + Q_OBJECT +public: + enum InputMode { + NormalInputMode, + PartialInputMode + }; + + ~QScriptDebuggerConsoleWidgetInterface(); + + QScriptDebuggerConsoleHistorianInterface *commandHistorian() const; + void setCommandHistorian(QScriptDebuggerConsoleHistorianInterface *historian); + + QScriptCompletionProviderInterface *completionProvider() const; + void setCompletionProvider(QScriptCompletionProviderInterface *completionProvider); + + virtual void setLineContinuationMode(bool enabled) = 0; + + virtual void clear() = 0; + +Q_SIGNALS: + void lineEntered(const QString &contents); + +protected: + QScriptDebuggerConsoleWidgetInterface(QScriptDebuggerConsoleWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerConsoleWidgetInterface) + Q_DISABLE_COPY(QScriptDebuggerConsoleWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface_p_p.h b/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface_p_p.h new file mode 100644 index 0000000..2dca798 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerconsolewidgetinterface_p_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERCONSOLEWIDGETINTERFACE_P_P_H +#define QSCRIPTDEBUGGERCONSOLEWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerConsoleHistorianInterface; +class QScriptCompletionProviderInterface; + +class QScriptDebuggerConsoleWidgetInterface; +class QScriptDebuggerConsoleWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerConsoleWidgetInterface) +public: + QScriptDebuggerConsoleWidgetInterfacePrivate(); + ~QScriptDebuggerConsoleWidgetInterfacePrivate(); + + QScriptDebuggerConsoleHistorianInterface *historian; + QScriptCompletionProviderInterface *completionProvider; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerevent.cpp b/src/scripttools/debugging/qscriptdebuggerevent.cpp new file mode 100644 index 0000000..9d971a9 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerevent.cpp @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerevent_p.h" +#include "qscriptdebuggervalue_p.h" + +#include <QtCore/qhash.h> +#include <QtCore/qdatastream.h> + +Q_DECLARE_METATYPE(QScriptDebuggerValue) + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerEventPrivate +{ +public: + QScriptDebuggerEventPrivate(); + ~QScriptDebuggerEventPrivate(); + + QScriptDebuggerEvent::Type type; + QHash<QScriptDebuggerEvent::Attribute, QVariant> attributes; +}; + +QScriptDebuggerEventPrivate::QScriptDebuggerEventPrivate() +{ +} + +QScriptDebuggerEventPrivate::~QScriptDebuggerEventPrivate() +{ +} + +QScriptDebuggerEvent::QScriptDebuggerEvent() + : d_ptr(new QScriptDebuggerEventPrivate) +{ + d_ptr->type = None; +} + +QScriptDebuggerEvent::QScriptDebuggerEvent(Type type) + : d_ptr(new QScriptDebuggerEventPrivate) +{ + d_ptr->type = type; +} + +QScriptDebuggerEvent::QScriptDebuggerEvent(Type type, qint64 scriptId, + int lineNumber, int columnNumber) + : d_ptr(new QScriptDebuggerEventPrivate) +{ + d_ptr->type = type; + d_ptr->attributes[ScriptID] = scriptId; + d_ptr->attributes[LineNumber] = lineNumber; + d_ptr->attributes[ColumnNumber] = columnNumber; +} + +QScriptDebuggerEvent::QScriptDebuggerEvent(const QScriptDebuggerEvent &other) + : d_ptr(new QScriptDebuggerEventPrivate) +{ + *d_ptr = *other.d_ptr; +} + +QScriptDebuggerEvent::~QScriptDebuggerEvent() +{ + delete d_ptr; +} + +QScriptDebuggerEvent &QScriptDebuggerEvent::operator=(const QScriptDebuggerEvent &other) +{ + *d_ptr = *other.d_ptr; + return *this; +} + +QScriptDebuggerEvent::Type QScriptDebuggerEvent::type() const +{ + Q_D(const QScriptDebuggerEvent); + return d->type; +} + +QVariant QScriptDebuggerEvent::attribute(Attribute attribute, + const QVariant &defaultValue) const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(attribute, defaultValue); +} + +void QScriptDebuggerEvent::setAttribute(Attribute attribute, + const QVariant &value) +{ + Q_D(QScriptDebuggerEvent); + if (!value.isValid()) + d->attributes.remove(attribute); + else + d->attributes[attribute] = value; +} + +QHash<QScriptDebuggerEvent::Attribute, QVariant> QScriptDebuggerEvent::attributes() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes; +} + +qint64 QScriptDebuggerEvent::scriptId() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(ScriptID, -1).toLongLong(); +} + +void QScriptDebuggerEvent::setScriptId(qint64 id) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[ScriptID] = id; +} + +QString QScriptDebuggerEvent::fileName() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(FileName).toString(); +} + +void QScriptDebuggerEvent::setFileName(const QString &fileName) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[FileName] = fileName; +} + +int QScriptDebuggerEvent::lineNumber() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(LineNumber, -1).toInt(); +} + +void QScriptDebuggerEvent::setLineNumber(int lineNumber) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[LineNumber] = lineNumber; +} + +int QScriptDebuggerEvent::columnNumber() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(ColumnNumber, -1).toInt(); +} + +void QScriptDebuggerEvent::setColumnNumber(int columnNumber) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[ColumnNumber] = columnNumber; +} + +int QScriptDebuggerEvent::breakpointId() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(BreakpointID, -1).toInt(); +} + +void QScriptDebuggerEvent::setBreakpointId(int id) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[BreakpointID] = id; +} + +QString QScriptDebuggerEvent::message() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(Message).toString(); +} + +void QScriptDebuggerEvent::setMessage(const QString &message) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[Message] = message; +} + +QScriptDebuggerValue QScriptDebuggerEvent::scriptValue() const +{ + Q_D(const QScriptDebuggerEvent); + return qvariant_cast<QScriptDebuggerValue>(d->attributes[Value]); +} + +void QScriptDebuggerEvent::setScriptValue(const QScriptDebuggerValue &value) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[Value] = qVariantFromValue(value); +} + +void QScriptDebuggerEvent::setNestedEvaluate(bool nested) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[IsNestedEvaluate] = nested; +} + +bool QScriptDebuggerEvent::isNestedEvaluate() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(IsNestedEvaluate).toBool(); +} + +void QScriptDebuggerEvent::setHasExceptionHandler(bool hasHandler) +{ + Q_D(QScriptDebuggerEvent); + d->attributes[HasExceptionHandler] = hasHandler; +} + +bool QScriptDebuggerEvent::hasExceptionHandler() const +{ + Q_D(const QScriptDebuggerEvent); + return d->attributes.value(HasExceptionHandler).toBool(); +} + +/*! + Returns true if this QScriptDebuggerEvent is equal to the \a other + event, otherwise returns false. +*/ +bool QScriptDebuggerEvent::operator==(const QScriptDebuggerEvent &other) const +{ + Q_D(const QScriptDebuggerEvent); + const QScriptDebuggerEventPrivate *od = other.d_func(); + if (d == od) + return true; + if (!d || !od) + return false; + return ((d->type == od->type) + && (d->attributes == od->attributes)); +} + +/*! + Returns true if this QScriptDebuggerEvent is not equal to the \a + other event, otherwise returns false. +*/ +bool QScriptDebuggerEvent::operator!=(const QScriptDebuggerEvent &other) const +{ + return !(*this == other); +} + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QScriptDebuggerEvent &event) + \relates QScriptDebuggerEvent + + Writes the given \a event to the specified \a stream. +*/ +QDataStream &operator<<(QDataStream &out, const QScriptDebuggerEvent &event) +{ + const QScriptDebuggerEventPrivate *d = event.d_ptr; + out << (quint32)d->type; + out << (qint32)d->attributes.size(); + QHash<QScriptDebuggerEvent::Attribute, QVariant>::const_iterator it; + for (it = d->attributes.constBegin(); it != d->attributes.constEnd(); ++it) { + out << (quint32)it.key(); + out << it.value(); + } + return out; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QScriptDebuggerEvent &event) + \relates QScriptDebuggerEvent + + Reads a QScriptDebuggerEvent from the specified \a stream into the + given \a event. +*/ +QDataStream &operator>>(QDataStream &in, QScriptDebuggerEvent &event) +{ + QScriptDebuggerEventPrivate *d = event.d_ptr; + + quint32 type; + in >> type; + d->type = QScriptDebuggerEvent::Type(type); + + qint32 attribCount; + in >> attribCount; + QHash<QScriptDebuggerEvent::Attribute, QVariant> attribs; + for (qint32 i = 0; i < attribCount; ++i) { + quint32 key; + in >> key; + QVariant value; + in >> value; + attribs[QScriptDebuggerEvent::Attribute(key)] = value; + } + d->attributes = attribs; + + return in; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerevent_p.h b/src/scripttools/debugging/qscriptdebuggerevent_p.h new file mode 100644 index 0000000..d9c073c --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerevent_p.h @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGEREVENT_P_H +#define QSCRIPTDEBUGGEREVENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qhash.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_NAMESPACE + +class QDataStream; +class QScriptDebuggerValue; + +class QScriptDebuggerEventPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerEvent +{ +public: + friend Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerEvent &); + friend Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerEvent &); + + enum Type { + None, + Interrupted, + SteppingFinished, + LocationReached, + Breakpoint, + Exception, + Trace, + InlineEvalFinished, + DebuggerInvocationRequest, + ForcedReturn, + UserEvent = 1000, + MaxUserEvent = 32767 + }; + + enum Attribute { + ScriptID, + FileName, + BreakpointID, + LineNumber, + ColumnNumber, + Value, + Message, + IsNestedEvaluate, + HasExceptionHandler, + UserAttribute = 1000, + MaxUserAttribute = 32767 + }; + + QScriptDebuggerEvent(); + QScriptDebuggerEvent(Type type); + QScriptDebuggerEvent(Type type, qint64 scriptId, int lineNumber, int columnNumber); + QScriptDebuggerEvent(const QScriptDebuggerEvent &other); + ~QScriptDebuggerEvent(); + + Type type() const; + + QVariant attribute(Attribute attribute, + const QVariant &defaultValue = QVariant()) const; + void setAttribute(Attribute attribute, const QVariant &value); + QHash<Attribute, QVariant> attributes() const; + + qint64 scriptId() const; + void setScriptId(qint64 id); + QString fileName() const; + void setFileName(const QString &fileName); + int lineNumber() const; + void setLineNumber(int lineNumber); + int columnNumber() const; + void setColumnNumber(int columnNumber); + int breakpointId() const; + void setBreakpointId(int id); + QString message() const; + void setMessage(const QString &message); + QScriptDebuggerValue scriptValue() const; + void setScriptValue(const QScriptDebuggerValue &value); + void setNestedEvaluate(bool nested); + bool isNestedEvaluate() const; + void setHasExceptionHandler(bool hasHandler); + bool hasExceptionHandler() const; + + QScriptDebuggerEvent &operator=(const QScriptDebuggerEvent &other); + + bool operator==(const QScriptDebuggerEvent &other) const; + bool operator!=(const QScriptDebuggerEvent &other) const; + +private: + QScriptDebuggerEventPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptDebuggerEvent) +}; + +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerEvent &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerEvent &); + +// helper class that's used to transport a debugger event through the Qt event loop +class QScriptDebuggerEventEvent : public QEvent +{ +public: + QScriptDebuggerEventEvent(const QScriptDebuggerEvent &event) + : QEvent(QEvent::Type(QEvent::User+1)), m_event(event) {} + ~QScriptDebuggerEventEvent() {} + const QScriptDebuggerEvent &event() const + { return m_event; } +private: + QScriptDebuggerEvent m_event; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggereventhandlerinterface_p.h b/src/scripttools/debugging/qscriptdebuggereventhandlerinterface_p.h new file mode 100644 index 0000000..612233e --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggereventhandlerinterface_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGEREVENTHANDLERINTERFACE_P_H +#define QSCRIPTDEBUGGEREVENTHANDLERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerEvent; + +class Q_AUTOTEST_EXPORT QScriptDebuggerEventHandlerInterface +{ +public: + virtual ~QScriptDebuggerEventHandlerInterface() {} + + virtual bool debuggerEvent(const QScriptDebuggerEvent &event) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerfrontend.cpp b/src/scripttools/debugging/qscriptdebuggerfrontend.cpp new file mode 100644 index 0000000..ced20b1 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerfrontend.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerfrontend_p.h" +#include "qscriptdebuggerfrontend_p_p.h" +#include "qscriptdebuggercommand_p.h" +#include "qscriptdebuggerevent_p.h" +#include "qscriptdebuggerresponse_p.h" +#include "qscriptdebuggereventhandlerinterface_p.h" +#include "qscriptdebuggerresponsehandlerinterface_p.h" + +#include <QtCore/qcoreevent.h> +#include <QtCore/qcoreapplication.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QScriptDebuggerFrontend + \since 4.5 + \internal + + \brief The QScriptDebuggerFrontend class is the base class of debugger front-ends. +*/ + +// helper class that's used to handle our custom Qt events +class QScriptDebuggerFrontendEventReceiver : public QObject +{ +public: + QScriptDebuggerFrontendEventReceiver(QScriptDebuggerFrontendPrivate *frontend, + QObject *parent = 0); + ~QScriptDebuggerFrontendEventReceiver(); + + bool event(QEvent *); + +private: + QScriptDebuggerFrontendPrivate *m_frontend; +}; + +QScriptDebuggerFrontendEventReceiver::QScriptDebuggerFrontendEventReceiver( + QScriptDebuggerFrontendPrivate *frontend, QObject *parent) + : QObject(parent), m_frontend(frontend) +{ +} + +QScriptDebuggerFrontendEventReceiver::~QScriptDebuggerFrontendEventReceiver() +{ +} + +bool QScriptDebuggerFrontendEventReceiver::event(QEvent *e) +{ + return m_frontend->event(e); +} + + +QScriptDebuggerFrontendPrivate::QScriptDebuggerFrontendPrivate() +{ + eventHandler = 0; + nextCommandId = 0; + eventReceiver = new QScriptDebuggerFrontendEventReceiver(this); +} + +QScriptDebuggerFrontendPrivate::~QScriptDebuggerFrontendPrivate() +{ + delete eventReceiver; +} + +void QScriptDebuggerFrontendPrivate::postEvent(QEvent *e) +{ + QCoreApplication::postEvent(eventReceiver, e); +} + +bool QScriptDebuggerFrontendPrivate::event(QEvent *e) +{ + Q_Q(QScriptDebuggerFrontend); + if (e->type() == QEvent::User+1) { + QScriptDebuggerEventEvent *de = static_cast<QScriptDebuggerEventEvent*>(e); + bool handled = q->notifyEvent(de->event()); + if (handled) { + q->scheduleCommand(QScriptDebuggerCommand::resumeCommand(), + /*responseHandler=*/0); + } + return true; + } else if (e->type() == QEvent::User+2) { + processCommands(); + return true; + } + return false; +} + +void QScriptDebuggerFrontendPrivate::processCommands() +{ + Q_Q(QScriptDebuggerFrontend); + while (!pendingCommands.isEmpty()) { + QScriptDebuggerCommand command(pendingCommands.takeFirst()); + int id = pendingCommandIds.takeFirst(); + q->processCommand(id, command); + } +} + +QScriptDebuggerFrontend::QScriptDebuggerFrontend() + : d_ptr(new QScriptDebuggerFrontendPrivate()) +{ + d_ptr->q_ptr = this; +} + +QScriptDebuggerFrontend::~QScriptDebuggerFrontend() +{ + delete d_ptr; +} + +QScriptDebuggerFrontend::QScriptDebuggerFrontend(QScriptDebuggerFrontendPrivate &dd) + : d_ptr(&dd) +{ + d_ptr->q_ptr = this; +} + +QScriptDebuggerEventHandlerInterface *QScriptDebuggerFrontend::eventHandler() const +{ + Q_D(const QScriptDebuggerFrontend); + return d->eventHandler; +} + +void QScriptDebuggerFrontend::setEventHandler(QScriptDebuggerEventHandlerInterface *eventHandler) +{ + Q_D(QScriptDebuggerFrontend); + d->eventHandler = eventHandler; +} + +/*! + Schedules the given \a command for execution by this front-end, + and returns a unique identifier associated with this command. + + Subclasses can call this function to schedule custom commands. + + \sa notifyCommandFinished() +*/ +int QScriptDebuggerFrontend::scheduleCommand( + const QScriptDebuggerCommand &command, + QScriptDebuggerResponseHandlerInterface *responseHandler) +{ + Q_D(QScriptDebuggerFrontend); + int id = ++d->nextCommandId; + d->pendingCommands.append(command); + d->pendingCommandIds.append(id); + if (responseHandler) + d->responseHandlers.insert(id, responseHandler); + if (d->pendingCommands.size() == 1) { + QEvent *e = new QEvent(QEvent::Type(QEvent::User+2)); // ProcessCommands + d->postEvent(e); + } + return id; +} + +/*! + Subclasses should call this function when the command identified by + the given \a id has finished and produced the given \a response. + + \sa processCommand(), notifyEvent() +*/ +void QScriptDebuggerFrontend::notifyCommandFinished(int id, const QScriptDebuggerResponse &response) +{ + Q_D(QScriptDebuggerFrontend); + if (d->responseHandlers.contains(id)) { + QScriptDebuggerResponseHandlerInterface *handler = d->responseHandlers.take(id); + Q_ASSERT(handler != 0); + handler->handleResponse(response, id); + } +} + +/*! + Subclasses should call this function when the given \a event is + received from the back-end. + + \sa notifyCommandFinished(), QScriptDebuggerBackend::event() +*/ +bool QScriptDebuggerFrontend::notifyEvent(const QScriptDebuggerEvent &event) +{ + Q_D(QScriptDebuggerFrontend); + if (d->eventHandler) + return d->eventHandler->debuggerEvent(event); + return false; +} + +int QScriptDebuggerFrontend::scheduledCommandCount() const +{ + Q_D(const QScriptDebuggerFrontend); + return d->nextCommandId; +} + +/*! + \fn void QScriptDebuggerFrontend::processCommand(int id, const QScriptDebuggerCommand &command) + + Subclasses must reimplement this function to process the given \a command + identified by \a id. Call notifyCommandFinished() when processing is + complete. +*/ + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerfrontend_p.h b/src/scripttools/debugging/qscriptdebuggerfrontend_p.h new file mode 100644 index 0000000..a763463 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerfrontend_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERFRONTEND_P_H +#define QSCRIPTDEBUGGERFRONTEND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qstring.h> + +#include "qscriptdebuggercommandschedulerinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerEventHandlerInterface; +class QScriptDebuggerCommand; +class QScriptDebuggerEvent; +class QScriptDebuggerResponse; + +class QScriptDebuggerFrontendPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerFrontend + : public QScriptDebuggerCommandSchedulerInterface +{ +public: + QScriptDebuggerFrontend(); + virtual ~QScriptDebuggerFrontend(); + + QScriptDebuggerEventHandlerInterface *eventHandler() const; + void setEventHandler(QScriptDebuggerEventHandlerInterface *eventHandler); + + int scheduleCommand(const QScriptDebuggerCommand &command, + QScriptDebuggerResponseHandlerInterface *responseHandler); + + int scheduledCommandCount() const; + +protected: + void notifyCommandFinished(int id, const QScriptDebuggerResponse &response); + bool notifyEvent(const QScriptDebuggerEvent &event); + + virtual void processCommand(int id, const QScriptDebuggerCommand &command) = 0; + +protected: + QScriptDebuggerFrontend(QScriptDebuggerFrontendPrivate &dd); + QScriptDebuggerFrontendPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerFrontend) + Q_DISABLE_COPY(QScriptDebuggerFrontend) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerfrontend_p_p.h b/src/scripttools/debugging/qscriptdebuggerfrontend_p_p.h new file mode 100644 index 0000000..aebcad2 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerfrontend_p_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERFRONTEND_P_P_H +#define QSCRIPTDEBUGGERFRONTEND_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qlist.h> +#include <QtCore/qhash.h> + +#include "qscriptdebuggercommand_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerEventHandlerInterface; +class QScriptDebuggerResponseHandlerInterface; +class QEvent; + +class QScriptDebuggerFrontend; +class QScriptDebuggerFrontendPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerFrontend) +public: + QScriptDebuggerFrontendPrivate(); + virtual ~QScriptDebuggerFrontendPrivate(); + + void postEvent(QEvent *e); + virtual bool event(QEvent *); + void processCommands(); + + QScriptDebuggerEventHandlerInterface *eventHandler; + QList<QScriptDebuggerCommand> pendingCommands; + QList<int> pendingCommandIds; + QHash<int, QScriptDebuggerResponseHandlerInterface*> responseHandlers; + int nextCommandId; + QObject *eventReceiver; + + QScriptDebuggerFrontend *q_ptr; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerjob.cpp b/src/scripttools/debugging/qscriptdebuggerjob.cpp new file mode 100644 index 0000000..109c805 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerjob.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerjob_p.h" +#include "qscriptdebuggerjob_p_p.h" +#include "qscriptdebuggerjobschedulerinterface_p.h" + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QScriptDebuggerJob + \since 4.5 + \internal + + \brief The QScriptDebuggerJob class is the base class of debugger jobs. + +*/ + +QScriptDebuggerJobPrivate::QScriptDebuggerJobPrivate() +{ +} + +QScriptDebuggerJobPrivate::~QScriptDebuggerJobPrivate() +{ +} + +QScriptDebuggerJobPrivate *QScriptDebuggerJobPrivate::get(QScriptDebuggerJob *q) +{ + return q->d_func(); +} + +QScriptDebuggerJob::QScriptDebuggerJob() + : d_ptr(new QScriptDebuggerJobPrivate) +{ + d_ptr->q_ptr = this; + d_ptr->jobScheduler = 0; +} + +QScriptDebuggerJob::QScriptDebuggerJob(QScriptDebuggerJobPrivate &dd) + : d_ptr(&dd) +{ + d_ptr->q_ptr = this; + d_ptr->jobScheduler = 0; +} + +QScriptDebuggerJob::~QScriptDebuggerJob() +{ + delete d_ptr; +} + +void QScriptDebuggerJob::finish() +{ + Q_D(QScriptDebuggerJob); + Q_ASSERT(d->jobScheduler != 0); + d->jobScheduler->finishJob(this); +} + +void QScriptDebuggerJob::hibernateUntilEvaluateFinished() +{ + Q_D(QScriptDebuggerJob); + Q_ASSERT(d->jobScheduler != 0); + d->jobScheduler->hibernateUntilEvaluateFinished(this); +} + +void QScriptDebuggerJob::evaluateFinished(const QScriptDebuggerValue &) +{ + Q_ASSERT_X(false, "QScriptDebuggerJob::evaluateFinished()", + "implement if hibernateUntilEvaluateFinished() is called"); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerjob_p.h b/src/scripttools/debugging/qscriptdebuggerjob_p.h new file mode 100644 index 0000000..e84d6d5 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerjob_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERJOB_P_H +#define QSCRIPTDEBUGGERJOB_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerJobSchedulerInterface; +class QScriptDebuggerValue; + +class QScriptDebuggerJobPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerJob +{ +public: + QScriptDebuggerJob(); + virtual ~QScriptDebuggerJob(); + + virtual void start() = 0; + + void finish(); + + void hibernateUntilEvaluateFinished(); + virtual void evaluateFinished(const QScriptDebuggerValue &result); + +protected: + QScriptDebuggerJob(QScriptDebuggerJobPrivate &dd); + QScriptDebuggerJobPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerJob) + Q_DISABLE_COPY(QScriptDebuggerJob) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerjob_p_p.h b/src/scripttools/debugging/qscriptdebuggerjob_p_p.h new file mode 100644 index 0000000..58d258a --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerjob_p_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERJOB_P_P_H +#define QSCRIPTDEBUGGERJOB_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerJobSchedulerInterface; + +class QScriptDebuggerJob; +class QScriptDebuggerJobPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerJob) +public: + QScriptDebuggerJobPrivate(); + virtual ~QScriptDebuggerJobPrivate(); + + static QScriptDebuggerJobPrivate *get(QScriptDebuggerJob *q); + + QScriptDebuggerJobSchedulerInterface *jobScheduler; + QScriptDebuggerJob *q_ptr; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerjobschedulerinterface_p.h b/src/scripttools/debugging/qscriptdebuggerjobschedulerinterface_p.h new file mode 100644 index 0000000..282e4c0 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerjobschedulerinterface_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERJOBSCHEDULERINTERFACE_P_H +#define QSCRIPTDEBUGGERJOBSCHEDULERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerJob; + +class Q_AUTOTEST_EXPORT QScriptDebuggerJobSchedulerInterface +{ +public: + virtual ~QScriptDebuggerJobSchedulerInterface() {} + + virtual int scheduleJob(QScriptDebuggerJob *job) = 0; + virtual void finishJob(QScriptDebuggerJob *job) = 0; + virtual void hibernateUntilEvaluateFinished(QScriptDebuggerJob *job) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp b/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp new file mode 100644 index 0000000..caeb971 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerlocalsmodel.cpp @@ -0,0 +1,931 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerlocalsmodel_p.h" +#include "qscriptdebuggercommandschedulerjob_p.h" +#include "qscriptdebuggervalue_p.h" +#include "qscriptdebuggerresponse_p.h" +#include "qscriptdebuggerevent_p.h" +#include "qscriptdebuggervalueproperty_p.h" +#include "qscriptdebuggercommandschedulerinterface_p.h" +#include "qscriptdebuggercommandschedulerfrontend_p.h" +#include "qscriptdebuggerjobschedulerinterface_p.h" +#include "qscriptdebuggerobjectsnapshotdelta_p.h" + +#include "private/qabstractitemmodel_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qbrush.h> +#include <QtGui/qfont.h> + +Q_DECLARE_METATYPE(QScriptDebuggerObjectSnapshotDelta) + +QT_BEGIN_NAMESPACE + +struct QScriptDebuggerLocalsModelNode +{ + enum PopulationState { + NotPopulated, + Populating, + Populated + }; + + QScriptDebuggerLocalsModelNode() + : parent(0), populationState(NotPopulated), snapshotId(-1), changed(false) {} + + QScriptDebuggerLocalsModelNode( + const QScriptDebuggerValueProperty &prop, + QScriptDebuggerLocalsModelNode *par) + : property(prop), parent(par), + populationState(NotPopulated), snapshotId(-1), changed(false) + { + parent->children.append(this); + } + + ~QScriptDebuggerLocalsModelNode() { qDeleteAll(children); } + + QScriptDebuggerLocalsModelNode *findChild(const QString &name) + { + for (int i = 0; i < children.size(); ++i) { + QScriptDebuggerLocalsModelNode *child = children.at(i); + if (child->property.name() == name) + return child; + } + return 0; + } + + QScriptDebuggerValueProperty property; + QScriptDebuggerLocalsModelNode *parent; + QList<QScriptDebuggerLocalsModelNode*> children; + PopulationState populationState; + int snapshotId; + bool changed; +}; + +class QScriptDebuggerLocalsModelPrivate + : public QAbstractItemModelPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerLocalsModel) +public: + QScriptDebuggerLocalsModelPrivate(); + ~QScriptDebuggerLocalsModelPrivate(); + + static QScriptDebuggerLocalsModelPrivate *get(QScriptDebuggerLocalsModel *q); + + QModelIndex addTopLevelObject(const QString &name, const QScriptDebuggerValue &object); + + QScriptDebuggerLocalsModelNode *nodeFromIndex(const QModelIndex &index) const; + QModelIndex indexFromNode(QScriptDebuggerLocalsModelNode *node) const; + bool isTopLevelNode(QScriptDebuggerLocalsModelNode *node) const; + + void populateIndex(const QModelIndex &index); + void reallyPopulateIndex(const QModelIndex &index, + const QScriptDebuggerValuePropertyList &props); + void syncIndex(const QModelIndex &index); + void reallySyncIndex(const QModelIndex &index, + const QScriptDebuggerObjectSnapshotDelta &delta); + void syncTopLevelNodes(); + void removeTopLevelNodes(); + void emitScopeObjectAvailable(const QModelIndex &index); + + void emitDataChanged(const QModelIndex &tl, const QModelIndex &br); + void removeChild(const QModelIndex &parentIndex, + QScriptDebuggerLocalsModelNode *parentNode, int row); + void depopulate(QScriptDebuggerLocalsModelNode *node); + void repopulate(QScriptDebuggerLocalsModelNode *node); + void addChildren(const QModelIndex &parentIndex, + QScriptDebuggerLocalsModelNode *parentNode, + const QScriptDebuggerValuePropertyList &props); + + void deleteObjectSnapshots(const QList<qint64> &snapshotIds); + + QScriptDebuggerJobSchedulerInterface *jobScheduler; + QScriptDebuggerCommandSchedulerInterface *commandScheduler; + QScriptDebuggerLocalsModelNode *invisibleRootNode; + int frameIndex; +}; + +QScriptDebuggerLocalsModelPrivate::QScriptDebuggerLocalsModelPrivate() +{ + invisibleRootNode = new QScriptDebuggerLocalsModelNode(); + frameIndex = -1; +} + +QScriptDebuggerLocalsModelPrivate::~QScriptDebuggerLocalsModelPrivate() +{ + delete invisibleRootNode; +} + +void QScriptDebuggerLocalsModelPrivate::emitDataChanged(const QModelIndex &tl, const QModelIndex &br) +{ + q_func()->dataChanged(tl, br); +} + +static QList<qint64> findSnapshotIdsRecursively(QScriptDebuggerLocalsModelNode *root) +{ + QList<qint64> result; + if (root->snapshotId == -1) { + Q_ASSERT(root->children.isEmpty()); + return result; + } + QList<QScriptDebuggerLocalsModelNode*> nodeStack; + nodeStack.append(root); + while (!nodeStack.isEmpty()) { + QScriptDebuggerLocalsModelNode *node = nodeStack.takeFirst(); + result.append(node->snapshotId); + for (int i = 0; i < node->children.count(); ++i) { + QScriptDebuggerLocalsModelNode *child = node->children.at(i); + if (child->snapshotId != -1) + nodeStack.prepend(child); + } + } + return result; +} + +void QScriptDebuggerLocalsModelPrivate::removeChild(const QModelIndex &parentIndex, + QScriptDebuggerLocalsModelNode *parentNode, + int row) +{ + Q_Q(QScriptDebuggerLocalsModel); + q->beginRemoveRows(parentIndex, row, row); + QScriptDebuggerLocalsModelNode *child = parentNode->children.takeAt(row); + QList<qint64> snapshotIds = findSnapshotIdsRecursively(child); + delete child; + q->endRemoveRows(); + deleteObjectSnapshots(snapshotIds); +} + +void QScriptDebuggerLocalsModelPrivate::depopulate(QScriptDebuggerLocalsModelNode *node) +{ + Q_Q(QScriptDebuggerLocalsModel); + bool hasChildren = !node->children.isEmpty(); + if (hasChildren) + q->beginRemoveRows(indexFromNode(node), 0, node->children.count() - 1); + QList<qint64> snapshotIds = findSnapshotIdsRecursively(node); + qDeleteAll(node->children); + node->children.clear(); + node->snapshotId = -1; + node->populationState = QScriptDebuggerLocalsModelNode::NotPopulated; + if (hasChildren) + q->endRemoveRows(); + deleteObjectSnapshots(snapshotIds); +} + +void QScriptDebuggerLocalsModelPrivate::repopulate(QScriptDebuggerLocalsModelNode *node) +{ + if (node->populationState != QScriptDebuggerLocalsModelNode::Populated) + return; + depopulate(node); + if (node->property.value().type() == QScriptDebuggerValue::ObjectValue) + populateIndex(indexFromNode(node)); +} + +void QScriptDebuggerLocalsModelPrivate::addChildren(const QModelIndex &parentIndex, + QScriptDebuggerLocalsModelNode *parentNode, + const QScriptDebuggerValuePropertyList &props) +{ + Q_Q(QScriptDebuggerLocalsModel); + if (props.isEmpty()) + return; + int first = parentNode->children.size(); + int last = first + props.size() - 1; + q->beginInsertRows(parentIndex, first, last); + for (int i = 0; i < props.size(); ++i) + new QScriptDebuggerLocalsModelNode(props.at(i), parentNode); + q->endInsertRows(); +} + +void QScriptDebuggerLocalsModelPrivate::deleteObjectSnapshots(const QList<qint64> &snapshotIds) +{ + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler, 0); + for (int i = 0; i < snapshotIds.size(); ++i) + frontend.scheduleDeleteScriptObjectSnapshot(snapshotIds.at(i)); +} + +QScriptDebuggerLocalsModelPrivate *QScriptDebuggerLocalsModelPrivate::get(QScriptDebuggerLocalsModel *q) +{ + return q->d_func(); +} + +namespace { + +class SetPropertyJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SetPropertyJob(const QPersistentModelIndex &index, + const QString &expression, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_index(index), m_expression(expression), m_state(0) {} + + QScriptDebuggerLocalsModelPrivate *model() const + { + if (!m_index.isValid()) + return 0; + QAbstractItemModel *m = const_cast<QAbstractItemModel*>(m_index.model()); + QScriptDebuggerLocalsModel *lm = qobject_cast<QScriptDebuggerLocalsModel*>(m); + return QScriptDebuggerLocalsModelPrivate::get(lm); + } + + void start() + { + if (!m_index.isValid()) { + // nothing to do, the node has been removed + return; + } + QScriptDebuggerLocalsModelNode *node = model()->nodeFromIndex(m_index); + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleEvaluate(model()->frameIndex, m_expression, + QString::fromLatin1("set property '%0' (%1)") + .arg(node->property.name()) + .arg(QDateTime::currentDateTime().toString())); + } + + void handleResponse(const QScriptDebuggerResponse &, int) + { + switch (m_state) { + case 0: + hibernateUntilEvaluateFinished(); + ++m_state; + break; + case 1: + finish(); + break; + } + } + + void evaluateFinished(const QScriptDebuggerValue &result) + { + if (!m_index.isValid()) { + // nothing to do, the node has been removed + return; + } + QScriptDebuggerLocalsModelNode *node = model()->nodeFromIndex(m_index); + Q_ASSERT(node->parent != 0); + QScriptDebuggerValue object = node->parent->property.value(); + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleSetScriptValueProperty(object, node->property.name(), result); + } + +private: + QPersistentModelIndex m_index; + QString m_expression; + int m_state; +}; + +} // namespace + +QScriptDebuggerLocalsModelNode *QScriptDebuggerLocalsModelPrivate::nodeFromIndex( + const QModelIndex &index) const +{ + if (!index.isValid()) + return invisibleRootNode; + return static_cast<QScriptDebuggerLocalsModelNode*>(index.internalPointer()); +} + +QModelIndex QScriptDebuggerLocalsModelPrivate::indexFromNode( + QScriptDebuggerLocalsModelNode *node) const +{ + if (!node || (node == invisibleRootNode)) + return QModelIndex(); + QScriptDebuggerLocalsModelNode *par = node->parent; + int row = par ? par->children.indexOf(node) : 0; + return createIndex(row, 0, node); +} + +bool QScriptDebuggerLocalsModelPrivate::isTopLevelNode(QScriptDebuggerLocalsModelNode *node) const +{ + return node && (node->parent == invisibleRootNode); +} + +namespace { + +class PopulateModelIndexJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + PopulateModelIndexJob(const QPersistentModelIndex &index, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_index(index), m_state(0) + { } + + QScriptDebuggerLocalsModelPrivate *model() const + { + if (!m_index.isValid()) + return 0; + QAbstractItemModel *m = const_cast<QAbstractItemModel*>(m_index.model()); + QScriptDebuggerLocalsModel *lm = qobject_cast<QScriptDebuggerLocalsModel*>(m); + return QScriptDebuggerLocalsModelPrivate::get(lm); + } + + void start() + { + if (!m_index.isValid()) { + // nothing to do, the node has been removed + return; + } + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleNewScriptObjectSnapshot(); + } + + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + if (!m_index.isValid()) { + // the node has been removed + finish(); + return; + } + switch (m_state) { + case 0: { + QScriptDebuggerLocalsModelNode *node = model()->nodeFromIndex(m_index); + Q_ASSERT(node->populationState == QScriptDebuggerLocalsModelNode::Populating); + node->snapshotId = response.resultAsInt(); + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleScriptObjectSnapshotCapture(node->snapshotId, node->property.value()); + ++m_state; + } break; + case 1: { + QScriptDebuggerObjectSnapshotDelta delta; + delta = qvariant_cast<QScriptDebuggerObjectSnapshotDelta>(response.result()); + Q_ASSERT(delta.removedProperties.isEmpty()); + Q_ASSERT(delta.changedProperties.isEmpty()); + QScriptDebuggerValuePropertyList props = delta.addedProperties; + model()->reallyPopulateIndex(m_index, props); + finish(); + } break; + } + } + +private: + QPersistentModelIndex m_index; + int m_state; +}; + +} // namespace + +void QScriptDebuggerLocalsModelPrivate::populateIndex( + const QModelIndex &index) +{ + if (!index.isValid()) + return; + QScriptDebuggerLocalsModelNode *node = nodeFromIndex(index); + if (node->populationState != QScriptDebuggerLocalsModelNode::NotPopulated) + return; + if (node->property.value().type() != QScriptDebuggerValue::ObjectValue) + return; + node->populationState = QScriptDebuggerLocalsModelNode::Populating; + QScriptDebuggerJob *job = new PopulateModelIndexJob(index, commandScheduler); + jobScheduler->scheduleJob(job); +} + +void QScriptDebuggerLocalsModelPrivate::reallyPopulateIndex( + const QModelIndex &index, + const QScriptDebuggerValuePropertyList &props) +{ + if (!index.isValid()) + return; + QScriptDebuggerLocalsModelNode *node = nodeFromIndex(index); + Q_ASSERT(node->populationState == QScriptDebuggerLocalsModelNode::Populating); + node->populationState = QScriptDebuggerLocalsModelNode::Populated; + addChildren(index, node, props); +} + +QScriptDebuggerLocalsModel::QScriptDebuggerLocalsModel( + QScriptDebuggerJobSchedulerInterface *jobScheduler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler, + QObject *parent) + : QAbstractItemModel(*new QScriptDebuggerLocalsModelPrivate, parent) +{ + Q_D(QScriptDebuggerLocalsModel); + d->jobScheduler = jobScheduler; + d->commandScheduler = commandScheduler; +} + +QScriptDebuggerLocalsModel::~QScriptDebuggerLocalsModel() +{ + Q_D(QScriptDebuggerLocalsModel); + QList<qint64> snapshotIds; + for (int i = 0; i < d->invisibleRootNode->children.count(); ++i) + snapshotIds += findSnapshotIdsRecursively(d->invisibleRootNode->children.at(i)); + QScriptDebuggerCommandSchedulerFrontend frontend(d->commandScheduler, 0); + for (int j = 0; j < snapshotIds.size(); ++j) + frontend.scheduleDeleteScriptObjectSnapshot(snapshotIds.at(j)); +} + +QModelIndex QScriptDebuggerLocalsModelPrivate::addTopLevelObject(const QString &name, const QScriptDebuggerValue &object) +{ + Q_Q(QScriptDebuggerLocalsModel); + QScriptDebuggerLocalsModelNode *node = invisibleRootNode->findChild(name); + if (node) + return indexFromNode(node); + QScriptDebuggerValueProperty prop(name, object, + QString::fromLatin1(""), // ### string representation of object + /*flags=*/0); + int rowIndex = invisibleRootNode->children.size(); + q->beginInsertRows(QModelIndex(), rowIndex, rowIndex); + node = new QScriptDebuggerLocalsModelNode(prop, invisibleRootNode); + q->endInsertRows(); + return indexFromNode(node); +} + +namespace { + +class InitModelJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + InitModelJob(QScriptDebuggerLocalsModelPrivate *model, + int frameIndex, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_model(model), m_frameIndex(frameIndex), m_state(0) + { } + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetScopeChain(m_frameIndex); + } + + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + switch (m_state) { + case 0: { + QScriptDebuggerValueList scopeChain = response.resultAsScriptValueList(); + for (int i = 0; i < scopeChain.size(); ++i) { + const QScriptDebuggerValue &scopeObject = scopeChain.at(i); + QString name = QString::fromLatin1("Scope"); + if (i > 0) + name.append(QString::fromLatin1(" (%0)").arg(i)); + QModelIndex index = m_model->addTopLevelObject(name, scopeObject); + if (i == 0) + m_model->emitScopeObjectAvailable(index); + } + frontend.scheduleGetThisObject(m_frameIndex); + ++m_state; + } break; + case 1: { + QScriptDebuggerValue thisObject = response.resultAsScriptValue(); + m_model->addTopLevelObject(QLatin1String("this"), thisObject); + finish(); + } break; + } + } + +private: + QScriptDebuggerLocalsModelPrivate *m_model; + int m_frameIndex; + int m_state; +}; + +} // namespace + +void QScriptDebuggerLocalsModel::init(int frameIndex) +{ + Q_D(QScriptDebuggerLocalsModel); + d->frameIndex = frameIndex; + QScriptDebuggerJob *job = new InitModelJob(d, frameIndex, d->commandScheduler); + d->jobScheduler->scheduleJob(job); +} + +namespace { + +class SyncModelJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SyncModelJob(QScriptDebuggerLocalsModelPrivate *model, + int frameIndex, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_model(model), m_frameIndex(frameIndex), m_state(0) + { } + + void start() + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + frontend.scheduleGetScopeChain(m_frameIndex); + } + + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + switch (m_state) { + case 0: { + QScriptDebuggerValueList scopeChain = response.resultAsScriptValueList(); + m_topLevelObjects << scopeChain; + frontend.scheduleGetThisObject(m_frameIndex); + ++m_state; + } break; + case 1: { + QScriptDebuggerValue thisObject = response.resultAsScriptValue(); + m_topLevelObjects.append(thisObject); + bool equal = (m_topLevelObjects.size() == m_model->invisibleRootNode->children.size()); + for (int i = 0; equal && (i < m_topLevelObjects.size()); ++i) { + const QScriptDebuggerValue &object = m_topLevelObjects.at(i); + equal = (object == m_model->invisibleRootNode->children.at(i)->property.value()); + } + if (!equal) { + // the scope chain and/or this-object changed, so invalidate the model. + // we could try to be more clever, i.e. figure out + // exactly which objects were popped/pushed + m_model->removeTopLevelNodes(); + for (int j = 0; j < m_topLevelObjects.size(); ++j) { + const QScriptDebuggerValue &object = m_topLevelObjects.at(j); + QString name; + if (j == m_topLevelObjects.size()-1) { + name = QString::fromLatin1("this"); + } else { + name = QString::fromLatin1("Scope"); + if (j > 0) + name.append(QString::fromLatin1(" (%0)").arg(j)); + } + QModelIndex index = m_model->addTopLevelObject(name, object); + if (j == 0) + m_model->emitScopeObjectAvailable(index); + } + } else { + m_model->syncTopLevelNodes(); + } + finish(); + } break; + } + } + +private: + QScriptDebuggerLocalsModelPrivate *m_model; + int m_frameIndex; + int m_state; + QScriptDebuggerValueList m_topLevelObjects; +}; + +} // namespace + +void QScriptDebuggerLocalsModel::sync(int frameIndex) +{ + Q_D(QScriptDebuggerLocalsModel); + d->frameIndex = frameIndex; + QScriptDebuggerJob *job = new SyncModelJob(d, frameIndex, d->commandScheduler); + d->jobScheduler->scheduleJob(job); +} + +namespace { + +class SyncModelIndexJob : public QScriptDebuggerCommandSchedulerJob +{ +public: + SyncModelIndexJob(const QPersistentModelIndex &index, + QScriptDebuggerCommandSchedulerInterface *scheduler) + : QScriptDebuggerCommandSchedulerJob(scheduler), + m_index(index) + { } + + QScriptDebuggerLocalsModelPrivate *model() const + { + if (!m_index.isValid()) + return 0; + QAbstractItemModel *m = const_cast<QAbstractItemModel*>(m_index.model()); + QScriptDebuggerLocalsModel *lm = qobject_cast<QScriptDebuggerLocalsModel*>(m); + return QScriptDebuggerLocalsModelPrivate::get(lm); + } + + void start() + { + if (!m_index.isValid()) { + // nothing to do, the node has been removed + return; + } + QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this); + QScriptDebuggerLocalsModelNode *node = model()->nodeFromIndex(m_index); + frontend.scheduleScriptObjectSnapshotCapture(node->snapshotId, node->property.value()); + } + + void handleResponse(const QScriptDebuggerResponse &response, + int) + { + QScriptDebuggerObjectSnapshotDelta delta; + delta = qvariant_cast<QScriptDebuggerObjectSnapshotDelta>(response.result()); + model()->reallySyncIndex(m_index, delta); + finish(); + } + +private: + QPersistentModelIndex m_index; +}; + +} // namespace + +void QScriptDebuggerLocalsModelPrivate::syncIndex(const QModelIndex &index) +{ + if (!index.isValid()) + return; + QScriptDebuggerLocalsModelNode *node = nodeFromIndex(index); + if (node->populationState != QScriptDebuggerLocalsModelNode::Populated) + return; + QScriptDebuggerJob *job = new SyncModelIndexJob(index, commandScheduler); + jobScheduler->scheduleJob(job); +} + +void QScriptDebuggerLocalsModelPrivate::reallySyncIndex(const QModelIndex &index, + const QScriptDebuggerObjectSnapshotDelta &delta) +{ + if (!index.isValid()) + return; + QScriptDebuggerLocalsModelNode *node = nodeFromIndex(index); + // update or remove existing children + for (int i = 0; i < node->children.count(); ++i) { + QScriptDebuggerLocalsModelNode *child = node->children.at(i); + int j; + for (j = 0; j < delta.changedProperties.count(); ++j) { + if (child->property.name() == delta.changedProperties.at(j).name()) { + child->property = delta.changedProperties.at(j); + child->changed = true; + emitDataChanged(index, index.sibling(0, 1)); + repopulate(child); + break; + } + } + if (j != delta.changedProperties.count()) + continue; // was changed + for (j = 0; j < delta.removedProperties.count(); ++j) { + if (child->property.name() == delta.removedProperties.at(j)) { + removeChild(index, node, i); + --i; + break; + } + } + if (j != delta.removedProperties.count()) + continue; // was removed + // neither changed nor removed, but its children might be + if (child->populationState == QScriptDebuggerLocalsModelNode::Populated) { + QScriptDebuggerJob *job = new SyncModelIndexJob(indexFromNode(child), commandScheduler); + jobScheduler->scheduleJob(job); + } + } + addChildren(index, node, delta.addedProperties); +} + +void QScriptDebuggerLocalsModelPrivate::syncTopLevelNodes() +{ + Q_Q(QScriptDebuggerLocalsModel); + for (int i = 0; i < invisibleRootNode->children.count(); ++i) { + QModelIndex index = q->index(i, 0, QModelIndex()); + syncIndex(index); + if (i == 0) + emit q->scopeObjectAvailable(index); + } +} + +void QScriptDebuggerLocalsModelPrivate::removeTopLevelNodes() +{ + while (!invisibleRootNode->children.isEmpty()) + removeChild(QModelIndex(), invisibleRootNode, 0); +} + +void QScriptDebuggerLocalsModelPrivate::emitScopeObjectAvailable(const QModelIndex &index) +{ + emit q_func()->scopeObjectAvailable(index); +} + +int QScriptDebuggerLocalsModel::frameIndex() const +{ + Q_D(const QScriptDebuggerLocalsModel); + return d->frameIndex; +} + +/*! + \reimp +*/ +QModelIndex QScriptDebuggerLocalsModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_D(const QScriptDebuggerLocalsModel); + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(parent); + if ((row < 0) || (row >= node->children.count())) + return QModelIndex(); + return createIndex(row, column, node->children.at(row)); +} + +/*! + \reimp +*/ +QModelIndex QScriptDebuggerLocalsModel::parent(const QModelIndex &index) const +{ + Q_D(const QScriptDebuggerLocalsModel); + if (!index.isValid()) + return QModelIndex(); + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(index); + return d->indexFromNode(node->parent); +} + +/*! + \reimp +*/ +int QScriptDebuggerLocalsModel::columnCount(const QModelIndex &) const +{ + return 2; +} + +/*! + \reimp +*/ +int QScriptDebuggerLocalsModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const QScriptDebuggerLocalsModel); + // ### need this to make it work with a sortfilterproxymodel (QSFPM is too eager) + const_cast<QScriptDebuggerLocalsModel*>(this)->fetchMore(parent); + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(parent); + return node ? node->children.count() : 0; +} + +/*! + \reimp +*/ +QVariant QScriptDebuggerLocalsModel::data(const QModelIndex &index, int role) const +{ + Q_D(const QScriptDebuggerLocalsModel); + if (!index.isValid()) + return QVariant(); + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(index); + if (role == Qt::DisplayRole) { + if (index.column() == 0) + return node->property.name(); + else if (index.column() == 1) { + QString str = node->property.valueAsString(); + if (str.indexOf(QLatin1Char('\n')) != -1) { + QStringList lines = str.split(QLatin1Char('\n')); + int lineCount = lines.size(); + if (lineCount > 1) { + lines = lines.mid(0, 1); + lines.append(QString::fromLatin1("(... %0 more lines ...)").arg(lineCount - 1)); + } + str = lines.join(QLatin1String("\n")); + } + return str; + } + } else if (role == Qt::EditRole) { + if ((index.column() == 1) && !d->isTopLevelNode(node)) { + QString str = node->property.valueAsString(); + if (node->property.value().type() == QScriptDebuggerValue::StringValue) { + // escape + str.replace(QLatin1String("\""), QLatin1String("\\\"")); + str.prepend(QLatin1Char('\"')); + str.append(QLatin1Char('\"')); + } + return str; + } + } else if (role == Qt::ToolTipRole) { + if (index.column() == 1) { + QString str = node->property.valueAsString(); + if (str.indexOf(QLatin1Char('\n')) != -1) + return str; + } + } + // ### do this in the delegate + else if (role == Qt::BackgroundRole) { + if (d->isTopLevelNode(node)) + return QBrush(Qt::darkGray); + } else if (role == Qt::TextColorRole) { + if (d->isTopLevelNode(node)) + return QColor(Qt::white); + } else if (role == Qt::FontRole) { + if (d->isTopLevelNode(node) || node->changed) { + QFont fnt; + fnt.setBold(true); + return fnt; + } + } + return QVariant(); +} + +/*! + \reimp +*/ +bool QScriptDebuggerLocalsModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_D(QScriptDebuggerLocalsModel); + if (!index.isValid()) + return false; + if (role != Qt::EditRole) + return false; + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(index); + if (!node) + return false; + QString expr = value.toString().trimmed(); + if (expr.isEmpty()) + return false; + QScriptDebuggerJob *job = new SetPropertyJob(index, expr, d->commandScheduler); + d->jobScheduler->scheduleJob(job); + return true; +} + +/*! + \reimp +*/ +QVariant QScriptDebuggerLocalsModel::headerData(int section, Qt::Orientation orient, int role) const +{ + if (orient == Qt::Horizontal) { + if (role == Qt::DisplayRole) { + if (section == 0) + return QObject::tr("Name"); + else if (section == 1) + return QObject::tr("Value"); + } + } + return QVariant(); +} + +/*! + \reimp +*/ +Qt::ItemFlags QScriptDebuggerLocalsModel::flags(const QModelIndex &index) const +{ + Q_D(const QScriptDebuggerLocalsModel); + if (!index.isValid()) + return 0; + Qt::ItemFlags ret = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if ((index.column() == 1) && index.parent().isValid()) { + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(index); + if (!(node->property.flags() & QScriptValue::ReadOnly)) + ret |= Qt::ItemIsEditable; + } + return ret; +} + +/*! + \reimp +*/ +bool QScriptDebuggerLocalsModel::hasChildren(const QModelIndex &parent) const +{ + Q_D(const QScriptDebuggerLocalsModel); + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(parent); + if (!node) + return false; + return !node->children.isEmpty() + || ((node->property.value().type() == QScriptDebuggerValue::ObjectValue) + && (node->populationState == QScriptDebuggerLocalsModelNode::NotPopulated)); +} + +/*! + \reimp +*/ +bool QScriptDebuggerLocalsModel::canFetchMore(const QModelIndex &parent) const +{ + Q_D(const QScriptDebuggerLocalsModel); + if (!parent.isValid()) + return false; + QScriptDebuggerLocalsModelNode *node = d->nodeFromIndex(parent); + return node + && (node->property.value().type() == QScriptDebuggerValue::ObjectValue) + && (node->populationState == QScriptDebuggerLocalsModelNode::NotPopulated); +} + +/*! + \reimp +*/ +void QScriptDebuggerLocalsModel::fetchMore(const QModelIndex &parent) +{ + Q_D(QScriptDebuggerLocalsModel); + d->populateIndex(parent); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerlocalsmodel_p.h b/src/scripttools/debugging/qscriptdebuggerlocalsmodel_p.h new file mode 100644 index 0000000..fc75aa3 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerlocalsmodel_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERLOCALSMODEL_P_H +#define QSCRIPTDEBUGGERLOCALSMODEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qabstractitemmodel.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerValue; +class QScriptDebuggerJobSchedulerInterface; +class QScriptDebuggerCommandSchedulerInterface; + +class QScriptDebuggerLocalsModelPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerLocalsModel + : public QAbstractItemModel +{ + Q_OBJECT +public: + QScriptDebuggerLocalsModel(QScriptDebuggerJobSchedulerInterface *jobScheduler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler, + QObject *parent = 0); + ~QScriptDebuggerLocalsModel(); + + void init(int frameIndex); + void sync(int frameIndex); + + int frameIndex() const; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + int columnCount(const QModelIndex &parent) const; + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation, int role = Qt::DisplayRole) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool hasChildren(const QModelIndex &parent) const; + bool canFetchMore(const QModelIndex &parent) const; + void fetchMore(const QModelIndex &parent); + +Q_SIGNALS: + void scopeObjectAvailable(const QModelIndex &index); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerLocalsModel) + Q_DISABLE_COPY(QScriptDebuggerLocalsModel) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp b/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp new file mode 100644 index 0000000..a4919be --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp @@ -0,0 +1,429 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerlocalswidget_p.h" +#include "qscriptdebuggerlocalswidgetinterface_p_p.h" +#include "qscriptdebuggerlocalsmodel_p.h" +#include "qscriptcompletionproviderinterface_p.h" +#include "qscriptcompletiontaskinterface_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qheaderview.h> +#include <QtGui/qcompleter.h> +#include <QtGui/qstringlistmodel.h> +#include <QtGui/qtreeview.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qsortfilterproxymodel.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qstyleditemdelegate.h> +#include <QtGui/qevent.h> +#include <QtGui/qmessagebox.h> +#include <QtScript/qscriptengine.h> + +QT_BEGIN_NAMESPACE + +namespace { + +class CustomProxyModel : public QSortFilterProxyModel +{ +public: + CustomProxyModel(QObject *parent = 0) + : QSortFilterProxyModel(parent) {} + + bool hasChildren(const QModelIndex &parent) const + { + QModelIndex sourceParent = mapToSource(parent); + if (parent.isValid() && !sourceParent.isValid()) + return false; + return sourceModel()->hasChildren(sourceParent); + } +}; + +} // namespace + +class QScriptDebuggerLocalsWidgetPrivate + : public QScriptDebuggerLocalsWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerLocalsWidget) +public: + QScriptDebuggerLocalsWidgetPrivate(); + ~QScriptDebuggerLocalsWidgetPrivate(); + + void complete(QLineEdit *le); + + // private slots + void _q_onCompletionTaskFinished(); + void _q_insertCompletion(const QString &text); + void _q_expandIndex(const QModelIndex &index); + + QTreeView *view; + QPointer<QLineEdit> completingEditor; + QCompleter *completer; + CustomProxyModel *proxy; +}; + +QScriptDebuggerLocalsWidgetPrivate::QScriptDebuggerLocalsWidgetPrivate() +{ + completingEditor = 0; + completer = 0; + proxy = 0; +} + +QScriptDebuggerLocalsWidgetPrivate::~QScriptDebuggerLocalsWidgetPrivate() +{ +} + +void QScriptDebuggerLocalsWidgetPrivate::complete(QLineEdit *le) +{ + Q_Q(QScriptDebuggerLocalsWidget); + QScriptCompletionTaskInterface *task = 0; + // ### need to pass the current frame # + task = completionProvider->createCompletionTask( + le->text(), le->cursorPosition(), + q->localsModel()->frameIndex(), /*options=*/0); + QObject::connect(task, SIGNAL(finished()), + q, SLOT(_q_onCompletionTaskFinished())); + completingEditor = le; + task->start(); +} + +void QScriptDebuggerLocalsWidgetPrivate::_q_onCompletionTaskFinished() +{ + Q_Q(QScriptDebuggerLocalsWidget); + QScriptCompletionTaskInterface *task = 0; + task = qobject_cast<QScriptCompletionTaskInterface*>(q_func()->sender()); + if (!completingEditor) { + task->deleteLater(); + return; + } + + if (task->resultCount() == 1) { + // do the completion right away + QString completion = task->resultAt(0); + completion.append(task->appendix()); + QString tmp = completingEditor->text(); + tmp.remove(task->position(), task->length()); + tmp.insert(task->position(), completion); + completingEditor->setText(tmp); + completingEditor = 0; + } else if (task->resultCount() > 1) { + // popup completion + if (!completer) { + completer = new QCompleter(q); + completer->setCompletionMode(QCompleter::PopupCompletion); + completer->setCaseSensitivity(Qt::CaseSensitive); + completer->setWrapAround(false); + QObject::connect(completer, SIGNAL(activated(QString)), + q, SLOT(_q_insertCompletion(QString))); + } + QStringListModel *model = qobject_cast<QStringListModel*>(completer->model()); + if (!model) { + model = new QStringListModel(q); + completer->setModel(model); + } + QStringList strings; + for (int i = 0; i < task->resultCount(); ++i) + strings.append(task->resultAt(i)); + model->setStringList(strings); + QString prefix = completingEditor->text().mid(task->position(), task->length()); + completer->setCompletionPrefix(prefix); + completingEditor->setCompleter(completer); + // we want to handle the insertion ourselves + QObject::disconnect(completer, 0, completingEditor, 0); + completer->complete(); + } + task->deleteLater(); +} + +void QScriptDebuggerLocalsWidgetPrivate::_q_insertCompletion(const QString &text) +{ + Q_ASSERT(completingEditor != 0); + QString tmp = completingEditor->text(); + tmp.insert(completingEditor->cursorPosition(), text.mid(completer->completionPrefix().length())); + completingEditor->setText(tmp); + completingEditor = 0; +} + +void QScriptDebuggerLocalsWidgetPrivate::_q_expandIndex(const QModelIndex &index) +{ + view->expand(proxy->mapFromSource(index)); +} + +class QScriptDebuggerLocalsItemDelegate + : public QStyledItemDelegate +{ + Q_OBJECT +public: + QScriptDebuggerLocalsItemDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + bool eventFilter(QObject *watched, QEvent *event); + +private Q_SLOTS: + void validateInput(const QString &text) + { + QWidget *editor = qobject_cast<QWidget*>(sender()); + QPalette pal = editor->palette(); + QColor col; +#if QT_VERSION >= 0x040500 + bool ok = (QScriptEngine::checkSyntax(text).state() == QScriptSyntaxCheckResult::Valid); +#else + bool ok = true; +#endif + if (ok) { + col = Qt::white; + } else { + QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax( + text + QLatin1Char('\n')); + if (result.state() == QScriptSyntaxCheckResult::Intermediate) + col = QColor(255, 240, 192); + else + col = QColor(255, 102, 102); + } + pal.setColor(QPalette::Active, QPalette::Base, col); + editor->setPalette(pal); + } + +private: + static const QWidget *widget(const QStyleOptionViewItem &option) + { + if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option)) + return v3->widget; + return 0; + } +}; + +QScriptDebuggerLocalsItemDelegate::QScriptDebuggerLocalsItemDelegate( + QObject *parent) + : QStyledItemDelegate(parent) +{ +} + +QWidget *QScriptDebuggerLocalsItemDelegate::createEditor( + QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index); + if (index.column() == 1) { + // value + QLineEdit *le = qobject_cast<QLineEdit*>(editor); + if (le) { + QObject::connect(le, SIGNAL(textEdited(QString)), + this, SLOT(validateInput(QString))); + } + } + return editor; +} + +bool QScriptDebuggerLocalsItemDelegate::eventFilter(QObject *watched, QEvent *event) +{ + QLineEdit *le = qobject_cast<QLineEdit*>(watched); + if (!le) + return QStyledItemDelegate::eventFilter(watched, event); + + QScriptDebuggerLocalsWidget *localsWidget = qobject_cast<QScriptDebuggerLocalsWidget*>(parent()); + Q_ASSERT(localsWidget != 0); + QScriptDebuggerLocalsWidgetPrivate *lvp = + reinterpret_cast<QScriptDebuggerLocalsWidgetPrivate*>( + QScriptDebuggerLocalsWidgetPrivate::get(localsWidget)); + + if ((event->type() == QEvent::FocusIn) && lvp->completingEditor) { + // because QLineEdit insists on being difficult... + return true; + } + + if (event->type() != QEvent::KeyPress) + return QStyledItemDelegate::eventFilter(watched, event); + QKeyEvent *ke = static_cast<QKeyEvent*>(event); + if ((ke->key() == Qt::Key_Enter) || (ke->key() == Qt::Key_Return)) { +#if QT_VERSION >= 0x040500 + if (QScriptEngine::checkSyntax(le->text()).state() != QScriptSyntaxCheckResult::Valid) { + // ignore when script contains syntax error + return true; + } +#endif + } + if (ke->key() != Qt::Key_Tab) + return QStyledItemDelegate::eventFilter(watched, event); + + // trigger completion + lvp->complete(le); + return true; +} + +void QScriptDebuggerLocalsItemDelegate::setModelData( + QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ +#if QT_VERSION >= 0x040500 + if (index.column() == 1) { + // check that the syntax is OK + QString expression = qobject_cast<QLineEdit*>(editor)->text(); + if (QScriptEngine::checkSyntax(expression).state() != QScriptSyntaxCheckResult::Valid) + return; + } +#endif + QStyledItemDelegate::setModelData(editor, model, index); +} + +void QScriptDebuggerLocalsItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); +#if 0 + QModelIndex parent = index.parent(); + if (parent.isValid()) { + QStyledItemDelegate::paint(painter, option, index); + } else { + // this is a top-level item. + const QTreeView *view = qobject_cast<const QTreeView*>(widget(option)); + Q_ASSERT(view != 0); + + QStyleOptionButton buttonOption; + + buttonOption.state = option.state; +#ifdef Q_WS_MAC + buttonOption.state |= QStyle::State_Raised; +#endif + buttonOption.state &= ~QStyle::State_HasFocus; + + buttonOption.rect = option.rect; + buttonOption.palette = option.palette; + buttonOption.features = QStyleOptionButton::None; + view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, view); + + QStyleOption branchOption; + static const int i = 9; // ### hardcoded in qcommonstyle.cpp + QRect r = option.rect; + branchOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i); + branchOption.palette = option.palette; + branchOption.state = QStyle::State_Children; + + if (view->isExpanded(index)) + branchOption.state |= QStyle::State_Open; + + view->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, view); + + // draw text + QRect textrect = QRect(r.left() + i*2, r.top(), r.width() - ((5*i)/2), r.height()); + QString text = elidedText(option.fontMetrics, textrect.width(), Qt::ElideMiddle, + index.data(Qt::DisplayRole).toString()); + view->style()->drawItemText(painter, textrect, Qt::AlignCenter, + option.palette, view->isEnabled(), text); + } +#endif +} + +QScriptDebuggerLocalsWidget::QScriptDebuggerLocalsWidget(QWidget *parent) + : QScriptDebuggerLocalsWidgetInterface(*new QScriptDebuggerLocalsWidgetPrivate, parent, 0) +{ + Q_D(QScriptDebuggerLocalsWidget); + d->view = new QTreeView(); + d->view->setItemDelegate(new QScriptDebuggerLocalsItemDelegate(this)); + d->view->setEditTriggers(QAbstractItemView::DoubleClicked); +// d->view->setEditTriggers(QAbstractItemView::NoEditTriggers); + d->view->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked); + d->view->setAlternatingRowColors(true); + d->view->setSelectionBehavior(QAbstractItemView::SelectRows); + d->view->setSortingEnabled(true); + d->view->header()->setDefaultAlignment(Qt::AlignLeft); +// d->view->header()->setSortIndicatorShown(true); +// d->view->header()->setResizeMode(QHeaderView::ResizeToContents); + + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->addWidget(d->view); +} + +QScriptDebuggerLocalsWidget::~QScriptDebuggerLocalsWidget() +{ +} + +/*! + \reimp +*/ +QScriptDebuggerLocalsModel *QScriptDebuggerLocalsWidget::localsModel() const +{ + Q_D(const QScriptDebuggerLocalsWidget); + if (!d->proxy) + return 0; + return qobject_cast<QScriptDebuggerLocalsModel*>(d->proxy->sourceModel()); +} + +/*! + \reimp +*/ +void QScriptDebuggerLocalsWidget::setLocalsModel(QScriptDebuggerLocalsModel *model) +{ + Q_D(QScriptDebuggerLocalsWidget); + if (localsModel()) { + QObject::disconnect(localsModel(), 0, d->view, 0); + } + if (model) { + QObject::connect(model, SIGNAL(scopeObjectAvailable(QModelIndex)), + this, SLOT(_q_expandIndex(QModelIndex))); + } + if (!d->proxy) { + d->proxy = new CustomProxyModel(this); + d->view->sortByColumn(0, Qt::AscendingOrder); + } + d->proxy->setSourceModel(model); + d->view->setModel(d->proxy); +} + +/*! + \reimp +*/ +void QScriptDebuggerLocalsWidget::expand(const QModelIndex &index) +{ + Q_D(QScriptDebuggerLocalsWidget); + d->view->expand(index); + d->view->setFirstColumnSpanned(index.row(), QModelIndex(), true); +} + +QT_END_NAMESPACE + +#include "qscriptdebuggerlocalswidget.moc" + +#include "moc_qscriptdebuggerlocalswidget_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebuggerlocalswidget_p.h b/src/scripttools/debugging/qscriptdebuggerlocalswidget_p.h new file mode 100644 index 0000000..960e8cb --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerlocalswidget_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERLOCALSWIDGET_P_H +#define QSCRIPTDEBUGGERLOCALSWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerlocalswidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerLocalsWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerLocalsWidget: + public QScriptDebuggerLocalsWidgetInterface +{ + Q_OBJECT +public: + QScriptDebuggerLocalsWidget(QWidget *parent = 0); + ~QScriptDebuggerLocalsWidget(); + + QScriptDebuggerLocalsModel *localsModel() const; + void setLocalsModel(QScriptDebuggerLocalsModel *model); + + void expand(const QModelIndex &index); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerLocalsWidget) + Q_DISABLE_COPY(QScriptDebuggerLocalsWidget) + + Q_PRIVATE_SLOT(d_func(), void _q_onCompletionTaskFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_insertCompletion(const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_expandIndex(const QModelIndex &)) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface.cpp b/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface.cpp new file mode 100644 index 0000000..6aabd06 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerlocalswidgetinterface_p.h" +#include "qscriptdebuggerlocalswidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerLocalsWidgetInterfacePrivate::QScriptDebuggerLocalsWidgetInterfacePrivate() +{ + completionProvider = 0; +} + +QScriptDebuggerLocalsWidgetInterfacePrivate::~QScriptDebuggerLocalsWidgetInterfacePrivate() +{ +} + +QScriptDebuggerLocalsWidgetInterface::~QScriptDebuggerLocalsWidgetInterface() +{ +} + +QScriptDebuggerLocalsWidgetInterface::QScriptDebuggerLocalsWidgetInterface( + QScriptDebuggerLocalsWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QScriptCompletionProviderInterface *QScriptDebuggerLocalsWidgetInterface::completionProvider() const +{ + Q_D(const QScriptDebuggerLocalsWidgetInterface); + return d->completionProvider; +} + +void QScriptDebuggerLocalsWidgetInterface::setCompletionProvider(QScriptCompletionProviderInterface *completionProvider) +{ + Q_D(QScriptDebuggerLocalsWidgetInterface); + d->completionProvider = completionProvider; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface_p.h b/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface_p.h new file mode 100644 index 0000000..ba31363 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERLOCALSWIDGETINTERFACE_P_H +#define QSCRIPTDEBUGGERLOCALSWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerLocalsModel; +class QModelIndex; +class QScriptCompletionProviderInterface; + +class QScriptDebuggerLocalsWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerLocalsWidgetInterface: + public QWidget +{ + Q_OBJECT +public: + ~QScriptDebuggerLocalsWidgetInterface(); + + QScriptCompletionProviderInterface *completionProvider() const; + void setCompletionProvider(QScriptCompletionProviderInterface *completionProvider); + + virtual QScriptDebuggerLocalsModel *localsModel() const = 0; + virtual void setLocalsModel(QScriptDebuggerLocalsModel *model) = 0; + + virtual void expand(const QModelIndex &index) = 0; + +protected: + QScriptDebuggerLocalsWidgetInterface( + QScriptDebuggerLocalsWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerLocalsWidgetInterface) + Q_DISABLE_COPY(QScriptDebuggerLocalsWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface_p_p.h b/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface_p_p.h new file mode 100644 index 0000000..9bfe5a4 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerlocalswidgetinterface_p_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERLOCALSWIDGETINTERFACE_P_P_H +#define QSCRIPTDEBUGGERLOCALSWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptCompletionProviderInterface; + +class QScriptDebuggerLocalsWidgetInterface; +class QScriptDebuggerLocalsWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerLocalsWidgetInterface) +public: + QScriptDebuggerLocalsWidgetInterfacePrivate(); + ~QScriptDebuggerLocalsWidgetInterfacePrivate(); + + QScriptCompletionProviderInterface *completionProvider; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerobjectsnapshotdelta_p.h b/src/scripttools/debugging/qscriptdebuggerobjectsnapshotdelta_p.h new file mode 100644 index 0000000..e3ec541 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerobjectsnapshotdelta_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGEROBJECTSNAPSHOTDELTA_P_H +#define QSCRIPTDEBUGGEROBJECTSNAPSHOTDELTA_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qstringlist.h> +#include "qscriptdebuggervalueproperty_p.h" + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QScriptDebuggerObjectSnapshotDelta +{ +public: + QStringList removedProperties; + QScriptDebuggerValuePropertyList changedProperties; + QScriptDebuggerValuePropertyList addedProperties; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerresponse.cpp b/src/scripttools/debugging/qscriptdebuggerresponse.cpp new file mode 100644 index 0000000..82bfff2 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerresponse.cpp @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerresponse_p.h" +#include "qscriptdebuggervalue_p.h" + +#include <QtScript/qscriptcontextinfo.h> +#include <QtCore/qdatastream.h> + +Q_DECLARE_METATYPE(QScriptBreakpointData) +Q_DECLARE_METATYPE(QScriptBreakpointMap) +Q_DECLARE_METATYPE(QScriptScriptData) +Q_DECLARE_METATYPE(QScriptScriptMap) +Q_DECLARE_METATYPE(QScriptDebuggerValue) +Q_DECLARE_METATYPE(QScriptDebuggerValueList) +Q_DECLARE_METATYPE(QScriptDebuggerValueProperty) +Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList) +Q_DECLARE_METATYPE(QScriptContextInfo) + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerResponse + \internal + + \brief The QScriptDebuggerResponse class represents a front-end's response to a QScriptDebuggerCommand. + + A response contains an error code and result. +*/ + +class QScriptDebuggerResponsePrivate +{ +public: + QScriptDebuggerResponsePrivate(); + ~QScriptDebuggerResponsePrivate(); + + QScriptDebuggerResponse::Error error; + QVariant result; + bool async; +}; + +QScriptDebuggerResponsePrivate::QScriptDebuggerResponsePrivate() +{ + error = QScriptDebuggerResponse::NoError; + async = false; +} + +QScriptDebuggerResponsePrivate::~QScriptDebuggerResponsePrivate() +{ +} + +QScriptDebuggerResponse::QScriptDebuggerResponse() + : d_ptr(new QScriptDebuggerResponsePrivate) +{ +} + +QScriptDebuggerResponse::QScriptDebuggerResponse(const QScriptDebuggerResponse &other) + : d_ptr(new QScriptDebuggerResponsePrivate) +{ + *d_ptr = *other.d_ptr; +} + +QScriptDebuggerResponse::~QScriptDebuggerResponse() +{ + delete d_ptr; +} + +QScriptDebuggerResponse &QScriptDebuggerResponse::operator=(const QScriptDebuggerResponse &other) +{ + *d_ptr = *other.d_ptr; + return *this; +} + +/*! + Returns the error code of this response. +*/ +QScriptDebuggerResponse::Error QScriptDebuggerResponse::error() const +{ + Q_D(const QScriptDebuggerResponse); + return d->error; +} + +/*! + Sets the \a error code of this response. +*/ +void QScriptDebuggerResponse::setError(Error error) +{ + Q_D(QScriptDebuggerResponse); + d->error = error; +} + +/*! + Returns the result of this response. This function is provided for + convenience. +*/ +QVariant QScriptDebuggerResponse::result() const +{ + Q_D(const QScriptDebuggerResponse); + return d->result; +} + +/*! + Sets the Result attribute of this response to the given \a + value. This function is provided for convenience. +*/ +void QScriptDebuggerResponse::setResult(const QVariant &value) +{ + Q_D(QScriptDebuggerResponse); + d->result = value; +} + +void QScriptDebuggerResponse::setResult(int value) +{ + Q_D(QScriptDebuggerResponse); + d->result = value; +} + +void QScriptDebuggerResponse::setResult(const QString &value) +{ + Q_D(QScriptDebuggerResponse); + d->result = value; +} + +void QScriptDebuggerResponse::setResult(const QScriptBreakpointData &data) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(data); +} + +void QScriptDebuggerResponse::setResult(const QScriptBreakpointMap &breakpoints) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(breakpoints); +} + +void QScriptDebuggerResponse::setResult(const QScriptScriptMap &scripts) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(scripts); +} + +void QScriptDebuggerResponse::setResult(const QScriptScriptData &data) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(data); +} + +void QScriptDebuggerResponse::setResult(const QScriptDebuggerValue &value) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(value); +} + +void QScriptDebuggerResponse::setResult(const QScriptDebuggerValueList &values) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(values); +} + +void QScriptDebuggerResponse::setResult(const QScriptDebuggerValuePropertyList &props) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(props); +} + +void QScriptDebuggerResponse::setResult(const QScriptContextInfo &info) +{ + Q_D(QScriptDebuggerResponse); + d->result = qVariantFromValue(info); +} + +int QScriptDebuggerResponse::resultAsInt() const +{ + Q_D(const QScriptDebuggerResponse); + return d->result.toInt(); +} + +qint64 QScriptDebuggerResponse::resultAsLongLong() const +{ + Q_D(const QScriptDebuggerResponse); + return d->result.toLongLong(); +} + +QString QScriptDebuggerResponse::resultAsString() const +{ + Q_D(const QScriptDebuggerResponse); + return d->result.toString(); +} + +QScriptBreakpointData QScriptDebuggerResponse::resultAsBreakpointData() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptBreakpointData>(d->result); +} + +QScriptBreakpointMap QScriptDebuggerResponse::resultAsBreakpoints() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptBreakpointMap>(d->result); +} + +QScriptScriptMap QScriptDebuggerResponse::resultAsScripts() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptScriptMap>(d->result); +} + +QScriptScriptData QScriptDebuggerResponse::resultAsScriptData() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptScriptData>(d->result); +} + +QScriptDebuggerValue QScriptDebuggerResponse::resultAsScriptValue() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptDebuggerValue>(d->result); +} + +QScriptDebuggerValueList QScriptDebuggerResponse::resultAsScriptValueList() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptDebuggerValueList>(d->result); +} + +QScriptDebuggerValuePropertyList QScriptDebuggerResponse::resultAsScriptValuePropertyList() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptDebuggerValuePropertyList>(d->result); +} + +QScriptContextInfo QScriptDebuggerResponse::resultAsContextInfo() const +{ + Q_D(const QScriptDebuggerResponse); + return qvariant_cast<QScriptContextInfo>(d->result); +} + +bool QScriptDebuggerResponse::async() const +{ + Q_D(const QScriptDebuggerResponse); + return d->async; +} + +void QScriptDebuggerResponse::setAsync(bool async) +{ + Q_D(QScriptDebuggerResponse); + d->async = async; +} + +/*! + Returns true if this QScriptDebuggerResponse is equal to the \a other + response, otherwise returns false. +*/ +bool QScriptDebuggerResponse::operator==(const QScriptDebuggerResponse &other) const +{ + Q_D(const QScriptDebuggerResponse); + const QScriptDebuggerResponsePrivate *od = other.d_func(); + if (d == od) + return true; + if (!d || !od) + return false; + return ((d->error == od->error) + && (d->result == od->result) + && (d->async == od->async)); +} + +/*! + Returns true if this QScriptDebuggerResponse is not equal to the \a + other response, otherwise returns false. +*/ +bool QScriptDebuggerResponse::operator!=(const QScriptDebuggerResponse &other) const +{ + return !(*this == other); +} + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QScriptDebuggerResponse &response) + \relates QScriptDebuggerResponse + + Writes the given \a response to the specified \a stream. +*/ +QDataStream &operator<<(QDataStream &out, const QScriptDebuggerResponse &response) +{ + const QScriptDebuggerResponsePrivate *d = response.d_ptr; + out << (quint32)d->error; + out << d->result; + out << d->async; + return out; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QScriptDebuggerResponse &response) + \relates QScriptDebuggerResponse + + Reads a QScriptDebuggerResponse from the specified \a stream into the + given \a response. +*/ +QDataStream &operator>>(QDataStream &in, QScriptDebuggerResponse &response) +{ + QScriptDebuggerResponsePrivate *d = response.d_ptr; + + quint32 error; + in >> error; + d->error = QScriptDebuggerResponse::Error(error); + in >> d->result; + in >> d->async; + + return in; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerresponse_p.h b/src/scripttools/debugging/qscriptdebuggerresponse_p.h new file mode 100644 index 0000000..dd65ffd --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerresponse_p.h @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERRESPONSE_P_H +#define QSCRIPTDEBUGGERRESPONSE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qmap.h> +#include <QtCore/qvariant.h> + +#include "qscriptbreakpointdata_p.h" +#include "qscriptscriptdata_p.h" +#include "qscriptdebuggervalue_p.h" +#include "qscriptdebuggervalueproperty_p.h" + +QT_BEGIN_NAMESPACE + +class QDataStream; +class QScriptContextInfo; + +class QScriptDebuggerResponsePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerResponse +{ +public: + friend Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerResponse &); + friend Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerResponse &); + + enum Error { + NoError, + InvalidContextIndex, + InvalidArgumentIndex, + InvalidScriptID, + InvalidBreakpointID, + UserError = 1000, + MaxUserError = 32767 + }; + + QScriptDebuggerResponse(); + QScriptDebuggerResponse(const QScriptDebuggerResponse &other); + ~QScriptDebuggerResponse(); + + Error error() const; + void setError(Error error); + + QVariant result() const; + void setResult(const QVariant &value); + + void setResult(int value); + void setResult(const QString &value); + void setResult(const QScriptBreakpointData &data); + void setResult(const QScriptBreakpointMap &breakpoints); + void setResult(const QScriptScriptMap &scripts); + void setResult(const QScriptScriptData &data); + void setResult(const QScriptDebuggerValue &value); + void setResult(const QScriptDebuggerValueList &value); + void setResult(const QScriptDebuggerValuePropertyList &props); + void setResult(const QScriptContextInfo &info); + + int resultAsInt() const; + qint64 resultAsLongLong() const; + QString resultAsString() const; + QScriptBreakpointData resultAsBreakpointData() const; + QScriptBreakpointMap resultAsBreakpoints() const; + QScriptScriptMap resultAsScripts() const; + QScriptScriptData resultAsScriptData() const; + QScriptDebuggerValue resultAsScriptValue() const; + QScriptDebuggerValueList resultAsScriptValueList() const; + QScriptDebuggerValuePropertyList resultAsScriptValuePropertyList() const; + QScriptContextInfo resultAsContextInfo() const; + + bool async() const; + void setAsync(bool async); + + QScriptDebuggerResponse &operator=(const QScriptDebuggerResponse &other); + + bool operator==(const QScriptDebuggerResponse &other) const; + bool operator!=(const QScriptDebuggerResponse &other) const; + +private: + QScriptDebuggerResponsePrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptDebuggerResponse) +}; + +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerResponse &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerResponse &); + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerresponsehandlerinterface_p.h b/src/scripttools/debugging/qscriptdebuggerresponsehandlerinterface_p.h new file mode 100644 index 0000000..9a13e05 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerresponsehandlerinterface_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERRESPONSEHANDLERINTERFACE_P_H +#define QSCRIPTDEBUGGERRESPONSEHANDLERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerResponse; + +class Q_AUTOTEST_EXPORT QScriptDebuggerResponseHandlerInterface +{ +public: + virtual ~QScriptDebuggerResponseHandlerInterface() {} + + virtual void handleResponse(const QScriptDebuggerResponse &response, + int commandId) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp new file mode 100644 index 0000000..20350f6 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp @@ -0,0 +1,665 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerscriptedconsolecommand_p.h" +#include "qscriptdebuggerconsolecommand_p_p.h" +#include "qscriptdebuggerconsolecommandjob_p.h" +#include "qscriptdebuggerconsolecommandjob_p_p.h" +#include "qscriptmessagehandlerinterface_p.h" +#include "qscriptdebuggerconsoleglobalobject_p.h" +#include "qscriptdebuggerresponse_p.h" +#include "qscriptdebuggervalue_p.h" +#include "qscriptdebuggervalueproperty_p.h" +#include "qscriptdebuggercommandschedulerinterface_p.h" + +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> +#include <QtScript/qscriptengine.h> +#include <QtScript/qscriptvalue.h> +#include <QtScript/qscriptvalueiterator.h> +#include <QtScript/qscriptcontextinfo.h> +#include <QtCore/qdebug.h> + +Q_DECLARE_METATYPE(QScriptDebuggerResponse) +Q_DECLARE_METATYPE(QScriptBreakpointData) +Q_DECLARE_METATYPE(QScriptBreakpointMap) +Q_DECLARE_METATYPE(QScriptScriptData) +Q_DECLARE_METATYPE(QScriptScriptMap) +Q_DECLARE_METATYPE(QScriptContextInfo) +Q_DECLARE_METATYPE(QScriptDebuggerValue) +Q_DECLARE_METATYPE(QScriptDebuggerValueProperty) +Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommand*) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandList) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupData) +Q_DECLARE_METATYPE(QScriptDebuggerConsoleCommandGroupMap) + +QT_BEGIN_NAMESPACE + +static QScriptValue debuggerResponseToScriptValue(QScriptEngine *eng, const QScriptDebuggerResponse &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("result"), qScriptValueFromValue(eng, in.result())); + out.setProperty(QString::fromLatin1("error"), QScriptValue(eng, in.error())); + out.setProperty(QString::fromLatin1("async"), QScriptValue(eng, in.async())); + return out; +} + +static void debuggerResponseFromScriptValue(const QScriptValue &, QScriptDebuggerResponse &) +{ + Q_ASSERT(0); +} + +static QScriptValue breakpointDataToScriptValue(QScriptEngine *eng, const QScriptBreakpointData &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId()))); + out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); + out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber())); + out.setProperty(QString::fromLatin1("enabled"), QScriptValue(eng, in.isEnabled())); + out.setProperty(QString::fromLatin1("singleShot"), QScriptValue(eng, in.isSingleShot())); + out.setProperty(QString::fromLatin1("ignoreCount"), QScriptValue(eng, in.ignoreCount())); + out.setProperty(QString::fromLatin1("condition"), QScriptValue(eng, in.condition())); + return out; +} + +static void breakpointDataFromScriptValue(const QScriptValue &in, QScriptBreakpointData &out) +{ + QScriptValue scriptId = in.property(QString::fromLatin1("scriptId")); + if (scriptId.isValid()) + out.setScriptId((qint64)scriptId.toNumber()); + out.setFileName(in.property(QString::fromLatin1("fileName")).toString()); + out.setLineNumber(in.property(QString::fromLatin1("lineNumber")).toInt32()); + QScriptValue enabled = in.property(QString::fromLatin1("enabled")); + if (enabled.isValid()) + out.setEnabled(enabled.toBoolean()); + QScriptValue singleShot = in.property(QString::fromLatin1("singleShot")); + if (singleShot.isValid()) + out.setSingleShot(singleShot.toBoolean()); + out.setIgnoreCount(in.property(QString::fromLatin1("ignoreCount")).toInt32()); + out.setCondition(in.property(QString::fromLatin1("condition")).toString()); +} + +static QScriptValue breakpointMapToScriptValue(QScriptEngine *eng, const QScriptBreakpointMap &in) +{ + QScriptValue out = eng->newObject(); + QScriptBreakpointMap::const_iterator it; + for (it = in.constBegin(); it != in.constEnd(); ++it) { + out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value())); + } + return out; +} + +static void breakpointMapFromScriptValue(const QScriptValue &, QScriptBreakpointMap &) +{ + Q_ASSERT(0); +} + +static QScriptValue scriptDataToScriptValue(QScriptEngine *eng, const QScriptScriptData &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("contents"), QScriptValue(eng, in.contents())); + out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); + out.setProperty(QString::fromLatin1("baseLineNumber"), QScriptValue(eng, in.baseLineNumber())); + return out; +} + +static void scriptDataFromScriptValue(const QScriptValue &in, QScriptScriptData &out) +{ + QString contents = in.property(QString::fromLatin1("contents")).toString(); + QString fileName = in.property(QString::fromLatin1("fileName")).toString(); + int baseLineNumber = in.property(QString::fromLatin1("baseLineNumber")).toInt32(); + QScriptScriptData tmp(contents, fileName, baseLineNumber); + out = tmp; +} + +static QScriptValue scriptMapToScriptValue(QScriptEngine *eng, const QScriptScriptMap &in) +{ + QScriptValue out = eng->newObject(); + QScriptScriptMap::const_iterator it; + for (it = in.constBegin(); it != in.constEnd(); ++it) { + out.setProperty(QString::number(it.key()), qScriptValueFromValue(eng, it.value())); + } + return out; +} + +static void scriptMapFromScriptValue(const QScriptValue &, QScriptScriptMap &) +{ + Q_ASSERT(0); +} + +static QScriptValue consoleCommandToScriptValue( + QScriptEngine *eng, QScriptDebuggerConsoleCommand* const &in) +{ + if (!in) + return eng->undefinedValue(); + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in->name())); + out.setProperty(QString::fromLatin1("group"), QScriptValue(eng, in->group())); + out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in->shortDescription())); + out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in->longDescription())); + out.setProperty(QString::fromLatin1("aliases"), qScriptValueFromValue(eng, in->aliases())); + out.setProperty(QString::fromLatin1("seeAlso"), qScriptValueFromValue(eng, in->seeAlso())); + return out; +} + +static void consoleCommandFromScriptValue( + const QScriptValue &, QScriptDebuggerConsoleCommand* &) +{ + Q_ASSERT(0); +} + +static QScriptValue consoleCommandGroupDataToScriptValue( + QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupData &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("longDescription"), QScriptValue(eng, in.longDescription())); + out.setProperty(QString::fromLatin1("shortDescription"), QScriptValue(eng, in.shortDescription())); + return out; +} + +static void consoleCommandGroupDataFromScriptValue( + const QScriptValue &, QScriptDebuggerConsoleCommandGroupData &) +{ + Q_ASSERT(0); +} + +static QScriptValue consoleCommandGroupMapToScriptValue( + QScriptEngine *eng, const QScriptDebuggerConsoleCommandGroupMap &in) +{ + QScriptValue out = eng->newObject(); + QScriptDebuggerConsoleCommandGroupMap::const_iterator it; + for (it = in.constBegin(); it != in.constEnd(); ++it) { + out.setProperty(it.key(), qScriptValueFromValue(eng, it.value())); + } + return out; +} + +static void consoleCommandGroupMapFromScriptValue( + const QScriptValue &, QScriptDebuggerConsoleCommandGroupMap &) +{ + Q_ASSERT(0); +} + +static QScriptValue contextInfoToScriptValue(QScriptEngine *eng, const QScriptContextInfo &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("scriptId"), QScriptValue(eng, qsreal(in.scriptId()))); + out.setProperty(QString::fromLatin1("fileName"), QScriptValue(eng, in.fileName())); + out.setProperty(QString::fromLatin1("lineNumber"), QScriptValue(eng, in.lineNumber())); + out.setProperty(QString::fromLatin1("columnNumber"), QScriptValue(eng, in.columnNumber())); + out.setProperty(QString::fromLatin1("functionName"), QScriptValue(eng, in.functionName())); + return out; +} + +static void contextInfoFromScriptValue(const QScriptValue &, QScriptContextInfo &) +{ + Q_ASSERT(0); +} + +static QScriptValue debuggerScriptValuePropertyToScriptValue(QScriptEngine *eng, const QScriptDebuggerValueProperty &in) +{ + QScriptValue out = eng->newObject(); + out.setProperty(QString::fromLatin1("name"), QScriptValue(eng, in.name())); + out.setProperty(QString::fromLatin1("value"), qScriptValueFromValue(eng, in.value())); + out.setProperty(QString::fromLatin1("valueAsString"), QScriptValue(eng, in.valueAsString())); + out.setProperty(QString::fromLatin1("flags"), QScriptValue(eng, static_cast<int>(in.flags()))); + return out; +} + +static void debuggerScriptValuePropertyFromScriptValue(const QScriptValue &in, QScriptDebuggerValueProperty &out) +{ + QString name = in.property(QString::fromLatin1("name")).toString(); + QScriptDebuggerValue value = qscriptvalue_cast<QScriptDebuggerValue>(in.property(QString::fromLatin1("value"))); + QString valueAsString = in.property(QString::fromLatin1("valueAsString")).toString(); + int flags = in.property(QString::fromLatin1("flags")).toInt32(); + QScriptDebuggerValueProperty tmp(name, value, valueAsString, QScriptValue::PropertyFlags(flags)); + out = tmp; +} + +/*! + \since 4.5 + \class QScriptDebuggerScriptedConsoleCommand + \internal + + \brief The QScriptDebuggerScriptedConsoleCommand class encapsulates a command defined in a script. +*/ + +class QScriptDebuggerScriptedConsoleCommandPrivate + : public QScriptDebuggerConsoleCommandPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerScriptedConsoleCommand) +public: + QScriptDebuggerScriptedConsoleCommandPrivate(); + ~QScriptDebuggerScriptedConsoleCommandPrivate(); + + QString name; + QString group; + QString shortDescription; + QString longDescription; + QStringList aliases; + QStringList seeAlso; + QStringList argumentTypes; + QStringList subCommands; + QScriptEngine *engine; + QScriptValue execFunction; + QScriptValue responseFunction; +}; + +QScriptDebuggerScriptedConsoleCommandPrivate::QScriptDebuggerScriptedConsoleCommandPrivate() +{ + engine = 0; +} + +QScriptDebuggerScriptedConsoleCommandPrivate::~QScriptDebuggerScriptedConsoleCommandPrivate() +{ + delete engine; +} + +QScriptDebuggerScriptedConsoleCommand::QScriptDebuggerScriptedConsoleCommand( + const QString &name, const QString &group, + const QString &shortDescription, const QString &longDescription, + const QStringList &aliases, const QStringList &seeAlso, + const QStringList &argumentTypes, const QStringList &subCommands, + const QScriptValue &execFunction, const QScriptValue &responseFunction) + : QScriptDebuggerConsoleCommand(*new QScriptDebuggerScriptedConsoleCommandPrivate) +{ + Q_D(QScriptDebuggerScriptedConsoleCommand); + d->name = name; + d->group = group; + d->shortDescription = shortDescription; + d->longDescription = longDescription; + d->aliases = aliases; + d->seeAlso = seeAlso; + d->argumentTypes = argumentTypes; + d->subCommands = subCommands; + d->execFunction = execFunction; + d->responseFunction = responseFunction; + d->engine = execFunction.engine(); + + qScriptRegisterMetaType<QScriptBreakpointData>(d->engine, breakpointDataToScriptValue, breakpointDataFromScriptValue); + qScriptRegisterMetaType<QScriptBreakpointMap>(d->engine, breakpointMapToScriptValue, breakpointMapFromScriptValue); + qScriptRegisterMetaType<QScriptScriptData>(d->engine, scriptDataToScriptValue, scriptDataFromScriptValue); + qScriptRegisterMetaType<QScriptScriptMap>(d->engine, scriptMapToScriptValue, scriptMapFromScriptValue); + qScriptRegisterMetaType<QScriptContextInfo>(d->engine, contextInfoToScriptValue, contextInfoFromScriptValue); + qScriptRegisterMetaType<QScriptDebuggerValueProperty>(d->engine, debuggerScriptValuePropertyToScriptValue, debuggerScriptValuePropertyFromScriptValue); + qScriptRegisterSequenceMetaType<QScriptDebuggerValuePropertyList>(d->engine); + qScriptRegisterMetaType<QScriptDebuggerResponse>(d->engine, debuggerResponseToScriptValue, debuggerResponseFromScriptValue); + qScriptRegisterMetaType<QScriptDebuggerConsoleCommand*>(d->engine, consoleCommandToScriptValue, consoleCommandFromScriptValue); + qScriptRegisterSequenceMetaType<QScriptDebuggerConsoleCommandList>(d->engine); + qScriptRegisterMetaType<QScriptDebuggerConsoleCommandGroupData>(d->engine, consoleCommandGroupDataToScriptValue, consoleCommandGroupDataFromScriptValue); + qScriptRegisterMetaType<QScriptDebuggerConsoleCommandGroupMap>(d->engine, consoleCommandGroupMapToScriptValue, consoleCommandGroupMapFromScriptValue); +// ### can't do this, if it's an object ID the conversion will be incorrect since +// ### the object ID refers to an object in a different engine! +// qScriptRegisterMetaType(d->engine, debuggerScriptValueToScriptValue, debuggerScriptValueFromScriptValue); +} + +QScriptDebuggerScriptedConsoleCommand::~QScriptDebuggerScriptedConsoleCommand() +{ +} + +class QScriptDebuggerScriptedConsoleCommandJobPrivate; +class QScriptDebuggerScriptedConsoleCommandJob + : public QScriptDebuggerConsoleCommandJob, + public QScriptDebuggerCommandSchedulerInterface +{ +public: + QScriptDebuggerScriptedConsoleCommandJob( + QScriptDebuggerScriptedConsoleCommandPrivate *command, + const QStringList &arguments, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler); + ~QScriptDebuggerScriptedConsoleCommandJob(); + + int scheduleCommand( + const QScriptDebuggerCommand &command, + QScriptDebuggerResponseHandlerInterface *responseHandler); + + void start(); + void handleResponse(const QScriptDebuggerResponse &response, + int commandId); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerScriptedConsoleCommandJob) + Q_DISABLE_COPY(QScriptDebuggerScriptedConsoleCommandJob) +}; + +class QScriptDebuggerScriptedConsoleCommandJobPrivate + : public QScriptDebuggerConsoleCommandJobPrivate +{ +public: + QScriptDebuggerScriptedConsoleCommandJobPrivate() {} + ~QScriptDebuggerScriptedConsoleCommandJobPrivate() {} + + QScriptDebuggerScriptedConsoleCommandPrivate *command; + QStringList arguments; + int commandCount; +}; + +QScriptDebuggerScriptedConsoleCommandJob::QScriptDebuggerScriptedConsoleCommandJob( + QScriptDebuggerScriptedConsoleCommandPrivate *command, + const QStringList &arguments, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler) + : QScriptDebuggerConsoleCommandJob(*new QScriptDebuggerScriptedConsoleCommandJobPrivate, + console, messageHandler, commandScheduler) +{ + Q_D(QScriptDebuggerScriptedConsoleCommandJob); + d->command = command; + d->arguments = arguments; +} + +QScriptDebuggerScriptedConsoleCommandJob::~QScriptDebuggerScriptedConsoleCommandJob() +{ +} + +int QScriptDebuggerScriptedConsoleCommandJob::scheduleCommand( + const QScriptDebuggerCommand &command, + QScriptDebuggerResponseHandlerInterface *responseHandler) +{ + Q_D(QScriptDebuggerScriptedConsoleCommandJob); + ++d->commandCount; + return commandScheduler()->scheduleCommand(command, responseHandler); +} + +void QScriptDebuggerScriptedConsoleCommandJob::start() +{ + Q_D(QScriptDebuggerScriptedConsoleCommandJob); + QScriptEngine *engine = d->command->engine; + QScriptValueList args; + for (int i = 0; i < d->arguments.size(); ++i) + args.append(QScriptValue(engine, d->arguments.at(i))); + QScriptDebuggerConsoleGlobalObject *global; +#if QT_VERSION >= 0x040500 + global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject()); +#else + global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().scope().toQObject()); +#endif + Q_ASSERT(global != 0); + global->setScheduler(this); + global->setResponseHandler(this); + global->setMessageHandler(d->messageHandler); + global->setConsole(d->console); + d->commandCount = 0; + QScriptValue ret = d->command->execFunction.call(QScriptValue(), args); + global->setScheduler(0); + global->setResponseHandler(0); + global->setMessageHandler(0); + global->setConsole(0); + if (ret.isError()) { + qWarning("*** internal error: %s", qPrintable(ret.toString())); + } + if (d->commandCount == 0) + finish(); +} + +void QScriptDebuggerScriptedConsoleCommandJob::handleResponse( + const QScriptDebuggerResponse &response, + int commandId) +{ + Q_D(QScriptDebuggerScriptedConsoleCommandJob); + // ### generalize + QScriptEngine *engine = d->command->engine; + QScriptValueList args; + args.append(qScriptValueFromValue(engine, response)); + args.append(QScriptValue(engine, commandId)); + QScriptDebuggerConsoleGlobalObject *global; +#if QT_VERSION >= 0x040500 + global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject()); +#else + global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().scope().toQObject()); +#endif + Q_ASSERT(global != 0); + global->setScheduler(this); + global->setResponseHandler(this); + global->setMessageHandler(d->messageHandler); + global->setConsole(d->console); + d->commandCount = 0; + QScriptValue ret = d->command->responseFunction.call(QScriptValue(), args); + global->setScheduler(0); + global->setResponseHandler(0); + global->setMessageHandler(0); + global->setConsole(0); + if (ret.isError()) { + qWarning("*** internal error: %s", qPrintable(ret.toString())); + } + if (d->commandCount == 0) + finish(); +} + +/*! + \reimp +*/ +QString QScriptDebuggerScriptedConsoleCommand::name() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->name; +} + +/*! + \reimp +*/ +QString QScriptDebuggerScriptedConsoleCommand::group() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->group; +} + +/*! + \reimp +*/ +QString QScriptDebuggerScriptedConsoleCommand::shortDescription() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->shortDescription; +} + +/*! + \reimp +*/ +QString QScriptDebuggerScriptedConsoleCommand::longDescription() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->longDescription; +} + +/*! + \reimp +*/ +QStringList QScriptDebuggerScriptedConsoleCommand::aliases() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->aliases; +} + +/*! + \reimp +*/ +QStringList QScriptDebuggerScriptedConsoleCommand::seeAlso() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->seeAlso; +} + +/*! + \reimp +*/ +QStringList QScriptDebuggerScriptedConsoleCommand::argumentTypes() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->argumentTypes; +} + +/*! + \reimp +*/ +QStringList QScriptDebuggerScriptedConsoleCommand::subCommands() const +{ + Q_D(const QScriptDebuggerScriptedConsoleCommand); + return d->subCommands; +} + +/*! + \reimp +*/ +QScriptDebuggerConsoleCommandJob *QScriptDebuggerScriptedConsoleCommand::createJob( + const QStringList &arguments, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler) +{ + Q_D(QScriptDebuggerScriptedConsoleCommand); + return new QScriptDebuggerScriptedConsoleCommandJob( + d, arguments, console, messageHandler, commandScheduler); +} + +/*! + Parses a command defined by the given \a program. + Returns an object that encapsulates the command, or 0 if parsing failed. +*/ +QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::parse( + const QString &program, const QString &fileName, + QScriptMessageHandlerInterface *messageHandler) +{ + QScriptEngine *engine = new QScriptEngine(); + // create a custom global object + QScriptDebuggerConsoleGlobalObject *cppGlobal = new QScriptDebuggerConsoleGlobalObject(); + QScriptValue global = engine->newQObject(cppGlobal, + QScriptEngine::ScriptOwnership, +#if QT_VERSION >= 0x040500 + QScriptEngine::ExcludeSuperClassContents); +#else + QScriptEngine::ExcludeSuperClassMethods + | QScriptEngine::ExcludeSuperClassProperties); +#endif + { + QScriptValueIterator it(engine->globalObject()); + while (it.hasNext()) { + it.next(); + global.setProperty(it.scriptName(), it.value(), it.flags()); + } + } +#if QT_VERSION >= 0x040500 + engine->setGlobalObject(global); +#else + engine->globalObject().setScope(global); + global = engine->globalObject(); +#endif + + cppGlobal->setMessageHandler(messageHandler); + QScriptValue ret = engine->evaluate(program, fileName); + cppGlobal->setMessageHandler(0); + if (engine->hasUncaughtException()) { + messageHandler->message(QtCriticalMsg, ret.toString(), fileName, + engine->uncaughtExceptionLineNumber()); + delete engine; + return 0; + } + + QScriptValue name = global.property(QLatin1String("name")); + if (!name.isString()) { + messageHandler->message(QtCriticalMsg, QLatin1String("command definition lacks a name"), fileName); + delete engine; + return 0; + } + QString nameStr = name.toString(); + + QScriptValue group = global.property(QLatin1String("group")); + if (!group.isString()) { + messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks a group name") + .arg(nameStr), fileName); + delete engine; + return 0; + } + QString groupStr = group.toString(); + + QScriptValue shortDesc = global.property(QLatin1String("shortDescription")); + if (!shortDesc.isString()) { + messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks shortDescription") + .arg(nameStr), fileName); + delete engine; + return 0; + } + QString shortDescStr = shortDesc.toString(); + + QScriptValue longDesc = global.property(QLatin1String("longDescription")); + if (!longDesc.isString()) { + messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks longDescription") + .arg(nameStr), fileName); + delete engine; + return 0; + } + QString longDescStr = longDesc.toString(); + + QStringList aliases; + qScriptValueToSequence(global.property(QLatin1String("aliases")), aliases); + + QStringList seeAlso; + qScriptValueToSequence(global.property(QLatin1String("seeAlso")), seeAlso); + + QStringList argTypes; + qScriptValueToSequence(global.property(QLatin1String("argumentTypes")), argTypes); + + QStringList subCommands; + qScriptValueToSequence(global.property(QLatin1String("subCommands")), subCommands); + + QScriptValue execFunction = global.property(QLatin1String("execute")); + if (!execFunction.isFunction()) { + messageHandler->message(QtCriticalMsg, QString::fromLatin1("definition of command \"%0\" lacks execute() function") + .arg(nameStr), fileName); + delete engine; + return 0; + } + + QScriptValue responseFunction = global.property(QLatin1String("handleResponse")); + + QScriptDebuggerScriptedConsoleCommand *result = new QScriptDebuggerScriptedConsoleCommand( + nameStr, groupStr, + shortDescStr, longDescStr, + aliases, seeAlso, + argTypes, subCommands, + execFunction, responseFunction); + return result; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand_p.h b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand_p.h new file mode 100644 index 0000000..5537604 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSCRIPTEDCONSOLECOMMAND_P_H +#define QSCRIPTDEBUGGERSCRIPTEDCONSOLECOMMAND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerconsolecommand_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptValue; + +class QScriptDebuggerScriptedConsoleCommandPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerScriptedConsoleCommand + : public QScriptDebuggerConsoleCommand +{ +protected: + QScriptDebuggerScriptedConsoleCommand(const QString &name, + const QString &group, + const QString &shortDescription, + const QString &longDescription, + const QStringList &aliases, + const QStringList &seeAlso, + const QStringList &argumentTypes, + const QStringList &subCommands, + const QScriptValue &execFunction, + const QScriptValue &responseFunction); +public: + ~QScriptDebuggerScriptedConsoleCommand(); + + static QScriptDebuggerScriptedConsoleCommand *parse( + const QString &program, const QString &fileName, + QScriptMessageHandlerInterface *messageHandler); + + QString name() const; + QString group() const; + QString shortDescription() const; + QString longDescription() const; + QStringList aliases() const; + QStringList seeAlso() const; + QStringList argumentTypes() const; + QStringList subCommands() const; + + QScriptDebuggerConsoleCommandJob *createJob( + const QStringList &arguments, + QScriptDebuggerConsole *console, + QScriptMessageHandlerInterface *messageHandler, + QScriptDebuggerCommandSchedulerInterface *commandScheduler); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerScriptedConsoleCommand) + Q_DISABLE_COPY(QScriptDebuggerScriptedConsoleCommand) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerscriptsmodel.cpp b/src/scripttools/debugging/qscriptdebuggerscriptsmodel.cpp new file mode 100644 index 0000000..17bee59 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptsmodel.cpp @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerscriptsmodel_p.h" +#include "qscriptscriptdata_p.h" + +#include "private/qabstractitemmodel_p.h" + +#include <QtCore/qfileinfo.h> +#include <QtCore/qpair.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerScriptsModelPrivate + : public QAbstractItemModelPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerScriptsModel) +public: + struct Node { + Node(qint64 sid, const QScriptScriptData &dt) + : scriptId(sid), data(dt) {} + + qint64 scriptId; + QScriptScriptData data; + QList<QPair<QString, int> > functionsInfo; + QSet<int> executableLineNumbers; + }; + + QScriptDebuggerScriptsModelPrivate(); + ~QScriptDebuggerScriptsModelPrivate(); + + Node *findScriptNode(qint64 scriptId) const; + + int nextNodeId; + QMap<int, Node*> nodes; +}; + +QScriptDebuggerScriptsModelPrivate::QScriptDebuggerScriptsModelPrivate() +{ + nextNodeId = 0; +} + +QScriptDebuggerScriptsModelPrivate::~QScriptDebuggerScriptsModelPrivate() +{ + qDeleteAll(nodes); +} + +QScriptDebuggerScriptsModelPrivate::Node *QScriptDebuggerScriptsModelPrivate::findScriptNode(qint64 scriptId) const +{ + QMap<int, Node*>::const_iterator it; + for (it = nodes.constBegin(); it != nodes.constEnd(); ++it) { + Node *n = it.value(); + if (n->scriptId == scriptId) + return n; + } + return 0; +} + +QScriptDebuggerScriptsModel::QScriptDebuggerScriptsModel(QObject *parent) + : QAbstractItemModel(*new QScriptDebuggerScriptsModelPrivate, parent) +{ +} + +QScriptDebuggerScriptsModel::~QScriptDebuggerScriptsModel() +{ +} + +void QScriptDebuggerScriptsModel::removeScript(qint64 id) +{ + Q_D(QScriptDebuggerScriptsModel); + QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::iterator it; + for (it = d->nodes.begin(); it != d->nodes.end(); ++it) { + QScriptDebuggerScriptsModelPrivate::Node *n = it.value(); + if (n->scriptId == id) { + d->nodes.erase(it); + delete n; + break; + } + } +} + +void QScriptDebuggerScriptsModel::addScript(qint64 sid, const QScriptScriptData &data) +{ + Q_D(QScriptDebuggerScriptsModel); + int id = d->nextNodeId; + ++d->nextNodeId; + d->nodes.insert(id, new QScriptDebuggerScriptsModelPrivate::Node(sid, data)); +} + +void QScriptDebuggerScriptsModel::addExtraScriptInfo( + qint64 sid, const QMap<QString, int> &functionsInfo, + const QSet<int> &executableLineNumbers) +{ + Q_D(QScriptDebuggerScriptsModel); + QScriptDebuggerScriptsModelPrivate::Node *node = d->findScriptNode(sid); + if (!node) + return; + QList<QPair<QString, int> > lst; + QMap<QString, int>::const_iterator it; + for (it = functionsInfo.constBegin(); it != functionsInfo.constEnd(); ++it) + lst.append(qMakePair(it.key(), it.value())); + node->functionsInfo = lst; + node->executableLineNumbers = executableLineNumbers; +} + +void QScriptDebuggerScriptsModel::commit() +{ + layoutAboutToBeChanged(); + layoutChanged(); +} + +QScriptScriptData QScriptDebuggerScriptsModel::scriptData(qint64 sid) const +{ + Q_D(const QScriptDebuggerScriptsModel); + QScriptDebuggerScriptsModelPrivate::Node *node = d->findScriptNode(sid); + if (!node) + return QScriptScriptData(); + return node->data; +} + +QScriptScriptMap QScriptDebuggerScriptsModel::scripts() const +{ + Q_D(const QScriptDebuggerScriptsModel); + QScriptScriptMap result; + QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::const_iterator it; + for (it = d->nodes.constBegin(); it != d->nodes.constEnd(); ++it) { + QScriptDebuggerScriptsModelPrivate::Node *n = it.value(); + result.insert(n->scriptId, n->data); + } + return result; +} + +qint64 QScriptDebuggerScriptsModel::resolveScript(const QString &fileName) const +{ + Q_D(const QScriptDebuggerScriptsModel); + QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::const_iterator it; + for (it = d->nodes.constBegin(); it != d->nodes.constEnd(); ++it) { + QScriptDebuggerScriptsModelPrivate::Node *n = it.value(); + if (n->data.fileName() == fileName) + return n->scriptId; + } + return -1; +} + +QSet<int> QScriptDebuggerScriptsModel::executableLineNumbers(qint64 scriptId) const +{ + Q_D(const QScriptDebuggerScriptsModel); + QScriptDebuggerScriptsModelPrivate::Node *node = d->findScriptNode(scriptId); + if (!node) + return QSet<int>(); + return node->executableLineNumbers; +} + +QModelIndex QScriptDebuggerScriptsModel::indexFromScriptId(qint64 sid) const +{ + Q_D(const QScriptDebuggerScriptsModel); + int row = 0; + QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::const_iterator it; + for (it = d->nodes.constBegin(); it != d->nodes.constEnd(); ++it, ++row) { + QScriptDebuggerScriptsModelPrivate::Node *n = it.value(); + if (n->scriptId == sid) + return createIndex(row, 0, it.key() << 12); + } + return QModelIndex(); +} + +qint64 QScriptDebuggerScriptsModel::scriptIdFromIndex(const QModelIndex &index) const +{ + Q_D(const QScriptDebuggerScriptsModel); + if (!index.isValid()) + return -1; + int id = index.internalId(); + if (id & 1) + return -1; + QScriptDebuggerScriptsModelPrivate::Node *n = d->nodes.value(id >> 12); + if (!n) + return -1; + return n->scriptId; +} + +QPair<QString, int> QScriptDebuggerScriptsModel::scriptFunctionInfoFromIndex(const QModelIndex &index) const +{ + Q_D(const QScriptDebuggerScriptsModel); + QPair<QString, int> result; + if (!index.isValid()) + return result; + int id = index.internalId(); + if (!(id & 1)) + return result; + QScriptDebuggerScriptsModelPrivate::Node *node = d->nodes.value(id >> 12); + if (!node) + return result; + int functionIndex = (id >> 1) & ((1 << 11) - 1); + result = node->functionsInfo.at(functionIndex); + return result; +} + +/*! + \reimp +*/ +QModelIndex QScriptDebuggerScriptsModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_D(const QScriptDebuggerScriptsModel); + if (!parent.isValid()) { + if ((row < 0) || (row >= d->nodes.size())) + return QModelIndex(); + if (column != 0) + return QModelIndex(); + return createIndex(row, column, d->nodes.keys().at(row) << 12); + } + int id = parent.internalId(); + if (id & 1) + return QModelIndex(); + return createIndex(row, column, id | (row << 1) | 1); +} + +/*! + \reimp +*/ +QModelIndex QScriptDebuggerScriptsModel::parent(const QModelIndex &index) const +{ + Q_D(const QScriptDebuggerScriptsModel); + if (!index.isValid()) + return QModelIndex(); + int id = index.internalId(); + if (!(id & 1)) + return QModelIndex(); + QScriptDebuggerScriptsModelPrivate::Node *n = d->nodes.value(id >> 12); + if (!n) + return QModelIndex(); + return indexFromScriptId(n->scriptId); +} + +/*! + \reimp +*/ +int QScriptDebuggerScriptsModel::columnCount(const QModelIndex &) const +{ + return 1; +} + +/*! + \reimp +*/ +int QScriptDebuggerScriptsModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const QScriptDebuggerScriptsModel); + if (!parent.isValid()) + return d->nodes.size(); + int id = parent.internalId(); + if (id & 1) + return 0; + QScriptDebuggerScriptsModelPrivate::Node *n = d->nodes.value(id >> 12); + if (!n) + return 0; + return n->functionsInfo.size(); +} + +/*! + \reimp +*/ +QVariant QScriptDebuggerScriptsModel::data(const QModelIndex &index, int role) const +{ + Q_D(const QScriptDebuggerScriptsModel); + if (!index.isValid()) + return QVariant(); + int id = index.internalId(); + QScriptDebuggerScriptsModelPrivate::Node *node = d->nodes.value(id >> 12); + if (!node) + return QVariant(); + if (!(id & 1)) { + if (role == Qt::DisplayRole) { + QString fn = node->data.fileName(); + if (fn.isEmpty()) + fn = QString::fromLatin1("<anonymous script, id=%0>").arg(node->scriptId); + return fn; + } else if (role == Qt::ToolTipRole) { + QString fn = node->data.fileName(); + if (QFileInfo(fn).fileName() != fn) + return fn; + } else if (role == Qt::UserRole) { + return node->scriptId; + } else if (role == Qt::UserRole+1) { + return node->data.baseLineNumber(); + } else if (role == Qt::UserRole+2) { + return node->data.contents(); + } + } else { + int functionIndex = (id >> 1) & ((1 << 11) - 1); + if (role == Qt::DisplayRole) + return node->functionsInfo[functionIndex].first; + } + return QVariant(); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerscriptsmodel_p.h b/src/scripttools/debugging/qscriptdebuggerscriptsmodel_p.h new file mode 100644 index 0000000..42afd4e --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptsmodel_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSCRIPTSMODEL_P_H +#define QSCRIPTDEBUGGERSCRIPTSMODEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qabstractitemmodel.h> +#include <QtCore/qpair.h> + +#include "qscriptscriptdata_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerScriptsModelPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerScriptsModel + : public QAbstractItemModel +{ + Q_OBJECT +public: + QScriptDebuggerScriptsModel(QObject *parent = 0); + ~QScriptDebuggerScriptsModel(); + + void removeScript(qint64 id); + void addScript(qint64 id, const QScriptScriptData &data); + void addExtraScriptInfo( + qint64 id, const QMap<QString, int> &functionsInfo, + const QSet<int> &executableLineNumbers); + void commit(); + + QScriptScriptData scriptData(qint64 id) const; + QScriptScriptMap scripts() const; + qint64 resolveScript(const QString &fileName) const; + QSet<int> executableLineNumbers(qint64 scriptId) const; + + QModelIndex indexFromScriptId(qint64 id) const; + qint64 scriptIdFromIndex(const QModelIndex &index) const; + QPair<QString, int> scriptFunctionInfoFromIndex(const QModelIndex &index) const; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerScriptsModel) + Q_DISABLE_COPY(QScriptDebuggerScriptsModel) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerscriptswidget.cpp b/src/scripttools/debugging/qscriptdebuggerscriptswidget.cpp new file mode 100644 index 0000000..63d604d --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptswidget.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerscriptswidget_p.h" +#include "qscriptdebuggerscriptswidgetinterface_p_p.h" +#include "qscriptdebuggerscriptsmodel_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qheaderview.h> +#include <QtGui/qtreeview.h> +#include <QtGui/qboxlayout.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerScriptsWidgetPrivate + : public QScriptDebuggerScriptsWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerScriptsWidget) +public: + QScriptDebuggerScriptsWidgetPrivate(); + ~QScriptDebuggerScriptsWidgetPrivate(); + + // private slots + void _q_onCurrentChanged(const QModelIndex &index); + + QTreeView *view; + qint64 currentScriptId; +}; + +QScriptDebuggerScriptsWidgetPrivate::QScriptDebuggerScriptsWidgetPrivate() +{ + currentScriptId = -1; +} + +QScriptDebuggerScriptsWidgetPrivate::~QScriptDebuggerScriptsWidgetPrivate() +{ +} + +void QScriptDebuggerScriptsWidgetPrivate::_q_onCurrentChanged(const QModelIndex &index) +{ + Q_Q(QScriptDebuggerScriptsWidget); + if (!index.isValid()) + return; + qint64 sid = q->scriptsModel()->scriptIdFromIndex(index); + if (sid != -1) { + if (currentScriptId != sid) { + currentScriptId = sid; + emit q->currentScriptChanged(sid); + } + } else { + qint64 sid = q->scriptsModel()->scriptIdFromIndex(index.parent()); + Q_ASSERT(sid != -1); + currentScriptId = sid; + emit q->currentScriptChanged(sid); + QPair<QString, int> info = q->scriptsModel()->scriptFunctionInfoFromIndex(index); + emit q->scriptLocationSelected(info.second); + } +} + +QScriptDebuggerScriptsWidget::QScriptDebuggerScriptsWidget(QWidget *parent) + : QScriptDebuggerScriptsWidgetInterface(*new QScriptDebuggerScriptsWidgetPrivate, parent, 0) +{ + Q_D(QScriptDebuggerScriptsWidget); + d->view = new QTreeView(); + d->view->setEditTriggers(QAbstractItemView::NoEditTriggers); +// d->view->setAlternatingRowColors(true); +// d->view->setRootIsDecorated(false); + d->view->setSelectionBehavior(QAbstractItemView::SelectRows); + d->view->header()->hide(); +// d->view->header()->setDefaultAlignment(Qt::AlignLeft); +// d->view->header()->setResizeMode(QHeaderView::ResizeToContents); + + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->addWidget(d->view); +} + +QScriptDebuggerScriptsWidget::~QScriptDebuggerScriptsWidget() +{ +} + +/*! + \reimp +*/ +QScriptDebuggerScriptsModel *QScriptDebuggerScriptsWidget::scriptsModel() const +{ + Q_D(const QScriptDebuggerScriptsWidget); + return qobject_cast<QScriptDebuggerScriptsModel*>(d->view->model()); +} + +/*! + \reimp +*/ +void QScriptDebuggerScriptsWidget::setScriptsModel(QScriptDebuggerScriptsModel *model) +{ + Q_D(QScriptDebuggerScriptsWidget); + d->view->setModel(model); + QObject::connect(d->view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(_q_onCurrentChanged(QModelIndex))); +} + +qint64 QScriptDebuggerScriptsWidget::currentScriptId() const +{ + Q_D(const QScriptDebuggerScriptsWidget); + return scriptsModel()->scriptIdFromIndex(d->view->currentIndex()); +} + +void QScriptDebuggerScriptsWidget::setCurrentScript(qint64 id) +{ + Q_D(QScriptDebuggerScriptsWidget); + d->view->setCurrentIndex(scriptsModel()->indexFromScriptId(id)); +} + +QT_END_NAMESPACE + +#include "moc_qscriptdebuggerscriptswidget_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebuggerscriptswidget_p.h b/src/scripttools/debugging/qscriptdebuggerscriptswidget_p.h new file mode 100644 index 0000000..b983a45 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptswidget_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSCRIPTSWIDGET_P_H +#define QSCRIPTDEBUGGERSCRIPTSWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerscriptswidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerScriptsWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerScriptsWidget: + public QScriptDebuggerScriptsWidgetInterface +{ + Q_OBJECT +public: + QScriptDebuggerScriptsWidget(QWidget *parent = 0); + ~QScriptDebuggerScriptsWidget(); + + QScriptDebuggerScriptsModel *scriptsModel() const; + void setScriptsModel(QScriptDebuggerScriptsModel *model); + + qint64 currentScriptId() const; + void setCurrentScript(qint64 id); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerScriptsWidget) + Q_DISABLE_COPY(QScriptDebuggerScriptsWidget) + + Q_PRIVATE_SLOT(d_func(), void _q_onCurrentChanged(const QModelIndex &)) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface.cpp b/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface.cpp new file mode 100644 index 0000000..5120395 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerscriptswidgetinterface_p.h" +#include "qscriptdebuggerscriptswidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerScriptsWidgetInterfacePrivate::QScriptDebuggerScriptsWidgetInterfacePrivate() +{ +} + +QScriptDebuggerScriptsWidgetInterfacePrivate::~QScriptDebuggerScriptsWidgetInterfacePrivate() +{ +} + +QScriptDebuggerScriptsWidgetInterface::~QScriptDebuggerScriptsWidgetInterface() +{ +} + +QScriptDebuggerScriptsWidgetInterface::QScriptDebuggerScriptsWidgetInterface( + QScriptDebuggerScriptsWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface_p.h b/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface_p.h new file mode 100644 index 0000000..1dcd626 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSCRIPTSWIDGETINTERFACE_P_H +#define QSCRIPTDEBUGGERSCRIPTSWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerScriptsModel; + +class QScriptDebuggerScriptsWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerScriptsWidgetInterface: + public QWidget +{ + Q_OBJECT +public: + ~QScriptDebuggerScriptsWidgetInterface(); + + virtual QScriptDebuggerScriptsModel *scriptsModel() const = 0; + virtual void setScriptsModel(QScriptDebuggerScriptsModel *model) = 0; + + virtual qint64 currentScriptId() const = 0; + virtual void setCurrentScript(qint64 id) = 0; + +Q_SIGNALS: + void currentScriptChanged(qint64 scriptId); + void scriptLocationSelected(int lineNumber); + +protected: + QScriptDebuggerScriptsWidgetInterface( + QScriptDebuggerScriptsWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerScriptsWidgetInterface) + Q_DISABLE_COPY(QScriptDebuggerScriptsWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface_p_p.h b/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface_p_p.h new file mode 100644 index 0000000..e3b0cd8 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerscriptswidgetinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSCRIPTSWIDGETINTERFACE_P_P_H +#define QSCRIPTDEBUGGERSCRIPTSWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerScriptsWidgetInterface; +class QScriptDebuggerScriptsWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerScriptsWidgetInterface) +public: + QScriptDebuggerScriptsWidgetInterfacePrivate(); + ~QScriptDebuggerScriptsWidgetInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerstackmodel.cpp b/src/scripttools/debugging/qscriptdebuggerstackmodel.cpp new file mode 100644 index 0000000..aecd2f8 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstackmodel.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerstackmodel_p.h" + +#include "private/qabstractitemmodel_p.h" + +#include <QtScript/qscriptcontextinfo.h> +#include <QtCore/qfileinfo.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerStackModelPrivate + : public QAbstractItemModelPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerStackModel) +public: + QScriptDebuggerStackModelPrivate(); + ~QScriptDebuggerStackModelPrivate(); + + QList<QScriptContextInfo> contextInfos; +}; + +QScriptDebuggerStackModelPrivate::QScriptDebuggerStackModelPrivate() +{ +} + +QScriptDebuggerStackModelPrivate::~QScriptDebuggerStackModelPrivate() +{ +} + +QScriptDebuggerStackModel::QScriptDebuggerStackModel(QObject *parent) + : QAbstractTableModel(*new QScriptDebuggerStackModelPrivate, parent) +{ +} + +QScriptDebuggerStackModel::~QScriptDebuggerStackModel() +{ +} + +QList<QScriptContextInfo> QScriptDebuggerStackModel::contextInfos() const +{ + Q_D(const QScriptDebuggerStackModel); + return d->contextInfos; +} + +void QScriptDebuggerStackModel::setContextInfos(const QList<QScriptContextInfo> &infos) +{ + Q_D(QScriptDebuggerStackModel); + layoutAboutToBeChanged(); + d->contextInfos = infos; + layoutChanged(); +} + +/*! + \reimp +*/ +int QScriptDebuggerStackModel::columnCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return 3; + return 0; +} + +/*! + \reimp +*/ +int QScriptDebuggerStackModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const QScriptDebuggerStackModel); + if (!parent.isValid()) + return d->contextInfos.count(); + return 0; +} + +/*! + \reimp +*/ +QVariant QScriptDebuggerStackModel::data(const QModelIndex &index, int role) const +{ + Q_D(const QScriptDebuggerStackModel); + if (!index.isValid()) + return QVariant(); + if (index.row() >= d->contextInfos.count()) + return QVariant(); + const QScriptContextInfo &info = d->contextInfos.at(index.row()); + if (role == Qt::DisplayRole) { + if (index.column() == 0) { + return index.row(); + } else if (index.column() == 1) { + QString name = info.functionName(); + if (name.isEmpty()) + name = QString::fromLatin1("<anonymous>"); + return name; + } else if (index.column() == 2) { + if (info.lineNumber() == -1) + return QString::fromLatin1("<native>"); + QString fn = QFileInfo(info.fileName()).fileName(); + if (fn.isEmpty()) + fn = QString::fromLatin1("<anonymous script, id=%0>").arg(info.scriptId()); + return QString::fromLatin1("%0:%1").arg(fn).arg(info.lineNumber()); + } + } else if (role == Qt::ToolTipRole) { + if (QFileInfo(info.fileName()).fileName() != info.fileName()) + return info.fileName(); + } + return QVariant(); +} + +/*! + \reimp +*/ +QVariant QScriptDebuggerStackModel::headerData(int section, Qt::Orientation orient, int role) const +{ + if (orient != Qt::Horizontal) + return QVariant(); + if (role == Qt::DisplayRole) { + if (section == 0) + return QObject::tr("Level"); + else if (section == 1) + return QObject::tr("Name"); + else if (section == 2) + return QObject::tr("Location"); + } + return QVariant(); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerstackmodel_p.h b/src/scripttools/debugging/qscriptdebuggerstackmodel_p.h new file mode 100644 index 0000000..37f5457 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstackmodel_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSTACKMODEL_P_H +#define QSCRIPTDEBUGGERSTACKMODEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qabstractitemmodel.h> + +#include <QtCore/qlist.h> + +QT_BEGIN_NAMESPACE + +class QScriptContextInfo; + +class QScriptDebuggerStackModelPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerStackModel + : public QAbstractTableModel +{ +public: + QScriptDebuggerStackModel(QObject *parent = 0); + ~QScriptDebuggerStackModel(); + + QList<QScriptContextInfo> contextInfos() const; + void setContextInfos(const QList<QScriptContextInfo> &infos); + + int columnCount(const QModelIndex &parent) const; + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation, int role) const; + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerStackModel) + Q_DISABLE_COPY(QScriptDebuggerStackModel) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerstackwidget.cpp b/src/scripttools/debugging/qscriptdebuggerstackwidget.cpp new file mode 100644 index 0000000..63ccb2b --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstackwidget.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerstackwidget_p.h" +#include "qscriptdebuggerstackwidgetinterface_p_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qheaderview.h> +#include <QtGui/qtreeview.h> +#include <QtGui/qboxlayout.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerStackWidgetPrivate + : public QScriptDebuggerStackWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerStackWidget) +public: + QScriptDebuggerStackWidgetPrivate(); + ~QScriptDebuggerStackWidgetPrivate(); + + // private slots + void _q_onCurrentChanged(const QModelIndex &index); + + QTreeView *view; +}; + +QScriptDebuggerStackWidgetPrivate::QScriptDebuggerStackWidgetPrivate() +{ +} + +QScriptDebuggerStackWidgetPrivate::~QScriptDebuggerStackWidgetPrivate() +{ +} + +void QScriptDebuggerStackWidgetPrivate::_q_onCurrentChanged(const QModelIndex &index) +{ + Q_Q(QScriptDebuggerStackWidget); + emit q->currentFrameChanged(index.row()); +} + +QScriptDebuggerStackWidget::QScriptDebuggerStackWidget(QWidget *parent) + : QScriptDebuggerStackWidgetInterface(*new QScriptDebuggerStackWidgetPrivate, parent, 0) +{ + Q_D(QScriptDebuggerStackWidget); + d->view = new QTreeView(); + d->view->setEditTriggers(QAbstractItemView::NoEditTriggers); + d->view->setAlternatingRowColors(true); + d->view->setRootIsDecorated(false); + d->view->setSelectionBehavior(QAbstractItemView::SelectRows); + d->view->header()->setDefaultAlignment(Qt::AlignLeft); +// d->view->header()->setResizeMode(QHeaderView::ResizeToContents); + + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->addWidget(d->view); +} + +QScriptDebuggerStackWidget::~QScriptDebuggerStackWidget() +{ +} + +/*! + \reimp +*/ +QAbstractItemModel *QScriptDebuggerStackWidget::stackModel() const +{ + Q_D(const QScriptDebuggerStackWidget); + return d->view->model(); +} + +/*! + \reimp +*/ +void QScriptDebuggerStackWidget::setStackModel(QAbstractItemModel *model) +{ + Q_D(QScriptDebuggerStackWidget); + d->view->setModel(model); + QObject::connect(d->view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(_q_onCurrentChanged(QModelIndex))); + d->view->header()->resizeSection(0, 50); +} + +/*! + \reimp +*/ +int QScriptDebuggerStackWidget::currentFrameIndex() const +{ + Q_D(const QScriptDebuggerStackWidget); + return d->view->currentIndex().row(); +} + +/*! + \reimp +*/ +void QScriptDebuggerStackWidget::setCurrentFrameIndex(int frameIndex) +{ + Q_D(QScriptDebuggerStackWidget); + d->view->setCurrentIndex(d->view->model()->index(frameIndex, 0)); +} + +QT_END_NAMESPACE + +#include "moc_qscriptdebuggerstackwidget_p.cpp" diff --git a/src/scripttools/debugging/qscriptdebuggerstackwidget_p.h b/src/scripttools/debugging/qscriptdebuggerstackwidget_p.h new file mode 100644 index 0000000..ffcbf8a --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstackwidget_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSTACKWIDGET_P_H +#define QSCRIPTDEBUGGERSTACKWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerstackwidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerStackWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerStackWidget: + public QScriptDebuggerStackWidgetInterface +{ + Q_OBJECT +public: + QScriptDebuggerStackWidget(QWidget *parent = 0); + ~QScriptDebuggerStackWidget(); + + QAbstractItemModel *stackModel() const; + void setStackModel(QAbstractItemModel *model); + + int currentFrameIndex() const; + void setCurrentFrameIndex(int frameIndex); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerStackWidget) + Q_DISABLE_COPY(QScriptDebuggerStackWidget) + + Q_PRIVATE_SLOT(d_func(), void _q_onCurrentChanged(const QModelIndex &)) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface.cpp b/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface.cpp new file mode 100644 index 0000000..d9612a7 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggerstackwidgetinterface_p.h" +#include "qscriptdebuggerstackwidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebuggerStackWidgetInterfacePrivate::QScriptDebuggerStackWidgetInterfacePrivate() +{ +} + +QScriptDebuggerStackWidgetInterfacePrivate::~QScriptDebuggerStackWidgetInterfacePrivate() +{ +} + +QScriptDebuggerStackWidgetInterface::~QScriptDebuggerStackWidgetInterface() +{ +} + +QScriptDebuggerStackWidgetInterface::QScriptDebuggerStackWidgetInterface( + QScriptDebuggerStackWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface_p.h b/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface_p.h new file mode 100644 index 0000000..1e3e6f0 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSTACKWIDGETINTERFACE_P_H +#define QSCRIPTDEBUGGERSTACKWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +QT_BEGIN_NAMESPACE + +class QAbstractItemModel; + +class QScriptDebuggerStackWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerStackWidgetInterface: + public QWidget +{ + Q_OBJECT +public: + ~QScriptDebuggerStackWidgetInterface(); + + virtual QAbstractItemModel *stackModel() const = 0; + virtual void setStackModel(QAbstractItemModel *model) = 0; + + virtual int currentFrameIndex() const = 0; + virtual void setCurrentFrameIndex(int frameIndex) = 0; + +Q_SIGNALS: + void currentFrameChanged(int newFrameIndex); + +protected: + QScriptDebuggerStackWidgetInterface( + QScriptDebuggerStackWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebuggerStackWidgetInterface) + Q_DISABLE_COPY(QScriptDebuggerStackWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface_p_p.h b/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface_p_p.h new file mode 100644 index 0000000..2662d7c --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerstackwidgetinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERSTACKWIDGETINTERFACE_P_P_H +#define QSCRIPTDEBUGGERSTACKWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebuggerStackWidgetInterface; +class QScriptDebuggerStackWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebuggerStackWidgetInterface) +public: + QScriptDebuggerStackWidgetInterfacePrivate(); + ~QScriptDebuggerStackWidgetInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggervalue.cpp b/src/scripttools/debugging/qscriptdebuggervalue.cpp new file mode 100644 index 0000000..bb41ee8 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggervalue.cpp @@ -0,0 +1,417 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggervalue_p.h" + +#include <QtScript/qscriptvalue.h> +#include <QtScript/qscriptengine.h> +#include <QtCore/qdatastream.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptDebuggerValue + \internal + + \brief The QScriptDebuggerValue class represents a script value. +*/ + +class QScriptDebuggerValuePrivate +{ +public: + QScriptDebuggerValuePrivate(); + ~QScriptDebuggerValuePrivate(); + + QScriptDebuggerValue::ValueType type; + union { + bool booleanValue; + QString *stringValue; + double numberValue; + qint64 objectId; + }; + + QBasicAtomicInt ref; +}; + +QScriptDebuggerValuePrivate::QScriptDebuggerValuePrivate() + : type(QScriptDebuggerValue::NoValue) +{ + ref = 0; +} + +QScriptDebuggerValuePrivate::~QScriptDebuggerValuePrivate() +{ + if (type == QScriptDebuggerValue::StringValue) + delete stringValue; +} + +QScriptDebuggerValue::QScriptDebuggerValue() + : d_ptr(0) +{ +} + +QScriptDebuggerValue::QScriptDebuggerValue(const QScriptValue &value) + : d_ptr(0) +{ + if (value.isValid()) { + d_ptr = new QScriptDebuggerValuePrivate; + if (value.isUndefined()) + d_ptr->type = UndefinedValue; + else if (value.isNull()) + d_ptr->type = NullValue; + else if (value.isNumber()) { + d_ptr->type = NumberValue; + d_ptr->numberValue = value.toNumber(); + } else if (value.isBoolean()) { + d_ptr->type = BooleanValue; + d_ptr->booleanValue = value.toBoolean(); + } else if (value.isString()) { + d_ptr->type = StringValue; + d_ptr->stringValue = new QString(value.toString()); + } else { + Q_ASSERT(value.isObject()); + d_ptr->type = ObjectValue; + d_ptr->objectId = value.objectId(); + } + d_ptr->ref.ref(); + } +} + +QScriptDebuggerValue::QScriptDebuggerValue(double value) + : d_ptr(new QScriptDebuggerValuePrivate) +{ + d_ptr->type = NumberValue; + d_ptr->numberValue = value; + d_ptr->ref.ref(); +} + +QScriptDebuggerValue::QScriptDebuggerValue(bool value) + : d_ptr(new QScriptDebuggerValuePrivate) +{ + d_ptr->type = BooleanValue; + d_ptr->booleanValue = value; + d_ptr->ref.ref(); +} + +QScriptDebuggerValue::QScriptDebuggerValue(const QString &value) + : d_ptr(new QScriptDebuggerValuePrivate) +{ + d_ptr->type = StringValue; + d_ptr->stringValue = new QString(value); + d_ptr->ref.ref(); +} + +QScriptDebuggerValue::QScriptDebuggerValue(qint64 objectId) + : d_ptr(new QScriptDebuggerValuePrivate) +{ + d_ptr->type = ObjectValue; + d_ptr->objectId = objectId; + d_ptr->ref.ref(); +} + +QScriptDebuggerValue::QScriptDebuggerValue(ValueType type) + : d_ptr(new QScriptDebuggerValuePrivate) +{ + d_ptr->type = type; + d_ptr->ref.ref(); +} + +QScriptDebuggerValue::QScriptDebuggerValue(const QScriptDebuggerValue &other) + : d_ptr(other.d_ptr) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +QScriptDebuggerValue::~QScriptDebuggerValue() +{ + if (d_ptr && !d_ptr->ref.deref()) { + delete d_ptr; + d_ptr = 0; + } +} + +QScriptDebuggerValue &QScriptDebuggerValue::operator=(const QScriptDebuggerValue &other) +{ + if (d_ptr == other.d_ptr) + return *this; + if (d_ptr && !d_ptr->ref.deref()) + delete d_ptr; + d_ptr = other.d_ptr; + if (d_ptr) + d_ptr->ref.ref(); + return *this; +} + +/*! + Returns the type of this value. +*/ +QScriptDebuggerValue::ValueType QScriptDebuggerValue::type() const +{ + Q_D(const QScriptDebuggerValue); + if (!d) + return NoValue; + return d->type; +} + +/*! + Returns this value as a number. +*/ +double QScriptDebuggerValue::numberValue() const +{ + Q_D(const QScriptDebuggerValue); + if (!d) + return 0; + Q_ASSERT(d->type == NumberValue); + return d->numberValue; +} + +/*! + Returns this value as a boolean. +*/ +bool QScriptDebuggerValue::booleanValue() const +{ + Q_D(const QScriptDebuggerValue); + if (!d) + return false; + Q_ASSERT(d->type == BooleanValue); + return d->booleanValue; +} + +/*! + Returns this value as a string. +*/ +QString QScriptDebuggerValue::stringValue() const +{ + Q_D(const QScriptDebuggerValue); + if (!d) + return QString(); + Q_ASSERT(d->type == StringValue); + return *d->stringValue; +} + +/*! + Returns this value as an object ID. +*/ +qint64 QScriptDebuggerValue::objectId() const +{ + Q_D(const QScriptDebuggerValue); + if (!d) + return -1; + Q_ASSERT(d->type == ObjectValue); + return d->objectId; +} + +/*! + Converts this QScriptDebuggerValue to a QScriptValue in the + given \a engine and returns the resulting value. +*/ +QScriptValue QScriptDebuggerValue::toScriptValue(QScriptEngine *engine) const +{ + Q_D(const QScriptDebuggerValue); + if (!d) + return QScriptValue(); + switch (d->type) { + case NoValue: + return QScriptValue(); + case UndefinedValue: + return engine->undefinedValue(); + case NullValue: + return engine->nullValue(); + case BooleanValue: + return QScriptValue(engine, d->booleanValue); + case StringValue: + return QScriptValue(engine, *d->stringValue); + case NumberValue: + return QScriptValue(engine, d->numberValue); + case ObjectValue: + return engine->objectById(d->objectId); + } + return QScriptValue(); +} + +/*! + Returns a string representation of this value. +*/ +QString QScriptDebuggerValue::toString() const +{ + Q_D(const QScriptDebuggerValue); + if (!d) + return QString(); + switch (d->type) { + case NoValue: + return QString(); + case UndefinedValue: + return QString::fromLatin1("undefined"); + case NullValue: + return QString::fromLatin1("null"); + case BooleanValue: + if (d->booleanValue) + return QString::fromLatin1("true"); + else + return QString::fromLatin1("false"); + case StringValue: + return *d->stringValue; + case NumberValue: + return QString::number(d->numberValue); // ### qScriptNumberToString() + case ObjectValue: + return QString::fromLatin1("[object Object]"); + } + return QString(); +} + +/*! + Returns true if this QScriptDebuggerValue is equal to the \a other + value, otherwise returns false. +*/ +bool QScriptDebuggerValue::operator==(const QScriptDebuggerValue &other) const +{ + Q_D(const QScriptDebuggerValue); + const QScriptDebuggerValuePrivate *od = other.d_func(); + if (d == od) + return true; + if (!d || !od) + return false; + if (d->type != od->type) + return false; + switch (d->type) { + case NoValue: + case UndefinedValue: + case NullValue: + return true; + case BooleanValue: + return d->booleanValue == od->booleanValue; + case StringValue: + return *d->stringValue == *od->stringValue; + case NumberValue: + return d->numberValue == od->numberValue; + case ObjectValue: + return d->objectId == od->objectId; + } + return false; +} + +/*! + Returns true if this QScriptDebuggerValue is not equal to the \a + other value, otherwise returns false. +*/ +bool QScriptDebuggerValue::operator!=(const QScriptDebuggerValue &other) const +{ + return !(*this == other); +} + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QScriptDebuggerValue &value) + \relates QScriptDebuggerValue + + Writes the given \a value to the specified \a stream. +*/ +QDataStream &operator<<(QDataStream &out, const QScriptDebuggerValue &value) +{ + out << (quint32)value.type(); + switch (value.type()) { + case QScriptDebuggerValue::NoValue: + case QScriptDebuggerValue::UndefinedValue: + case QScriptDebuggerValue::NullValue: + break; + case QScriptDebuggerValue::BooleanValue: + out << value.booleanValue(); + break; + case QScriptDebuggerValue::StringValue: + out << value.stringValue(); + break; + case QScriptDebuggerValue::NumberValue: + out << value.numberValue(); + break; + case QScriptDebuggerValue::ObjectValue: + out << value.objectId(); + break; + } + return out; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QScriptDebuggerValue &value) + \relates QScriptDebuggerValue + + Reads a QScriptDebuggerValue from the specified \a stream into the + given \a value. +*/ +QDataStream &operator>>(QDataStream &in, QScriptDebuggerValue &value) +{ + quint32 type; + in >> type; + switch (QScriptDebuggerValue::ValueType(type)) { + case QScriptDebuggerValue::UndefinedValue: + case QScriptDebuggerValue::NullValue: + value = QScriptDebuggerValue(QScriptDebuggerValue::ValueType(type)); + break; + case QScriptDebuggerValue::BooleanValue: { + bool b; + in >> b; + value = QScriptDebuggerValue(b); + } break; + case QScriptDebuggerValue::StringValue: { + QString s; + in >> s; + value = QScriptDebuggerValue(s); + } break; + case QScriptDebuggerValue::NumberValue: { + double d; + in >> d; + value = QScriptDebuggerValue(d); + } break; + case QScriptDebuggerValue::ObjectValue: { + qint64 id; + in >> id; + value = QScriptDebuggerValue(id); + } break; + case QScriptDebuggerValue::NoValue: + default: + value = QScriptDebuggerValue(); + break; + } + return in; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggervalue_p.h b/src/scripttools/debugging/qscriptdebuggervalue_p.h new file mode 100644 index 0000000..0142de0 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggervalue_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERVALUE_P_H +#define QSCRIPTDEBUGGERVALUE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qlist.h> + +QT_BEGIN_NAMESPACE + +class QScriptValue; +class QScriptEngine; +class QDataStream; + +class QScriptDebuggerValuePrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerValue +{ +public: + enum ValueType { + NoValue, + UndefinedValue, + NullValue, + BooleanValue, + StringValue, + NumberValue, + ObjectValue + }; + + QScriptDebuggerValue(); + QScriptDebuggerValue(const QScriptValue &value); + QScriptDebuggerValue(double value); + QScriptDebuggerValue(bool value); + QScriptDebuggerValue(const QString &value); + QScriptDebuggerValue(qint64 objectId); + QScriptDebuggerValue(ValueType type); + QScriptDebuggerValue(const QScriptDebuggerValue &other); + ~QScriptDebuggerValue(); + + QScriptDebuggerValue &operator=(const QScriptDebuggerValue &other); + + ValueType type() const; + + double numberValue() const; + bool booleanValue() const; + QString stringValue() const; + qint64 objectId() const; + + QScriptValue toScriptValue(QScriptEngine *engine) const; + QString toString() const; + + bool operator==(const QScriptDebuggerValue &other) const; + bool operator!=(const QScriptDebuggerValue &other) const; + +private: + QScriptDebuggerValuePrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptDebuggerValue) +}; + +typedef QList<QScriptDebuggerValue> QScriptDebuggerValueList; + +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerValue &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerValue &); + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp b/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp new file mode 100644 index 0000000..723e304 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebuggervalueproperty_p.h" +#include "qscriptdebuggervalue_p.h" + +#include <QtCore/qatomic.h> +#include <QtCore/qdatastream.h> +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +/*! + \internal + \class QScriptDebuggerValueProperty +*/ + +class QScriptDebuggerValuePropertyPrivate +{ +public: + QScriptDebuggerValuePropertyPrivate(); + ~QScriptDebuggerValuePropertyPrivate(); + + QString name; + QScriptDebuggerValue value; + QString valueAsString; + QScriptValue::PropertyFlags flags; + + QBasicAtomicInt ref; +}; + +QScriptDebuggerValuePropertyPrivate::QScriptDebuggerValuePropertyPrivate() +{ + ref = 0; +} + +QScriptDebuggerValuePropertyPrivate::~QScriptDebuggerValuePropertyPrivate() +{ +} + +/*! + Constructs an invalid QScriptDebuggerValueProperty. +*/ +QScriptDebuggerValueProperty::QScriptDebuggerValueProperty() + : d_ptr(0) +{ +} + +/*! + Constructs a QScriptDebuggerValueProperty with the given \a name, + \a value and \a flags. +*/ +QScriptDebuggerValueProperty::QScriptDebuggerValueProperty(const QString &name, + const QScriptDebuggerValue &value, + const QString &valueAsString, + QScriptValue::PropertyFlags flags) + : d_ptr(new QScriptDebuggerValuePropertyPrivate) +{ + d_ptr->name = name; + d_ptr->value = value; + d_ptr->valueAsString = valueAsString; + d_ptr->flags = flags; + d_ptr->ref.ref(); +} + +/*! + Constructs a QScriptDebuggerValueProperty that is a copy of the \a other property. +*/ +QScriptDebuggerValueProperty::QScriptDebuggerValueProperty(const QScriptDebuggerValueProperty &other) + : d_ptr(other.d_ptr) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +/*! + Destroys this QScriptDebuggerValueProperty. +*/ +QScriptDebuggerValueProperty::~QScriptDebuggerValueProperty() +{ + if (d_ptr && !d_ptr->ref.deref()) { + delete d_ptr; + d_ptr = 0; + } +} + +/*! + Assigns the \a other property to this QScriptDebuggerValueProperty. +*/ +QScriptDebuggerValueProperty &QScriptDebuggerValueProperty::operator=(const QScriptDebuggerValueProperty &other) +{ + if (d_ptr == other.d_ptr) + return *this; + if (d_ptr && !d_ptr->ref.deref()) + delete d_ptr; + d_ptr = other.d_ptr; + if (d_ptr) + d_ptr->ref.ref(); + return *this; +} + +/*! + Returns the name of this QScriptDebuggerValueProperty. +*/ +QString QScriptDebuggerValueProperty::name() const +{ + Q_D(const QScriptDebuggerValueProperty); + if (!d) + return QString(); + return d->name; +} + +/*! + Returns the value of this QScriptDebuggerValueProperty. +*/ +QScriptDebuggerValue QScriptDebuggerValueProperty::value() const +{ + Q_D(const QScriptDebuggerValueProperty); + if (!d) + return QScriptDebuggerValue(); + return d->value; +} + +QString QScriptDebuggerValueProperty::valueAsString() const +{ + Q_D(const QScriptDebuggerValueProperty); + if (!d) + return QString(); + return d->valueAsString; +} + +/*! + Returns the flags of this QScriptDebuggerValueProperty. +*/ +QScriptValue::PropertyFlags QScriptDebuggerValueProperty::flags() const +{ + Q_D(const QScriptDebuggerValueProperty); + if (!d) + return 0; + return d->flags; +} + +/*! + Returns true if this QScriptDebuggerValueProperty is valid, otherwise + returns false. +*/ +bool QScriptDebuggerValueProperty::isValid() const +{ + Q_D(const QScriptDebuggerValueProperty); + return (d != 0); +} + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QScriptDebuggerValueProperty &property) + \relates QScriptDebuggerValueProperty + + Writes the given \a property to the specified \a stream. +*/ +QDataStream &operator<<(QDataStream &out, const QScriptDebuggerValueProperty &property) +{ + out << property.name(); + out << property.value(); + out << property.valueAsString(); + out << (quint32)property.flags(); + return out; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QScriptDebuggerValueProperty &property) + \relates QScriptDebuggerValueProperty + + Reads a QScriptDebuggerValueProperty from the specified \a stream into the + given \a property. +*/ +QDataStream &operator>>(QDataStream &in, QScriptDebuggerValueProperty &property) +{ + QString name; + QScriptDebuggerValue value; + QString valueAsString; + quint32 flags; + in >> name; + in >> value; + in >> valueAsString; + in >> flags; + property = QScriptDebuggerValueProperty( + name, value, valueAsString, QScriptValue::PropertyFlags(flags)); + return in; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebuggervalueproperty_p.h b/src/scripttools/debugging/qscriptdebuggervalueproperty_p.h new file mode 100644 index 0000000..f67bafd --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggervalueproperty_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERVALUEPROPERTY_P_H +#define QSCRIPTDEBUGGERVALUEPROPERTY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> +#include <QtCore/qlist.h> +#include <QtScript/qscriptvalue.h> + +QT_BEGIN_NAMESPACE + +class QDataStream; +class QString; +class QScriptDebuggerValue; + +class QScriptDebuggerValuePropertyPrivate; +class Q_AUTOTEST_EXPORT QScriptDebuggerValueProperty +{ +public: + QScriptDebuggerValueProperty(); + QScriptDebuggerValueProperty(const QString &name, + const QScriptDebuggerValue &value, + const QString &valueAsString, + QScriptValue::PropertyFlags flags); + QScriptDebuggerValueProperty(const QScriptDebuggerValueProperty &other); + ~QScriptDebuggerValueProperty(); + + QScriptDebuggerValueProperty &operator=(const QScriptDebuggerValueProperty &other); + + QString name() const; + QScriptDebuggerValue value() const; + QString valueAsString() const; + QScriptValue::PropertyFlags flags() const; + + bool isValid() const; + +private: + QScriptDebuggerValuePropertyPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptDebuggerValueProperty) +}; + +typedef QList<QScriptDebuggerValueProperty> QScriptDebuggerValuePropertyList; + +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptDebuggerValueProperty &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptDebuggerValueProperty &); + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebuggerwidgetfactoryinterface_p.h b/src/scripttools/debugging/qscriptdebuggerwidgetfactoryinterface_p.h new file mode 100644 index 0000000..9ad1eeb --- /dev/null +++ b/src/scripttools/debugging/qscriptdebuggerwidgetfactoryinterface_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGGERWIDGETFACTORYINTERFACE_P_H +#define QSCRIPTDEBUGGERWIDGETFACTORYINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebugOutputWidgetInterface; +class QScriptDebuggerConsoleWidgetInterface; +class QScriptErrorLogWidgetInterface; +class QScriptDebuggerCodeFinderWidgetInterface; + +class Q_AUTOTEST_EXPORT QScriptDebuggerWidgetFactoryInterface +{ +public: + virtual ~QScriptDebuggerWidgetFactoryInterface() {} + + virtual QScriptDebugOutputWidgetInterface *createDebugOutputWidget() = 0; + virtual QScriptDebuggerConsoleWidgetInterface *createConsoleWidget() = 0; + virtual QScriptErrorLogWidgetInterface *createErrorLogWidget() = 0; + virtual QScriptDebuggerCodeFinderWidgetInterface *createCodeFinderWidget() = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebugoutputwidget.cpp b/src/scripttools/debugging/qscriptdebugoutputwidget.cpp new file mode 100644 index 0000000..40c7aae --- /dev/null +++ b/src/scripttools/debugging/qscriptdebugoutputwidget.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebugoutputwidget_p.h" +#include "qscriptdebugoutputwidgetinterface_p_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qplaintextedit.h> +#include <QtGui/qscrollbar.h> + +QT_BEGIN_NAMESPACE + +namespace { + +class OutputEdit : public QPlainTextEdit +{ +public: + OutputEdit(QWidget *parent = 0) + : QPlainTextEdit(parent) + { + setReadOnly(true); +// setFocusPolicy(Qt::NoFocus); + setMaximumBlockCount(2500); + } + + void scrollToBottom() + { + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); + } + + int charactersPerLine() const + { + QFontMetrics fm(font()); + return width() / fm.maxWidth(); + } +}; + +} // namespace + +class QScriptDebugOutputWidgetPrivate + : public QScriptDebugOutputWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptDebugOutputWidget) +public: + QScriptDebugOutputWidgetPrivate(); + ~QScriptDebugOutputWidgetPrivate(); + + OutputEdit *outputEdit; +}; + +QScriptDebugOutputWidgetPrivate::QScriptDebugOutputWidgetPrivate() +{ +} + +QScriptDebugOutputWidgetPrivate::~QScriptDebugOutputWidgetPrivate() +{ +} + +QScriptDebugOutputWidget::QScriptDebugOutputWidget(QWidget *parent) + : QScriptDebugOutputWidgetInterface(*new QScriptDebugOutputWidgetPrivate, parent, 0) +{ + Q_D(QScriptDebugOutputWidget); + d->outputEdit = new OutputEdit(); + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->setSpacing(0); + vbox->addWidget(d->outputEdit); + +#ifndef QT_NO_STYLE_STYLESHEET + QString sheet = QString::fromLatin1("font-size: 14px; font-family: \"Monospace\";"); + setStyleSheet(sheet); +#endif +} + +QScriptDebugOutputWidget::~QScriptDebugOutputWidget() +{ +} + +void QScriptDebugOutputWidget::message( + QtMsgType type, const QString &text, const QString &fileName, + int lineNumber, int columnNumber, const QVariant &/*data*/) +{ + // ### unify with QScriptDebuggerConsoleWidget::message() + Q_D(QScriptDebugOutputWidget); + QString msg; + if (!fileName.isEmpty() || (lineNumber != -1)) { + if (!fileName.isEmpty()) + msg.append(fileName); + else + msg.append(QLatin1String("<noname>")); + if (lineNumber != -1) { + msg.append(QLatin1Char(':')); + msg.append(QString::number(lineNumber)); + if (columnNumber != -1) { + msg.append(QLatin1Char(':')); + msg.append(QString::number(columnNumber)); + } + } + msg.append(QLatin1String(": ")); + } + msg.append(text); + QTextCharFormat oldFmt = d->outputEdit->currentCharFormat(); + QTextCharFormat fmt(oldFmt); + if (type == QtCriticalMsg) { + fmt.setForeground(Qt::red); + d->outputEdit->setCurrentCharFormat(fmt); + } + d->outputEdit->appendPlainText(msg); + d->outputEdit->setCurrentCharFormat(oldFmt); + d->outputEdit->scrollToBottom(); +} + +void QScriptDebugOutputWidget::clear() +{ + Q_D(QScriptDebugOutputWidget); + d->outputEdit->clear(); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebugoutputwidget_p.h b/src/scripttools/debugging/qscriptdebugoutputwidget_p.h new file mode 100644 index 0000000..d4cfd71 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebugoutputwidget_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGOUTPUTWIDGET_P_H +#define QSCRIPTDEBUGOUTPUTWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebugoutputwidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebugOutputWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptDebugOutputWidget: + public QScriptDebugOutputWidgetInterface +{ + Q_OBJECT +public: + QScriptDebugOutputWidget(QWidget *parent = 0); + ~QScriptDebugOutputWidget(); + + void message(QtMsgType type, const QString &text, + const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1, + const QVariant &data = QVariant()); + + void clear(); + +private: + Q_DECLARE_PRIVATE(QScriptDebugOutputWidget) + Q_DISABLE_COPY(QScriptDebugOutputWidget) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebugoutputwidgetinterface.cpp b/src/scripttools/debugging/qscriptdebugoutputwidgetinterface.cpp new file mode 100644 index 0000000..6052ccc --- /dev/null +++ b/src/scripttools/debugging/qscriptdebugoutputwidgetinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdebugoutputwidgetinterface_p.h" +#include "qscriptdebugoutputwidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptDebugOutputWidgetInterfacePrivate::QScriptDebugOutputWidgetInterfacePrivate() +{ +} + +QScriptDebugOutputWidgetInterfacePrivate::~QScriptDebugOutputWidgetInterfacePrivate() +{ +} + +QScriptDebugOutputWidgetInterface::~QScriptDebugOutputWidgetInterface() +{ +} + +QScriptDebugOutputWidgetInterface::QScriptDebugOutputWidgetInterface( + QScriptDebugOutputWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptdebugoutputwidgetinterface_p.h b/src/scripttools/debugging/qscriptdebugoutputwidgetinterface_p.h new file mode 100644 index 0000000..ec3f88c --- /dev/null +++ b/src/scripttools/debugging/qscriptdebugoutputwidgetinterface_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGOUTPUTWIDGETINTERFACE_P_H +#define QSCRIPTDEBUGOUTPUTWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +#include "qscriptmessagehandlerinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptDebugOutputWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptDebugOutputWidgetInterface: + public QWidget, + public QScriptMessageHandlerInterface +{ + Q_OBJECT +public: + ~QScriptDebugOutputWidgetInterface(); + + virtual void clear() = 0; + +protected: + QScriptDebugOutputWidgetInterface(QScriptDebugOutputWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptDebugOutputWidgetInterface) + Q_DISABLE_COPY(QScriptDebugOutputWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptdebugoutputwidgetinterface_p_p.h b/src/scripttools/debugging/qscriptdebugoutputwidgetinterface_p_p.h new file mode 100644 index 0000000..0536b89 --- /dev/null +++ b/src/scripttools/debugging/qscriptdebugoutputwidgetinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTDEBUGOUTPUTWIDGETINTERFACE_P_P_H +#define QSCRIPTDEBUGOUTPUTWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptDebugOutputWidgetInterface; +class QScriptDebugOutputWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptDebugOutputWidgetInterface) +public: + QScriptDebugOutputWidgetInterfacePrivate(); + ~QScriptDebugOutputWidgetInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptedit.cpp b/src/scripttools/debugging/qscriptedit.cpp new file mode 100644 index 0000000..2bc0a40 --- /dev/null +++ b/src/scripttools/debugging/qscriptedit.cpp @@ -0,0 +1,453 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptedit_p.h" +#include "qscriptsyntaxhighlighter_p.h" + +#include <QtGui/qpainter.h> +#include <QtGui/qicon.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qlabel.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qmenu.h> +#include <QtGui/qaction.h> +#include <QtGui/qwidgetaction.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QScriptEditExtraArea : public QWidget +{ +public: + QScriptEditExtraArea(QScriptEdit *edit) + : QWidget(edit) + { + setMouseTracking(true); + } + + QSize sizeHint() const { + return QSize(editor()->extraAreaWidth(), 0); + } + +protected: + void paintEvent(QPaintEvent *event) + { + editor()->extraAreaPaintEvent(event); + } + void mousePressEvent(QMouseEvent *event) + { + editor()->extraAreaMouseEvent(event); + } + void mouseMoveEvent(QMouseEvent *event) + { + editor()->extraAreaMouseEvent(event); + } + void mouseReleaseEvent(QMouseEvent *event) + { + editor()->extraAreaMouseEvent(event); + } + bool event(QEvent *event) + { + if (editor()->extraAreaEvent(event)) + return true; + return QWidget::event(event); + } + +private: + QScriptEdit *editor() const + { + return qobject_cast<QScriptEdit*>(parent()); + } +}; + + + +QScriptEdit::QScriptEdit(QWidget *parent) + : QPlainTextEdit(parent) +{ + m_baseLineNumber = 1; + m_executionLineNumber = -1; + + m_extraArea = new QScriptEditExtraArea(this); + + QObject::connect(this, SIGNAL(blockCountChanged(int)), + this, SLOT(updateExtraAreaWidth())); + QObject::connect(this, SIGNAL(updateRequest(const QRect &, int)), + this, SLOT(updateExtraArea(const QRect &, int))); + QObject::connect(this, SIGNAL(cursorPositionChanged()), + this, SLOT(highlightCurrentLine())); + + updateExtraAreaWidth(); + +#ifndef QT_NO_SYNTAXHIGHLIGHTER + (void) new QScriptSyntaxHighlighter(document()); +#endif +} + +QScriptEdit::~QScriptEdit() +{ +} + +int QScriptEdit::baseLineNumber() const +{ + return m_baseLineNumber; +} + +void QScriptEdit::setBaseLineNumber(int base) +{ + m_baseLineNumber = base; + m_extraArea->update(); +} + +int QScriptEdit::executionLineNumber() const +{ + return m_executionLineNumber; +} + +void QScriptEdit::setExecutionLineNumber(int lineNumber, bool error) +{ + m_executionLineNumber = lineNumber; + m_executionLineNumberHasError = error; + m_extraArea->update(); + updateExtraSelections(); + gotoLine(lineNumber); +} + +void QScriptEdit::setExecutableLineNumbers(const QSet<int> &lineNumbers) +{ + m_executableLineNumbers = lineNumbers; +} + +int QScriptEdit::currentLineNumber() const +{ + return textCursor().blockNumber() + m_baseLineNumber; +} + +void QScriptEdit::gotoLine(int lineNumber) +{ + int blockNumber = lineNumber - m_baseLineNumber; + const QTextBlock &block = document()->findBlockByNumber(blockNumber); + if (block.isValid()) { + setTextCursor(QTextCursor(block)); + centerCursor(); + } +} + +void QScriptEdit::setBreakpoint(int lineNumber) +{ + m_breakpoints[lineNumber] = BreakpointData(); + m_extraArea->update(); +} + +void QScriptEdit::setBreakpointEnabled(int lineNumber, bool enable) +{ + m_breakpoints[lineNumber].enabled = enable; + m_extraArea->update(); +} + +void QScriptEdit::deleteBreakpoint(int lineNumber) +{ + m_breakpoints.remove(lineNumber); + m_extraArea->update(); +} + +void QScriptEdit::paintEvent(QPaintEvent *e) +{ + QPlainTextEdit::paintEvent(e); +} + +void QScriptEdit::resizeEvent(QResizeEvent *e) +{ + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + int x = isLeftToRight() ? cr.left() : cr.left() + cr.width() - extraAreaWidth(); + m_extraArea->setGeometry(QRect(x, cr.top(), extraAreaWidth(), cr.height())); +} + +void QScriptEdit::updateExtraAreaWidth() +{ + if (isLeftToRight()) + setViewportMargins(extraAreaWidth(), 0, 0, 0); + else + setViewportMargins(0, 0, extraAreaWidth(), 0); +} + +void QScriptEdit::updateExtraArea(const QRect &rect, int dy) +{ + if (dy) + m_extraArea->scroll(0, dy); + else + m_extraArea->update(0, rect.y(), m_extraArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateExtraAreaWidth(); +} + +void QScriptEdit::highlightCurrentLine() +{ + updateExtraSelections(); +} + +void QScriptEdit::updateExtraSelections() +{ + QList<QTextEdit::ExtraSelection> extraSelections; + + { + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + if (m_executionLineNumber != -1) { + QTextEdit::ExtraSelection selection; + QColor lineColor; + if (m_executionLineNumberHasError) + lineColor = QColor(Qt::red); + else + lineColor = QColor(Qt::green).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + int blockNumber = m_executionLineNumber - m_baseLineNumber; + selection.cursor = QTextCursor(document()->findBlockByNumber(blockNumber)); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + + setExtraSelections(extraSelections); +} + +int QScriptEdit::extraAreaWidth() const +{ + int space = 0; + const QFontMetrics fm(fontMetrics()); + + int digits = 1; + int max = qMax(1, blockCount() + m_baseLineNumber); + while (max >= 10) { + max /= 10; + ++digits; + } + space += fm.width(QLatin1Char('9')) * digits; + + int markWidth = fm.lineSpacing(); + space += markWidth; + + space += 4; + + return space; +} + +void QScriptEdit::extraAreaPaintEvent(QPaintEvent *e) +{ + QRect rect = e->rect(); + QPalette pal = palette(); + pal.setCurrentColorGroup(QPalette::Active); + QPainter painter(m_extraArea); + painter.fillRect(rect, Qt::lightGray); + const QFontMetrics fm(fontMetrics()); + + int markWidth = fm.lineSpacing(); + int extraAreaWidth = m_extraArea->width(); + + QLinearGradient gradient(QPointF(extraAreaWidth - 10, 0), QPointF(extraAreaWidth, 0)); + gradient.setColorAt(0, pal.color(QPalette::Background)); + gradient.setColorAt(1, pal.color(QPalette::Base)); + painter.fillRect(rect, gradient); + + QLinearGradient gradient2(QPointF(0, 0), QPointF(markWidth, 0)); + gradient2.setColorAt(0, pal.color(QPalette::Dark)); + gradient2.setColorAt(1, pal.color(QPalette::Background)); + painter.fillRect(rect.intersected(QRect(rect.x(), rect.y(), markWidth, rect.height())), gradient2); + + painter.setPen(QPen(pal.color(QPalette::Background), 2)); + if (isLeftToRight()) + painter.drawLine(rect.x() + extraAreaWidth-1, rect.top(), rect.x() + extraAreaWidth-1, rect.bottom()); + else + painter.drawLine(rect.x(), rect.top(), rect.x(), rect.bottom()); + painter.setRenderHint(QPainter::Antialiasing); + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + qreal top = blockBoundingGeometry(block).translated(contentOffset()).top(); + qreal bottom = top + blockBoundingRect(block).height(); + + QString imagesPath = QString::fromLatin1(":/qt/scripttools/debugging/images"); + QString imageExt; +// SVGs don't work on all platforms, even when QT_NO_SVG is not defined, so disable SVG usage for now. +// #ifndef QT_NO_SVG +#if 0 + imageExt = QString::fromLatin1("svg"); +#else + imageExt = QString::fromLatin1("png"); +#endif + + while (block.isValid() && top <= rect.bottom()) { + if (block.isVisible() && bottom >= rect.top()) { + + int lineNumber = blockNumber + m_baseLineNumber; + if (m_breakpoints.contains(lineNumber)) { + int radius = fm.lineSpacing() - 1; + QRect r(rect.x(), (int)top, radius, radius); + QIcon icon(m_breakpoints[lineNumber].enabled + ? QString::fromLatin1("%0/breakpoint.%1").arg(imagesPath).arg(imageExt) + : QString::fromLatin1("%0/d_breakpoint.%1").arg(imagesPath).arg(imageExt)); + icon.paint(&painter, r, Qt::AlignCenter); + } + if (m_executionLineNumber == lineNumber) { + int radius = fm.lineSpacing() - 1; + QRect r(rect.x(), (int)top, radius, radius); + QIcon icon(QString::fromLatin1("%0/location.%1").arg(imagesPath).arg(imageExt)); + icon.paint(&painter, r, Qt::AlignCenter); + } + +#if QT_VERSION >= 0x040500 + if (!m_executableLineNumbers.contains(lineNumber)) + painter.setPen(pal.color(QPalette::Mid)); + else +#endif + painter.setPen(QColor(Qt::darkCyan)); + QString number = QString::number(lineNumber); + painter.drawText(rect.x() + markWidth, (int)top, rect.x() + extraAreaWidth - markWidth - 4, + fm.height(), Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + blockBoundingRect(block).height(); + ++blockNumber; + } +} + +void QScriptEdit::extraAreaMouseEvent(QMouseEvent *e) +{ + QTextCursor cursor = cursorForPosition(QPoint(0, e->pos().y())); + cursor.setPosition(cursor.block().position()); + + QFontMetrics fm(font()); + int markWidth = fm.lineSpacing(); + + if (e->type() == QEvent::MouseMove && e->buttons() == 0) { // mouse tracking + bool hand = (e->pos().x() <= markWidth); +#if QT_VERSION >= 0x040500 + int lineNumber = cursor.blockNumber() + m_baseLineNumber; + hand = hand && m_executableLineNumbers.contains(lineNumber); +#endif +#ifndef QT_NO_CURSOR + if (hand != (m_extraArea->cursor().shape() == Qt::PointingHandCursor)) + m_extraArea->setCursor(hand ? Qt::PointingHandCursor : Qt::ArrowCursor); +#endif + } + + if (e->type() == QEvent::MouseButtonPress) { + if (e->button() == Qt::LeftButton) { +#if QT_VERSION >= 0x040500 + int lineNumber = cursor.blockNumber() + m_baseLineNumber; + bool executable = m_executableLineNumbers.contains(lineNumber); +#else + bool executable = true; +#endif + if ((e->pos().x() <= markWidth) && executable) + m_extraAreaToggleBlockNumber = cursor.blockNumber(); + else + m_extraAreaToggleBlockNumber = -1; + } + } else if (e->type() == QEvent::MouseButtonRelease) { + if (e->button() == Qt::LeftButton) { + if ((m_extraAreaToggleBlockNumber != -1) && (e->pos().x() <= markWidth)) { + int lineNumber = m_extraAreaToggleBlockNumber + m_baseLineNumber; + bool on = !m_breakpoints.contains(lineNumber); + emit breakpointToggleRequest(lineNumber, on); + } + } else if (e->button() == Qt::RightButton) { + int lineNumber = cursor.blockNumber() + m_baseLineNumber; +#if QT_VERSION >= 0x040500 + if (!m_executableLineNumbers.contains(lineNumber)) + return; +#endif + bool has = m_breakpoints.contains(lineNumber); + QMenu *popup = new QMenu(); + QAction *toggleAct = new QAction(QObject::tr("Toggle Breakpoint"), popup); + popup->addAction(toggleAct); + QAction *disableAct = new QAction(QObject::tr("Disable Breakpoint"), popup); + QAction *enableAct = new QAction(QObject::tr("Enable Breakpoint"), popup); + QWidget *conditionWidget = new QWidget(); + { + QHBoxLayout *hbox = new QHBoxLayout(conditionWidget); + hbox->addWidget(new QLabel(QObject::tr("Breakpoint Condition:"))); + hbox->addWidget(new QLineEdit()); + } +// QWidgetAction *conditionAct = new QWidgetAction(popup); +// conditionAct->setDefaultWidget(conditionWidget); + if (has) { + popup->addSeparator(); + popup->addAction(m_breakpoints[lineNumber].enabled ? disableAct : enableAct); +// popup->addAction(conditionAct); + } + QAction *ret = popup->exec(e->globalPos()); + if (ret) { + if (ret == toggleAct) { + emit breakpointToggleRequest(lineNumber, !has); + } else if (ret == disableAct) { + emit breakpointEnableRequest(lineNumber, false); + } else if (ret == enableAct) { + emit breakpointEnableRequest(lineNumber, true); + }// else if (ret == conditionAct) { + //} + } + popup->deleteLater(); + } + } +} + +bool QScriptEdit::extraAreaEvent(QEvent *e) +{ + if (e->type() == QEvent::ToolTip) { + // ### show the breakpoint's condition, if any + return true; + } + return false; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptedit_p.h b/src/scripttools/debugging/qscriptedit_p.h new file mode 100644 index 0000000..f2bdf14 --- /dev/null +++ b/src/scripttools/debugging/qscriptedit_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTEDIT_P_H +#define QSCRIPTEDIT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qplaintextedit.h> + +#include <QtCore/qhash.h> +#include <QtCore/qset.h> + +QT_BEGIN_NAMESPACE + +class QScriptEditExtraArea; + +class Q_AUTOTEST_EXPORT QScriptEdit : public QPlainTextEdit +{ + Q_OBJECT +public: + QScriptEdit(QWidget *parent = 0); + ~QScriptEdit(); + + int baseLineNumber() const; + void setBaseLineNumber(int base); + + int executionLineNumber() const; + void setExecutionLineNumber(int lineNumber, bool error); + void setExecutableLineNumbers(const QSet<int> &lineNumbers); + + int currentLineNumber() const; + void gotoLine(int lineNumber); + + void setBreakpoint(int lineNumber); + void setBreakpointEnabled(int lineNumber, bool enable); + void deleteBreakpoint(int lineNumber); + + int extraAreaWidth() const; + +signals: + void breakpointToggleRequest(int lineNumber, bool on); + void breakpointEnableRequest(int lineNumber, bool enable); + +protected: + void paintEvent(QPaintEvent *e); + void resizeEvent(QResizeEvent *e); + + void extraAreaPaintEvent(QPaintEvent *e); + void extraAreaMouseEvent(QMouseEvent *e); + bool extraAreaEvent(QEvent *e); + +private slots: + void updateExtraAreaWidth(); + void updateExtraArea(const QRect &, int); + void highlightCurrentLine(); + +private: + QTextEdit::ExtraSelection currentLineSelection() const; + QTextEdit::ExtraSelection currentExecutionLineSelection() const; + void updateExtraSelections(); + +private: + QScriptEditExtraArea *m_extraArea; + int m_baseLineNumber; + int m_executionLineNumber; + QSet<int> m_executableLineNumbers; + bool m_executionLineNumberHasError; + int m_extraAreaToggleBlockNumber; + + struct BreakpointData { + BreakpointData() : enabled(true) {} + bool enabled; + }; + QHash<int, BreakpointData> m_breakpoints; + +private: + Q_DISABLE_COPY(QScriptEdit) + friend class QScriptEditExtraArea; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptenginedebugger.cpp b/src/scripttools/debugging/qscriptenginedebugger.cpp new file mode 100644 index 0000000..e35bd1d --- /dev/null +++ b/src/scripttools/debugging/qscriptenginedebugger.cpp @@ -0,0 +1,792 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptenginedebugger.h" +#include "qscriptdebugger_p.h" +#include "qscriptenginedebuggerfrontend_p.h" +#include "qscriptdebuggerconsolewidget_p.h" +#include "qscriptdebuggerstackwidget_p.h" +#include "qscriptdebuggerscriptswidget_p.h" +#include "qscriptdebuggerlocalswidget_p.h" +#include "qscriptdebuggercodewidget_p.h" +#include "qscriptdebuggercodefinderwidget_p.h" +#include "qscriptbreakpointswidget_p.h" +#include "qscriptdebugoutputwidget_p.h" +#include "qscripterrorlogwidget_p.h" +#include "qscriptdebuggerwidgetfactoryinterface_p.h" +#include <private/qobject_p.h> + +#include <QtCore/qsettings.h> +#include <QtGui/qapplication.h> +#include <QtGui/qdockwidget.h> +#include <QtGui/qmainwindow.h> +#include <QtGui/qmenu.h> +#include <QtGui/qmenubar.h> +#include <QtGui/qtoolbar.h> +#include <QtGui/qboxlayout.h> + +class QtScriptDebuggerResourceInitializer +{ +public: + QtScriptDebuggerResourceInitializer() { + Q_INIT_RESOURCE(scripttools_debugging); + } +}; + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptEngineDebugger + + \brief The QScriptEngineDebugger class provides a QScriptEngine debugger. + + \ingroup scripttools + \mainclass + + The QScriptEngineDebugger class provides a debugger that can be + embedded into Qt applications that use Qt Script. The debugger + enables the application user to inspect the state of the script + environment and control script execution. + + To attach the debugger to a script engine, call the attachTo() + function. + + \snippet doc/src/snippets/code/src.scripttools.qscriptenginedebugger.cpp 0 + + Once the debugger has been attached to a script engine, you can + proceed to evaluate scripts as usual, e.g. by calling + QScriptEngine::evaluate(). The debugger will be triggered when an + uncaught exception occurs, or when a \c{debugger} statement is + encountered in a script. It is also possible to interrupt script + evaluation at an arbitrary time by triggering the InterruptAction. + For instance, to start the debugger when script evaluation starts, + you trigger the action before you begin to \l{QScriptEngine::}{evaluate()} + the script. + + \snippet doc/src/snippets/scriptdebugger.cpp 2 + + By default, the \l{standardWindow()}{standard debugger window} is shown when + evaluation is suspended. This can be changed by calling the + setAutoShowStandardWindow() function. + + The debugger defines a set of \l{DebuggerAction}{actions} that are + available, such as stopping execution or printing the contents of a + variable. It also provides a set of widgets (components) that + display the information available from the debugger and that trigger + the actions on request. The actions available are identified by the + DebuggerAction enum, and the widgets are identified by the + DebuggerWidget enum. + + Access to the individual debugger widgets is provided by the + widget() function. This makes it possible to arrange the widgets in + a custom manner. Similarly, the action() function provides access + to the various debugger actions. + + The createStandardToolBar() function creates a standard toolbar, and the + createStandardMenu() function creates a standard menu; these functions can + be useful if you are creating a custom debugger configuration. + + The evaluationSuspended() signal is emitted when the debugger has + suspended script evaluation and entered interactive mode, i.e., the + mode in which it accepts input from the user. The + evaluationResumed() signal is emitted when script evaluation is + resumed, i.e, when execution control is given back to the script + engine. + + When calling QScriptEngine::evaluate() it is useful to pass a + descriptive script name (file name) as second argument, as this is + the name that will be displayed by the debugger in the + ScriptsWidget; if a name is not passed, the script will be labelled + "anonymous". + + When evaluation is suspended, the debugger will also suspend the + event loop of the script. In the following snippet, the call to + QScriptEngine::evaluate() causes the debugger to be triggered, and + the function call does not return until the user has finished + interacting with the debugger. + + \snippet doc/src/snippets/code/src.scripttools.qscriptenginedebugger.cpp 1 + + When the Qt Script debugger is running, the C++ application itself + is not "frozen". This means that it is possible that more scripts + are evaluated, even though the debugger has suspended evaluation of + the \bold{current} script evaluation. For example, a C++ timer might + trigger that causes a script function to be called, or the user + might click on a button in the main application user interface whose + clicked() signal is connected to a script function. This kind of + nested evaluation is permitted. The debugger will enter interactive + mode for the new script if an exception is thrown or a breakpoint is + reached. Note that it will not stop when encountering \c{debugger} + statements. \omit The effects are similar to those achieved by + typing a program into the debugger's console and evaluating + it. \endomit + + Nested evaluation requires some thought when deciding + how the debugger is presented to the user; for example, whether a + modal dialog is suitable, or whether some parts of the main + application user interface should be disabled while the debugger is + running. \omit Seems unfinished somehow \endomit + + Debugging inside of a \l{QWidget::paintEvent()}{paintEvent}() is + currently not supported. If you need to debug painting-related + script code, that code should be evaluated outside of the C++ + paintEvent(), e.g. by rendering to an image, like the Context2D and + Tetrix QtScript examples do. This will make the code safe for + debugging. + + The debugger adds some special properties to the script engine: + \c{__FILE__} holds the name of the script in which the current + evaluation occurs, and \c{__LINE__} holds the current line + number. These are useful when doing print()-style debugging (the + messages appear in the debugger's debug output widget). + + The \l{Qt Script Debugger Manual} describes how to use the debugger. + The \l{Context2D Example}{Context2D example} shows how to integrate + the debugger in applications. + + \sa QScriptEngine, {Context2D Example} +*/ + +/*! + \enum QScriptEngineDebugger::DebuggerWidget + + This enum decides the widget that the widget() function should + retrieve. We treat these widgets in more detail in the \l{Qt + Script Debugger Manual}. + + \value ConsoleWidget Provides a command-line interface to the debugger. + \value StackWidget Shows a backtrace of the script's execution state. + \value ScriptsWidget Displays a list of currently loaded scripts. + \value LocalsWidget Shows the local variables of the current stack frame. + \value CodeWidget Displays the code of the current script. + \value CodeFinderWidget Provides a widget that can search for text in the script shown in the + CodeWidget. + \value BreakpointsWidget Shows breakpoints that have been set. + \value DebugOutputWidget Contains output from the \c print() script function. + \value ErrorLogWidget Shows error messages that have been generated. +*/ + +/*! + \enum QScriptEngineDebugger::DebuggerAction + + This enum specifies the action that the action() function should + retrieve. The actions retrieved can be connected to any slot and + connected to any widget. Please see the \l{Qt Script Debugger Manual}'s + \l{Console Command Reference} for a detailed description of these actions. + + \value InterruptAction Suspends script execution as soon as the next script statement is reached. + \value ContinueAction Gives the execution control back to the script engine. + \value StepIntoAction Performs a step action. + \value StepOverAction Performs a next action. + \value StepOutAction Executes the script until the current function returns. + \value RunToCursorAction Continues execution to the selected line (which contains the cursor) in the CodeWidget. + \value RunToNewScriptAction Returns control to the script engine until a new script is executed. + \value ToggleBreakpointAction Toggles a breakpoint at the selected line in the CodeWidget. + \value ClearDebugOutputAction Clears the contents of the DebugOutputWidget. + \value ClearErrorLogAction Clears the contents of the ErrorLogWidget. + \value ClearConsoleAction Clears the contents of the ConsoleWidget. + \value FindInScriptAction Displays the CodeFinderWidget. + \value FindNextInScriptAction Finds next occurrence in the CodeWidget. + \value FindPreviousInScriptAction Finds previous occurrence in the CodeWidget. + \value GoToLineAction Shows the "Go to Line" dialog. +*/ + +class QScriptEngineDebuggerPrivate + : public QObjectPrivate, + public QScriptDebuggerWidgetFactoryInterface +{ + Q_DECLARE_PUBLIC(QScriptEngineDebugger) +public: + QScriptEngineDebuggerPrivate(); + ~QScriptEngineDebuggerPrivate(); + + QScriptDebugOutputWidgetInterface *createDebugOutputWidget(); + QScriptDebuggerConsoleWidgetInterface *createConsoleWidget(); + QScriptErrorLogWidgetInterface *createErrorLogWidget(); + QScriptDebuggerCodeFinderWidgetInterface *createCodeFinderWidget(); + + // private slots + void _q_showStandardWindow(); + + void createDebugger(); + + QScriptDebugger *debugger; + QScriptEngineDebuggerFrontend *frontend; + QMainWindow *standardWindow; + bool autoShow; + + static QtScriptDebuggerResourceInitializer resourceInitializer; +}; + +namespace { + +class WidgetClosedNotifier : public QObject +{ + Q_OBJECT +public: + WidgetClosedNotifier(QWidget *w, QObject *parent = 0) + : QObject(parent), widget(w) + { + w->installEventFilter(this); + } + + bool eventFilter(QObject *watched, QEvent *e) + { + if (watched != widget) + return false; + if (e->type() != QEvent::Close) + return false; + emit widgetClosed(); + return true; + } + +Q_SIGNALS: + void widgetClosed(); + +private: + QWidget *widget; +}; + +} // namespace + +QtScriptDebuggerResourceInitializer QScriptEngineDebuggerPrivate::resourceInitializer; + +QScriptEngineDebuggerPrivate::QScriptEngineDebuggerPrivate() +{ + debugger = 0; + frontend = 0; + standardWindow = 0; + autoShow = true; +} + +QScriptEngineDebuggerPrivate::~QScriptEngineDebuggerPrivate() +{ + delete debugger; + delete frontend; + if (standardWindow) { + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + QByteArray geometry = standardWindow->saveGeometry(); + settings.setValue(QLatin1String("Qt/scripttools/debugging/mainWindowGeometry"), geometry); + QByteArray state = standardWindow->saveState(); + settings.setValue(QLatin1String("Qt/scripttools/debugging/mainWindowState"), state); + if (standardWindow->parent() == 0) + delete standardWindow; + } +} + +QScriptDebugOutputWidgetInterface *QScriptEngineDebuggerPrivate::createDebugOutputWidget() +{ + return new QScriptDebugOutputWidget(); +} + +QScriptDebuggerConsoleWidgetInterface *QScriptEngineDebuggerPrivate::createConsoleWidget() +{ + return new QScriptDebuggerConsoleWidget(); +} + +QScriptErrorLogWidgetInterface *QScriptEngineDebuggerPrivate::createErrorLogWidget() +{ + return new QScriptErrorLogWidget(); +} + +QScriptDebuggerCodeFinderWidgetInterface *QScriptEngineDebuggerPrivate::createCodeFinderWidget() +{ + return new QScriptDebuggerCodeFinderWidget(); +} + +void QScriptEngineDebuggerPrivate::_q_showStandardWindow() +{ + Q_Q(QScriptEngineDebugger); + (void)q->standardWindow(); // ensure it's created + standardWindow->show(); +} + +void QScriptEngineDebuggerPrivate::createDebugger() +{ + Q_Q(QScriptEngineDebugger); + if (!debugger) { + debugger = new QScriptDebugger(); + debugger->setWidgetFactory(this); + QObject::connect(debugger, SIGNAL(started()), + q, SIGNAL(evaluationResumed())); + QObject::connect(debugger, SIGNAL(stopped()), + q, SIGNAL(evaluationSuspended())); + if (autoShow) { + QObject::connect(q, SIGNAL(evaluationSuspended()), + q, SLOT(_q_showStandardWindow())); + } + } +} + +/*! + Constructs a new QScriptEngineDebugger object with the given \a + parent. + + To attach a QScriptEngine to the debugger, use attachTo() + function. + +*/ +QScriptEngineDebugger::QScriptEngineDebugger(QObject *parent) + : QObject(*new QScriptEngineDebuggerPrivate, parent) +{ +} + +/*! + Destroys this QScriptEngineDebugger. +*/ +QScriptEngineDebugger::~QScriptEngineDebugger() +{ +} + +/*! + Attaches to the given \a engine. + + The debugger will install a custom agent (using + QScriptEngine::setAgent()) to monitor the engine. While the debugger + is attached, you should not change the agent; however, if you do + have to perform additional monitoring, you must set a proxy agent + that forwards all events to the debugger's agent. + + \sa detach() +*/ +void QScriptEngineDebugger::attachTo(QScriptEngine *engine) +{ + Q_D(QScriptEngineDebugger); + if (!engine) { + detach(); + return; + } + d->createDebugger(); + if (!d->frontend) + d->frontend = new QScriptEngineDebuggerFrontend(); + d->frontend->attachTo(engine); + d->debugger->setFrontend(d->frontend); +} + +/*! + Detaches from the current script engine, if any. + + \sa attachTo() +*/ +void QScriptEngineDebugger::detach() +{ + Q_D(QScriptEngineDebugger); + if (d->frontend) + d->frontend->detach(); + if (d->debugger) + d->debugger->setFrontend(0); +} + +/*! + + Returns a pointer to the instance of the specified standard \a + widget. The widgets available are defined by the DebuggerWidget + enum. + + A main window containing all widgets is returned by + standardWindow(). If you do not want to use this window, you can + fetch the individual widgets with this function. For instance, the + code example below shows how to set up a layout containing a + \l{QScriptEngineDebugger::CodeWidget}{code window} and a + \l{QScriptEngineDebugger::StackWidget}{stack widget}. + + \snippet doc/src/snippets/scriptdebugger.cpp 0 + + Note that you need to set setAutoShowStandardWindow() to false; if + not, the standard window will be shown regardless. + + \sa action(), standardWindow(), setAutoShowStandardWindow() +*/ +QWidget *QScriptEngineDebugger::widget(DebuggerWidget widget) const +{ + Q_D(const QScriptEngineDebugger); + const_cast<QScriptEngineDebuggerPrivate*>(d)->createDebugger(); + switch (widget) { + case ConsoleWidget: { + QScriptDebuggerConsoleWidgetInterface *w = d->debugger->consoleWidget(); + if (!w) { + w = new QScriptDebuggerConsoleWidget(); + d->debugger->setConsoleWidget(w); + } + return w; + } + case StackWidget: { + QScriptDebuggerStackWidgetInterface *w = d->debugger->stackWidget(); + if (!w) { + w = new QScriptDebuggerStackWidget(); + d->debugger->setStackWidget(w); + } + return w; + } + case ScriptsWidget: { + QScriptDebuggerScriptsWidgetInterface *w = d->debugger->scriptsWidget(); + if (!w) { + w = new QScriptDebuggerScriptsWidget(); + d->debugger->setScriptsWidget(w); + } + return w; + } + case LocalsWidget: { + QScriptDebuggerLocalsWidgetInterface *w = d->debugger->localsWidget(); + if (!w) { + w = new QScriptDebuggerLocalsWidget(); + d->debugger->setLocalsWidget(w); + } + return w; + } + case CodeWidget: { + QScriptDebuggerCodeWidgetInterface *w = d->debugger->codeWidget(); + if (!w) { + w = new QScriptDebuggerCodeWidget(); + d->debugger->setCodeWidget(w); + } + return w; + } + case CodeFinderWidget: { + QScriptDebuggerCodeFinderWidgetInterface *w = d->debugger->codeFinderWidget(); + if (!w) { + w = new QScriptDebuggerCodeFinderWidget(); + d->debugger->setCodeFinderWidget(w); + } + return w; + } + case BreakpointsWidget: { + QScriptBreakpointsWidgetInterface *w = d->debugger->breakpointsWidget(); + if (!w) { + w = new QScriptBreakpointsWidget(); + d->debugger->setBreakpointsWidget(w); + } + return w; + } + case DebugOutputWidget: { + QScriptDebugOutputWidgetInterface *w = d->debugger->debugOutputWidget(); + if (!w) { + w = new QScriptDebugOutputWidget(); + d->debugger->setDebugOutputWidget(w); + } + return w; + } + case ErrorLogWidget: { + QScriptErrorLogWidgetInterface *w = d->debugger->errorLogWidget(); + if (!w) { + w = new QScriptErrorLogWidget(); + d->debugger->setErrorLogWidget(w); + } + return w; + } + } + return 0; +} + +/*! + Returns a pointer to the specified \a action. The actions available + are given by the DebuggerAction enum. + + With this function, you can add the actions to your own widgets, + toolbars, and menus. It is also convenient if you, for example, + wish to spice things up with your own groovy icons. The code + example below shows how to add actions to a QToolBar. + + \snippet doc/src/snippets/scriptdebugger.cpp 1 + + Note that QScriptEngineDebugger has already added the actions to + its \l{DebuggerWidget}{standard widgets} and \l{standardWindow()}{standard window}. + + \sa widget(), createStandardMenu(), createStandardToolBar(), standardWindow() +*/ +QAction *QScriptEngineDebugger::action(DebuggerAction action) const +{ + Q_D(const QScriptEngineDebugger); + QScriptEngineDebugger *that = const_cast<QScriptEngineDebugger*>(this); + that->d_func()->createDebugger(); + switch (action) { + case InterruptAction: + return d->debugger->interruptAction(that); + case ContinueAction: + return d->debugger->continueAction(that); + case StepIntoAction: + return d->debugger->stepIntoAction(that); + case StepOverAction: + return d->debugger->stepOverAction(that); + case StepOutAction: + return d->debugger->stepOutAction(that); + case RunToCursorAction: + return d->debugger->runToCursorAction(that); + case RunToNewScriptAction: + return d->debugger->runToNewScriptAction(that); + case ToggleBreakpointAction: + return d->debugger->toggleBreakpointAction(that); + case ClearDebugOutputAction: + return d->debugger->clearDebugOutputAction(that); + case ClearErrorLogAction: + return d->debugger->clearErrorLogAction(that); + case ClearConsoleAction: + return d->debugger->clearConsoleAction(that); + case FindInScriptAction: + return d->debugger->findInScriptAction(that); + case FindNextInScriptAction: + return d->debugger->findNextInScriptAction(that); + case FindPreviousInScriptAction: + return d->debugger->findPreviousInScriptAction(that); + case GoToLineAction: + return d->debugger->goToLineAction(that); + } + return 0; +} + +/*! + Returns whether the standard debugger window is automatically shown when + evaluation is suspended. + + The default is true. +*/ +bool QScriptEngineDebugger::autoShowStandardWindow() const +{ + Q_D(const QScriptEngineDebugger); + return d->autoShow; +} + +/*! + Sets whether the standard debugger window is automatically shown when + evaluation is suspended. If \a autoShow is true, the window will be + automatically shown, otherwise it will not. +*/ +void QScriptEngineDebugger::setAutoShowStandardWindow(bool autoShow) +{ + Q_D(QScriptEngineDebugger); + if (autoShow == d->autoShow) + return; + if (autoShow) { + QObject::connect(this, SIGNAL(evaluationSuspended()), + this, SLOT(_q_showStandardWindow())); + } else { + QObject::disconnect(this, SIGNAL(evaluationSuspended()), + this, SLOT(_q_showStandardWindow())); + } + d->autoShow = autoShow; +} + +/*! + Returns a main window with a standard configuration of the debugger's + components. + + \sa createStandardMenu(), createStandardToolBar() +*/ +QMainWindow *QScriptEngineDebugger::standardWindow() const +{ + Q_D(const QScriptEngineDebugger); + if (d->standardWindow) + return d->standardWindow; + if (!QApplication::instance()) + return 0; + QScriptEngineDebugger *that = const_cast<QScriptEngineDebugger*>(this); + + QMainWindow *win = new QMainWindow(); + QDockWidget *scriptsDock = new QDockWidget(win); + scriptsDock->setObjectName(QLatin1String("qtscriptdebugger_scriptsDockWidget")); + scriptsDock->setWindowTitle(QObject::tr("Loaded Scripts")); + scriptsDock->setWidget(widget(ScriptsWidget)); + win->addDockWidget(Qt::LeftDockWidgetArea, scriptsDock); + + QDockWidget *breakpointsDock = new QDockWidget(win); + breakpointsDock->setObjectName(QLatin1String("qtscriptdebugger_breakpointsDockWidget")); + breakpointsDock->setWindowTitle(QObject::tr("Breakpoints")); + breakpointsDock->setWidget(widget(BreakpointsWidget)); + win->addDockWidget(Qt::LeftDockWidgetArea, breakpointsDock); + + QDockWidget *stackDock = new QDockWidget(win); + stackDock->setObjectName(QLatin1String("qtscriptdebugger_stackDockWidget")); + stackDock->setWindowTitle(QObject::tr("Stack")); + stackDock->setWidget(widget(StackWidget)); + win->addDockWidget(Qt::RightDockWidgetArea, stackDock); + + QDockWidget *localsDock = new QDockWidget(win); + localsDock->setObjectName(QLatin1String("qtscriptdebugger_localsDockWidget")); + localsDock->setWindowTitle(QObject::tr("Locals")); + localsDock->setWidget(widget(LocalsWidget)); + win->addDockWidget(Qt::RightDockWidgetArea, localsDock); + + QDockWidget *consoleDock = new QDockWidget(win); + consoleDock->setObjectName(QLatin1String("qtscriptdebugger_consoleDockWidget")); + consoleDock->setWindowTitle(QObject::tr("Console")); + consoleDock->setWidget(widget(ConsoleWidget)); + win->addDockWidget(Qt::BottomDockWidgetArea, consoleDock); + + QDockWidget *debugOutputDock = new QDockWidget(win); + debugOutputDock->setObjectName(QLatin1String("qtscriptdebugger_debugOutputDockWidget")); + debugOutputDock->setWindowTitle(QObject::tr("Debug Output")); + debugOutputDock->setWidget(widget(DebugOutputWidget)); + win->addDockWidget(Qt::BottomDockWidgetArea, debugOutputDock); + + QDockWidget *errorLogDock = new QDockWidget(win); + errorLogDock->setObjectName(QLatin1String("qtscriptdebugger_errorLogDockWidget")); + errorLogDock->setWindowTitle(QObject::tr("Error Log")); + errorLogDock->setWidget(widget(ErrorLogWidget)); + win->addDockWidget(Qt::BottomDockWidgetArea, errorLogDock); + + win->tabifyDockWidget(errorLogDock, debugOutputDock); + win->tabifyDockWidget(debugOutputDock, consoleDock); + + win->addToolBar(Qt::TopToolBarArea, that->createStandardToolBar()); + +#ifndef QT_NO_MENUBAR + win->menuBar()->addMenu(that->createStandardMenu(win)); + + QMenu *editMenu = win->menuBar()->addMenu(QObject::tr("Search")); + editMenu->addAction(action(FindInScriptAction)); + editMenu->addAction(action(FindNextInScriptAction)); + editMenu->addAction(action(FindPreviousInScriptAction)); + editMenu->addSeparator(); + editMenu->addAction(action(GoToLineAction)); + + QMenu *viewMenu = win->menuBar()->addMenu(QObject::tr("View")); + viewMenu->addAction(scriptsDock->toggleViewAction()); + viewMenu->addAction(breakpointsDock->toggleViewAction()); + viewMenu->addAction(stackDock->toggleViewAction()); + viewMenu->addAction(localsDock->toggleViewAction()); + viewMenu->addAction(consoleDock->toggleViewAction()); + viewMenu->addAction(debugOutputDock->toggleViewAction()); + viewMenu->addAction(errorLogDock->toggleViewAction()); +#endif + + QWidget *central = new QWidget(); + QVBoxLayout *vbox = new QVBoxLayout(central); + vbox->setMargin(0); + vbox->addWidget(widget(CodeWidget)); + vbox->addWidget(widget(CodeFinderWidget)); + widget(CodeFinderWidget)->hide(); + win->setCentralWidget(central); + + win->setWindowTitle(QObject::tr("Qt Script Debugger")); + win->setUnifiedTitleAndToolBarOnMac(true); + + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + QVariant geometry = settings.value(QLatin1String("Qt/scripttools/debugging/mainWindowGeometry")); + if (geometry.isValid()) + win->restoreGeometry(geometry.toByteArray()); + QVariant state = settings.value(QLatin1String("Qt/scripttools/debugging/mainWindowState")); + if (state.isValid()) + win->restoreState(state.toByteArray()); + + WidgetClosedNotifier *closedNotifier = new WidgetClosedNotifier(win, that); + QObject::connect(closedNotifier, SIGNAL(widgetClosed()), + action(ContinueAction), SLOT(trigger())); + + const_cast<QScriptEngineDebuggerPrivate*>(d)->standardWindow = win; + return win; +} + +/*! + Creates a standard debugger menu with the given \a parent. + Returns the new menu object. + + \sa createStandardToolBar() +*/ +QMenu *QScriptEngineDebugger::createStandardMenu(QWidget *parent) +{ + QMenu *menu = new QMenu(parent); + menu->setTitle(QObject::tr("Debug")); + menu->addAction(action(ContinueAction)); + menu->addAction(action(InterruptAction)); + menu->addAction(action(StepIntoAction)); + menu->addAction(action(StepOverAction)); + menu->addAction(action(StepOutAction)); + menu->addAction(action(RunToCursorAction)); + menu->addAction(action(RunToNewScriptAction)); + + menu->addSeparator(); + menu->addAction(action(ToggleBreakpointAction)); + + menu->addSeparator(); + menu->addAction(action(ClearDebugOutputAction)); + menu->addAction(action(ClearErrorLogAction)); + menu->addAction(action(ClearConsoleAction)); + + return menu; +} + +/*! + Creates a standard debugger toolbar with the given \a parent. + Returns the new toolbar object. + + \sa createStandardMenu() +*/ +QToolBar *QScriptEngineDebugger::createStandardToolBar(QWidget *parent) +{ + QToolBar *tb = new QToolBar(parent); + tb->setObjectName(QLatin1String("qtscriptdebugger_standardToolBar")); + tb->addAction(action(ContinueAction)); + tb->addAction(action(InterruptAction)); + tb->addAction(action(StepIntoAction)); + tb->addAction(action(StepOverAction)); + tb->addAction(action(StepOutAction)); + tb->addAction(action(RunToCursorAction)); + tb->addAction(action(RunToNewScriptAction)); + tb->addSeparator(); + tb->addAction(action(FindInScriptAction)); + return tb; +} + +/*! + \fn QScriptEngineDebugger::evaluationSuspended() + + This signal is emitted when the debugger has suspended script + evaluation for whatever reason (e.g. due to an uncaught script + exception, or due to a breakpoint being triggered). + + \sa evaluationResumed() +*/ + +/*! + \fn QScriptEngineDebugger::evaluationResumed() + + This signal is emitted when the debugger has resumed script + evaluation (e.g. the user gave the "continue" command). + + \sa evaluationSuspended() +*/ + +QT_END_NAMESPACE + +#include "qscriptenginedebugger.moc" + +#include "moc_qscriptenginedebugger.cpp" diff --git a/src/scripttools/debugging/qscriptenginedebugger.h b/src/scripttools/debugging/qscriptenginedebugger.h new file mode 100644 index 0000000..d5e127f --- /dev/null +++ b/src/scripttools/debugging/qscriptenginedebugger.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTENGINEDEBUGGER_H +#define QSCRIPTENGINEDEBUGGER_H + +#include <QtCore/qobject.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +#if QT_VERSION >= 0x040500 +QT_MODULE(ScriptTools) +#else +# define Q_SCRIPTTOOLS_EXPORT +#endif + +class QAction; +class QScriptEngine; +class QWidget; +class QMainWindow; +class QMenu; +class QToolBar; + +class QScriptEngineDebuggerPrivate; +class Q_SCRIPTTOOLS_EXPORT QScriptEngineDebugger : public QObject +{ + Q_OBJECT +public: + enum DebuggerWidget { + ConsoleWidget, + StackWidget, + ScriptsWidget, + LocalsWidget, + CodeWidget, + CodeFinderWidget, + BreakpointsWidget, + DebugOutputWidget, + ErrorLogWidget + }; + + enum DebuggerAction { + InterruptAction, + ContinueAction, + StepIntoAction, + StepOverAction, + StepOutAction, + RunToCursorAction, + RunToNewScriptAction, + ToggleBreakpointAction, + ClearDebugOutputAction, + ClearErrorLogAction, + ClearConsoleAction, + FindInScriptAction, + FindNextInScriptAction, + FindPreviousInScriptAction, + GoToLineAction + }; + + QScriptEngineDebugger(QObject *parent = 0); + ~QScriptEngineDebugger(); + + void attachTo(QScriptEngine *engine); + void detach(); + + bool autoShowStandardWindow() const; + void setAutoShowStandardWindow(bool autoShow); + + QMainWindow *standardWindow() const; + QToolBar *createStandardToolBar(QWidget *parent = 0); + QMenu *createStandardMenu(QWidget *parent = 0); + + QWidget *widget(DebuggerWidget widget) const; + QAction *action(DebuggerAction action) const; + +Q_SIGNALS: + void evaluationSuspended(); + void evaluationResumed(); + +private: + Q_DECLARE_PRIVATE(QScriptEngineDebugger) + Q_DISABLE_COPY(QScriptEngineDebugger) + + Q_PRIVATE_SLOT(d_func(), void _q_showStandardWindow()) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/scripttools/debugging/qscriptenginedebuggerfrontend.cpp b/src/scripttools/debugging/qscriptenginedebuggerfrontend.cpp new file mode 100644 index 0000000..d35a86b --- /dev/null +++ b/src/scripttools/debugging/qscriptenginedebuggerfrontend.cpp @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptenginedebuggerfrontend_p.h" +#include "qscriptdebuggerfrontend_p_p.h" +#include "qscriptdebuggerbackend_p.h" +#include "qscriptdebuggerbackend_p_p.h" +#include "qscriptdebuggerevent_p.h" +#include "qscriptdebuggercommandexecutor_p.h" +#include "qscriptdebuggerresponse_p.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qeventloop.h> +#include <QtCore/qlist.h> +#include <QtScript/qscriptvalue.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QScriptEngineDebuggerFrontend + \since 4.5 + \internal + + \brief The QScriptEngineDebuggerFrontend class provides an in-process debugger frontend. + + This type of frontend is used when the QScriptEngine being debugged + lives in the same process as the debugger. + + Call the attachTo() function to attach to an engine. +*/ + +class QScriptDebuggerCommandEvent : public QEvent +{ +public: + QScriptDebuggerCommandEvent(int id, const QScriptDebuggerCommand &command) + : QEvent(QEvent::Type(QEvent::User+3)), m_id(id), m_command(command) {} + ~QScriptDebuggerCommandEvent() {} + int id() const + { return m_id; } + const QScriptDebuggerCommand &command() const + { return m_command; } +private: + int m_id; + QScriptDebuggerCommand m_command; +}; + +class QScriptDebuggerCommandFinishedEvent : public QEvent +{ +public: + QScriptDebuggerCommandFinishedEvent(int id, const QScriptDebuggerResponse &response) + : QEvent(QEvent::Type(QEvent::User+4)), m_id(id), m_response(response) {} + ~QScriptDebuggerCommandFinishedEvent() {} + int id() const + { return m_id; } + const QScriptDebuggerResponse &response() const + { return m_response; } +private: + int m_id; + QScriptDebuggerResponse m_response; +}; + +class QScriptEngineDebuggerBackendPrivate; +class QScriptEngineDebuggerBackend : public QScriptDebuggerBackend +{ +public: + QScriptEngineDebuggerBackend(QScriptEngineDebuggerFrontendPrivate *frontend); + ~QScriptEngineDebuggerBackend(); + + void processCommand(int id, const QScriptDebuggerCommand &command); + void resume(); + +protected: + void event(const QScriptDebuggerEvent &event); + +private: + Q_DECLARE_PRIVATE(QScriptEngineDebuggerBackend) + Q_DISABLE_COPY(QScriptEngineDebuggerBackend) +}; + +class QScriptEngineDebuggerBackendPrivate + : public QScriptDebuggerBackendPrivate +{ + Q_DECLARE_PUBLIC(QScriptEngineDebuggerBackend) +public: + QScriptEngineDebuggerBackendPrivate(); + ~QScriptEngineDebuggerBackendPrivate(); + + bool event(QEvent *e); + + QScriptEngineDebuggerFrontendPrivate *frontend; + QList<QEventLoop*> eventLoopPool; + QList<QEventLoop*> eventLoopStack; +}; + +class QScriptEngineDebuggerFrontendPrivate + : public QScriptDebuggerFrontendPrivate +{ + Q_DECLARE_PUBLIC(QScriptEngineDebuggerFrontend) +public: + QScriptEngineDebuggerFrontendPrivate(); + ~QScriptEngineDebuggerFrontendPrivate(); + + void postCommandFinished(int id, const QScriptDebuggerResponse &response); + bool event(QEvent *e); + + QScriptEngineDebuggerBackend *backend; +}; + +QScriptEngineDebuggerBackendPrivate::QScriptEngineDebuggerBackendPrivate() +{ + frontend = 0; +} + +QScriptEngineDebuggerBackendPrivate::~QScriptEngineDebuggerBackendPrivate() +{ + eventLoopPool << eventLoopStack; + eventLoopStack.clear(); + while (!eventLoopPool.isEmpty()) { + QEventLoop *eventLoop = eventLoopPool.takeFirst(); + if (eventLoop->isRunning()) { + eventLoop->quit(); + eventLoop->deleteLater(); + } else { + delete eventLoop; + } + } +} + +/*! + \reimp +*/ +bool QScriptEngineDebuggerBackendPrivate::event(QEvent *e) +{ + Q_Q(QScriptEngineDebuggerBackend); + if (e->type() == QEvent::User+3) { + QScriptDebuggerCommandEvent *ce = static_cast<QScriptDebuggerCommandEvent*>(e); + QScriptDebuggerCommandExecutor *executor = q->commandExecutor(); + QScriptDebuggerResponse response = executor->execute(q, ce->command()); + frontend->postCommandFinished(ce->id(), response); + return true; + } + return QScriptDebuggerBackendPrivate::event(e); +} + +/*! + \internal + + Creates a new QScriptEngineDebuggerBackend object for the given \a + engine. The back-end will forward events to the given \a frontend. +*/ +QScriptEngineDebuggerBackend::QScriptEngineDebuggerBackend( + QScriptEngineDebuggerFrontendPrivate *frontend) + : QScriptDebuggerBackend(*new QScriptEngineDebuggerBackendPrivate) +{ + Q_D(QScriptEngineDebuggerBackend); + d->frontend = frontend; +} + +QScriptEngineDebuggerBackend::~QScriptEngineDebuggerBackend() +{ +} + +void QScriptEngineDebuggerBackend::processCommand(int id, const QScriptDebuggerCommand &command) +{ + Q_D(QScriptEngineDebuggerBackend); + d->postEvent(new QScriptDebuggerCommandEvent(id, command)); +} + +/*! + \reimp +*/ +void QScriptEngineDebuggerBackend::event(const QScriptDebuggerEvent &event) +{ + Q_D(QScriptEngineDebuggerBackend); + if (d->eventLoopPool.isEmpty()) + d->eventLoopPool.append(new QEventLoop()); + QEventLoop *eventLoop = d->eventLoopPool.takeFirst(); + Q_ASSERT(!eventLoop->isRunning()); + d->eventLoopStack.prepend(eventLoop); + + d->frontend->postEvent(new QScriptDebuggerEventEvent(event)); + + // Run an event loop until resume() is called. + // This effectively stalls script execution and makes it possible + // for the debugger to inspect the execution state in the meantime. + eventLoop->exec(); + + if (!d->eventLoopStack.isEmpty()) { + // the event loop was quit directly (i.e. not via resume()) + d->eventLoopStack.takeFirst(); + } + d->eventLoopPool.append(eventLoop); + doPendingEvaluate(/*postEvent=*/false); +} + +/*! + \reimp +*/ +void QScriptEngineDebuggerBackend::resume() +{ + Q_D(QScriptEngineDebuggerBackend); + // quitting the event loops will cause event() to return (see above) + while (!d->eventLoopStack.isEmpty()) { + QEventLoop *eventLoop = d->eventLoopStack.takeFirst(); + if (eventLoop->isRunning()) + eventLoop->quit(); + } +} + +QScriptEngineDebuggerFrontendPrivate::QScriptEngineDebuggerFrontendPrivate() +{ + backend = 0; +} + +QScriptEngineDebuggerFrontendPrivate::~QScriptEngineDebuggerFrontendPrivate() +{ + delete backend; +} + +void QScriptEngineDebuggerFrontendPrivate::postCommandFinished( + int id, const QScriptDebuggerResponse &response) +{ + postEvent(new QScriptDebuggerCommandFinishedEvent(id, response)); +} + +/*! + \reimp +*/ +bool QScriptEngineDebuggerFrontendPrivate::event(QEvent *e) +{ + Q_Q(QScriptEngineDebuggerFrontend); + if (e->type() == QEvent::User+4) { + QScriptDebuggerCommandFinishedEvent *fe = static_cast<QScriptDebuggerCommandFinishedEvent*>(e); + q->notifyCommandFinished(fe->id(), fe->response()); + return true; + } + return QScriptDebuggerFrontendPrivate::event(e); +} + +QScriptEngineDebuggerFrontend::QScriptEngineDebuggerFrontend() + : QScriptDebuggerFrontend(*new QScriptEngineDebuggerFrontendPrivate) +{ +} + +QScriptEngineDebuggerFrontend::~QScriptEngineDebuggerFrontend() +{ + detach(); +} + +/*! + Attaches this front-end to the given \a engine. +*/ +void QScriptEngineDebuggerFrontend::attachTo(QScriptEngine *engine) +{ + Q_D(QScriptEngineDebuggerFrontend); + if (d->backend) + d->backend->detach(); + else + d->backend = new QScriptEngineDebuggerBackend(d); + d->backend->attachTo(engine); +} + +/*! + Detaches this front-end from the current script engine. +*/ +void QScriptEngineDebuggerFrontend::detach() +{ + Q_D(QScriptEngineDebuggerFrontend); + if (d->backend) + d->backend->detach(); +} + +QScriptValue QScriptEngineDebuggerFrontend::traceFunction() const +{ + Q_D(const QScriptEngineDebuggerFrontend); + if (d->backend) + d->backend->traceFunction(); + return QScriptValue(); +} + +QScriptDebuggerBackend *QScriptEngineDebuggerFrontend::backend() const +{ + Q_D(const QScriptEngineDebuggerFrontend); + return d->backend; +} + +/*! + \reimp +*/ +void QScriptEngineDebuggerFrontend::processCommand(int id, const QScriptDebuggerCommand &command) +{ + Q_D(QScriptEngineDebuggerFrontend); + Q_ASSERT(d->backend != 0); + d->backend->processCommand(id, command); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptenginedebuggerfrontend_p.h b/src/scripttools/debugging/qscriptenginedebuggerfrontend_p.h new file mode 100644 index 0000000..3c74d5e --- /dev/null +++ b/src/scripttools/debugging/qscriptenginedebuggerfrontend_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTENGINEDEBUGGERFRONTEND_P_H +#define QSCRIPTENGINEDEBUGGERFRONTEND_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptdebuggerfrontend_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptEngine; +class QScriptValue; +class QScriptDebuggerBackend; + +class QScriptEngineDebuggerFrontendPrivate; +class Q_AUTOTEST_EXPORT QScriptEngineDebuggerFrontend + : public QScriptDebuggerFrontend +{ +public: + QScriptEngineDebuggerFrontend(); + ~QScriptEngineDebuggerFrontend(); + + void attachTo(QScriptEngine *engine); + void detach(); + + QScriptValue traceFunction() const; + + QScriptDebuggerBackend *backend() const; + +protected: + void processCommand(int id, const QScriptDebuggerCommand &command); + +private: + Q_DECLARE_PRIVATE(QScriptEngineDebuggerFrontend) + Q_DISABLE_COPY(QScriptEngineDebuggerFrontend) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscripterrorlogwidget.cpp b/src/scripttools/debugging/qscripterrorlogwidget.cpp new file mode 100644 index 0000000..425f4a7 --- /dev/null +++ b/src/scripttools/debugging/qscripterrorlogwidget.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscripterrorlogwidget_p.h" +#include "qscripterrorlogwidgetinterface_p_p.h" + +#include <QtCore/qdatetime.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qtextedit.h> +#include <QtGui/qscrollbar.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +namespace { + +class OutputEdit : public QTextEdit +{ +public: + OutputEdit(QWidget *parent = 0) + : QTextEdit(parent) + { + setReadOnly(true); +// setFocusPolicy(Qt::NoFocus); + document()->setMaximumBlockCount(255); + } + + void scrollToBottom() + { + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); + } +}; + +} // namespace + +class QScriptErrorLogWidgetPrivate + : public QScriptErrorLogWidgetInterfacePrivate +{ + Q_DECLARE_PUBLIC(QScriptErrorLogWidget) +public: + QScriptErrorLogWidgetPrivate(); + ~QScriptErrorLogWidgetPrivate(); + + OutputEdit *outputEdit; +}; + +QScriptErrorLogWidgetPrivate::QScriptErrorLogWidgetPrivate() +{ +} + +QScriptErrorLogWidgetPrivate::~QScriptErrorLogWidgetPrivate() +{ +} + +QScriptErrorLogWidget::QScriptErrorLogWidget(QWidget *parent) + : QScriptErrorLogWidgetInterface(*new QScriptErrorLogWidgetPrivate, parent, 0) +{ + Q_D(QScriptErrorLogWidget); + d->outputEdit = new OutputEdit(); + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->setSpacing(0); + vbox->addWidget(d->outputEdit); + +// QString sheet = QString::fromLatin1("font-size: 14px; font-family: \"Monospace\";"); +// setStyleSheet(sheet); +} + +QScriptErrorLogWidget::~QScriptErrorLogWidget() +{ +} + +void QScriptErrorLogWidget::message( + QtMsgType type, const QString &text, const QString &fileName, + int lineNumber, int columnNumber, const QVariant &/*data*/) +{ + // ### we need the error message rather than Error.toString() + Q_UNUSED(type); + Q_UNUSED(fileName); + Q_UNUSED(lineNumber); + Q_UNUSED(columnNumber); + Q_D(QScriptErrorLogWidget); + QString html; + html.append(QString::fromLatin1("<b>%0</b> %1<br>") + .arg(QDateTime::currentDateTime().toString()).arg(Qt::escape(text))); + d->outputEdit->insertHtml(html); + d->outputEdit->scrollToBottom(); +} + +void QScriptErrorLogWidget::clear() +{ + Q_D(QScriptErrorLogWidget); + d->outputEdit->clear(); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscripterrorlogwidget_p.h b/src/scripttools/debugging/qscripterrorlogwidget_p.h new file mode 100644 index 0000000..1c206bb --- /dev/null +++ b/src/scripttools/debugging/qscripterrorlogwidget_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTERRORLOGWIDGET_P_H +#define QSCRIPTERRORLOGWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscripterrorlogwidgetinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptErrorLogWidgetPrivate; +class Q_AUTOTEST_EXPORT QScriptErrorLogWidget: + public QScriptErrorLogWidgetInterface +{ + Q_OBJECT +public: + QScriptErrorLogWidget(QWidget *parent = 0); + ~QScriptErrorLogWidget(); + + void message(QtMsgType type, const QString &text, + const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1, + const QVariant &data = QVariant()); + + void clear(); + +private: + Q_DECLARE_PRIVATE(QScriptErrorLogWidget) + Q_DISABLE_COPY(QScriptErrorLogWidget) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscripterrorlogwidgetinterface.cpp b/src/scripttools/debugging/qscripterrorlogwidgetinterface.cpp new file mode 100644 index 0000000..727450c --- /dev/null +++ b/src/scripttools/debugging/qscripterrorlogwidgetinterface.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscripterrorlogwidgetinterface_p.h" +#include "qscripterrorlogwidgetinterface_p_p.h" + +QT_BEGIN_NAMESPACE + +QScriptErrorLogWidgetInterfacePrivate::QScriptErrorLogWidgetInterfacePrivate() +{ +} + +QScriptErrorLogWidgetInterfacePrivate::~QScriptErrorLogWidgetInterfacePrivate() +{ +} + +QScriptErrorLogWidgetInterface::~QScriptErrorLogWidgetInterface() +{ +} + +QScriptErrorLogWidgetInterface::QScriptErrorLogWidgetInterface( + QScriptErrorLogWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags) + : QWidget(dd, parent, flags) +{ +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscripterrorlogwidgetinterface_p.h b/src/scripttools/debugging/qscripterrorlogwidgetinterface_p.h new file mode 100644 index 0000000..d720ec2 --- /dev/null +++ b/src/scripttools/debugging/qscripterrorlogwidgetinterface_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTERRORLOGWIDGETINTERFACE_P_H +#define QSCRIPTERRORLOGWIDGETINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qwidget.h> + +#include "qscriptmessagehandlerinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptErrorLogWidgetInterfacePrivate; +class Q_AUTOTEST_EXPORT QScriptErrorLogWidgetInterface: + public QWidget, + public QScriptMessageHandlerInterface +{ + Q_OBJECT +public: + ~QScriptErrorLogWidgetInterface(); + + virtual void clear() = 0; + +protected: + QScriptErrorLogWidgetInterface(QScriptErrorLogWidgetInterfacePrivate &dd, + QWidget *parent, Qt::WindowFlags flags); + +private: + Q_DECLARE_PRIVATE(QScriptErrorLogWidgetInterface) + Q_DISABLE_COPY(QScriptErrorLogWidgetInterface) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscripterrorlogwidgetinterface_p_p.h b/src/scripttools/debugging/qscripterrorlogwidgetinterface_p_p.h new file mode 100644 index 0000000..59261f4 --- /dev/null +++ b/src/scripttools/debugging/qscripterrorlogwidgetinterface_p_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTERRORLOGWIDGETINTERFACE_P_P_H +#define QSCRIPTERRORLOGWIDGETINTERFACE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +class QScriptErrorLogWidgetInterface; +class QScriptErrorLogWidgetInterfacePrivate + : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(QScriptErrorLogWidgetInterface) +public: + QScriptErrorLogWidgetInterfacePrivate(); + ~QScriptErrorLogWidgetInterfacePrivate(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptmessagehandlerinterface_p.h b/src/scripttools/debugging/qscriptmessagehandlerinterface_p.h new file mode 100644 index 0000000..eb77096 --- /dev/null +++ b/src/scripttools/debugging/qscriptmessagehandlerinterface_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTMESSAGEHANDLERINTERFACE_P_H +#define QSCRIPTMESSAGEHANDLERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qvariant.h> + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QScriptMessageHandlerInterface +{ +public: + virtual ~QScriptMessageHandlerInterface() {} + + virtual void message(QtMsgType type, const QString &text, + const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1, + const QVariant &data = QVariant()) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptobjectsnapshot.cpp b/src/scripttools/debugging/qscriptobjectsnapshot.cpp new file mode 100644 index 0000000..88649f1 --- /dev/null +++ b/src/scripttools/debugging/qscriptobjectsnapshot.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptobjectsnapshot_p.h" + +#include <QtCore/qmap.h> +#include <QtCore/qset.h> +#include <QtCore/qvector.h> +#include <QtCore/qnumeric.h> +#include <QtScript/qscriptvalueiterator.h> + +QT_BEGIN_NAMESPACE + +QScriptObjectSnapshot::QScriptObjectSnapshot() +{ +} + +QScriptObjectSnapshot::~QScriptObjectSnapshot() +{ +} + +static bool _q_equal(const QScriptValue &v1, const QScriptValue &v2) +{ + if (v1.strictlyEquals(v2)) + return true; + if (v1.isNumber() && v2.isNumber() && qIsNaN(v1.toNumber()) && qIsNaN(v2.toNumber())) + return true; + return false; +} + +QScriptObjectSnapshot::Delta QScriptObjectSnapshot::capture(const QScriptValue &object) +{ + Delta result; + QMap<QString, QScriptValueProperty> currProps; + QHash<QString, int> propertyNameToIndex; + { + int i = 0; + QScriptValueIterator it(object); + while (it.hasNext()) { + it.next(); + QScriptValueProperty prop(it.name(), it.value(), it.flags()); + currProps.insert(it.name(), prop); + propertyNameToIndex.insert(it.name(), i); + ++i; + } + if (object.prototype().isValid()) { + QString __proto__ = QString::fromLatin1("__proto__"); + QScriptValueProperty protoProp( + __proto__, object.prototype(), + QScriptValue::Undeletable | QScriptValue::ReadOnly); + currProps.insert(__proto__, protoProp); + propertyNameToIndex.insert(__proto__, i); + ++i; + } + } + + QSet<QString> prevSet; + for (int i = 0; i < m_properties.size(); ++i) + prevSet.insert(m_properties.at(i).name()); + QSet<QString> currSet = currProps.keys().toSet(); + QSet<QString> removedProperties = prevSet - currSet; + QSet<QString> addedProperties = currSet - prevSet; + QSet<QString> maybeChangedProperties = currSet & prevSet; + + { + QMap<int, QScriptValueProperty> am; + QSet<QString>::const_iterator it; + for (it = addedProperties.constBegin(); it != addedProperties.constEnd(); ++it) { + int idx = propertyNameToIndex[*it]; + am[idx] = currProps[*it]; + } + result.addedProperties = am.values(); + } + + { + QSet<QString>::const_iterator it; + for (it = maybeChangedProperties.constBegin(); it != maybeChangedProperties.constEnd(); ++it) { + const QScriptValueProperty &p1 = currProps[*it]; + const QScriptValueProperty &p2 = findProperty(*it); + if (!_q_equal(p1.value(), p2.value()) + || (p1.flags() != p2.flags())) { + result.changedProperties.append(p1); + } + } + } + + result.removedProperties = removedProperties.toList(); + + m_properties = currProps.values(); + + return result; +} + +QScriptValueProperty QScriptObjectSnapshot::findProperty(const QString &name) const +{ + for (int i = 0; i < m_properties.size(); ++i) { + if (m_properties.at(i).name() == name) + return m_properties.at(i); + } + return QScriptValueProperty(); +} + +QScriptValuePropertyList QScriptObjectSnapshot::properties() const +{ + return m_properties; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptobjectsnapshot_p.h b/src/scripttools/debugging/qscriptobjectsnapshot_p.h new file mode 100644 index 0000000..3082a60 --- /dev/null +++ b/src/scripttools/debugging/qscriptobjectsnapshot_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTOBJECTSNAPSHOT_P_H +#define QSCRIPTOBJECTSNAPSHOT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qstringlist.h> +#include "qscriptvalueproperty_p.h" + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QScriptObjectSnapshot +{ +public: + struct Delta { + QStringList removedProperties; + QScriptValuePropertyList changedProperties; + QScriptValuePropertyList addedProperties; + }; + + QScriptObjectSnapshot(); + ~QScriptObjectSnapshot(); + + Delta capture(const QScriptValue &object); + QScriptValuePropertyList properties() const; + + QScriptValueProperty findProperty(const QString &name) const; + +private: + QScriptValuePropertyList m_properties; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptscriptdata.cpp b/src/scripttools/debugging/qscriptscriptdata.cpp new file mode 100644 index 0000000..068748f --- /dev/null +++ b/src/scripttools/debugging/qscriptscriptdata.cpp @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptscriptdata_p.h" + +#include <QtCore/qdatastream.h> +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptScriptData + \internal + + \brief The QScriptScriptData class holds data associated with a script. +*/ + +class QScriptScriptDataPrivate +{ +public: + QScriptScriptDataPrivate(); + ~QScriptScriptDataPrivate(); + + QString contents; + QString fileName; + int baseLineNumber; + QDateTime timeStamp; + + QBasicAtomicInt ref; +}; + +QScriptScriptDataPrivate::QScriptScriptDataPrivate() +{ + ref = 0; +} + +QScriptScriptDataPrivate::~QScriptScriptDataPrivate() +{ +} + +QScriptScriptData::QScriptScriptData() + : d_ptr(0) +{ +} + +QScriptScriptData::QScriptScriptData(const QString &contents, const QString &fileName, + int baseLineNumber, const QDateTime &timeStamp) + : d_ptr(new QScriptScriptDataPrivate) +{ + d_ptr->contents = contents; + d_ptr->fileName = fileName; + d_ptr->baseLineNumber = baseLineNumber; + if (timeStamp.isValid()) + d_ptr->timeStamp = timeStamp; + else + d_ptr->timeStamp = QDateTime::currentDateTime(); + d_ptr->ref.ref(); +} + +QScriptScriptData::QScriptScriptData(const QScriptScriptData &other) + : d_ptr(other.d_ptr) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +QScriptScriptData::~QScriptScriptData() +{ + if (d_ptr && !d_ptr->ref.deref()) { + delete d_ptr; + d_ptr = 0; + } +} + +QScriptScriptData &QScriptScriptData::operator=(const QScriptScriptData &other) +{ + if (d_ptr == other.d_ptr) + return *this; + if (d_ptr && !d_ptr->ref.deref()) + delete d_ptr; + d_ptr = other.d_ptr; + if (d_ptr) + d_ptr->ref.ref(); + return *this; +} + +QString QScriptScriptData::contents() const +{ + Q_D(const QScriptScriptData); + if (!d) + return QString(); + return d->contents; +} + +QStringList QScriptScriptData::lines(int startLineNumber, int count) const +{ + Q_D(const QScriptScriptData); + if (!d) + return QStringList(); + QStringList allLines = d->contents.split(QLatin1Char('\n')); + return allLines.mid(qMax(0, startLineNumber - d->baseLineNumber), count); +} + +QString QScriptScriptData::fileName() const +{ + Q_D(const QScriptScriptData); + if (!d) + return QString(); + return d->fileName; +} + +int QScriptScriptData::baseLineNumber() const +{ + Q_D(const QScriptScriptData); + if (!d) + return -1; + return d->baseLineNumber; +} + +QDateTime QScriptScriptData::timeStamp() const +{ + Q_D(const QScriptScriptData); + if (!d) + return QDateTime(); + return d->timeStamp; +} + +bool QScriptScriptData::isValid() const +{ + Q_D(const QScriptScriptData); + return (d != 0); +} + +bool QScriptScriptData::operator==(const QScriptScriptData &other) const +{ + Q_D(const QScriptScriptData); + const QScriptScriptDataPrivate *od = other.d_func(); + if (d == od) + return true; + if (!d || !od) + return false; + return ((d->contents == od->contents) + && (d->fileName == od->fileName) + && (d->baseLineNumber == od->baseLineNumber)); +} + +bool QScriptScriptData::operator!=(const QScriptScriptData &other) const +{ + return !(*this == other); +} + +QDataStream &operator<<(QDataStream &out, const QScriptScriptData &data) +{ + const QScriptScriptDataPrivate *d = data.d_ptr; + if (d) { + out << d->contents; + out << d->fileName; + out << qint32(d->baseLineNumber); + } else { + out << QString(); + out << QString(); + out << qint32(0); + } + return out; +} + +QDataStream &operator>>(QDataStream &in, QScriptScriptData &data) +{ + if (!data.d_ptr) { + data.d_ptr = new QScriptScriptDataPrivate(); + data.d_ptr->ref.ref(); + } + QScriptScriptDataPrivate *d = data.d_ptr; + in >> d->contents; + in >> d->fileName; + qint32 ln; + in >> ln; + d->baseLineNumber = ln; + return in; +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptscriptdata_p.h b/src/scripttools/debugging/qscriptscriptdata_p.h new file mode 100644 index 0000000..50cad32 --- /dev/null +++ b/src/scripttools/debugging/qscriptscriptdata_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTSCRIPTDATA_P_H +#define QSCRIPTSCRIPTDATA_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qdatetime.h> +#include <QtCore/qmap.h> + +QT_BEGIN_NAMESPACE + +class QDataStream; +class QString; +class QStringList; + +class QScriptScriptDataPrivate; +class Q_AUTOTEST_EXPORT QScriptScriptData +{ +public: + friend Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptScriptData &); + friend Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptScriptData &); + + QScriptScriptData(); + QScriptScriptData(const QString &contents, const QString &fileName, + int baseLineNumber, const QDateTime &timeStamp = QDateTime()); + QScriptScriptData(const QScriptScriptData &other); + ~QScriptScriptData(); + + QString contents() const; + QStringList lines(int startLineNumber, int count) const; + QString fileName() const; + int baseLineNumber() const; + QDateTime timeStamp() const; + + bool isValid() const; + + QScriptScriptData &operator=(const QScriptScriptData &other); + + bool operator==(const QScriptScriptData &other) const; + bool operator!=(const QScriptScriptData &other) const; + +private: + QScriptScriptDataPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptScriptData) +}; + +typedef QMap<qint64, QScriptScriptData> QScriptScriptMap; + +Q_AUTOTEST_EXPORT QDataStream &operator<<(QDataStream &, const QScriptScriptData &); +Q_AUTOTEST_EXPORT QDataStream &operator>>(QDataStream &, QScriptScriptData &); + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptstdmessagehandler.cpp b/src/scripttools/debugging/qscriptstdmessagehandler.cpp new file mode 100644 index 0000000..4e0f12c --- /dev/null +++ b/src/scripttools/debugging/qscriptstdmessagehandler.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptstdmessagehandler_p.h" +#include <stdio.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.5 + \class QScriptStdMessageHandler + \internal + + \brief The QScriptStdMessageHandler class implements a message handler that writes to standard output. +*/ + +class QScriptStdMessageHandlerPrivate +{ +public: + QScriptStdMessageHandlerPrivate() {} + ~QScriptStdMessageHandlerPrivate() {} +}; + +QScriptStdMessageHandler::QScriptStdMessageHandler() + : d_ptr(new QScriptStdMessageHandlerPrivate) +{ +} + +QScriptStdMessageHandler::~QScriptStdMessageHandler() +{ + delete d_ptr; +} + +void QScriptStdMessageHandler::message(QtMsgType type, const QString &text, + const QString &fileName, + int lineNumber, int columnNumber, + const QVariant &/*data*/) +{ + QString msg; + if (!fileName.isEmpty() || (lineNumber != -1)) { + if (!fileName.isEmpty()) + msg.append(fileName); + else + msg.append(QLatin1String("<noname>")); + if (lineNumber != -1) { + msg.append(QLatin1Char(':')); + msg.append(QString::number(lineNumber)); + if (columnNumber != -1) { + msg.append(QLatin1Char(':')); + msg.append(QString::number(columnNumber)); + } + } + msg.append(QLatin1String(": ")); + } + msg.append(text); + + FILE *fp = 0; + switch (type) { + case QtDebugMsg: + fp = stdout; + break; + case QtWarningMsg: + case QtCriticalMsg: + case QtFatalMsg: + fp = stderr; + break; + } + + fprintf(fp, "%s\n", msg.toLatin1().constData()); + fflush(fp); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptstdmessagehandler_p.h b/src/scripttools/debugging/qscriptstdmessagehandler_p.h new file mode 100644 index 0000000..8b75f6a --- /dev/null +++ b/src/scripttools/debugging/qscriptstdmessagehandler_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTSTDMESSAGEHANDLER_P_H +#define QSCRIPTSTDMESSAGEHANDLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qscriptmessagehandlerinterface_p.h" + +QT_BEGIN_NAMESPACE + +class QScriptStdMessageHandlerPrivate; +class Q_AUTOTEST_EXPORT QScriptStdMessageHandler + : public QScriptMessageHandlerInterface +{ +public: + QScriptStdMessageHandler(); + ~QScriptStdMessageHandler(); + + void message(QtMsgType type, const QString &text, + const QString &fileName = QString(), + int lineNumber = -1, int columnNumber = -1, + const QVariant &data = QVariant()); + +private: + QScriptStdMessageHandlerPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QScriptStdMessageHandler) + Q_DISABLE_COPY(QScriptStdMessageHandler) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptsyntaxhighlighter.cpp b/src/scripttools/debugging/qscriptsyntaxhighlighter.cpp new file mode 100644 index 0000000..85ccf4e --- /dev/null +++ b/src/scripttools/debugging/qscriptsyntaxhighlighter.cpp @@ -0,0 +1,544 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptsyntaxhighlighter_p.h" +#include "private/qfunctions_p.h" + +#ifndef QT_NO_SYNTAXHIGHLIGHTER + +QT_BEGIN_NAMESPACE + +enum ScriptIds { + Comment = 1, + Number, + String, + Type, + Keyword, + PreProcessor, + Label +}; + +#define MAX_KEYWORD 63 +static const char *const keywords[MAX_KEYWORD] = { + "Infinity", + "NaN", + "abstract", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "constructor", + "continue", + "debugger", + "default", + "delete", + "do", + "double", + "else", + "enum", + "export", + "extends", + "false", + "final", + "finally", + "float", + "for", + "function", + "goto", + "if", + "implements", + "import", + "in", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "typeof", + "undefined", + "var", + "void", + "volatile", + "while", + "with", // end of array + 0 +}; + +struct KeywordHelper +{ + inline KeywordHelper(const QString &word) : needle(word) {} + const QString needle; +}; + +Q_STATIC_GLOBAL_OPERATOR bool operator<(const KeywordHelper &helper, const char *kw) +{ + return helper.needle < QLatin1String(kw); +} + +Q_STATIC_GLOBAL_OPERATOR bool operator<(const char *kw, const KeywordHelper &helper) +{ + return QLatin1String(kw) < helper.needle; +} + +static bool isKeyword(const QString &word) +{ + const char * const *start = &keywords[0]; + const char * const *end = &keywords[MAX_KEYWORD - 1]; + const char * const *kw = qBinaryFind(start, end, KeywordHelper(word)); + + return kw != end; +} + +QScriptSyntaxHighlighter::QScriptSyntaxHighlighter(QTextDocument *document) + : QSyntaxHighlighter(document) +{ + + m_formats[ScriptNumberFormat].setForeground(Qt::darkBlue); + m_formats[ScriptStringFormat].setForeground(Qt::darkGreen); + m_formats[ScriptTypeFormat].setForeground(Qt::darkMagenta); + m_formats[ScriptKeywordFormat].setForeground(Qt::darkYellow); + m_formats[ScriptPreprocessorFormat].setForeground(Qt::darkBlue); + m_formats[ScriptLabelFormat].setForeground(Qt::darkRed); + m_formats[ScriptCommentFormat].setForeground(Qt::darkGreen); + m_formats[ScriptCommentFormat].setFontItalic(true); +} + +QScriptSyntaxHighlighter::~QScriptSyntaxHighlighter() +{ +} + +void QScriptSyntaxHighlighter::highlightBlock(const QString &text) +{ + + // states + enum States { StateStandard, StateCommentStart1, StateCCommentStart2, + StateScriptCommentStart2, StateCComment, StateScriptComment, StateCCommentEnd1, + StateCCommentEnd2, StateStringStart, StateString, StateStringEnd, + StateString2Start, StateString2, StateString2End, + StateNumber, StatePreProcessor, NumStates }; + + // tokens + enum Tokens { InputAlpha, InputNumber, InputAsterix, InputSlash, InputParen, + InputSpace, InputHash, InputQuotation, InputApostrophe, InputSep, NumTokens }; + + static uchar table[NumStates][NumTokens] = { + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStandard + { StateStandard, StateNumber, StateCCommentStart2, StateScriptCommentStart2, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCommentStart1 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentStart2 + { StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment }, // ScriptCommentStart2 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCComment + { StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment, StateScriptComment }, // StateScriptComment + { StateCComment, StateCComment, StateCCommentEnd1, StateCCommentEnd2, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentEnd1 + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCCommentEnd2 + { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateStringStart + { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateString + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStringEnd + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2Start + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2 + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateString2End + { StateNumber, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateNumber + { StatePreProcessor, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard } // StatePreProcessor + }; + + QString buffer; + buffer.reserve(text.length()); + + QTextCharFormat emptyFormat; + + int state = StateStandard; + int braceDepth = 0; + const int previousState = previousBlockState(); + if (previousState != -1) { + state = previousState & 0xff; + braceDepth = previousState >> 8; + } + + if (text.isEmpty()) { + setCurrentBlockState(previousState); +#if 0 + TextEditDocumentLayout::clearParentheses(currentBlock()); +#endif + return; + } +#if 0 + Parentheses parentheses; + parentheses.reserve(20); // assume wizard level ;-) +#endif + int input = -1; + int i = 0; + bool lastWasBackSlash = false; + bool makeLastStandard = false; + + static const QString alphabeth = QLatin1String("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + static const QString mathChars = QLatin1String("xXeE"); + static const QString numbers = QLatin1String("0123456789"); + bool questionMark = false; + QChar lastChar; + + int firstNonSpace = -1; + int lastNonSpace = -1; + + for (;;) { + const QChar c = text.at(i); + + if (lastWasBackSlash) { + input = InputSep; + } else { + switch (c.toAscii()) { + case '*': + input = InputAsterix; + break; + case '/': + input = InputSlash; + break; + case '{': + braceDepth++; + // fall through + case '(': case '[': + input = InputParen; + switch (state) { + case StateStandard: + case StateNumber: + case StatePreProcessor: + case StateCCommentEnd2: + case StateCCommentEnd1: + case StateString2End: + case StateStringEnd: +// parentheses.push_back(Parenthesis(Parenthesis::Opened, c, i)); + break; + default: + break; + } + break; + case '}': + if (--braceDepth < 0) + braceDepth = 0; + // fall through + case ')': case ']': + input = InputParen; + switch (state) { + case StateStandard: + case StateNumber: + case StatePreProcessor: + case StateCCommentEnd2: + case StateCCommentEnd1: + case StateString2End: + case StateStringEnd: +// parentheses.push_back(Parenthesis(Parenthesis::Closed, c, i)); + break; + default: + break; + } + break; + case '#': + input = InputHash; + break; + case '"': + input = InputQuotation; + break; + case '\'': + input = InputApostrophe; + break; + case ' ': + input = InputSpace; + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '0': + if (alphabeth.contains(lastChar) + && (!mathChars.contains(lastChar) || !numbers.contains(text.at(i - 1))) + ) { + input = InputAlpha; + } else { + if (input == InputAlpha && numbers.contains(lastChar)) + input = InputAlpha; + else + input = InputNumber; + } + break; + case ':': { + input = InputAlpha; + const QChar colon = QLatin1Char(':'); + if (state == StateStandard && !questionMark && lastChar != colon) { + const QChar nextChar = i < text.length() - 1 ? text.at(i + 1) : QLatin1Char(' '); + if (nextChar != colon) + for (int j = 0; j < i; ++j) { + if (format(j) == emptyFormat ) + setFormat(j, 1, m_formats[ScriptLabelFormat]); + } + } + } break; + default: + if (!questionMark && c == QLatin1Char('?')) + questionMark = true; + if (c.isLetter() || c == QLatin1Char('_')) + input = InputAlpha; + else + input = InputSep; + break; + } + } + + if (input != InputSpace) { + if (firstNonSpace < 0) + firstNonSpace = i; + lastNonSpace = i; + } + + lastWasBackSlash = !lastWasBackSlash && c == QLatin1Char('\\'); + + if (input == InputAlpha) + buffer += c; + + state = table[state][input]; + + switch (state) { + case StateStandard: { + setFormat(i, 1, emptyFormat); + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + if (input != InputAlpha) { + highlightWord(i, buffer); + buffer = QString::null; + } + } break; + case StateCommentStart1: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = true; + buffer = QString::null; + break; + case StateCCommentStart2: + setFormat(i - 1, 2, m_formats[ScriptCommentFormat]); + makeLastStandard = false; +// parentheses.push_back(Parenthesis(Parenthesis::Opened, QLatin1Char('/'), i-1)); + buffer = QString::null; + break; + case StateScriptCommentStart2: + setFormat(i - 1, 2, m_formats[ScriptCommentFormat]); + makeLastStandard = false; + buffer = QString::null; + break; + case StateCComment: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptCommentFormat]); + buffer = QString::null; + break; + case StateScriptComment: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptCommentFormat]); + buffer = QString::null; + break; + case StateCCommentEnd1: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptCommentFormat]); + buffer = QString::null; + break; + case StateCCommentEnd2: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptCommentFormat]); +// parentheses.push_back(Parenthesis(Parenthesis::Closed, QLatin1Char('/'), i)); + buffer = QString::null; + break; + case StateStringStart: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, emptyFormat); + buffer = QString::null; + break; + case StateString: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptStringFormat]); + buffer = QString::null; + break; + case StateStringEnd: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, emptyFormat); + buffer = QString::null; + break; + case StateString2Start: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, emptyFormat); + buffer = QString::null; + break; + case StateString2: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptStringFormat]); + buffer = QString::null; + break; + case StateString2End: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, emptyFormat); + buffer = QString::null; + break; + case StateNumber: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptNumberFormat]); + buffer = QString::null; + break; + case StatePreProcessor: + if (makeLastStandard) + setFormat(i - 1, 1, emptyFormat); + makeLastStandard = false; + setFormat(i, 1, m_formats[ScriptPreprocessorFormat]); + buffer = QString::null; + break; + } + + lastChar = c; + i++; + if (i >= text.length()) { +#if 0 + if (TextBlockUserData *userData = TextEditDocumentLayout::testUserData(currentBlock())) { + userData->setHasClosingCollapse(false); + userData->setCollapseMode(TextBlockUserData::NoCollapse); + } + int collapse = Parenthesis::collapseAtPos(parentheses); + if (collapse >= 0) { + if (collapse == firstNonSpace) + TextEditDocumentLayout::userData(currentBlock())->setCollapseMode(TextBlockUserData::CollapseThis); + else + TextEditDocumentLayout::userData(currentBlock())->setCollapseMode(TextBlockUserData::CollapseAfter); + } + if (Parenthesis::hasClosingCollapse(parentheses)) { + TextEditDocumentLayout::userData(currentBlock())->setHasClosingCollapse(true); + } +#endif + + break; + } + } + + highlightWord(text.length(), buffer); + + switch (state) { + case StateCComment: + case StateCCommentEnd1: + case StateCCommentStart2: + state = StateCComment; + break; + case StateString: + // quotes cannot span multiple lines, so if somebody starts + // typing a quoted string we don't need to look for the ending + // quote in another line (or highlight until the end of the + // document) and therefore slow down editing. + state = StateStandard; + break; + case StateString2: + state = StateStandard; + break; + default: + state = StateStandard; + break; + } + +#if 0 + TextEditDocumentLayout::setParentheses(currentBlock(), parentheses); +#endif + + setCurrentBlockState((braceDepth << 8) | state); +} + +void QScriptSyntaxHighlighter::highlightWord(int currentPos, const QString &buffer) +{ + if (buffer.isEmpty()) + return; + + // try to highlight Qt 'identifiers' like QObject and Q_PROPERTY + // but don't highlight words like 'Query' + if (buffer.length() > 1 + && buffer.at(0) == QLatin1Char('Q') + && (buffer.at(1).isUpper() + || buffer.at(1) == QLatin1Char('_') + || buffer.at(1) == QLatin1Char('t'))) { + setFormat(currentPos - buffer.length(), buffer.length(), m_formats[ScriptTypeFormat]); + } else { + if (isKeyword(buffer)) + setFormat(currentPos - buffer.length(), buffer.length(), m_formats[ScriptKeywordFormat]); + } +} + +QT_END_NAMESPACE + +#endif // QT_NO_SYNTAXHIGHLIGHTER + diff --git a/src/scripttools/debugging/qscriptsyntaxhighlighter_p.h b/src/scripttools/debugging/qscriptsyntaxhighlighter_p.h new file mode 100644 index 0000000..53e3397 --- /dev/null +++ b/src/scripttools/debugging/qscriptsyntaxhighlighter_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTSYNTAXHIGHLIGHTER_P_H +#define QSCRIPTSYNTAXHIGHLIGHTER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +#ifndef QT_NO_SYNTAXHIGHLIGHTER + +#include <QtGui/qsyntaxhighlighter.h> + +#include <QtGui/qtextformat.h> + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QScriptSyntaxHighlighter : public QSyntaxHighlighter +{ +public: + QScriptSyntaxHighlighter(QTextDocument *document = 0); + ~QScriptSyntaxHighlighter(); + +protected: + void highlightBlock(const QString &text); + +private: + void highlightWord(int currentPos, const QString &buffer); + + enum ScriptFormats { + ScriptTextFormat, ScriptNumberFormat, + ScriptStringFormat, ScriptTypeFormat, + ScriptKeywordFormat, ScriptPreprocessorFormat, + ScriptLabelFormat, ScriptCommentFormat, + NumScriptFormats + }; + QTextCharFormat m_formats[NumScriptFormats]; + +private: + Q_DISABLE_COPY(QScriptSyntaxHighlighter) +}; + +QT_END_NAMESPACE + +#endif // QT_NO_SYNTAXHIGHLIGHTER + +#endif diff --git a/src/scripttools/debugging/qscripttooltipproviderinterface_p.h b/src/scripttools/debugging/qscripttooltipproviderinterface_p.h new file mode 100644 index 0000000..0a273d9 --- /dev/null +++ b/src/scripttools/debugging/qscripttooltipproviderinterface_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTTOOLTIPPROVIDERINTERFACE_P_H +#define QSCRIPTTOOLTIPPROVIDERINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +QT_BEGIN_NAMESPACE + +class QStringList; + +class Q_AUTOTEST_EXPORT QScriptToolTipProviderInterface +{ +public: + virtual ~QScriptToolTipProviderInterface() {} + + virtual QString toolTip(int frameIndex, int lineNumber, + const QStringList &path) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptvalueproperty.cpp b/src/scripttools/debugging/qscriptvalueproperty.cpp new file mode 100644 index 0000000..245edc3 --- /dev/null +++ b/src/scripttools/debugging/qscriptvalueproperty.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptvalueproperty_p.h" + +#include <QtCore/qatomic.h> +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +class QScriptValuePropertyPrivate +{ +public: + QScriptValuePropertyPrivate(); + ~QScriptValuePropertyPrivate(); + + QString name; + QScriptValue value; + QScriptValue::PropertyFlags flags; + + QBasicAtomicInt ref; +}; + +QScriptValuePropertyPrivate::QScriptValuePropertyPrivate() +{ + ref = 0; +} + +QScriptValuePropertyPrivate::~QScriptValuePropertyPrivate() +{ +} + +/*! + Constructs an invalid QScriptValueProperty. +*/ +QScriptValueProperty::QScriptValueProperty() + : d_ptr(0) +{ +} + +/*! + Constructs a QScriptValueProperty with the given \a name, + \a value and \a flags. +*/ +QScriptValueProperty::QScriptValueProperty(const QString &name, + const QScriptValue &value, + QScriptValue::PropertyFlags flags) + : d_ptr(new QScriptValuePropertyPrivate) +{ + d_ptr->name = name; + d_ptr->value = value; + d_ptr->flags = flags; + d_ptr->ref.ref(); +} + +/*! + Constructs a QScriptValueProperty that is a copy of the \a other property. +*/ +QScriptValueProperty::QScriptValueProperty(const QScriptValueProperty &other) + : d_ptr(other.d_ptr) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +/*! + Destroys this QScriptValueProperty. +*/ +QScriptValueProperty::~QScriptValueProperty() +{ + if (d_ptr && !d_ptr->ref.deref()) { + delete d_ptr; + d_ptr = 0; + } +} + +/*! + Assigns the \a other property to this QScriptValueProperty. +*/ +QScriptValueProperty &QScriptValueProperty::operator=(const QScriptValueProperty &other) +{ + if (d_ptr == other.d_ptr) + return *this; + if (d_ptr && !d_ptr->ref.deref()) + delete d_ptr; + d_ptr = other.d_ptr; + if (d_ptr) + d_ptr->ref.ref(); + return *this; +} + +/*! + Returns the name of this QScriptValueProperty. +*/ +QString QScriptValueProperty::name() const +{ + Q_D(const QScriptValueProperty); + if (!d) + return QString(); + return d->name; +} + +/*! + Returns the value of this QScriptValueProperty. +*/ +QScriptValue QScriptValueProperty::value() const +{ + Q_D(const QScriptValueProperty); + if (!d) + return QScriptValue(); + return d->value; +} + +/*! + Returns the flags of this QScriptValueProperty. +*/ +QScriptValue::PropertyFlags QScriptValueProperty::flags() const +{ + Q_D(const QScriptValueProperty); + if (!d) + return 0; + return d->flags; +} + +/*! + Returns true if this QScriptValueProperty is valid, otherwise + returns false. +*/ +bool QScriptValueProperty::isValid() const +{ + Q_D(const QScriptValueProperty); + return (d != 0); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptvalueproperty_p.h b/src/scripttools/debugging/qscriptvalueproperty_p.h new file mode 100644 index 0000000..938ab83 --- /dev/null +++ b/src/scripttools/debugging/qscriptvalueproperty_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTVALUEPROPERTY_P_H +#define QSCRIPTVALUEPROPERTY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> +#include <QtCore/qlist.h> +#include <QtScript/qscriptvalue.h> + +QT_BEGIN_NAMESPACE + +class QString; + +class QScriptValuePropertyPrivate; +class Q_AUTOTEST_EXPORT QScriptValueProperty +{ +public: + QScriptValueProperty(); + QScriptValueProperty(const QString &name, + const QScriptValue &value, + QScriptValue::PropertyFlags flags); + QScriptValueProperty(const QScriptValueProperty &other); + ~QScriptValueProperty(); + + QScriptValueProperty &operator=(const QScriptValueProperty &other); + + QString name() const; + QScriptValue value() const; + QScriptValue::PropertyFlags flags() const; + + bool isValid() const; + +private: + QScriptValuePropertyPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QScriptValueProperty) +}; + +typedef QList<QScriptValueProperty> QScriptValuePropertyList; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptxmlparser.cpp b/src/scripttools/debugging/qscriptxmlparser.cpp new file mode 100644 index 0000000..1082759 --- /dev/null +++ b/src/scripttools/debugging/qscriptxmlparser.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptxmlparser_p.h" + +#include <QtCore/qstringlist.h> +#include <QtCore/qxmlstream.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +static void tokenUntil(QXmlStreamReader &reader, QXmlStreamReader::TokenType target, + QList<int> &lineNumbers) +{ + int level = 0; + while (!reader.atEnd()) { + QXmlStreamReader::TokenType t = reader.readNext(); + if ((t == target) && (level == 0)) + return; + if (t == QXmlStreamReader::StartElement) { + ++level; + QString line = reader.attributes().value(QLatin1String("line")).toString(); + if (!line.isEmpty()) + lineNumbers.append(line.toInt()); + } else if (t == QXmlStreamReader::EndElement) { + --level; + } + } +// Q_ASSERT_X(false, "QScriptXmlParser", "premature end of file"); +} + +QScriptXmlParser::Result QScriptXmlParser::parse(const QString &xml) +{ + QMap<QString, int> functionsInfo; + QList<int> lineNumbers; + QXmlStreamReader reader(xml); + reader.readNext(); // StartDocument + reader.readNext(); // <program> + reader.readNext(); // <source-elements> + while (reader.readNext() == QXmlStreamReader::StartElement) { +// qDebug() << reader.name().toString(); + int line = reader.attributes().value(QLatin1String("line")).toString().toInt(); + lineNumbers.append(line); + if (reader.name() == QLatin1String("function-declaration")) { + // extract the line number, name and formal parameters + reader.readNext(); // <name> + reader.readNext(); // Characters + QString name = reader.text().toString(); + reader.readNext(); // </name> + reader.readNext(); // <formal-parameter-list> + QStringList formalParameters; + while (reader.readNext() == QXmlStreamReader::StartElement) { + reader.readNext(); // Characters + formalParameters.append(reader.text().toString()); + reader.readNext(); // </identifier> + } + reader.readNext(); // <function-body> + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + + QString signature; + signature.append(name); + signature.append(QLatin1Char('(')); + for (int i = 0; i < formalParameters.size(); ++i) { + if (i > 0) + signature.append(QLatin1String(", ")); + signature.append(formalParameters.at(i)); + } + signature.append(QLatin1Char(')')); + functionsInfo.insert(signature, line); + } else if (reader.name() == QLatin1String("expression-statement")) { + reader.readNext(); + if ((reader.name() == QLatin1String("binary-expression")) + && reader.attributes().value(QLatin1String("op")) == QLatin1String("=")) { + // try to match a statement of the form Foo.prototype.bar = function() { ... } + // this can be generalized... + QString first, second, third; + reader.readNext(); // LHS + if (reader.name() == QLatin1String("field-member-expression")) { + reader.readNext(); + if (reader.name() == QLatin1String("field-member-expression")) { + reader.readNext(); + if (reader.name() == QLatin1String("identifier")) { + reader.readNext(); + first = reader.text().toString(); + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + reader.readNext(); + if (reader.name() == QLatin1String("identifier")) { + reader.readNext(); + second = reader.text().toString(); + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + } else if (reader.name() == QLatin1String("identifier")) { + reader.readNext(); + first = reader.text().toString(); + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + reader.readNext(); + if (reader.name() == QLatin1String("identifier")) { + reader.readNext(); + if (second.isEmpty()) + second = reader.text().toString(); + else + third = reader.text().toString(); + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + reader.readNext(); // RHS + if (reader.name() == QLatin1String("function-expression")) { + if (!first.isEmpty()) { + QString signature = first; + if (!second.isEmpty()) { + signature.append(QLatin1Char('.')); + signature.append(second); + if (!third.isEmpty()) { + signature.append(QLatin1Char('.')); + signature.append(third); + } + } + signature.append(QLatin1String("()")); + functionsInfo.insert(signature, line); + } + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + } + tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers); + } + reader.readNext(); // </source-elements> + reader.readNext(); // </program> + reader.readNext(); // EndDocument + Q_ASSERT(reader.atEnd()); + return Result(functionsInfo, lineNumbers.toSet()); +} + +QT_END_NAMESPACE diff --git a/src/scripttools/debugging/qscriptxmlparser_p.h b/src/scripttools/debugging/qscriptxmlparser_p.h new file mode 100644 index 0000000..0bfccbf --- /dev/null +++ b/src/scripttools/debugging/qscriptxmlparser_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtSCriptTools module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTXMLPARSER_P_H +#define QSCRIPTXMLPARSER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qmap.h> +#include <QtCore/qset.h> +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QScriptXmlParser +{ +public: + struct Result + { + Result(const QMap<QString, int> &fi, const QSet<int> &eln) + : functionsInfo(fi), executableLineNumbers(eln) {} + + QMap<QString, int> functionsInfo; + QSet<int> executableLineNumbers; + }; + + static Result parse(const QString &xml); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/scripts/commands/advance.qs b/src/scripttools/debugging/scripts/commands/advance.qs new file mode 100644 index 0000000..2647dc1 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/advance.qs @@ -0,0 +1,41 @@ +name = "advance"; + +group = "running"; + +shortDescription = "Continue the program up to the given location"; + +longDescription = "This command has the same syntax as the \"break\" command."; + +seeAlso = [ "break", "tbreak" ]; + +argumentTypes = [ "script-filename" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument(s)."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scheduleRunToLocation(sid, lineNumber); + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + // ### resolve the script to see if it's loaded or not? (e.g. so we can issue a warning) + scheduleRunToLocation(fileName, lineNumber); + } +} + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/backtrace.qs b/src/scripttools/debugging/scripts/commands/backtrace.qs new file mode 100644 index 0000000..4e959fd --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/backtrace.qs @@ -0,0 +1,26 @@ +name = "backtrace"; + +group = "stack"; + +shortDescription = "Print backtrace of stack frames"; + +longDescription = ""; + +aliases = [ "bt" ]; + +seeAlso = [ "frame", "info" ]; + +function execute() { + scheduleGetBacktrace(); +}; + +function handleResponse(resp) { + var strings = resp.result; + var msg = ""; + for (var i = 0; i < strings.length; ++i) { + if (i > 0) + msg += "\n"; + msg += "#" + i + " " + strings[i]; + } + message(msg); +} diff --git a/src/scripttools/debugging/scripts/commands/break.qs b/src/scripttools/debugging/scripts/commands/break.qs new file mode 100644 index 0000000..8363685 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/break.qs @@ -0,0 +1,59 @@ +name = "break"; + +group = "breakpoints"; + +shortDescription = "Set a breakpoint at specified location"; + +longDescription = "break <file>:<line> : Sets a breakpoint at the given location."; +longDescription += "\nbreak <line> : Sets a breakpoint at the given line of the current file."; + +argumentTypes = [ "script-filename" ]; + +aliases = [ "b" ]; + +seeAlso = [ "condition", "delete", "disable", "tbreak" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Breakpoint location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scheduleGetScriptData(sid); + scriptId = sid; + state = 1; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + // ### resolve the script to see if it's loaded or not? (e.g. so we can issue a warning) + scheduleSetBreakpoint({ fileName: fileName, lineNumber: lineNumber}); + state = 2; + } +} + +function handleResponse(resp) { + if (state == 1) { + fileName = resp.result.fileName; + if (fileName.length == 0) + fileName = "<anonymous script, id=" + scriptId + ">"; + scheduleSetBreakpoint({ scriptId: scriptId, lineNumber: lineNumber}); + state = 2; + } else if (state == 2) { + if (resp.error == 0) { + var id = resp.result; + message("Breakpoint " + id + ": " + fileName + ", line " + lineNumber + "."); + } + } +} diff --git a/src/scripttools/debugging/scripts/commands/clear.qs b/src/scripttools/debugging/scripts/commands/clear.qs new file mode 100644 index 0000000..3a22587 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/clear.qs @@ -0,0 +1,59 @@ +name = "clear"; + +group = "breakpoints"; + +shortDescription = "Clear breakpoint at specified location"; + +longDescription = "clear <file>:<line> : Clear breakpoints at the given location."; +longDescription += "\nclear <line> : Clear breakpoints at the given line of the current script."; + +seeAlso = [ "delete" ]; + +argumentTypes = [ "script-filename" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Breakpoint location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scriptId = sid; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + } + scheduleGetBreakpoints(); + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var breakpoints = resp.result; + if (breakpoints == undefined) + return; + for (var id in breakpoints) { + var data = breakpoints[id]; + if ((data.lineNumber == lineNumber) + && (data.fileName == fileName) + || ((data.scriptId != -1) && (data.scriptId = scriptId))) { + scheduleDeleteBreakpoint(id); + message("Deleted breakpoint " + id + "."); + } + } + state = 2; + } else if (state == 2) { + + } +} diff --git a/src/scripttools/debugging/scripts/commands/complete.qs b/src/scripttools/debugging/scripts/commands/complete.qs new file mode 100644 index 0000000..9d60312 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/complete.qs @@ -0,0 +1,14 @@ +name = "complete"; + +group = "void"; + +shortDescription = "List the completions for the rest of the line as a command"; + +longDescription = ""; + +function execute() { + var prefix = (arguments.length > 0) ? arguments[0] : ""; + var completions = getCommandCompletions(prefix); + for (var i = 0; i < completions.length; ++i) + message(completions[i]); +} diff --git a/src/scripttools/debugging/scripts/commands/condition.qs b/src/scripttools/debugging/scripts/commands/condition.qs new file mode 100644 index 0000000..9bf6ae2 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/condition.qs @@ -0,0 +1,52 @@ +name = "condition"; + +group = "breakpoints"; + +shortDescription = "Specify breakpoint condition"; + +longDescription = "condition <breakpoint-id> <expression> : Specify that the breakpoint with the given id should only be triggered if the given expression evaluates to true."; + +argumentTypes = [ "breakpoint-id", "script" ]; + +seeAlso = [ "ignore" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing arguments (breakpoint number and condition)."); + return; + } + var arg = arguments[0]; + var spaceIndex = arg.indexOf(' '); + if (spaceIndex == -1) + spaceIndex = arg.length; + var id = parseInt(arg.slice(0, spaceIndex)); + if (isNaN(id)) { + message("First argument must be a number (breakpoint id)."); + return; + } + var cond = arg.slice(spaceIndex+1); + if ((cond.length != 0) && !checkSyntax(cond)) { + message("The condition has a syntax error."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + condition = cond; + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } + data.condition = condition; + scheduleSetBreakpointData(breakpointId, data); + state = 2; + } else if (state == 2) { + if (condition.length == 0) + message("Breakpoint " + breakpointId + " now unconditional."); + } +} diff --git a/src/scripttools/debugging/scripts/commands/continue.qs b/src/scripttools/debugging/scripts/commands/continue.qs new file mode 100644 index 0000000..a940f13 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/continue.qs @@ -0,0 +1,22 @@ +name = "continue"; + +group = "running"; + +shortDescription = "Continue evaluation"; + +longDescription = "Evaluation will continue until an uncaught exception occurs, " +longDescription += "a breakpoint is hit or evaluation is explicitly interrupted."; + +aliases = [ "c", "fg" ]; + +seeAlso = [ "step", "interrupt" ]; + +function execute() { + scheduleContinue(); +}; + +function handleResponse(resp) { + if (!resp.async) { + message("The target is not evaluating code."); + } +} diff --git a/src/scripttools/debugging/scripts/commands/delete.qs b/src/scripttools/debugging/scripts/commands/delete.qs new file mode 100644 index 0000000..84497a7 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/delete.qs @@ -0,0 +1,36 @@ +name = "delete"; + +group = "breakpoints"; + +shortDescription = "Delete breakpoint(s)"; + +longDescription = "delete <breakpoint-id> : Deletes the breakpoint with the given id."; + +seeAlso = [ "clear", "disable" ]; + +function execute() { + if (arguments.length == 0) { + // delete all breakpoints + scheduleClearBreakpoints(); + state = 1; + } else { + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleDeleteBreakpoint(id); + breakpointId = id; + state = 2; + } +} + +function handleResponse(resp) { + if (state == 1) { + } else if (state == 2) { + if (resp.error != 0) { + message("No breakpoint number " + breakpointId + "."); + return; + } + } +} diff --git a/src/scripttools/debugging/scripts/commands/disable.qs b/src/scripttools/debugging/scripts/commands/disable.qs new file mode 100644 index 0000000..91bf44b --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/disable.qs @@ -0,0 +1,56 @@ +name = "disable"; + +group = "breakpoints"; + +shortDescription = "Disable breakpoint(s)"; + +longDescription = "disable <breakpoint-id> : Disables the breakpoint with the given id."; + +seeAlso = [ "enable", "delete", "ignore" ]; + +function execute() { + if (arguments.length == 0) { + // disable all breakpoints + state = 1; + scheduleGetBreakpoints(); + } else { + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + state = 3; + } +}; + +function handleResponse(resp) { + if (state == 1) { + var breakpoints = resp.result; + if (breakpoints == undefined) + return; + for (var id in breakpoints) { + var data = breakpoints[id]; + if (data.enabled) { + data.enabled = false; + scheduleSetBreakpointData(id, data); + } + } + state = 2; + } else if (state == 2) { + state = 0; + } else if (state == 3) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } else if (data.enabled) { + data.enabled = false; + scheduleSetBreakpointData(breakpointId, data); + state = 4; + } + } else if (state == 4) { + state = 0; + } +} diff --git a/src/scripttools/debugging/scripts/commands/down.qs b/src/scripttools/debugging/scripts/commands/down.qs new file mode 100644 index 0000000..dc0429b --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/down.qs @@ -0,0 +1,33 @@ +name = "down"; + +group = "stack"; + +shortDescription = "Select and print the stack frame below the current one"; + +longDescription = ""; + +seeAlso = [ "up", "frame" ]; + +function execute() { + var idx = getCurrentFrameIndex(); + if (idx == 0) { + warning("Already at bottom (innermost) frame."); + return; + } + setCurrentFrameIndex(idx - 1); + scheduleGetContextInfo(idx - 1); + state = 1; +} + +function handleResponse(resp, id) { + if (state == 1) { + var info = resp.result; + setCurrentScriptId(info.scriptId); + setCurrentLineNumber(info.lineNumber); + scheduleGetBacktrace(); + state = 2; + } else if (state == 2) { + var backtrace = resp.result; + message("#" + getCurrentFrameIndex() + " " + backtrace[getCurrentFrameIndex()]); + } +} diff --git a/src/scripttools/debugging/scripts/commands/enable.qs b/src/scripttools/debugging/scripts/commands/enable.qs new file mode 100644 index 0000000..6468d0a --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/enable.qs @@ -0,0 +1,56 @@ +name = "enable"; + +group = "breakpoints"; + +shortDescription = "Enable breakpoint(s)"; + +longDescription = "enable <breakpoint-id> : Enable the breakpoint with the given id."; + +seeAlso = [ "disable" ]; + +function execute() { + if (arguments.length == 0) { + // enable all breakpoints + state = 1; + scheduleGetBreakpoints(); + } else { + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + state = 3; + } +}; + +function handleResponse(resp) { + if (state == 1) { + var breakpoints = resp.result; + if (breakpoints == undefined) + return; + for (var id in breakpoints) { + var data = breakpoints[id]; + if (!data.enabled) { + data.enabled = true; + scheduleSetBreakpointData(id, data); + } + } + state = 2; + } else if (state == 2) { + state = 0; + } else if (state == 3) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } else if (!data.enabled) { + data.enabled = true; + scheduleSetBreakpointData(breakpointId, data); + state = 4; + } + } else if (state == 4) { + state = 0; + } +} diff --git a/src/scripttools/debugging/scripts/commands/eval.qs b/src/scripttools/debugging/scripts/commands/eval.qs new file mode 100644 index 0000000..02a1b9f --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/eval.qs @@ -0,0 +1,21 @@ +name = "eval"; + +group = "running"; + +shortDescription = "Evaluate program"; + +longDescription = ""; + +argumentTypes = [ "script" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument (program)."); + return; + } + setEvaluateAction(0); + scheduleEvaluate(getCurrentFrameIndex(), arguments[0], "console input (" + Date() + ")"); +}; + +function handleResponse(resp, id) { +} diff --git a/src/scripttools/debugging/scripts/commands/finish.qs b/src/scripttools/debugging/scripts/commands/finish.qs new file mode 100644 index 0000000..bf19fc0 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/finish.qs @@ -0,0 +1,16 @@ +name = "finish"; + +group = "running"; + +shortDescription = "Execute until the current stack frame returns"; + +longDescription = "Upon return, the value returned is printed."; + +seeAlso = [ "next", "continue" ]; + +function execute() { + scheduleStepOut(); +}; + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/frame.qs b/src/scripttools/debugging/scripts/commands/frame.qs new file mode 100644 index 0000000..5dc4611 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/frame.qs @@ -0,0 +1,36 @@ +name = "frame"; + +group = "stack"; + +shortDescription = "Select and print a stack frame"; + +longDescription = ""; + +aliases = [ "f" ]; + +function execute() { + if (arguments.length == 0) + requestedFrameIndex = getCurrentFrameIndex(); + else + requestedFrameIndex = parseInt(arguments[0]); + scheduleGetContextInfo(requestedFrameIndex); + state = 1; +}; + +function handleResponse(resp, id) { + if (state == 1) { + var info = resp.result; + if (info == undefined) { + message("Frame index out of range."); + return; + } + setCurrentFrameIndex(requestedFrameIndex); + setCurrentScriptId(info.scriptId); + setCurrentLineNumber(info.lineNumber); + scheduleGetBacktrace(); + state = 2; + } else if (state == 2) { + var backtrace = resp.result; + message("#" + getCurrentFrameIndex() + " " + backtrace[getCurrentFrameIndex()]); + } +} diff --git a/src/scripttools/debugging/scripts/commands/help.qs b/src/scripttools/debugging/scripts/commands/help.qs new file mode 100644 index 0000000..121db11 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/help.qs @@ -0,0 +1,71 @@ +name = "help"; + +group = "void"; + +shortDescription = "Print list of commands"; + +longDescription = ""; + +argumentTypes = [ "command-or-group-name" ]; + +function execute() { + if (arguments.length == 0) { + var groups = getCommandGroups(); + message("List of command categories:"); + message(""); + for (var name in groups) { + if (name == "void") + continue; + var data = groups[name]; + message(name + " :: " + data.shortDescription); + } + message(""); + message("Type \"help\" followed by a category name for a list of commands in that category."); + message("Type \"help all\" for the list of all commands."); + message("Type \"help\" followed by a command name for full documentation."); + message("Command name abbreviations are allowed if they are unambiguous."); + } else { + var arg = arguments[0]; + if (arg == "all") { + var groups = getCommandGroups(); + for (var name in groups) { + if (name == "void") + continue; + message("Command category: " + name); + message(""); + var commands = getCommandsInGroup(name); + for (var i = 0; i < commands.length; ++i) { + var data = commands[i]; + message(data.name + " :: " + data.shortDescription); + } + message(""); + } + } else { + var data = findCommand(arg); + if (data != undefined) { + message(data.shortDescription + "."); + if (data.longDescription.length != 0) + message(data.longDescription); + if (data.aliases.length != 0) + message("Aliases: " + data.aliases.join(", ")); + if (data.seeAlso.length != 0) + message("See also: " + data.seeAlso.join(", ")); + } else { + data = getCommandGroups()[arg]; + if (data != undefined) { + message(data.shortDescription + "."); + message(""); + message("List of commands:"); + message(""); + var commands = getCommandsInGroup(arg); + for (var i = 0; i < commands.length; ++i) { + var data = commands[i]; + message(data.name + " :: " + data.shortDescription); + } + } else { + message("Undefined command \"" + arg + "\". Try \"help\"."); + } + } + } + } +}; diff --git a/src/scripttools/debugging/scripts/commands/ignore.qs b/src/scripttools/debugging/scripts/commands/ignore.qs new file mode 100644 index 0000000..b625bae --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/ignore.qs @@ -0,0 +1,51 @@ +name = "ignore"; + +group = "breakpoints"; + +shortDescription = "Set ignore-count of a breakpoint"; + +longDescription = "ignore <breakpoint-id> <count> : Ignores the breakpoint with the given id the next count times it is hit."; + +seeAlso = [ "condition" ]; + +function execute() { + if (arguments.length < 1) { + message("Missing arguments (breakpoing number and ignore-count)."); + return; + } + if (arguments.length < 2) { + message("Missing argument (ignore-count)."); + return; + } + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("First argument (breakpoint id) must be a number."); + return; + } + var count = parseInt(arguments[1]); + if (isNaN(count)) { + message("Second argument (ignore-count) must be a number."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + if (count < 0) + count = 0; + ignoreCount = count; + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } + data.ignoreCount = ignoreCount; + scheduleSetBreakpointData(breakpointId, data); + state = 2; + } else if (state == 2) { + message("Breakpoint " + breakpointId + " will be ignored the next " + ignoreCount + " time(s)."); + } +} diff --git a/src/scripttools/debugging/scripts/commands/info.qs b/src/scripttools/debugging/scripts/commands/info.qs new file mode 100644 index 0000000..2577e92 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/info.qs @@ -0,0 +1,128 @@ +name = "info"; + +group = "status"; + +shortDescription = "Display information about something"; + +longDescription = "info scripts : Names of scripts being debugged"; +longDescription += "\ninfo breakpoints : Status of breakpoints currently set"; +longDescription += "\ninfo locals : Local variables of current stack frame"; + +argumentTypes = [ "subcommand-name" ]; + +subCommands = [ "breakpoints", "locals", "scripts" ]; + +function execute() { + var arg = arguments[0]; + if (arg == undefined) { + message("\"info\" must be followed by the name of an info command."); + return; + } else if (arg == "scripts") { + scheduleGetScripts(); + state = 1; + } else if (arg == "breakpoints") { + if (arguments.length > 1) { + var id = parseInt(arguments[1]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + state = 3; + } else { + scheduleGetBreakpoints(); + state = 2; + } + } else if (arg == "locals") { + scheduleGetActivationObject(getCurrentFrameIndex()); + state = 4; + } else { + warning("Undefined info command \"" + arg + "\". Try \"help info\"."); + } +} + +function breakpointString(id, data) { + var fn = data.fileName; + if (fn.length == 0) + fn = "<anonymous script, id=" + data.scriptId + ">"; + var ret = id + "\t" + (data.enabled ? "yes" : "no") + + "\t" + fn + ":" + data.lineNumber; + if (data.condition.length != 0) { + ret += "\n\tstop only if " + data.condition; + } + return ret; +} + +function handleResponse(resp) { + if (state == 1) { + // info scripts + var scripts = resp.result; + if (scripts == undefined) { + message("No scripts loaded."); + return; + } + for (var id in scripts) { + var fn = scripts[id].fileName; + if (fn.length == 0) + fn = "<anonymous script, id=" + id + ">"; + message("\t" + fn); + } + } + + else if (state == 2) { + // info breakpoints + var breakpoints = resp.result; + if (breakpoints == undefined) { + message("No breakpoints set."); + return; + } + message("Id\tEnabled\tWhere"); + for (var id in breakpoints) { + var data = breakpoints[id]; + message(breakpointString(id, data)); + } + } else if (state == 3) { + // info breakpoints N + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } + message("Id\tEnabled\tWhere"); + message(breakpointString(breakpointId, data)); + } + + else if (state == 4) { + // info locals + var act = resp.result; + scheduleNewScriptValueIterator(act); + state = 5; + } else if (state == 5) { + var id = resp.result; + scheduleGetPropertiesByIterator(id, 100); + iteratorId = id; + state = 6; + } else if (state == 6) { + var props = resp.result; + if (props.length == 0) { + scheduleDeleteScriptValueIterator(iteratorId); + state = 7; + return; + } + var maxLength = 0; + for (var i = 0; i < props.length; ++i) + maxLength = Math.max(props[i].name.length, maxLength); + for (var i = 0; i < props.length; ++i) { + var prop = props[i]; + var msg = prop.name; + var pad = maxLength - prop.name.length; + for (var j = 0; j < pad; ++j) + msg += ' '; + message(msg + " : " + prop.valueAsString); + } + scheduleGetPropertiesByIterator(iteratorId, 100); + } else if (state == 7) { + // done + } +} diff --git a/src/scripttools/debugging/scripts/commands/interrupt.qs b/src/scripttools/debugging/scripts/commands/interrupt.qs new file mode 100644 index 0000000..d4b66cc --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/interrupt.qs @@ -0,0 +1,14 @@ +name = "interrupt"; + +group = "running"; + +shortDescription = "Interrupt evaluation"; + +longDescription = "Interruption will occur as soon as a new script statement is reached."; + +function execute() { + scheduleInterrupt(); +} + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/list.qs b/src/scripttools/debugging/scripts/commands/list.qs new file mode 100644 index 0000000..312b123 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/list.qs @@ -0,0 +1,90 @@ +name = "list"; + +group = "files"; + +shortDescription = "List lines of a script"; + +longDescription = "list <file>:<line> : Lists lines around the given location."; +longDescription += "\nlist <line> : Lists lines in the current file."; + +argumentTypes = [ "script-filename" ]; + +listLineNumber = 1; +listScriptId = -1; +lastSessionId = -1; +lastFrameIndex = -1; + +function execute() { + state = 0; + if (arguments.length > 0) { + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + var fileName; + var lineNumber; + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + fileName = arg; + lineNumber = 1; + } + } else if (colonIndex == 0) { + fileName = arg; + lineNumber = 1; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + } + listLineNumber = Math.max(lineNumber, 1); + if (fileName != undefined) { + scheduleResolveScript(fileName); + state = 1; + } else { + setCurrentLineNumber(listLineNumber); + execute(); + } + } else { + if ((getSessionId() != lastSessionId) + || (getCurrentFrameIndex() != lastFrameIndex) + || (listScriptId == -1)) { + listScriptId = getCurrentScriptId(); + listLineNumber = getCurrentLineNumber(); + lastSessionId = getSessionId(); + lastFrameIndex = getCurrentFrameIndex(); + } + scheduleGetScriptData(listScriptId); + state = 2; + } +}; + +function handleResponse(resp) { + if (state == 1) { + var id = resp.result; + if (id == -1) { + message("That script isn't loaded."); + state = 0; + return; + } + listScriptId = id; + scheduleGetScriptData(listScriptId); + state = 2; + } else if (state == 2) { + var data = resp.result; + if (data == undefined) { + message("No script."); + state = 0; + return; + } + var base = data.baseLineNumber; + var lines = data.contents.split('\n'); + var start = Math.max(listLineNumber - 5, base); + for (var i = start; i < start + 10; ++i) { + var ln = lines[i - base]; + var msg = String(i); + if (ln != undefined) + msg += "\t" + ln; + message(msg); + } + listLineNumber += 10; + state = 0; + } +} diff --git a/src/scripttools/debugging/scripts/commands/next.qs b/src/scripttools/debugging/scripts/commands/next.qs new file mode 100644 index 0000000..bc37a01 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/next.qs @@ -0,0 +1,27 @@ +name = "next"; + +group = "running"; + +shortDescription = "Step program, proceeding through subroutine calls"; + +longDescription = "Like the \"step\" command as long as subroutine calls do not happen;"; +longDescription += "\nwhen they do, the call is treated as one instruction."; +longDescription += "\nIf a number N is given as argument, this will be done N times before execution is stopped."; +aliases = [ "n" ]; + +seeAlso = [ "step", "continue", "finish", "advance" ]; + +function execute() { + var count = 1; + if (arguments.length != 0) { + var arg = arguments[0]; + // ### evaluate the expression in the current frame? + var num = parseInt(arg); + if (!isNaN(num) && (num >= 1)) + count = num; + } + scheduleStepOver(count); +}; + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/print.qs b/src/scripttools/debugging/scripts/commands/print.qs new file mode 100644 index 0000000..9b98d16 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/print.qs @@ -0,0 +1,23 @@ +// ### exactly the same as eval, but provided for convenience + +name = "print"; + +group = "status"; + +shortDescription = "Print value of an expression"; + +longDescription = ""; + +argumentTypes = [ "script" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument (expression)."); + return; + } + setEvaluateAction(0); + scheduleEvaluate(getCurrentFrameIndex(), arguments[0], "console input (" + Date() + ")"); +}; + +function handleResponse(resp, id) { +} diff --git a/src/scripttools/debugging/scripts/commands/return.qs b/src/scripttools/debugging/scripts/commands/return.qs new file mode 100644 index 0000000..372c818 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/return.qs @@ -0,0 +1,20 @@ +name = "return"; + +group = "running"; + +shortDescription = "Make selected stack frame return to its caller"; + +longDescription = ""; + +argumentTypes = [ "script" ]; + +function execute() { + // TODO: + // 1. schedule evaluate of the expression. + // 2. install event handler/filter, so that we're notified when the evaluate is done. + // - what if another event occurs while we evaluate? (e.g. an exception or breakpoint) + // - the event filter needs to uninstall itself, or the event needs to be consumed internally + // 3. in the event handler, schedule forced return with the result as argument. + setEvaluateAction(1); + scheduleEvaluate(getCurrentFrameIndex(), arguments[0], "console input (" + Date() + ")"); +}; diff --git a/src/scripttools/debugging/scripts/commands/step.qs b/src/scripttools/debugging/scripts/commands/step.qs new file mode 100644 index 0000000..1aacec0 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/step.qs @@ -0,0 +1,26 @@ +name = "step"; + +group = "running"; + +shortDescription = "Step program until a new statement is reached"; + +longDescription = "If a number N is given as argument, this will be done N times before execution is stopped."; + +aliases = [ "s" ]; + +seeAlso = [ "next" ]; + +function execute() { + var count = 1; + if (arguments.length != 0) { + var arg = arguments[0]; + // ### evaluate the expression in the current frame? + var num = parseInt(arg); + if (!isNaN(num) && (num >= 1)) + count = num; + } + scheduleStepInto(count); +}; + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/tbreak.qs b/src/scripttools/debugging/scripts/commands/tbreak.qs new file mode 100644 index 0000000..66a8224 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/tbreak.qs @@ -0,0 +1,59 @@ +name = "tbreak"; + +group = "breakpoints"; + +shortDescription = "Set a temporary breakpoint"; + +longDescription = "The same as the \"break\" command, except that the breakpoint is automatically deleted as soon as it is triggered."; + +seeAlso = [ "break", "ignore" ]; + +argumentTypes = [ "script-filename" ]; + +// ### merge with break.qs: only difference is the "singleShot: true" in call to scheduleSetBreakpoint() +// ### maybe an include() function so commands can share code? + +function execute() { + if (arguments.length == 0) { + message("Missing argument."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Breakpoint location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scheduleGetScriptData(sid); + scriptId = sid; + state = 1; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + // ### resolve the script to see if it's loaded or not? (e.g. so we can issue a warning) + scheduleSetBreakpoint({ fileName: fileName, lineNumber: lineNumber, singleShot: true }); + state = 2; + } +} + +function handleResponse(resp) { + if (state == 1) { + fileName = resp.result.fileName; + if (fileName.length == 0) + fileName = "<anonymous script, id=" + scriptId + ">"; + scheduleSetBreakpoint({ scriptId: scriptId, lineNumber: lineNumber, singleShot: true }); + state = 2; + } else if (state == 2) { + if (resp.error == 0) { + var id = resp.result; + message("Breakpoint " + id + ": " + fileName + ", line " + lineNumber + "."); + } + } +} diff --git a/src/scripttools/debugging/scripts/commands/up.qs b/src/scripttools/debugging/scripts/commands/up.qs new file mode 100644 index 0000000..2d49df3 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/up.qs @@ -0,0 +1,37 @@ +name = "up"; + +group = "stack"; + +shortDescription = "Select and print the stack frame above the current one"; + +longDescription = ""; + +seeAlso = [ "down", "frame" ]; + +function execute() { + scheduleGetContextCount(); + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var count = resp.result; + var idx = getCurrentFrameIndex() + 1; + if (idx == count) { + warning("Already at top (outermost) frame."); + return; + } + setCurrentFrameIndex(idx); + scheduleGetContextInfo(idx); + state = 2; + } else if (state == 2) { + var info = resp.result; + setCurrentScriptId(info.scriptId); + setCurrentLineNumber(info.lineNumber); + scheduleGetBacktrace(); + state = 3; + } else if (state == 3) { + var backtrace = resp.result; + message("#" + getCurrentFrameIndex() + " " + backtrace[getCurrentFrameIndex()]); + } +} diff --git a/src/scripttools/debugging/scripttools_debugging.qrc b/src/scripttools/debugging/scripttools_debugging.qrc new file mode 100644 index 0000000..ba0aba8 --- /dev/null +++ b/src/scripttools/debugging/scripttools_debugging.qrc @@ -0,0 +1,63 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/qt/scripttools/debugging/"> + +<file>scripts/commands/advance.qs</file> +<file>scripts/commands/backtrace.qs</file> +<file>scripts/commands/break.qs</file> +<file>scripts/commands/clear.qs</file> +<file>scripts/commands/complete.qs</file> +<file>scripts/commands/condition.qs</file> +<file>scripts/commands/continue.qs</file> +<file>scripts/commands/delete.qs</file> +<file>scripts/commands/disable.qs</file> +<file>scripts/commands/down.qs</file> +<file>scripts/commands/enable.qs</file> +<file>scripts/commands/eval.qs</file> +<file>scripts/commands/finish.qs</file> +<file>scripts/commands/frame.qs</file> +<file>scripts/commands/help.qs</file> +<file>scripts/commands/ignore.qs</file> +<file>scripts/commands/info.qs</file> +<file>scripts/commands/interrupt.qs</file> +<file>scripts/commands/list.qs</file> +<file>scripts/commands/next.qs</file> +<file>scripts/commands/print.qs</file> +<file>scripts/commands/return.qs</file> +<file>scripts/commands/step.qs</file> +<file>scripts/commands/tbreak.qs</file> +<file>scripts/commands/up.qs</file> + +<file>images/interrupt.png</file> +<file>images/d_interrupt.png</file> +<file>images/play.png</file> +<file>images/d_play.png</file> +<file>images/stepinto.png</file> +<file>images/stepover.png</file> +<file>images/stepout.png</file> +<file>images/runtocursor.png</file> +<file>images/runtonewscript.png</file> +<file>images/return.png</file> +<file>images/reload.png</file> + +<file>images/location.svg</file> +<file>images/breakpoint.svg</file> +<file>images/d_breakpoint.svg</file> +<file>images/location.png</file> +<file>images/breakpoint.png</file> +<file>images/d_breakpoint.png</file> + +<file>images/mac/closetab.png</file> +<file>images/mac/next.png</file> +<file>images/mac/previous.png</file> +<file>images/mac/plus.png</file> +<file>images/win/closetab.png</file> +<file>images/win/next.png</file> +<file>images/win/previous.png</file> +<file>images/win/plus.png</file> +<file>images/wrap.png</file> +<file>images/find.png</file> +<file>images/new.png</file> +<file>images/delete.png</file> + +</qresource> +</RCC> |