From af47510b051f4c73e2d56ce91b4a66d8bc5e6b9e Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Tue, 15 Apr 2014 00:30:01 +0200 Subject: [PATCH 01/11] Initial script editor widget / icons made by MaximillianMerlin ty --- interface/resources/icons/load-script.svg | 125 ++++ interface/resources/icons/new-script.svg | 129 +++++ interface/resources/icons/save-script.svg | 674 ++++++++++++++++++++++ interface/src/Application.h | 1 + interface/src/Menu.cpp | 8 + interface/src/Menu.h | 4 + interface/src/ScriptHighlighting.cpp | 18 + interface/src/ScriptHighlighting.h | 25 + interface/src/ui/ScriptEditorWidget.cpp | 39 ++ interface/src/ui/ScriptEditorWidget.h | 34 ++ interface/src/ui/ScriptEditorWindow.cpp | 62 ++ interface/src/ui/ScriptEditorWindow.h | 39 ++ interface/ui/ScriptEditorWidget.ui | 89 +++ interface/ui/ScriptEditorWindow.ui | 290 ++++++++++ 14 files changed, 1537 insertions(+) create mode 100644 interface/resources/icons/load-script.svg create mode 100644 interface/resources/icons/new-script.svg create mode 100644 interface/resources/icons/save-script.svg create mode 100644 interface/src/ScriptHighlighting.cpp create mode 100644 interface/src/ScriptHighlighting.h create mode 100644 interface/src/ui/ScriptEditorWidget.cpp create mode 100644 interface/src/ui/ScriptEditorWidget.h create mode 100644 interface/src/ui/ScriptEditorWindow.cpp create mode 100644 interface/src/ui/ScriptEditorWindow.h create mode 100644 interface/ui/ScriptEditorWidget.ui create mode 100644 interface/ui/ScriptEditorWindow.ui diff --git a/interface/resources/icons/load-script.svg b/interface/resources/icons/load-script.svg new file mode 100644 index 0000000000..21be61c321 --- /dev/null +++ b/interface/resources/icons/load-script.svg @@ -0,0 +1,125 @@ +<?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://creativecommons.org/ns#" + 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="45" + height="45" + id="svg3827" + version="1.1" + inkscape:version="0.48.1 r9760" + sodipodi:docname="load-script.svg"> + <defs + id="defs3829" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="3.959798" + inkscape:cx="171.17264" + inkscape:cy="-8.0710166" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="1028" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" /> + <metadata + id="metadata3832"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + <dc:creator> + <cc:Agent> + <dc:title>T.Hofmeister</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1007.3622)"> + <g + id="layer1-7" + transform="matrix(-0.25019951,0,0,0.28877175,123.44112,917.40972)" + style="fill:#696969"> + <g + id="g3257" + transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)" + style="fill:#696969"> + <path + id="path3224" + d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z" + style="fill:#696969;fill-rule:evenodd" + inkscape:connector-curvature="0" /> + <path + id="path3237" + d="m 531.39,275.61 23.34,-4.6" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3243" + d="m 532.1,280.91 22.27,-2.83" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3247" + d="m 531.92,285.86 22.89,-1.95" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3249" + d="m 530.15,292.84 24.22,-2.12" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3251" + d="m 529.45,297.53 22.98,-0.8" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3253" + d="m 528.65,304.24 22.45,-2.56" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3255" + d="m 527.5,309.37 22.81,-1.77" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + </g> + </g> + <path + display="block" + d="m 22.50945,1041.7031 c 10.249979,14.5758 18.326744,5.8628 15.179173,-14.1826 l 3.401516,-0.2354 -8.04206,-17.0393 -2.800459,17.789 3.507825,-0.2428 c 2.535261,14.6877 0.402108,18.0407 -11.324416,13.7916 z" + style="color:#000000;fill:#a9a9a9;stroke:#000000;stroke-width:0.61923206;display:block" + id="path1432" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccc" /> + <rect + style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3032" + width="44.57473" + height="44.57473" + x="0.18852967" + y="1007.5989" /> + </g> +</svg> diff --git a/interface/resources/icons/new-script.svg b/interface/resources/icons/new-script.svg new file mode 100644 index 0000000000..f68fcfa967 --- /dev/null +++ b/interface/resources/icons/new-script.svg @@ -0,0 +1,129 @@ +<?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://creativecommons.org/ns#" + 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="45" + height="45" + id="svg3827" + version="1.1" + inkscape:version="0.48.1 r9760" + sodipodi:docname="new-script - Kopie (2).svg"> + <defs + id="defs3829" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="5.6" + inkscape:cx="39.376692" + inkscape:cy="9.0006701" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="1028" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" /> + <metadata + id="metadata3832"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + <dc:creator> + <cc:Agent> + <dc:title>T.Hofmeister</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1007.3622)"> + <rect + style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3032" + width="44.57473" + height="44.57473" + x="0.18852967" + y="1007.5989" /> + <g + id="layer1-7-7" + transform="matrix(-0.23943965,0,0,0.3096188,117.90945,912.00498)" + style="fill:#696969"> + <g + id="g3257-4" + transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)" + style="fill:#696969"> + <path + id="path3224-0" + d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z" + style="fill:#696969;fill-rule:evenodd" + inkscape:connector-curvature="0" /> + <path + id="path3237-9" + d="m 531.39,275.61 23.34,-4.6" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3243-4" + d="m 532.1,280.91 22.27,-2.83" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3247-8" + d="m 531.92,285.86 22.89,-1.95" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3249-8" + d="m 530.15,292.84 24.22,-2.12" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3251-2" + d="m 529.45,297.53 22.98,-0.8" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3253-4" + d="m 528.65,304.24 22.45,-2.56" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3255-5" + d="m 527.5,309.37 22.81,-1.77" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + </g> + </g> + <g + id="layer1-1" + transform="matrix(0.85515704,0.72492349,-0.91920854,2.1402565,983.21735,-1213.0824)" + style="fill:#a9a9a9;stroke:#000000"> + <path + style="fill:#a9a9a9;fill-opacity:1;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + id="path2996" + transform="translate(0,1036.3622)" + d="m 3.4723994,8.5185577 3.0304576,-7.0710678 6.944799,0 -5.0191957,5.08233 4.1353117,0 -8.1127873,9.0913731 2.0834396,-7.1342026 z" + inkscape:connector-curvature="0" /> + </g> + </g> +</svg> diff --git a/interface/resources/icons/save-script.svg b/interface/resources/icons/save-script.svg new file mode 100644 index 0000000000..04d41b8302 --- /dev/null +++ b/interface/resources/icons/save-script.svg @@ -0,0 +1,674 @@ +<?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://creativecommons.org/ns#" + 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="45" + height="45" + id="svg3827" + version="1.1" + inkscape:version="0.48.1 r9760" + sodipodi:docname="load-script - Kopie.svg"> + <defs + id="defs3829"> + <linearGradient + x1="28.061" + x2="28.061" + y1="31.431" + gradientUnits="userSpaceOnUse" + y2="36.437" + id="linearGradient6971"> + <stop + offset="0" + stop-color="#ddd" + id="stop6967" /> + <stop + offset="1" + stop-color="#fdfdfd" + id="stop6969" /> + </linearGradient> + <linearGradient + x1="12.25" + x2="7" + y1="18.25" + gradientUnits="userSpaceOnUse" + y2="21.118" + id="linearGradient6931"> + <stop + offset="0" + stop-color="#204a87" + id="stop6927" /> + <stop + offset="1" + stop-opacity="0" + stop-color="#204a87" + id="stop6929" /> + </linearGradient> + <linearGradient + x1="14.752" + x2="8.8953" + y1="15.868" + gradientUnits="userSpaceOnUse" + y2="16.743" + id="linearGradient6907"> + <stop + offset="0" + stop-color="#3465a4" + id="stop6903" /> + <stop + offset="1" + stop-opacity="0" + stop-color="#3465a4" + id="stop6905" /> + </linearGradient> + <linearGradient + x1="33.431" + x2="21.748" + y1="31.965" + gradientUnits="userSpaceOnUse" + y2="11.781" + id="linearGradient2553"> + <stop + offset="0" + stop-color="#fff" + id="stop2557" /> + <stop + offset=".5" + stop-color="#e6e6e6" + id="stop2561" /> + <stop + offset=".75" + stop-color="#fff" + id="stop2563" /> + <stop + offset=".84167" + stop-color="#e1e1e1" + id="stop2565" /> + <stop + offset="1" + stop-color="#fff" + id="stop2559" /> + </linearGradient> + <linearGradient + y2="26.357" + y1="11.319" + gradientTransform="translate(0,5.125)" + x2="23.688" + gradientUnits="userSpaceOnUse" + x1="23.688" + id="linearGradient4272"> + <stop + offset="0" + stop-opacity=".2549" + stop-color="#fff" + id="stop4276" /> + <stop + offset="1" + stop-color="#fff" + id="stop4278" /> + </linearGradient> + <linearGradient + y2="47.621" + y1="4.4331" + gradientTransform="translate(0,5.125)" + x2="44.096" + gradientUnits="userSpaceOnUse" + x1="12.378" + id="linearGradient4260"> + <stop + offset="0" + stop-color="#fff" + id="stop4256" /> + <stop + offset="1" + stop-opacity="0" + stop-color="#fff" + id="stop4258" /> + </linearGradient> + <radialGradient + r="20.936" + gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)" + cx="15.571" + cy="2.9585" + gradientUnits="userSpaceOnUse" + id="radialGradient4250"> + <stop + offset="0" + stop-color="#e4e4e4" + id="stop4246" /> + <stop + offset="1" + stop-color="#d3d3d3" + id="stop4248" /> + </radialGradient> + <linearGradient + y2="33.759" + y1="37.206" + gradientTransform="translate(0,5.125)" + x2="12.222" + gradientUnits="userSpaceOnUse" + x1="12.277" + id="linearGradient4242"> + <stop + offset="0" + stop-color="#eee" + id="stop4238" /> + <stop + offset="1" + stop-opacity="0" + stop-color="#eee" + id="stop4240" /> + </linearGradient> + <linearGradient + y2="40.944" + y1="28.481" + gradientTransform="translate(0,5.125)" + x2="36.183" + gradientUnits="userSpaceOnUse" + x1="7.6046" + id="linearGradient4234"> + <stop + offset="0" + stop-color="#bbb" + id="stop4230" /> + <stop + offset="1" + stop-color="#9f9f9f" + id="stop4232" /> + </linearGradient> + <linearGradient + y2="35.281" + y1="35.281" + gradientTransform="translate(0.79549,3.7992)" + x2="24.688" + gradientUnits="userSpaceOnUse" + x1="7.0625" + id="linearGradient4209"> + <stop + offset="0" + stop-color="#838383" + id="stop4186" /> + <stop + offset="1" + stop-opacity="0" + stop-color="#bbb" + id="stop4188" /> + </linearGradient> + <radialGradient + r="15.645" + gradientTransform="matrix(1,0,0,0.53672,0,16.873)" + cx="24.837" + cy="36.421" + gradientUnits="userSpaceOnUse" + id="radialGradient8668"> + <stop + offset="0" + id="stop8664" /> + <stop + offset="1" + stop-opacity="0" + id="stop8666" /> + </radialGradient> + <linearGradient + y2="12.584" + x2="12.624" + gradientTransform="matrix(0.91411,0,0,0.91411,-3.8687,-2.7069)" + y1="27.394" + gradientUnits="userSpaceOnUse" + x1="33.06" + id="linearGradient1764"> + <stop + offset="0" + stop-color="#fff" + id="stop2189" /> + <stop + offset="1" + stop-opacity="0" + stop-color="#fff" + id="stop2191" /> + </linearGradient> + <radialGradient + r="19.062" + gradientTransform="matrix(-1.3145,-0.010063,-0.01023,1.3362,46.221,-4.9099)" + cx="23.447" + cy="6.4577" + gradientUnits="userSpaceOnUse" + id="radialGradient4997"> + <stop + offset="0" + stop-color="#fff" + id="stop4993" /> + <stop + offset="1" + stop-opacity="0" + stop-color="#fff" + id="stop4995" /> + </radialGradient> + <linearGradient + y2="609.51" + x2="302.86" + gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)" + y1="366.65" + gradientUnits="userSpaceOnUse" + x1="302.86" + id="linearGradient5027"> + <stop + offset="0" + stop-opacity="0" + id="stop5050" /> + <stop + offset=".5" + id="stop5056" /> + <stop + offset="1" + stop-opacity="0" + id="stop5052" /> + </linearGradient> + <radialGradient + r="117.14" + gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)" + cx="605.71" + cy="486.65" + gradientUnits="userSpaceOnUse" + xlink:href="#linearGradient5060" + id="radialGradient5029" /> + <linearGradient + id="linearGradient5060"> + <stop + offset="0" + id="stop5062" /> + <stop + offset="1" + stop-opacity="0" + id="stop5064" /> + </linearGradient> + <radialGradient + r="117.14" + gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)" + cx="605.71" + cy="486.65" + gradientUnits="userSpaceOnUse" + xlink:href="#linearGradient5060" + id="radialGradient5031" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6971" + id="linearGradient3239" + gradientUnits="userSpaceOnUse" + x1="28.061" + y1="31.431" + x2="28.061" + y2="36.437" + gradientTransform="translate(51.972416,1005.3761)" /> + <radialGradient + inkscape:collect="always" + xlink:href="#radialGradient8668" + id="radialGradient3253" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)" + cx="24.837" + cy="36.421" + r="15.645" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5027" + id="linearGradient3361" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)" + x1="302.86" + y1="366.65" + x2="302.86" + y2="609.51" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient3363" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)" + cx="605.71" + cy="486.65" + r="117.14" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient3365" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)" + cx="605.71" + cy="486.65" + r="117.14" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4234" + id="linearGradient3367" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="7.6046" + y1="28.481" + x2="36.183" + y2="40.944" /> + <radialGradient + inkscape:collect="always" + xlink:href="#radialGradient4250" + id="radialGradient3369" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)" + cx="15.571" + cy="2.9585" + r="20.936" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4209" + id="linearGradient3371" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0.79549,3.7992)" + x1="7.0625" + y1="35.281" + x2="24.688" + y2="35.281" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4242" + id="linearGradient3373" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="12.277" + y1="37.206" + x2="12.222" + y2="33.759" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4272" + id="linearGradient3375" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="23.688" + y1="11.319" + x2="23.688" + y2="26.357" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4260" + id="linearGradient3377" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="12.378" + y1="4.4331" + x2="44.096" + y2="47.621" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2553" + id="linearGradient3379" + gradientUnits="userSpaceOnUse" + x1="33.431" + y1="31.965" + x2="21.748" + y2="11.781" /> + <radialGradient + inkscape:collect="always" + xlink:href="#radialGradient8668" + id="radialGradient3381" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)" + cx="24.837" + cy="36.421" + r="15.645" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6971" + id="linearGradient3383" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(51.972416,1005.3761)" + x1="28.061" + y1="31.431" + x2="28.061" + y2="36.437" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="5.6" + inkscape:cx="113.76169" + inkscape:cy="-12.107928" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="1028" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" /> + <metadata + id="metadata3832"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + <dc:creator> + <cc:Agent> + <dc:title>T.Hofmeister</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1007.3622)"> + <g + id="g3385"> + <g + transform="matrix(0.87964671,0,0,1,-44.027424,-2)" + id="g3255"> + <g + id="layer2" + transform="translate(51.972416,1005.3761)"> + <g + id="g5022" + transform="matrix(0.024114,0,0,0.019292,45.49,41.752)"> + <rect + id="rect4173" + style="opacity:0.40206;color:#000000;fill:url(#linearGradient3361)" + height="478.35999" + width="1339.6" + y="-150.7" + x="-1559.3" /> + <path + inkscape:connector-curvature="0" + id="path5058" + style="opacity:0.40206;color:#000000;fill:url(#radialGradient3363)" + d="m -219.62,-150.68 v 478.33 c 142.88,0.9 345.4,-107.17 345.4,-239.2 0,-132.02 -159.44,-239.13 -345.4,-239.13 z" /> + <path + inkscape:connector-curvature="0" + id="path5018" + style="opacity:0.40206;color:#000000;fill:url(#radialGradient3365)" + d="m -1559.3,-150.68 v 478.33 c -142.8,0.9 -345.4,-107.17 -345.4,-239.2 0,-132.02 159.5,-239.13 345.4,-239.13 z" /> + </g> + <path + style="fill:none;stroke:#535353;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" + inkscape:connector-curvature="0" + id="path4196" + d="m 11.286,13.088 c -0.625,0 -1.032,0.29 -1.282,0.843 L 3.5357,31.035 c 0,0 -0.25,0.671 -0.25,1.781 v 9.65 c 0,1.083 0.6578,1.625 1.6562,1.625 h 38.562 c 0.985,0 1.594,-0.718 1.594,-1.844 v -9.65 c 0,0 0.106,-0.77 -0.094,-1.312 l -6.718,-17.197 c -0.185,-0.512 -0.637,-0.988 -1.125,-1 h -25.875 z" /> + <path + style="fill:url(#linearGradient3367);fill-rule:evenodd" + inkscape:connector-curvature="0" + id="path4170" + d="m 3.2736,32.122 0.7646,-0.692 37.61,0.062 3.462,0.317 v 10.439 c 0,1.125 -0.607,1.843 -1.592,1.843 H 4.9352 c -0.998,0 -1.6614,-0.542 -1.6614,-1.624 V 32.122 z" /> + <path + style="fill:url(#radialGradient3369);fill-rule:evenodd" + inkscape:connector-curvature="0" + id="path3093" + d="m 3.5491,31.039 c -0.7143,1.465 -6e-4,2.393 1.0357,2.393 h 39 c 1.119,-0.024 1.845,-1.012 1.428,-2.143 l -6.714,-17.21 c -0.184,-0.512 -0.655,-0.988 -1.143,-1 h -25.857 c -0.625,0 -1.036,0.303 -1.286,0.857 L 3.5489,31.039 z" /> + <rect + id="rect4174" + style="color:#000000;fill:url(#linearGradient3371);fill-rule:evenodd" + height="5.5625" + width="17.625" + y="36.299" + x="7.8579998" /> + <path + style="opacity:0.81142997;fill:url(#linearGradient3373);fill-rule:evenodd" + inkscape:connector-curvature="0" + id="path4194" + d="M 7.858,41.862 V 37.85 c 1.8355,3.179 8.296,4.012 12.937,4.012 H 7.858 z" /> + <path + style="fill:#ffffff;fill-rule:evenodd" + inkscape:connector-curvature="0" + id="path4201" + d="m 44.796,30.754 c 0.064,1.25 -0.414,2.316 -1.322,2.343 H 5.355 c -1.2889,0 -1.8674,-0.325 -2.0837,-0.868 0.0917,0.945 0.8258,1.65 2.084,1.65 h 38.119 c 1.076,-0.033 1.753,-1.424 1.352,-2.995 l -0.03,-0.13 z" /> + <path + inkscape:connector-curvature="0" + id="path4211" + style="opacity:0.69142995;color:#000000;fill:url(#linearGradient3375);fill-rule:evenodd" + d="m 10.969,15.281 c -0.046,0.201 -0.188,0.387 -0.188,0.594 0,0.949 0.591,1.789 1.344,2.594 0.24,-0.154 0.365,-0.355 0.625,-0.5 -0.94,-0.816 -1.553,-1.717 -1.781,-2.688 z m 26.656,0 c -0.229,0.97 -0.842,1.873 -1.781,2.688 0.274,0.153 0.404,0.368 0.656,0.531 0.757,-0.807 1.312,-1.673 1.312,-2.625 0,-0.207 -0.141,-0.393 -0.187,-0.594 z m 2.187,8.438 c -0.613,4.04 -7.298,7.25 -15.531,7.25 -8.212,0 -14.86,-3.193 -15.5,-7.219 -0.0321,0.197 -0.1248,0.392 -0.1248,0.594 10e-5,4.318 6.9888,7.844 15.625,7.844 8.636,0 15.656,-3.526 15.657,-7.844 0,-0.213 -0.09,-0.418 -0.126,-0.625 z" /> + <path + inkscape:connector-curvature="0" + id="path4224" + style="color:#000000;fill:#ffffff;fill-opacity:0.45762999;fill-rule:evenodd" + d="m 8.5737,25.594 a 1.37005,1.0165371 0 1 1 -2.7401,0 1.37005,1.0165371 0 1 1 2.7401,0 z" + transform="translate(0.088388,5.3018)" /> + <path + inkscape:connector-curvature="0" + id="path4226" + style="color:#000000;fill:#ffffff;fill-opacity:0.45762999;fill-rule:evenodd" + d="m 8.5737,25.594 a 1.37005,1.0165371 0 1 1 -2.7401,0 1.37005,1.0165371 0 1 1 2.7401,0 z" + transform="translate(33.967,5.2134)" /> + <path + style="fill:none;stroke:url(#linearGradient3377);stroke-linecap:round;stroke-linejoin:round" + inkscape:connector-curvature="0" + id="path4252" + d="m 11.643,13.541 c -0.602,0 -0.993,0.279 -1.234,0.812 L 3.994,30.944 c 0,0 -0.2406,0.646 -0.2406,1.715 v 9.29 c 0,1.354 0.444,1.627 1.5944,1.627 h 37.687 c 1.323,0 1.534,-0.317 1.534,-1.838 v -9.29 c 0,0 0.102,-0.742 -0.09,-1.264 l -6.593,-16.806 c -0.178,-0.492 -0.551,-0.826 -1.021,-0.837 h -25.222 z" /> + <path + style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999" + inkscape:connector-curvature="0" + id="path4282" + d="m 40.5,36.554 v 5.021" /> + <path + style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999" + inkscape:connector-curvature="0" + id="path4284" + d="m 38.5,36.614 v 5.021" /> + <path + style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999" + inkscape:connector-curvature="0" + id="path4286" + d="m 36.5,36.614 v 5.021" /> + <path + style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999" + inkscape:connector-curvature="0" + id="path4288" + d="m 34.5,36.614 v 5.021" /> + <path + style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999" + inkscape:connector-curvature="0" + id="path4290" + d="m 32.5,36.614 v 5.021" /> + <path + style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999" + inkscape:connector-curvature="0" + id="path4292" + d="m 30.5,36.614 v 5.021" /> + <path + style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square" + inkscape:connector-curvature="0" + id="path4294" + d="m 39.5,36.604 v 5.021" /> + <path + style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square" + inkscape:connector-curvature="0" + id="path4296" + d="m 37.5,36.664 v 5.021" /> + <path + style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square" + inkscape:connector-curvature="0" + id="path4298" + d="m 35.5,36.664 v 5.021" /> + <path + style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square" + inkscape:connector-curvature="0" + id="path4300" + d="m 33.5,36.664 v 5.021" /> + <path + style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square" + inkscape:connector-curvature="0" + id="path4302" + d="m 31.5,36.664 v 5.021" /> + <path + style="opacity:0.43999999;fill:#ffffff;fill-rule:evenodd" + inkscape:connector-curvature="0" + id="path4572" + d="m 7.875,36.312 v 5.532 H 20.438 L 8.219,41.5 7.875,36.312 z" /> + <path + inkscape:connector-curvature="0" + id="path2545" + style="opacity:0.20571002;color:#000000;fill:url(#linearGradient3379);fill-rule:evenodd" + d="m 39.875,19.562 a 14.875,6.6875 0 1 1 -29.75,0 14.875,6.6875 0 1 1 29.75,0 z" + transform="matrix(1.0378,0,0,1.0607,-1.6329,3.0304)" /> + </g> + <path + d="m 93.815472,1031.3767 a 17.681979,6.3782852 0 1 0 -35.363958,0 17.681979,6.3782852 0 1 0 35.363958,0 z" + style="opacity:0.14118;color:#000000;fill:url(#radialGradient3381);fill-rule:evenodd" + id="path8660" + inkscape:connector-curvature="0" /> + <rect + x="56.535915" + y="1035.6741" + width="39.248001" + height="12.278" + ry="1.625" + rx="1.625" + display="block" + style="color:#000000;fill:url(#linearGradient3383);stroke:#7d7d7d;stroke-linecap:round;display:block" + id="rect6951" /> + <rect + x="58.972416" + y="1038.3761" + width="16" + height="7" + ry="0" + display="block" + style="opacity:0.59658999;color:#000000;fill:#7d7d7d;display:block" + id="rect6953" /> + <rect + display="block" + height="9" + x="75.97242" + y="1037.3761" + width="1" + style="color:#000000;display:block" + id="rect6957" /> + </g> + <path + sodipodi:nodetypes="cccccccc" + inkscape:connector-curvature="0" + id="path1432" + style="color:#000000;fill:#a9a9a9;stroke:#000000;stroke-width:0.48586071;display:block" + d="m 6.087091,1019.0168 c -2.4783484,-13.3382 7.140839,-12.9964 16.821938,-0.5354 l 2.083662,-1.7011 5.154697,13.4755 -11.796108,-8.0529 2.148807,-1.7542 c -6.962373,-9.2534 -10.105498,-9.9089 -14.389461,-1.3256 z" + display="block" /> + <rect + y="1007.8514" + x="0.20883489" + height="44.57473" + width="44.57473" + id="rect3032" + style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + </g> + </g> +</svg> diff --git a/interface/src/Application.h b/interface/src/Application.h index 6a14788caa..761b24bb31 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -244,6 +244,7 @@ public: void skipVersion(QString latestVersion); QStringList getRunningScripts() { return _scriptEnginesHash.keys(); } + ScriptEngine* getScriptEngine(QString scriptHash) { return _scriptEnginesHash.contains(scriptHash) ? _scriptEnginesHash[scriptHash] : NULL; } signals: diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 8ad55dec5b..87ab75cf3f 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -192,6 +192,7 @@ Menu::Menu() : QMenu* toolsMenu = addMenu("Tools"); addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor())); + addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, 0, this, SLOT(showScriptEditor())); #ifdef HAVE_QXMPP _chatAction = addActionToQMenuAndActionHash(toolsMenu, @@ -1058,6 +1059,13 @@ void Menu::showMetavoxelEditor() { _MetavoxelEditor->raise(); } +void Menu::showScriptEditor() { + if(!_ScriptEditor) { + _ScriptEditor = new ScriptEditorWindow(); + } + _ScriptEditor->raise(); +} + void Menu::showChat() { QMainWindow* mainWindow = Application::getInstance()->getWindow(); if (!_chatWindow) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e827e43014..14ebbf356d 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -24,6 +24,7 @@ #include "location/LocationManager.h" #include "ui/PreferencesDialog.h" #include "ui/ChatWindow.h" +#include "ui/ScriptEditorWindow.h" const float ADJUST_LOD_DOWN_FPS = 40.0; const float ADJUST_LOD_UP_FPS = 55.0; @@ -161,6 +162,7 @@ private slots: void cycleFrustumRenderMode(); void runTests(); void showMetavoxelEditor(); + void showScriptEditor(); void showChat(); void toggleChat(); void audioMuteToggled(); @@ -212,6 +214,7 @@ private: FrustumDrawMode _frustumDrawMode; ViewFrustumOffset _viewFrustumOffset; QPointer<MetavoxelEditor> _MetavoxelEditor; + QPointer<ScriptEditorWindow> _ScriptEditor; QPointer<ChatWindow> _chatWindow; OctreeStatsDialog* _octreeStatsDialog; LodToolsDialog* _lodToolsDialog; @@ -308,6 +311,7 @@ namespace MenuOption { const QString ResetAvatarSize = "Reset Avatar Size"; const QString RunningScripts = "Running Scripts"; const QString RunTimingTests = "Run Timing Tests"; + const QString ScriptEditor = "Script Editor..."; const QString SettingsExport = "Export Settings"; const QString SettingsImport = "Import Settings"; const QString Shadows = "Shadows"; diff --git a/interface/src/ScriptHighlighting.cpp b/interface/src/ScriptHighlighting.cpp new file mode 100644 index 0000000000..15505ac49a --- /dev/null +++ b/interface/src/ScriptHighlighting.cpp @@ -0,0 +1,18 @@ +// +// ScriptHighlighting.cpp +// interface/src +// +// Created by Thijs Wenker on 4/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ScriptHighlighting.h" + +ScriptHighlighting::ScriptHighlighting(QObject* parent) : + QSyntaxHighlighter(parent) +{ + +} \ No newline at end of file diff --git a/interface/src/ScriptHighlighting.h b/interface/src/ScriptHighlighting.h new file mode 100644 index 0000000000..f2bd97930e --- /dev/null +++ b/interface/src/ScriptHighlighting.h @@ -0,0 +1,25 @@ +// +// ScriptHighlighting.h +// interface/src +// +// Created by Thijs Wenker on 4/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ScriptHighlighting_h +#define hifi_ScriptHighlighting_h + +#include <QSyntaxHighlighter> + +class ScriptHighlighting : public QSyntaxHighlighter { + Q_OBJECT + +public: + ScriptHighlighting(QObject* parent = 0); + +}; + +#endif // hifi_ScriptHighlighting_h diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp new file mode 100644 index 0000000000..4adf01a28a --- /dev/null +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -0,0 +1,39 @@ +// +// ScriptEditorWidget.cpp +// interface/src/ui +// +// Created by Thijs Wenker on 4/14/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include <QGridLayout> +#include <QFrame> +#include <QLayoutItem> +#include <QMainWindow> +#include <QPalette> +#include <QScrollBar> +#include <QSizePolicy> +#include <QTimer> +#include <QWidget> + +#include "Application.h" +#include "ui_scriptEditorWidget.h" + +#include "ScriptEditorWidget.h" + +ScriptEditorWidget::ScriptEditorWidget() : + ui(new Ui::ScriptEditorWidget) +{ + ui->setupUi(this); + + // remove the title bar (see the Qt docs on setTitleBarWidget) + setTitleBarWidget(new QWidget()); + //QSyntaxHighlighter* highlighter = new QSyntaxHighlighter(); +} + +ScriptEditorWidget::~ScriptEditorWidget() { + delete ui; +} \ No newline at end of file diff --git a/interface/src/ui/ScriptEditorWidget.h b/interface/src/ui/ScriptEditorWidget.h new file mode 100644 index 0000000000..931ec105c9 --- /dev/null +++ b/interface/src/ui/ScriptEditorWidget.h @@ -0,0 +1,34 @@ +// +// ScriptEditorWidget.h +// interface/src/ui +// +// Created by Thijs Wenker on 4/14/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ScriptEditorWidget_h +#define hifi_ScriptEditorWidget_h + +#include <QDockWidget> + +#include <Application.h> + +namespace Ui { +class ScriptEditorWidget; +} + +class ScriptEditorWidget : public QDockWidget { + Q_OBJECT + +public: + ScriptEditorWidget(); + ~ScriptEditorWidget(); + +private: + Ui::ScriptEditorWidget* ui; +}; + +#endif // hifi_ScriptEditorWidget_h diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp new file mode 100644 index 0000000000..38fa26622a --- /dev/null +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -0,0 +1,62 @@ +// +// ScriptEditorWindow.cpp +// interface/src/ui +// +// Created by Thijs Wenker on 4/14/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include <QGridLayout> +#include <QFrame> +#include <QLayoutItem> +#include <QMainWindow> +#include <QPalette> +#include <QScrollBar> +#include <QSizePolicy> +#include <QTimer> +#include <QWidget> + +#include "Application.h" +#include "FlowLayout.h" +#include "ui_scriptEditorWindow.h" +#include "ScriptEditorWidget.h" + +#include "ScriptEditorWindow.h" + +ScriptEditorWindow::ScriptEditorWindow() : + ui(new Ui::ScriptEditorWindow) +{ + ui->setupUi(this); + show(); +} + +ScriptEditorWindow::~ScriptEditorWindow() { + delete ui; +} + +void ScriptEditorWindow::loadScriptClicked(){ + +} + +void ScriptEditorWindow::newScriptClicked(){ + addScriptEditorWidget(QString("new Script")); +} + +void ScriptEditorWindow::toggleRunScriptClicked(){ + +} + +void ScriptEditorWindow::saveScriptClicked(){ + +} + +void ScriptEditorWindow::addScriptEditorWidget(QString title){ + ScriptEditorWidget* newScriptEditorWidget = new ScriptEditorWidget();//ScriptEditorWidget(); + ui->tabWidget->addTab(newScriptEditorWidget, title); + ui->tabWidget->setCurrentWidget(newScriptEditorWidget); + newScriptEditorWidget->setUpdatesEnabled(true); + newScriptEditorWidget->adjustSize(); +} \ No newline at end of file diff --git a/interface/src/ui/ScriptEditorWindow.h b/interface/src/ui/ScriptEditorWindow.h new file mode 100644 index 0000000000..718826cf9d --- /dev/null +++ b/interface/src/ui/ScriptEditorWindow.h @@ -0,0 +1,39 @@ +// +// ScriptEditorWindow.h +// interface/src/ui +// +// Created by Thijs Wenker on 4/14/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ScriptEditorWindow_h +#define hifi_ScriptEditorWindow_h + +#include <Application.h> + +namespace Ui { +class ScriptEditorWindow; +} + +class ScriptEditorWindow : public QWidget { + Q_OBJECT + +public: + ScriptEditorWindow(); + ~ScriptEditorWindow(); + +private: + Ui::ScriptEditorWindow* ui; + void addScriptEditorWidget(QString title); + +private slots: + void loadScriptClicked(); + void newScriptClicked(); + void toggleRunScriptClicked(); + void saveScriptClicked(); +}; + +#endif // hifi_ScriptEditorWindow_h diff --git a/interface/ui/ScriptEditorWidget.ui b/interface/ui/ScriptEditorWidget.ui new file mode 100644 index 0000000000..82398d587c --- /dev/null +++ b/interface/ui/ScriptEditorWidget.ui @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ScriptEditorWidget</class> + <widget class="QDockWidget" name="ScriptEditorWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>702</width> + <height>543</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>238</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">font-family: Helvetica, Arial, sans-serif;</string> + </property> + <property name="features"> + <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + </property> + <property name="allowedAreas"> + <set>Qt::NoDockWidgetArea</set> + </property> + <property name="windowTitle"> + <string>Edit Script</string> + </property> + <widget class="QWidget" name="dockWidgetContents"> + <layout class="QVBoxLayout" name="verticalLayout" stretch="5,0,1"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QTextEdit" name="textEdit"> + <property name="font"> + <font> + <family>Courier</family> + <pointsize>9</pointsize> + <weight>50</weight> + <italic>false</italic> + <bold>false</bold> + </font> + </property> + <property name="styleSheet"> + <string notr="true">font: 9pt "Courier";</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Debug Log:</string> + </property> + </widget> + </item> + <item> + <widget class="QPlainTextEdit" name="plainTextEdit"> + <property name="styleSheet"> + <string notr="true">font: 8pt "Courier";</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/interface/ui/ScriptEditorWindow.ui b/interface/ui/ScriptEditorWindow.ui new file mode 100644 index 0000000000..a612b2b1c9 --- /dev/null +++ b/interface/ui/ScriptEditorWindow.ui @@ -0,0 +1,290 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ScriptEditorWindow</class> + <widget class="QWidget" name="ScriptEditorWindow"> + <property name="windowModality"> + <enum>Qt::WindowModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>474</width> + <height>638</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>250</height> + </size> + </property> + <property name="windowTitle"> + <string>Script editor []</string> + </property> + <property name="styleSheet"> + <string notr="true">font-family: Helvetica, Arial, sans-serif;</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0"> + <property name="spacing"> + <number>3</number> + </property> + <property name="sizeConstraint"> + <enum>QLayout::SetNoConstraint</enum> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QToolButton" name="newButton"> + <property name="toolTip"> + <string>New Script</string> + </property> + <property name="text"> + <string>New</string> + </property> + <property name="icon"> + <iconset> + <normaloff>../resources/icons/new-script.svg</normaloff> + <normalon>../resources/images/pinned.svg</normalon>../resources/icons/new-script.svg</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="loadButton"> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>25</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Load Script</string> + </property> + <property name="text"> + <string>Load</string> + </property> + <property name="icon"> + <iconset> + <normaloff>../resources/icons/load-script.svg</normaloff>../resources/icons/load-script.svg</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="popupMode"> + <enum>QToolButton::MenuButtonPopup</enum> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonIconOnly</enum> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="saveButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>Qt::NoFocus</enum> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string>Save Script</string> + </property> + <property name="text"> + <string>Save</string> + </property> + <property name="icon"> + <iconset> + <normaloff>../resources/icons/save-script.svg</normaloff>../resources/icons/save-script.svg</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="autoRepeatDelay"> + <number>316</number> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="toggleRunButton"> + <property name="toolTip"> + <string>Toggle Run Script</string> + </property> + <property name="text"> + <string>Run/Stop</string> + </property> + <property name="icon"> + <iconset> + <normaloff>../resources/images/plus.svg</normaloff>../resources/images/plus.svg</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="minimumSize"> + <size> + <width>250</width> + <height>80</height> + </size> + </property> + <property name="tabPosition"> + <enum>QTabWidget::West</enum> + </property> + <property name="tabShape"> + <enum>QTabWidget::Triangular</enum> + </property> + <property name="currentIndex"> + <number>-1</number> + </property> + <property name="elideMode"> + <enum>Qt::ElideNone</enum> + </property> + <property name="tabsClosable"> + <bool>true</bool> + </property> + <property name="movable"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>saveButton</sender> + <signal>clicked()</signal> + <receiver>ScriptEditorWindow</receiver> + <slot>saveScriptClicked()</slot> + <hints> + <hint type="sourcelabel"> + <x>236</x> + <y>10</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>264</y> + </hint> + </hints> + </connection> + <connection> + <sender>toggleRunButton</sender> + <signal>clicked()</signal> + <receiver>ScriptEditorWindow</receiver> + <slot>toggleRunScriptClicked()</slot> + <hints> + <hint type="sourcelabel"> + <x>330</x> + <y>10</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>264</y> + </hint> + </hints> + </connection> + <connection> + <sender>newButton</sender> + <signal>clicked()</signal> + <receiver>ScriptEditorWindow</receiver> + <slot>newScriptClicked()</slot> + <hints> + <hint type="sourcelabel"> + <x>58</x> + <y>10</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>264</y> + </hint> + </hints> + </connection> + <connection> + <sender>loadButton</sender> + <signal>clicked()</signal> + <receiver>ScriptEditorWindow</receiver> + <slot>loadScriptClicked()</slot> + <hints> + <hint type="sourcelabel"> + <x>85</x> + <y>10</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>264</y> + </hint> + </hints> + </connection> + </connections> +</ui> From e66822c6ee56cc12854628e6b1448bdc635fdb82 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Wed, 16 Apr 2014 00:55:06 +0200 Subject: [PATCH 02/11] ScriptEditor: Syntax highlighting update --- interface/src/ScriptHighlighting.cpp | 57 ++++++++++++++++++++- interface/src/ScriptHighlighting.h | 20 +++++++- interface/src/ui/ScriptEditorWidget.cpp | 5 +- interface/ui/ScriptEditorWidget.ui | 66 ++++++++++++++++++++++--- 4 files changed, 137 insertions(+), 11 deletions(-) diff --git a/interface/src/ScriptHighlighting.cpp b/interface/src/ScriptHighlighting.cpp index 15505ac49a..119926742c 100644 --- a/interface/src/ScriptHighlighting.cpp +++ b/interface/src/ScriptHighlighting.cpp @@ -11,8 +11,61 @@ #include "ScriptHighlighting.h" -ScriptHighlighting::ScriptHighlighting(QObject* parent) : +ScriptHighlighting::ScriptHighlighting(QTextDocument* parent) : QSyntaxHighlighter(parent) { + keywordRegex = QRegExp("\\b(break|case|catch|continue|debugger|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with)\\b"); + qoutedTextRegex = QRegExp("\".*\""); + multiLineCommentBegin = QRegExp("/\\*"); + multiLineCommentEnd = QRegExp("\\*/"); + numberRegex = QRegExp("[0-9]+(\\.[0-9]+){0,1}"); +} -} \ No newline at end of file +void ScriptHighlighting::highlightBlock(const QString &text) { + this->highlightKeywords(text); + this->formatComments(text); + this->formatQoutedText(text); + this->formatNumbers(text); +} + +void ScriptHighlighting::highlightKeywords(const QString &text) { + int index = keywordRegex.indexIn(text); + while (index >= 0) { + int length = keywordRegex.matchedLength(); + setFormat(index, length, Qt::blue); + index = keywordRegex.indexIn(text, index + length); + } +} + +void ScriptHighlighting::formatComments(const QString &text) { + + setCurrentBlockState(BlockStateClean); + + int start = (previousBlockState() != BlockStateInMultiComment) ? text.indexOf(multiLineCommentBegin) : 0; + + while (start > -1) { + int end = text.indexOf(multiLineCommentEnd, start); + int length = (end == -1 ? text.length() : (end + multiLineCommentEnd.matchedLength())) - start; + setFormat(start, length, Qt::lightGray); + start = text.indexOf(multiLineCommentBegin, start + length); + if (end == -1) setCurrentBlockState(BlockStateInMultiComment); + } +} + +void ScriptHighlighting::formatQoutedText(const QString &text){ + int index = qoutedTextRegex.indexIn(text); + while (index >= 0) { + int length = qoutedTextRegex.matchedLength(); + setFormat(index, length, Qt::red); + index = qoutedTextRegex.indexIn(text, index + length); + } +} + +void ScriptHighlighting::formatNumbers(const QString &text){ + int index = numberRegex.indexIn(text); + while (index >= 0) { + int length = numberRegex.matchedLength(); + setFormat(index, length, Qt::green); + index = numberRegex.indexIn(text, index + length); + } +} diff --git a/interface/src/ScriptHighlighting.h b/interface/src/ScriptHighlighting.h index f2bd97930e..b9567cb06a 100644 --- a/interface/src/ScriptHighlighting.h +++ b/interface/src/ScriptHighlighting.h @@ -18,8 +18,26 @@ class ScriptHighlighting : public QSyntaxHighlighter { Q_OBJECT public: - ScriptHighlighting(QObject* parent = 0); + ScriptHighlighting(QTextDocument* parent = 0); + enum BlockState { + BlockStateClean, + BlockStateInMultiComment + }; + +protected: + void highlightBlock(const QString &text); + void highlightKeywords(const QString &text); + void formatComments(const QString &text); + void formatQoutedText(const QString &text); + void formatNumbers(const QString &text); + +private: + QRegExp keywordRegex; + QRegExp qoutedTextRegex; + QRegExp multiLineCommentBegin; + QRegExp multiLineCommentEnd; + QRegExp numberRegex; }; #endif // hifi_ScriptHighlighting_h diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 4adf01a28a..618e405448 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -20,6 +20,7 @@ #include <QWidget> #include "Application.h" +#include "ScriptHighlighting.h" #include "ui_scriptEditorWidget.h" #include "ScriptEditorWidget.h" @@ -31,7 +32,9 @@ ScriptEditorWidget::ScriptEditorWidget() : // remove the title bar (see the Qt docs on setTitleBarWidget) setTitleBarWidget(new QWidget()); - //QSyntaxHighlighter* highlighter = new QSyntaxHighlighter(); + QFontMetrics fm(this->ui->scriptEdit->font()); + this->ui->scriptEdit->setTabStopWidth(fm.width('0') * 4); + ScriptHighlighting* highlighting = new ScriptHighlighting(this->ui->scriptEdit->document()); } ScriptEditorWidget::~ScriptEditorWidget() { diff --git a/interface/ui/ScriptEditorWidget.ui b/interface/ui/ScriptEditorWidget.ui index 82398d587c..5878f26c69 100644 --- a/interface/ui/ScriptEditorWidget.ui +++ b/interface/ui/ScriptEditorWidget.ui @@ -52,7 +52,7 @@ <number>0</number> </property> <item> - <widget class="QTextEdit" name="textEdit"> + <widget class="QTextEdit" name="scriptEdit"> <property name="font"> <font> <family>Courier</family> @@ -68,22 +68,74 @@ </widget> </item> <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Debug Log:</string> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>0</number> </property> - </widget> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Debug Log:</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="clearButton"> + <property name="text"> + <string>Clear</string> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </widget> + </item> + </layout> </item> <item> - <widget class="QPlainTextEdit" name="plainTextEdit"> + <widget class="QPlainTextEdit" name="debugText"> <property name="styleSheet"> <string notr="true">font: 8pt "Courier";</string> </property> + <property name="readOnly"> + <bool>true</bool> + </property> </widget> </item> </layout> </widget> </widget> <resources/> - <connections/> + <connections> + <connection> + <sender>clearButton</sender> + <signal>clicked()</signal> + <receiver>debugText</receiver> + <slot>clear()</slot> + <hints> + <hint type="sourcelabel"> + <x>663</x> + <y>447</y> + </hint> + <hint type="destinationlabel"> + <x>350</x> + <y>501</y> + </hint> + </hints> + </connection> + </connections> </ui> From 0b644b5738b8ed3324f61fbb7957529865b79b63 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Wed, 16 Apr 2014 22:58:44 +0200 Subject: [PATCH 03/11] ctrl+shift+s to open the script editor --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index cfeba0705f..303e155da6 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -192,7 +192,7 @@ Menu::Menu() : QMenu* toolsMenu = addMenu("Tools"); addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor())); - addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, 0, this, SLOT(showScriptEditor())); + addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::CTRL | Qt::SHIFT | Qt::Key_S, this, SLOT(showScriptEditor())); #ifdef HAVE_QXMPP _chatAction = addActionToQMenuAndActionHash(toolsMenu, From c016d6557ef5f473b866a0e850718aa2401bde67 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Mon, 21 Apr 2014 05:25:28 +0200 Subject: [PATCH 04/11] - few Adjustments in Application class for Script editor - Shortkey for script editor (Alt+S) - highlighter: bold true/false , single line comments - Run scripts from the editor works - More icons from Maximillian, Thanks - Run on the fly checkbox, works if the script is running. - Load/save features --- interface/resources/icons/start-script.svg | 557 +++++++++++++++++++ interface/resources/icons/stop-script.svg | 163 ++++++ interface/src/Application.cpp | 35 +- interface/src/Application.h | 2 +- interface/src/Menu.cpp | 4 +- interface/src/ScriptHighlighting.cpp | 26 +- interface/src/ScriptHighlighting.h | 13 +- interface/src/ui/ScriptEditorWidget.cpp | 114 ++++ interface/src/ui/ScriptEditorWidget.h | 22 + interface/src/ui/ScriptEditorWindow.cpp | 148 ++++- interface/src/ui/ScriptEditorWindow.h | 17 +- interface/ui/ScriptEditorWidget.ui | 13 +- interface/ui/ScriptEditorWindow.ui | 69 ++- libraries/script-engine/src/ScriptEngine.cpp | 24 +- libraries/script-engine/src/ScriptEngine.h | 7 + 15 files changed, 1163 insertions(+), 51 deletions(-) create mode 100644 interface/resources/icons/start-script.svg create mode 100644 interface/resources/icons/stop-script.svg diff --git a/interface/resources/icons/start-script.svg b/interface/resources/icons/start-script.svg new file mode 100644 index 0000000000..86354a555d --- /dev/null +++ b/interface/resources/icons/start-script.svg @@ -0,0 +1,557 @@ +<?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://creativecommons.org/ns#" + 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="45" + height="45" + id="svg3827" + version="1.1" + inkscape:version="0.48.1 r9760" + sodipodi:docname="start-script.svg"> + <defs + id="defs3829"> + <radialGradient + r="15.645" + cy="36.421" + cx="24.837" + gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)" + gradientUnits="userSpaceOnUse" + id="radialGradient3253" + xlink:href="#radialGradient8668" + inkscape:collect="always" /> + <linearGradient + gradientTransform="translate(51.972416,1005.3761)" + y2="36.437" + x2="28.061" + y1="31.431" + x1="28.061" + gradientUnits="userSpaceOnUse" + id="linearGradient3239" + xlink:href="#linearGradient6971" + inkscape:collect="always" /> + <radialGradient + id="radialGradient5031" + xlink:href="#linearGradient5060" + gradientUnits="userSpaceOnUse" + cy="486.65" + cx="605.71" + gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)" + r="117.14" /> + <linearGradient + id="linearGradient5060"> + <stop + id="stop5062" + offset="0" /> + <stop + id="stop5064" + stop-opacity="0" + offset="1" /> + </linearGradient> + <radialGradient + id="radialGradient5029" + xlink:href="#linearGradient5060" + gradientUnits="userSpaceOnUse" + cy="486.65" + cx="605.71" + gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)" + r="117.14" /> + <linearGradient + id="linearGradient5027" + x1="302.86" + gradientUnits="userSpaceOnUse" + y1="366.65" + gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)" + x2="302.86" + y2="609.51"> + <stop + id="stop5050" + stop-opacity="0" + offset="0" /> + <stop + id="stop5056" + offset=".5" /> + <stop + id="stop5052" + stop-opacity="0" + offset="1" /> + </linearGradient> + <radialGradient + id="radialGradient4997" + gradientUnits="userSpaceOnUse" + cy="6.4577" + cx="23.447" + gradientTransform="matrix(-1.3145,-0.010063,-0.01023,1.3362,46.221,-4.9099)" + r="19.062"> + <stop + id="stop4993" + stop-color="#fff" + offset="0" /> + <stop + id="stop4995" + stop-color="#fff" + stop-opacity="0" + offset="1" /> + </radialGradient> + <linearGradient + id="linearGradient1764" + x1="33.06" + gradientUnits="userSpaceOnUse" + y1="27.394" + gradientTransform="matrix(0.91411,0,0,0.91411,-3.8687,-2.7069)" + x2="12.624" + y2="12.584"> + <stop + id="stop2189" + stop-color="#fff" + offset="0" /> + <stop + id="stop2191" + stop-color="#fff" + stop-opacity="0" + offset="1" /> + </linearGradient> + <radialGradient + id="radialGradient8668" + gradientUnits="userSpaceOnUse" + cy="36.421" + cx="24.837" + gradientTransform="matrix(1,0,0,0.53672,0,16.873)" + r="15.645"> + <stop + id="stop8664" + offset="0" /> + <stop + id="stop8666" + stop-opacity="0" + offset="1" /> + </radialGradient> + <linearGradient + id="linearGradient4209" + x1="7.0625" + gradientUnits="userSpaceOnUse" + x2="24.688" + gradientTransform="translate(0.79549,3.7992)" + y1="35.281" + y2="35.281"> + <stop + id="stop4186" + stop-color="#838383" + offset="0" /> + <stop + id="stop4188" + stop-color="#bbb" + stop-opacity="0" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient4234" + x1="7.6046" + gradientUnits="userSpaceOnUse" + x2="36.183" + gradientTransform="translate(0,5.125)" + y1="28.481" + y2="40.944"> + <stop + id="stop4230" + stop-color="#bbb" + offset="0" /> + <stop + id="stop4232" + stop-color="#9f9f9f" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient4242" + x1="12.277" + gradientUnits="userSpaceOnUse" + x2="12.222" + gradientTransform="translate(0,5.125)" + y1="37.206" + y2="33.759"> + <stop + id="stop4238" + stop-color="#eee" + offset="0" /> + <stop + id="stop4240" + stop-color="#eee" + stop-opacity="0" + offset="1" /> + </linearGradient> + <radialGradient + id="radialGradient4250" + gradientUnits="userSpaceOnUse" + cy="2.9585" + cx="15.571" + gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)" + r="20.936"> + <stop + id="stop4246" + stop-color="#e4e4e4" + offset="0" /> + <stop + id="stop4248" + stop-color="#d3d3d3" + offset="1" /> + </radialGradient> + <linearGradient + id="linearGradient4260" + x1="12.378" + gradientUnits="userSpaceOnUse" + x2="44.096" + gradientTransform="translate(0,5.125)" + y1="4.4331" + y2="47.621"> + <stop + id="stop4256" + stop-color="#fff" + offset="0" /> + <stop + id="stop4258" + stop-color="#fff" + stop-opacity="0" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient4272" + x1="23.688" + gradientUnits="userSpaceOnUse" + x2="23.688" + gradientTransform="translate(0,5.125)" + y1="11.319" + y2="26.357"> + <stop + id="stop4276" + stop-color="#fff" + stop-opacity=".2549" + offset="0" /> + <stop + id="stop4278" + stop-color="#fff" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient2553" + y2="11.781" + gradientUnits="userSpaceOnUse" + y1="31.965" + x2="21.748" + x1="33.431"> + <stop + id="stop2557" + stop-color="#fff" + offset="0" /> + <stop + id="stop2561" + stop-color="#e6e6e6" + offset=".5" /> + <stop + id="stop2563" + stop-color="#fff" + offset=".75" /> + <stop + id="stop2565" + stop-color="#e1e1e1" + offset=".84167" /> + <stop + id="stop2559" + stop-color="#fff" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient6907" + y2="16.743" + gradientUnits="userSpaceOnUse" + y1="15.868" + x2="8.8953" + x1="14.752"> + <stop + id="stop6903" + stop-color="#3465a4" + offset="0" /> + <stop + id="stop6905" + stop-color="#3465a4" + stop-opacity="0" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient6931" + y2="21.118" + gradientUnits="userSpaceOnUse" + y1="18.25" + x2="7" + x1="12.25"> + <stop + id="stop6927" + stop-color="#204a87" + offset="0" /> + <stop + id="stop6929" + stop-color="#204a87" + stop-opacity="0" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient6971" + y2="36.437" + gradientUnits="userSpaceOnUse" + y1="31.431" + x2="28.061" + x1="28.061"> + <stop + id="stop6967" + stop-color="#ddd" + offset="0" /> + <stop + id="stop6969" + stop-color="#fdfdfd" + offset="1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5027" + id="linearGradient3248" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)" + x1="302.86" + y1="366.65" + x2="302.86" + y2="609.51" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient3250" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)" + cx="605.71" + cy="486.65" + r="117.14" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient3252" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)" + cx="605.71" + cy="486.65" + r="117.14" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4234" + id="linearGradient3254" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="7.6046" + y1="28.481" + x2="36.183" + y2="40.944" /> + <radialGradient + inkscape:collect="always" + xlink:href="#radialGradient4250" + id="radialGradient3256" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)" + cx="15.571" + cy="2.9585" + r="20.936" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4209" + id="linearGradient3258" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0.79549,3.7992)" + x1="7.0625" + y1="35.281" + x2="24.688" + y2="35.281" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4242" + id="linearGradient3260" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="12.277" + y1="37.206" + x2="12.222" + y2="33.759" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4272" + id="linearGradient3262" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="23.688" + y1="11.319" + x2="23.688" + y2="26.357" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4260" + id="linearGradient3264" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,5.125)" + x1="12.378" + y1="4.4331" + x2="44.096" + y2="47.621" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2553" + id="linearGradient3266" + gradientUnits="userSpaceOnUse" + x1="33.431" + y1="31.965" + x2="21.748" + y2="11.781" /> + <radialGradient + inkscape:collect="always" + xlink:href="#radialGradient8668" + id="radialGradient3268" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)" + cx="24.837" + cy="36.421" + r="15.645" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6971" + id="linearGradient3270" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(51.972416,1005.3761)" + x1="28.061" + y1="31.431" + x2="28.061" + y2="36.437" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="5.6" + inkscape:cx="76.804753" + inkscape:cy="13.198134" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="1028" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" /> + <metadata + id="metadata3832"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + <dc:creator> + <cc:Agent> + <dc:title>Maximillian Merlin</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1007.3622)"> + <g + id="layer1-7" + transform="matrix(-0.25019951,0,0,0.28877175,123.44112,917.40972)" + style="fill:#696969"> + <g + id="g3257" + transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)" + style="fill:#696969"> + <path + id="path3224" + d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z" + style="fill:#696969;fill-rule:evenodd" + inkscape:connector-curvature="0" /> + <path + id="path3237" + d="m 531.39,275.61 23.34,-4.6" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3243" + d="m 532.1,280.91 22.27,-2.83" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3247" + d="m 531.92,285.86 22.89,-1.95" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3249" + d="m 530.15,292.84 24.22,-2.12" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3251" + d="m 529.45,297.53 22.98,-0.8" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3253" + d="m 528.65,304.24 22.45,-2.56" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3255" + d="m 527.5,309.37 22.81,-1.77" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3032" + width="44.57473" + height="44.57473" + x="0.18852967" + y="1007.5989" /> + <rect + style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3032-4" + width="44.57473" + height="44.57473" + x="84.498352" + y="1050.0748" /> + <g + id="g3322" + transform="translate(-46.607143,-3.5714285)"> + <use + x="0" + y="0" + width="744.09448" + height="1052.3622" + transform="translate(0.5864354,0.4607839)" + xlink:href="#rect899" + id="use1503" /> + <path + d="m 75.506508,1023.3478 1.372845,5.4631 -14.094975,-1.152 2.35e-4,7.2772 14.094975,-1.152 -1.372845,5.1249 13.761293,-7.6113 -13.761293,-7.9499 z" + id="rect899" + inkscape:connector-curvature="0" + style="fill:#d3d3d3;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.77974033;stroke-linecap:round;stroke-linejoin:round" /> + </g> + </g> +</svg> diff --git a/interface/resources/icons/stop-script.svg b/interface/resources/icons/stop-script.svg new file mode 100644 index 0000000000..31cdcee749 --- /dev/null +++ b/interface/resources/icons/stop-script.svg @@ -0,0 +1,163 @@ +<?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://creativecommons.org/ns#" + 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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="45" + height="45" + id="svg3827" + version="1.1" + inkscape:version="0.48.1 r9760" + sodipodi:docname="stop-script.svg"> + <defs + id="defs3829" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="5.6" + inkscape:cx="15.598703" + inkscape:cy="22.861751" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="1028" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" /> + <metadata + id="metadata3832"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + <dc:creator> + <cc:Agent> + <dc:title>Maximillian Merlin</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1007.3622)"> + <g + id="layer1-7" + transform="matrix(-0.25019951,0,0,0.28877175,123.44112,917.40972)" + style="fill:#696969"> + <g + id="g3257" + transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)" + style="fill:#696969"> + <path + id="path3224" + d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z" + style="fill:#696969;fill-rule:evenodd" + inkscape:connector-curvature="0" /> + <path + id="path3237" + d="m 531.39,275.61 23.34,-4.6" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3243" + d="m 532.1,280.91 22.27,-2.83" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3247" + d="m 531.92,285.86 22.89,-1.95" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3249" + d="m 530.15,292.84 24.22,-2.12" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3251" + d="m 529.45,297.53 22.98,-0.8" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3253" + d="m 528.65,304.24 22.45,-2.56" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + <path + id="path3255" + d="m 527.5,309.37 22.81,-1.77" + style="fill:#696969;stroke:#000000;stroke-width:1px" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3032" + width="44.57473" + height="44.57473" + x="0.18852967" + y="1007.5989" /> + <g + id="stop" + transform="matrix(0.08804464,0,0,0.0856179,29.060719,1033.5397)"> + <g + id="g3004"> + <path + d="M 0,-150 H 62.132 L 150,-62.132 V 62.128 L 62.132,150 H -62.128 L -149,62.132 V -62.128 L -61.132,-150 H 1 0 z" + id="stop_octagon" + inkscape:connector-curvature="0" + style="fill:#e81108" /> + </g> + <g + id="g3007" + transform="scale(0.95,0.95)"> + <path + d="M 0,-142.5 H 59.025 L 142.5,-59.025 V 59.025 L 59.025,142.5 H -59.025 L -141.549,59.025 V -59.025 L -58.074,-142.5 H 0.951 0.001 z" + id="stop_octagon_1_" + inkscape:connector-curvature="0" + style="fill:none;stroke:#ffffff;stroke-width:5" /> + </g> + <g + id="g3010" + transform="scale(1,1.45)"> + <g + id="g3012" + style="fill:#ffffff;enable-background:new"> + <path + id="path3014" + d="m -124.2,12.152 8.489,-0.742 c 0.401,3.402 1.337,6.192 2.806,8.373 1.469,2.18 3.75,3.943 6.842,5.288 3.092,1.345 6.571,2.018 10.437,2.018 3.433,0 6.463,-0.51 9.092,-1.53 2.628,-1.021 4.584,-2.42 5.868,-4.198 1.283,-1.778 1.925,-3.718 1.925,-5.821 0,-2.134 -0.619,-3.997 -1.855,-5.59 -1.237,-1.592 -3.278,-2.93 -6.123,-4.013 -1.825,-0.711 -5.861,-1.816 -12.107,-3.317 -6.247,-1.5 -10.623,-2.914 -13.127,-4.244 -3.247,-1.7 -5.667,-3.811 -7.26,-6.332 -1.593,-2.52 -2.389,-5.342 -2.389,-8.465 0,-3.433 0.974,-6.641 2.922,-9.625 1.948,-2.984 4.793,-5.249 8.535,-6.796 3.741,-1.546 7.901,-2.319 12.478,-2.319 5.04,0 9.486,0.812 13.336,2.435 3.85,1.623 6.811,4.012 8.883,7.167 2.071,3.154 3.185,6.726 3.34,10.715 l -8.628,0.65 c -0.464,-4.298 -2.034,-7.545 -4.708,-9.741 -2.675,-2.195 -6.626,-3.293 -11.852,-3.293 -5.443,0 -9.409,0.997 -11.898,2.992 -2.489,1.995 -3.734,4.4 -3.734,7.213 0,2.443 0.881,4.453 2.644,6.03 1.731,1.577 6.254,3.194 13.568,4.847 7.313,1.655 12.331,3.101 15.053,4.337 3.958,1.825 6.88,4.136 8.767,6.935 1.886,2.799 2.83,6.023 2.83,9.672 0,3.618 -1.037,7.028 -3.108,10.228 -2.072,3.201 -5.049,5.69 -8.93,7.468 -3.881,1.778 -8.25,2.667 -13.104,2.667 -6.154,0 -11.311,-0.897 -15.47,-2.691 -4.159,-1.793 -7.422,-4.492 -9.788,-8.094 -2.37,-3.604 -3.62,-7.678 -3.74,-12.224 z" + inkscape:connector-curvature="0" /> + <path + id="path3016" + d="m -40.473,34 v -59.978 h -22.405 v -8.025 h 53.901 v 8.025 H -31.475 V 34 h -8.998 z" + inkscape:connector-curvature="0" /> + <path + id="path3018" + d="m -4.198,0.88 c 0,-11.287 3.03,-20.124 9.092,-26.51 6.061,-6.385 13.885,-9.579 23.472,-9.579 6.277,0 11.937,1.5 16.978,4.5 5.04,3 8.883,7.182 11.527,12.547 2.644,5.366 3.966,11.45 3.966,18.253 0,6.896 -1.392,13.066 -4.175,18.508 -2.783,5.443 -6.726,9.564 -11.829,12.362 -5.103,2.799 -10.607,4.198 -16.514,4.198 -6.401,0 -12.123,-1.546 -17.163,-4.639 C 6.115,27.428 2.296,23.207 -0.302,17.856 -2.899,12.508 -4.198,6.848 -4.198,0.88 z m 9.277,0.139 c 0,8.195 2.203,14.651 6.61,19.366 4.407,4.716 9.934,7.074 16.583,7.074 6.772,0 12.346,-2.381 16.722,-7.143 4.376,-4.762 6.564,-11.519 6.564,-20.271 0,-5.535 -0.936,-10.367 -2.807,-14.496 -1.871,-4.129 -4.608,-7.329 -8.21,-9.602 -3.603,-2.273 -7.646,-3.41 -12.13,-3.41 -6.371,0 -11.852,2.188 -16.444,6.564 -4.592,4.377 -6.888,11.682 -6.888,21.918 z" + inkscape:connector-curvature="0" /> + <path + id="path3020" + d="m 72.433,34 v -68.003 h 25.652 c 4.515,0 7.962,0.217 10.344,0.65 3.34,0.557 6.138,1.616 8.396,3.178 2.257,1.562 4.074,3.75 5.45,6.564 1.376,2.815 2.064,5.907 2.064,9.277 0,5.783 -1.84,10.677 -5.52,14.681 -3.681,4.005 -10.329,6.007 -19.946,6.007 H 81.431 V 34 h -8.999 z m 8.999,-35.672 h 17.581 c 5.813,0 9.942,-1.082 12.385,-3.247 2.442,-2.164 3.665,-5.21 3.665,-9.138 0,-2.845 -0.719,-5.28 -2.157,-7.306 -1.438,-2.025 -3.333,-3.363 -5.682,-4.012 -1.516,-0.401 -4.314,-0.603 -8.396,-0.603 H 81.436 v 24.306 z" + inkscape:connector-curvature="0" /> + </g> + </g> + </g> + </g> +</svg> diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 438722df17..769791d09f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -797,6 +797,7 @@ void Application::keyPressEvent(QKeyEvent* event) { if (activeWindow() == _window) { bool isShifted = event->modifiers().testFlag(Qt::ShiftModifier); bool isMeta = event->modifiers().testFlag(Qt::ControlModifier); + bool isOption = event->modifiers().testFlag(Qt::AltModifier); switch (event->key()) { break; case Qt::Key_BracketLeft: @@ -839,9 +840,11 @@ void Application::keyPressEvent(QKeyEvent* event) { break; case Qt::Key_S: - if (isShifted && isMeta) { + if (isShifted && isMeta && !isOption) { Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings); - } else if (!isShifted && isMeta) { + } else if (isOption && !isShifted && !isMeta) { + Menu::getInstance()->triggerOption(MenuOption::ScriptEditor); + } else if (!isOption && !isShifted && isMeta) { takeSnapshot(); } else { _myAvatar->setDriveKeys(BACK, 1.f); @@ -3299,13 +3302,14 @@ void Application::stopAllScripts() { bumpSettings(); } -void Application::stopScript(const QString &scriptName) -{ - _scriptEnginesHash.value(scriptName)->stop(); - qDebug() << "stopping script..." << scriptName; - _scriptEnginesHash.remove(scriptName); - _runningScriptsWidget->setRunningScripts(getRunningScripts()); - bumpSettings(); +void Application::stopScript(const QString &scriptName) { + if (_scriptEnginesHash.contains(scriptName)) { + _scriptEnginesHash.value(scriptName)->stop(); + qDebug() << "stopping script..." << scriptName; + _scriptEnginesHash.remove(scriptName); + _runningScriptsWidget->setRunningScripts(getRunningScripts()); + bumpSettings(); + } } void Application::reloadAllScripts() { @@ -3366,7 +3370,10 @@ void Application::uploadSkeleton() { uploadFST(false); } -void Application::loadScript(const QString& scriptName) { +ScriptEngine* Application::loadScript(const QString& scriptName, bool focusMainWindow) { + if(_scriptEnginesHash.contains(scriptName) && !_scriptEnginesHash[scriptName]->isFinished()){ + return _scriptEnginesHash[scriptName]; + } // start the script on a new thread... ScriptEngine* scriptEngine = new ScriptEngine(QUrl(scriptName), &_controllerScriptingInterface); @@ -3374,7 +3381,7 @@ void Application::loadScript(const QString& scriptName) { if (!scriptEngine->hasScript()) { qDebug() << "Application::loadScript(), script failed to load..."; - return; + return NULL; } _runningScriptsWidget->setRunningScripts(getRunningScripts()); @@ -3422,8 +3429,12 @@ void Application::loadScript(const QString& scriptName) { workerThread->start(); // restore the main window's active state - _window->activateWindow(); + if (focusMainWindow) { + _window->activateWindow(); + } bumpSettings(); + + return scriptEngine; } void Application::loadDialog() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 00b71c4ce7..3254c874b6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -121,7 +121,7 @@ public: ~Application(); void restoreSizeAndPosition(); - void loadScript(const QString& fileNameString); + ScriptEngine* loadScript(const QString& fileNameString, bool focusMainWindow = true); void loadScripts(); void storeSizeAndPosition(); void clearScriptsBeforeRunning(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6f70c5616c..4e6dd2eec2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -195,7 +195,7 @@ Menu::Menu() : QMenu* toolsMenu = addMenu("Tools"); addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor())); - addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::CTRL | Qt::SHIFT | Qt::Key_S, this, SLOT(showScriptEditor())); + addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::ALT | Qt::Key_S, this, SLOT(showScriptEditor())); #ifdef HAVE_QXMPP _chatAction = addActionToQMenuAndActionHash(toolsMenu, @@ -1125,7 +1125,7 @@ void Menu::showMetavoxelEditor() { } void Menu::showScriptEditor() { - if(!_ScriptEditor) { + if(!_ScriptEditor || !_ScriptEditor->isVisible()) { _ScriptEditor = new ScriptEditorWindow(); } _ScriptEditor->raise(); diff --git a/interface/src/ScriptHighlighting.cpp b/interface/src/ScriptHighlighting.cpp index 119926742c..b2c5ca2ec6 100644 --- a/interface/src/ScriptHighlighting.cpp +++ b/interface/src/ScriptHighlighting.cpp @@ -10,6 +10,7 @@ // #include "ScriptHighlighting.h" +#include <QTextDocument> ScriptHighlighting::ScriptHighlighting(QTextDocument* parent) : QSyntaxHighlighter(parent) @@ -19,13 +20,16 @@ ScriptHighlighting::ScriptHighlighting(QTextDocument* parent) : multiLineCommentBegin = QRegExp("/\\*"); multiLineCommentEnd = QRegExp("\\*/"); numberRegex = QRegExp("[0-9]+(\\.[0-9]+){0,1}"); + singleLineComment = QRegExp("//[^\n]*"); + truefalseRegex = QRegExp("\\b(true|false)\\b"); } void ScriptHighlighting::highlightBlock(const QString &text) { this->highlightKeywords(text); - this->formatComments(text); - this->formatQoutedText(text); this->formatNumbers(text); + this->formatTrueFalse(text); + this->formatQoutedText(text); + this->formatComments(text); } void ScriptHighlighting::highlightKeywords(const QString &text) { @@ -50,6 +54,13 @@ void ScriptHighlighting::formatComments(const QString &text) { start = text.indexOf(multiLineCommentBegin, start + length); if (end == -1) setCurrentBlockState(BlockStateInMultiComment); } + + int index = singleLineComment.indexIn(text); + while (index >= 0) { + int length = singleLineComment.matchedLength(); + setFormat(index, length, Qt::lightGray); + index = singleLineComment.indexIn(text, index + length); + } } void ScriptHighlighting::formatQoutedText(const QString &text){ @@ -69,3 +80,14 @@ void ScriptHighlighting::formatNumbers(const QString &text){ index = numberRegex.indexIn(text, index + length); } } + +void ScriptHighlighting::formatTrueFalse(const QString text){ + int index = truefalseRegex.indexIn(text); + while (index >= 0) { + int length = truefalseRegex.matchedLength(); + QFont* font = new QFont(this->document()->defaultFont()); + font->setBold(true); + setFormat(index, length, *font); + index = truefalseRegex.indexIn(text, index + length); + } +} \ No newline at end of file diff --git a/interface/src/ScriptHighlighting.h b/interface/src/ScriptHighlighting.h index b9567cb06a..9cbbf277cc 100644 --- a/interface/src/ScriptHighlighting.h +++ b/interface/src/ScriptHighlighting.h @@ -26,11 +26,12 @@ public: }; protected: - void highlightBlock(const QString &text); - void highlightKeywords(const QString &text); - void formatComments(const QString &text); - void formatQoutedText(const QString &text); - void formatNumbers(const QString &text); + void highlightBlock(const QString& text); + void highlightKeywords(const QString& text); + void formatComments(const QString& text); + void formatQoutedText(const QString& text); + void formatNumbers(const QString& text); + void formatTrueFalse(const QString text); private: QRegExp keywordRegex; @@ -38,6 +39,8 @@ private: QRegExp multiLineCommentBegin; QRegExp multiLineCommentEnd; QRegExp numberRegex; + QRegExp singleLineComment; + QRegExp truefalseRegex; }; #endif // hifi_ScriptHighlighting_h diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 618e405448..98b6f2fe96 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -13,6 +13,7 @@ #include <QFrame> #include <QLayoutItem> #include <QMainWindow> +#include <QMessageBox> #include <QPalette> #include <QScrollBar> #include <QSizePolicy> @@ -30,13 +31,126 @@ ScriptEditorWidget::ScriptEditorWidget() : { ui->setupUi(this); + scriptEngine = NULL; + + connect(ui->scriptEdit->document(), SIGNAL(modificationChanged(bool)), this, SIGNAL(scriptModified())); + connect(ui->scriptEdit->document(), SIGNAL(contentsChanged()), this, SLOT(onScriptModified())); + // remove the title bar (see the Qt docs on setTitleBarWidget) setTitleBarWidget(new QWidget()); QFontMetrics fm(this->ui->scriptEdit->font()); this->ui->scriptEdit->setTabStopWidth(fm.width('0') * 4); ScriptHighlighting* highlighting = new ScriptHighlighting(this->ui->scriptEdit->document()); + QTimer::singleShot(0, this->ui->scriptEdit, SLOT(setFocus())); } ScriptEditorWidget::~ScriptEditorWidget() { delete ui; +} + +void ScriptEditorWidget::onScriptModified() { + if(ui->onTheFlyCheckBox->isChecked() && isRunning()) { + setRunning(false); + setRunning(true); + } +} + +bool ScriptEditorWidget::isModified() { + return ui->scriptEdit->document()->isModified(); +} + +bool ScriptEditorWidget::isRunning() { + return (scriptEngine != NULL) ? scriptEngine->isRunning() : false; +} + +bool ScriptEditorWidget::setRunning(bool run) { + if (run && !save()) { + return false; + } + // Clean-up old connections. + disconnect(this, SLOT(onScriptError(const QString&))); + disconnect(this, SLOT(onScriptPrint(const QString&))); + + if (run) { + scriptEngine = Application::getInstance()->loadScript(this->currentScript, false); + connect(scriptEngine, SIGNAL(runningStateChanged()), this, SIGNAL(runningStateChanged())); + + // Make new connections. + connect(scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(onScriptError(const QString&))); + connect(scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(onScriptPrint(const QString&))); + } else { + Application::getInstance()->stopScript(this->currentScript); + scriptEngine = NULL; + } + return true; +} + +bool ScriptEditorWidget::saveFile(const QString &scriptPath) { + QFile file(scriptPath); + if (!file.open(QFile::WriteOnly | QFile::Text)) { + QMessageBox::warning(this, tr("Interface"), tr("Cannot write script %1:\n%2.").arg(scriptPath).arg(file.errorString())); + return false; + } + + QTextStream out(&file); + out << ui->scriptEdit->toPlainText(); + + setScriptFile(scriptPath); + return true; +} + +void ScriptEditorWidget::loadFile(const QString &scriptPath) { + QFile file(scriptPath); + if (!file.open(QFile::ReadOnly | QFile::Text)) { + QMessageBox::warning(this, tr("Interface"), tr("Cannot read script %1:\n%2.").arg(scriptPath).arg(file.errorString())); + return; + } + + QTextStream in(&file); + ui->scriptEdit->setPlainText(in.readAll()); + + setScriptFile(scriptPath); + + disconnect(this, SLOT(onScriptError(const QString&))); + disconnect(this, SLOT(onScriptPrint(const QString&))); + + scriptEngine = Application::getInstance()->getScriptEngine(scriptPath); + if (scriptEngine != NULL) { + connect(scriptEngine, SIGNAL(runningStateChanged()), this, SIGNAL(runningStateChanged())); + connect(scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(onScriptError(const QString&))); + connect(scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(onScriptPrint(const QString&))); + } +} + +bool ScriptEditorWidget::save() { + return currentScript.isEmpty() ? saveAs() : saveFile(currentScript); +} + +bool ScriptEditorWidget::saveAs() { + QString fileName = QFileDialog::getSaveFileName(this, tr("Save script"), QString(), tr("Javascript (*.js)")); + return !fileName.isEmpty() ? saveFile(fileName) : false; +} + +void ScriptEditorWidget::setScriptFile(const QString& scriptPath) { + currentScript = scriptPath; + ui->scriptEdit->document()->setModified(false); + setWindowModified(false); + + emit scriptnameChanged(); +} + +bool ScriptEditorWidget::questionSave() { + if (ui->scriptEdit->document()->isModified()) { + QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Interface"), tr("The script has been modified.\nDo you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); + return button == QMessageBox::Save ? save() : (button == QMessageBox::Cancel ? false : true); + } + return true; +} + +void ScriptEditorWidget::onScriptError(const QString& message) { + ui->debugText->appendPlainText("ERROR: "+ message); +} + +void ScriptEditorWidget::onScriptPrint(const QString& message) { + ui->debugText->appendPlainText("> "+message); } \ No newline at end of file diff --git a/interface/src/ui/ScriptEditorWidget.h b/interface/src/ui/ScriptEditorWidget.h index 931ec105c9..674304acb6 100644 --- a/interface/src/ui/ScriptEditorWidget.h +++ b/interface/src/ui/ScriptEditorWidget.h @@ -27,8 +27,30 @@ public: ScriptEditorWidget(); ~ScriptEditorWidget(); + bool isModified(); + bool isRunning(); + bool setRunning(bool run); + bool saveFile(const QString& scriptPath); + void loadFile(const QString& scriptPath); + void setScriptFile(const QString& scriptPath); + bool save(); + bool saveAs(); + bool questionSave(); + const QString getScriptName() const { return currentScript; }; +signals: + void runningStateChanged(); + void scriptnameChanged(); + void scriptModified(); + +private slots: + void onScriptError(const QString& message); + void onScriptPrint(const QString& message); + void onScriptModified(); + private: Ui::ScriptEditorWidget* ui; + ScriptEngine* scriptEngine; + QString currentScript; }; #endif // hifi_ScriptEditorWidget_h diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 38fa26622a..687b992c5f 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -13,8 +13,10 @@ #include <QFrame> #include <QLayoutItem> #include <QMainWindow> +#include <QMessageBox.h> #include <QPalette> #include <QScrollBar> +#include <QShortcut> #include <QSizePolicy> #include <QTimer> #include <QWidget> @@ -31,32 +33,158 @@ ScriptEditorWindow::ScriptEditorWindow() : { ui->setupUi(this); show(); + addScriptEditorWidget("New script"); + loadMenu = new QMenu(); + connect(loadMenu, SIGNAL(aboutToShow()), this, SLOT(loadMenuAboutToShow())); + ui->loadButton->setMenu(loadMenu); + + saveMenu = new QMenu(); + saveMenu->addAction("Save as..", this, SLOT(saveScriptAsClicked()), Qt::CTRL|Qt::SHIFT|Qt::Key_S); + + ui->saveButton->setMenu(saveMenu); + + connect(new QShortcut(QKeySequence("Ctrl+N"), this), SIGNAL(activated()), this, SLOT(newScriptClicked())); + connect(new QShortcut(QKeySequence("Ctrl+S"), this), SIGNAL(activated()), this, SLOT(saveScriptClicked())); + connect(new QShortcut(QKeySequence("Ctrl+O"), this), SIGNAL(activated()), this, SLOT(loadScriptClicked())); + connect(new QShortcut(QKeySequence("F5"), this), SIGNAL(activated()), this, SLOT(toggleRunScriptClicked())); } ScriptEditorWindow::~ScriptEditorWindow() { delete ui; } -void ScriptEditorWindow::loadScriptClicked(){ - +void ScriptEditorWindow::setRunningState(bool run) { + if (ui->tabWidget->currentIndex() != -1) { + ((ScriptEditorWidget*)ui->tabWidget->currentWidget())->setRunning(run); + } + this->updateButtons(); } -void ScriptEditorWindow::newScriptClicked(){ - addScriptEditorWidget(QString("new Script")); +void ScriptEditorWindow::updateButtons() { + ui->toggleRunButton->setEnabled(ui->tabWidget->currentIndex() != -1); + ui->toggleRunButton->setIcon(ui->tabWidget->currentIndex() != -1 && ((ScriptEditorWidget*)ui->tabWidget->currentWidget())->isRunning() ? QIcon("../resources/icons/stop-script.svg"):QIcon("../resources/icons/start-script.svg")); } -void ScriptEditorWindow::toggleRunScriptClicked(){ - +void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) { + addScriptEditorWidget("loading...")->loadFile(scriptName); + updateButtons(); } -void ScriptEditorWindow::saveScriptClicked(){ - +void ScriptEditorWindow::loadScriptClicked() { + QString scriptName = QFileDialog::getOpenFileName(this, tr("Interface"), QString(), tr("Javascript (*.js)")); + if (!scriptName.isEmpty()) { + addScriptEditorWidget("loading...")->loadFile(scriptName); + updateButtons(); + } } -void ScriptEditorWindow::addScriptEditorWidget(QString title){ - ScriptEditorWidget* newScriptEditorWidget = new ScriptEditorWidget();//ScriptEditorWidget(); +void ScriptEditorWindow::loadMenuAboutToShow() { + loadMenu->clear(); + QStringList runningScripts = Application::getInstance()->getRunningScripts(); + if (runningScripts.count() > 0) { + QSignalMapper* signalMapper = new QSignalMapper(this); + foreach (const QString& runningScript, runningScripts) { + QAction* runningScriptAction = new QAction(runningScript, loadMenu); + connect(runningScriptAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + signalMapper->setMapping(runningScriptAction, runningScript); + loadMenu->addAction(runningScriptAction); + } + connect(signalMapper, SIGNAL(mapped(const QString &)), this, SLOT(loadScriptMenu(const QString &))); + } else { + QAction* naAction = new QAction("(no running scripts)",loadMenu); + naAction->setDisabled(true); + loadMenu->addAction(naAction); + } +} + +void ScriptEditorWindow::newScriptClicked() { + addScriptEditorWidget(QString("New script")); +} + +void ScriptEditorWindow::toggleRunScriptClicked() { + this->setRunningState(!(ui->tabWidget->currentIndex() !=-1 && ((ScriptEditorWidget*)ui->tabWidget->currentWidget())->isRunning())); +} + +void ScriptEditorWindow::saveScriptClicked() { + if (ui->tabWidget->currentIndex() != -1) { + ScriptEditorWidget* currentScriptWidget = (ScriptEditorWidget*)ui->tabWidget->currentWidget(); + currentScriptWidget->save(); + } +} + +void ScriptEditorWindow::saveScriptAsClicked() { + if (ui->tabWidget->currentIndex() != -1) { + ScriptEditorWidget* currentScriptWidget = (ScriptEditorWidget*)ui->tabWidget->currentWidget(); + currentScriptWidget->saveAs(); + } +} + +ScriptEditorWidget* ScriptEditorWindow::addScriptEditorWidget(QString title) { + ScriptEditorWidget* newScriptEditorWidget = new ScriptEditorWidget(); + connect(newScriptEditorWidget, SIGNAL(scriptnameChanged()), this, SLOT(updateScriptNameOrStatus())); + connect(newScriptEditorWidget, SIGNAL(scriptModified()), this, SLOT(updateScriptNameOrStatus())); + connect(newScriptEditorWidget, SIGNAL(runningStateChanged()), this, SLOT(updateButtons())); ui->tabWidget->addTab(newScriptEditorWidget, title); ui->tabWidget->setCurrentWidget(newScriptEditorWidget); newScriptEditorWidget->setUpdatesEnabled(true); newScriptEditorWidget->adjustSize(); + return newScriptEditorWidget; +} + +void ScriptEditorWindow::tabSwitched(int tabIndex) { + this->updateButtons(); + if (ui->tabWidget->currentIndex() != -1) { + ScriptEditorWidget* currentScriptWidget = (ScriptEditorWidget*)ui->tabWidget->currentWidget(); + QString modifiedStar = (currentScriptWidget->isModified()?"*":""); + if (currentScriptWidget->getScriptName().length() > 0) { + this->setWindowTitle("Script Editor ["+currentScriptWidget->getScriptName()+modifiedStar+"]"); + } else { + this->setWindowTitle("Script Editor [New script"+modifiedStar+"]"); + } + } else { + this->setWindowTitle("Script Editor"); + } +} + +void ScriptEditorWindow::tabCloseRequested(int tabIndex) { + ScriptEditorWidget* closingScriptWidget = (ScriptEditorWidget*)ui->tabWidget->widget(tabIndex); + if(closingScriptWidget->questionSave()) { + ui->tabWidget->removeTab(tabIndex); + } +} + +void ScriptEditorWindow::closeEvent(QCloseEvent *event) { + bool unsaved_docs_warning = false; + for (int i = 0; i < ui->tabWidget->count(); i++ && !unsaved_docs_warning){ + if(((ScriptEditorWidget*)ui->tabWidget->widget(i))->isModified()){ + unsaved_docs_warning = true; + } + } + + if (!unsaved_docs_warning || QMessageBox::warning(this, tr("Interface"), tr("There are some unsaved scripts, are you sure you want to close the editor? Changes will be lost!"), QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Discard) { + event->accept(); + } else { + event->ignore(); + } +} + +void ScriptEditorWindow::updateScriptNameOrStatus() { + ScriptEditorWidget* source = (ScriptEditorWidget*)QObject::sender(); + QString modifiedStar = (source->isModified()?"*":""); + if (source->getScriptName().length() > 0) { + for (int i = 0; i < ui->tabWidget->count(); i++){ + if (ui->tabWidget->widget(i) == source) { + ui->tabWidget->setTabText(i,modifiedStar+QFileInfo(source->getScriptName()).fileName()); + ui->tabWidget->setTabToolTip(i, source->getScriptName()); + } + } + } + + if (ui->tabWidget->currentWidget() == source) { + if (source->getScriptName().length() > 0) { + this->setWindowTitle("Script Editor ["+source->getScriptName()+modifiedStar+"]"); + } else { + this->setWindowTitle("Script Editor [New script"+modifiedStar+"]"); + } + } } \ No newline at end of file diff --git a/interface/src/ui/ScriptEditorWindow.h b/interface/src/ui/ScriptEditorWindow.h index 718826cf9d..290a9d6051 100644 --- a/interface/src/ui/ScriptEditorWindow.h +++ b/interface/src/ui/ScriptEditorWindow.h @@ -13,6 +13,7 @@ #define hifi_ScriptEditorWindow_h #include <Application.h> +#include "ScriptEditorWidget.h" namespace Ui { class ScriptEditorWindow; @@ -25,15 +26,29 @@ public: ScriptEditorWindow(); ~ScriptEditorWindow(); +protected: + void closeEvent(QCloseEvent *event); + private: Ui::ScriptEditorWindow* ui; - void addScriptEditorWidget(QString title); + QMenu* loadMenu; + QMenu* saveMenu; + ScriptEditorWidget* addScriptEditorWidget(QString title); + void setRunningState(bool run); + void setScriptName(const QString& scriptName); private slots: + void loadScriptMenu(const QString& scriptName); void loadScriptClicked(); void newScriptClicked(); void toggleRunScriptClicked(); void saveScriptClicked(); + void saveScriptAsClicked(); + void loadMenuAboutToShow(); + void tabSwitched(int tabIndex); + void tabCloseRequested(int tabIndex); + void updateScriptNameOrStatus(); + void updateButtons(); }; #endif // hifi_ScriptEditorWindow_h diff --git a/interface/ui/ScriptEditorWidget.ui b/interface/ui/ScriptEditorWidget.ui index 5878f26c69..88761c91c5 100644 --- a/interface/ui/ScriptEditorWidget.ui +++ b/interface/ui/ScriptEditorWidget.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>702</width> - <height>543</height> + <width>691</width> + <height>549</height> </rect> </property> <property name="sizePolicy"> @@ -18,7 +18,7 @@ </property> <property name="minimumSize"> <size> - <width>400</width> + <width>541</width> <height>238</height> </size> </property> @@ -91,6 +91,13 @@ </property> </widget> </item> + <item> + <widget class="QCheckBox" name="onTheFlyCheckBox"> + <property name="text"> + <string>Run on the fly (Careful: Any valid change made to the code will run immediately)</string> + </property> + </widget> + </item> <item> <widget class="QPushButton" name="clearButton"> <property name="text"> diff --git a/interface/ui/ScriptEditorWindow.ui b/interface/ui/ScriptEditorWindow.ui index a612b2b1c9..9e1b08de3e 100644 --- a/interface/ui/ScriptEditorWindow.ui +++ b/interface/ui/ScriptEditorWindow.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>474</width> - <height>638</height> + <width>706</width> + <height>682</height> </rect> </property> <property name="minimumSize"> @@ -20,7 +20,7 @@ </size> </property> <property name="windowTitle"> - <string>Script editor []</string> + <string>Script Editor</string> </property> <property name="styleSheet"> <string notr="true">font-family: Helvetica, Arial, sans-serif;</string> @@ -58,7 +58,7 @@ <item> <widget class="QToolButton" name="newButton"> <property name="toolTip"> - <string>New Script</string> + <string>New Script (Ctrl+N)</string> </property> <property name="text"> <string>New</string> @@ -66,7 +66,7 @@ <property name="icon"> <iconset> <normaloff>../resources/icons/new-script.svg</normaloff> - <normalon>../resources/images/pinned.svg</normalon>../resources/icons/new-script.svg</iconset> + <normalon>../resources/icons/new-script.svg</normalon>../resources/icons/new-script.svg</iconset> </property> <property name="iconSize"> <size> @@ -91,7 +91,7 @@ </size> </property> <property name="toolTip"> - <string>Load Script</string> + <string>Load Script (Ctrl+O)</string> </property> <property name="text"> <string>Load</string> @@ -119,11 +119,17 @@ </item> <item> <widget class="QToolButton" name="saveButton"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>2</verstretch> - </sizepolicy> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>32</width> + <height>0</height> + </size> </property> <property name="focusPolicy"> <enum>Qt::NoFocus</enum> @@ -132,7 +138,7 @@ <enum>Qt::NoContextMenu</enum> </property> <property name="toolTip"> - <string>Save Script</string> + <string>Save Script (Ctrl+S)</string> </property> <property name="text"> <string>Save</string> @@ -150,19 +156,22 @@ <property name="autoRepeatDelay"> <number>316</number> </property> + <property name="popupMode"> + <enum>QToolButton::MenuButtonPopup</enum> + </property> </widget> </item> <item> <widget class="QToolButton" name="toggleRunButton"> <property name="toolTip"> - <string>Toggle Run Script</string> + <string>Toggle Run Script (F5)</string> </property> <property name="text"> <string>Run/Stop</string> </property> <property name="icon"> <iconset> - <normaloff>../resources/images/plus.svg</normaloff>../resources/images/plus.svg</iconset> + <normaloff>../resources/icons/start-script.svg</normaloff>../resources/icons/start-script.svg</iconset> </property> <property name="iconSize"> <size> @@ -286,5 +295,37 @@ </hint> </hints> </connection> + <connection> + <sender>tabWidget</sender> + <signal>currentChanged(int)</signal> + <receiver>ScriptEditorWindow</receiver> + <slot>tabSwitched(int)</slot> + <hints> + <hint type="sourcelabel"> + <x>352</x> + <y>360</y> + </hint> + <hint type="destinationlabel"> + <x>352</x> + <y>340</y> + </hint> + </hints> + </connection> + <connection> + <sender>tabWidget</sender> + <signal>tabCloseRequested(int)</signal> + <receiver>ScriptEditorWindow</receiver> + <slot>tabCloseRequested(int)</slot> + <hints> + <hint type="sourcelabel"> + <x>352</x> + <y>360</y> + </hint> + <hint type="destinationlabel"> + <x>352</x> + <y>340</y> + </hint> + </hints> + </connection> </connections> </ui> diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 684c55fbb0..eeb1cebe09 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -43,6 +43,11 @@ static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* eng return soundScriptValue; } +static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){ + qDebug() << "script:print()<<" << context->argument(0).toString(); + engine->evaluate("Script.print('"+context->argument(0).toString()+"')"); + return QScriptValue(); +} ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString, AbstractControllerScriptingInterface* controllerScriptingInterface) : @@ -115,6 +120,7 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL, _scriptContents = in.readAll(); } else { qDebug() << "ERROR Loading file:" << fileName; + emit errorMessage("ERROR Loading file:" + fileName); } } else { QNetworkAccessManager* networkManager = new QNetworkAccessManager(this); @@ -200,6 +206,9 @@ void ScriptEngine::init() { qScriptRegisterSequenceMetaType<QVector<glm::quat> >(&_engine); qScriptRegisterSequenceMetaType<QVector<QString> >(&_engine); + QScriptValue printConstructorValue = _engine.newFunction(debugPrint); + _engine.globalObject().setProperty("print", printConstructorValue); + QScriptValue soundConstructorValue = _engine.newFunction(soundConstructor); QScriptValue soundMetaObject = _engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue); _engine.globalObject().setProperty("Sound", soundMetaObject); @@ -246,6 +255,7 @@ void ScriptEngine::evaluate() { if (_engine.hasUncaughtException()) { int line = _engine.uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at line" << line << ":" << result.toString(); + emit errorMessage("Uncaught exception at line" + QString::number(line) + ":" + result.toString()); } } @@ -266,11 +276,14 @@ void ScriptEngine::run() { init(); } _isRunning = true; + emit runningStateChanged(); QScriptValue result = _engine.evaluate(_scriptContents); if (_engine.hasUncaughtException()) { int line = _engine.uncaughtExceptionLineNumber(); + qDebug() << "Uncaught exception at line" << line << ":" << result.toString(); + emit errorMessage("Uncaught exception at line" + QString::number(line) + ":" + result.toString()); } timeval startTime; @@ -401,6 +414,7 @@ void ScriptEngine::run() { if (_engine.hasUncaughtException()) { int line = _engine.uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at line" << line << ":" << _engine.uncaughtException().toString(); + emit errorMessage("Uncaught exception at line" + QString::number(line) + ":" + _engine.uncaughtException().toString()); } } emit scriptEnding(); @@ -436,10 +450,12 @@ void ScriptEngine::run() { emit finished(_fileNameString); _isRunning = false; + emit runningStateChanged(); } void ScriptEngine::stop() { _isFinished = true; + emit runningStateChanged(); } void ScriptEngine::timerFired() { @@ -510,6 +526,10 @@ QUrl ScriptEngine::resolveInclude(const QString& include) const { return url; } +void ScriptEngine::print(const QString& message) { + emit printedMessage(message); +} + void ScriptEngine::include(const QString& includeFile) { QUrl url = resolveInclude(includeFile); QString includeContents; @@ -523,6 +543,7 @@ void ScriptEngine::include(const QString& includeFile) { includeContents = in.readAll(); } else { qDebug() << "ERROR Loading file:" << fileName; + emit errorMessage("ERROR Loading file:" + fileName); } } else { QNetworkAccessManager* networkManager = new QNetworkAccessManager(this); @@ -538,5 +559,6 @@ void ScriptEngine::include(const QString& includeFile) { if (_engine.hasUncaughtException()) { int line = _engine.uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at (" << includeFile << ") line" << line << ":" << result.toString(); + emit errorMessage("Uncaught exception at (" + includeFile + ") line" + QString::number(line) + ":" + result.toString()); } -} +} \ No newline at end of file diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 941c6bbe27..9ea99276d3 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -80,6 +80,9 @@ public: bool hasScript() const { return !_scriptContents.isEmpty(); } + bool isFinished() const { return _isFinished; } + bool isRunning() const { return _isRunning; } + public slots: void stop(); @@ -88,12 +91,16 @@ public slots: void clearInterval(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); } void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); } void include(const QString& includeFile); + void print(const QString& message); signals: void update(float deltaTime); void scriptEnding(); void finished(const QString& fileNameString); void cleanupMenuItem(const QString& menuItemString); + void printedMessage(const QString& message); + void errorMessage(const QString& message); + void runningStateChanged(); protected: QString _scriptContents; From 5bffb17643f013e267deeeea6efe615449386232 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Mon, 21 Apr 2014 05:51:34 +0200 Subject: [PATCH 05/11] #include <QMessageBox.h> -> #include <QMessageBox> --- interface/src/ui/ScriptEditorWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 687b992c5f..0774ed02f0 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -13,7 +13,7 @@ #include <QFrame> #include <QLayoutItem> #include <QMainWindow> -#include <QMessageBox.h> +#include <QMessageBox> #include <QPalette> #include <QScrollBar> #include <QShortcut> From 77994ae0cbaecdb0175051de3ae04d4db80ca123 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Mon, 21 Apr 2014 06:20:18 +0200 Subject: [PATCH 06/11] header cleanup (hopefully the ubuntu test-build will like this) --- interface/src/ui/ScriptEditorWidget.cpp | 6 +++--- interface/src/ui/ScriptEditorWidget.h | 4 ++-- interface/src/ui/ScriptEditorWindow.cpp | 8 ++++---- interface/src/ui/ScriptEditorWindow.h | 1 - 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 98b6f2fe96..91e3efe1df 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -9,6 +9,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "ui_scriptEditorWidget.h" +#include "ScriptEditorWidget.h" + #include <QGridLayout> #include <QFrame> #include <QLayoutItem> @@ -22,9 +25,6 @@ #include "Application.h" #include "ScriptHighlighting.h" -#include "ui_scriptEditorWidget.h" - -#include "ScriptEditorWidget.h" ScriptEditorWidget::ScriptEditorWidget() : ui(new Ui::ScriptEditorWidget) diff --git a/interface/src/ui/ScriptEditorWidget.h b/interface/src/ui/ScriptEditorWidget.h index 674304acb6..5fed373658 100644 --- a/interface/src/ui/ScriptEditorWidget.h +++ b/interface/src/ui/ScriptEditorWidget.h @@ -13,8 +13,8 @@ #define hifi_ScriptEditorWidget_h #include <QDockWidget> - -#include <Application.h> +#include "ScriptEditorWidget.h" +#include "ScriptEngine.h" namespace Ui { class ScriptEditorWidget; diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 0774ed02f0..69283feccf 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -9,6 +9,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "ui_scriptEditorWindow.h" +#include "ScriptEditorWindow.h" +#include "ScriptEditorWidget.h" + #include <QGridLayout> #include <QFrame> #include <QLayoutItem> @@ -23,10 +27,6 @@ #include "Application.h" #include "FlowLayout.h" -#include "ui_scriptEditorWindow.h" -#include "ScriptEditorWidget.h" - -#include "ScriptEditorWindow.h" ScriptEditorWindow::ScriptEditorWindow() : ui(new Ui::ScriptEditorWindow) diff --git a/interface/src/ui/ScriptEditorWindow.h b/interface/src/ui/ScriptEditorWindow.h index 290a9d6051..a1b72423ec 100644 --- a/interface/src/ui/ScriptEditorWindow.h +++ b/interface/src/ui/ScriptEditorWindow.h @@ -12,7 +12,6 @@ #ifndef hifi_ScriptEditorWindow_h #define hifi_ScriptEditorWindow_h -#include <Application.h> #include "ScriptEditorWidget.h" namespace Ui { From 0e28ff2fcda7ee5e1bd13decb5cb6b20eed2506c Mon Sep 17 00:00:00 2001 From: "U-Uthoypia\\Thijs" <Thijs@Uthoypia.(none)> Date: Mon, 21 Apr 2014 06:33:20 +0200 Subject: [PATCH 07/11] This should fix the ubuntu build --- interface/ui/{ScriptEditorWidget.ui => scriptEditorWidget.ui} | 0 interface/ui/{ScriptEditorWindow.ui => scriptEditorWindow.ui} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename interface/ui/{ScriptEditorWidget.ui => scriptEditorWidget.ui} (100%) rename interface/ui/{ScriptEditorWindow.ui => scriptEditorWindow.ui} (100%) diff --git a/interface/ui/ScriptEditorWidget.ui b/interface/ui/scriptEditorWidget.ui similarity index 100% rename from interface/ui/ScriptEditorWidget.ui rename to interface/ui/scriptEditorWidget.ui diff --git a/interface/ui/ScriptEditorWindow.ui b/interface/ui/scriptEditorWindow.ui similarity index 100% rename from interface/ui/ScriptEditorWindow.ui rename to interface/ui/scriptEditorWindow.ui From c1ed38f4deddbd7e9873b522e6bb3d3f3d559cc0 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Mon, 21 Apr 2014 21:23:39 +0200 Subject: [PATCH 08/11] Style --- interface/src/ScriptHighlighting.cpp | 68 +++++++++--------- interface/src/ScriptHighlighting.h | 18 ++--- interface/src/ui/ScriptEditorWidget.cpp | 74 +++++++++---------- interface/src/ui/ScriptEditorWidget.h | 11 +-- interface/src/ui/ScriptEditorWindow.cpp | 96 ++++++++++++++----------- interface/src/ui/ScriptEditorWindow.h | 11 +-- 6 files changed, 147 insertions(+), 131 deletions(-) diff --git a/interface/src/ScriptHighlighting.cpp b/interface/src/ScriptHighlighting.cpp index b2c5ca2ec6..9b58298b62 100644 --- a/interface/src/ScriptHighlighting.cpp +++ b/interface/src/ScriptHighlighting.cpp @@ -15,16 +15,16 @@ ScriptHighlighting::ScriptHighlighting(QTextDocument* parent) : QSyntaxHighlighter(parent) { - keywordRegex = QRegExp("\\b(break|case|catch|continue|debugger|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with)\\b"); - qoutedTextRegex = QRegExp("\".*\""); - multiLineCommentBegin = QRegExp("/\\*"); - multiLineCommentEnd = QRegExp("\\*/"); - numberRegex = QRegExp("[0-9]+(\\.[0-9]+){0,1}"); - singleLineComment = QRegExp("//[^\n]*"); - truefalseRegex = QRegExp("\\b(true|false)\\b"); + _keywordRegex = QRegExp("\\b(break|case|catch|continue|debugger|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with)\\b"); + _qoutedTextRegex = QRegExp("\".*\""); + _multiLineCommentBegin = QRegExp("/\\*"); + _multiLineCommentEnd = QRegExp("\\*/"); + _numberRegex = QRegExp("[0-9]+(\\.[0-9]+){0,1}"); + _singleLineComment = QRegExp("//[^\n]*"); + _truefalseRegex = QRegExp("\\b(true|false)\\b"); } -void ScriptHighlighting::highlightBlock(const QString &text) { +void ScriptHighlighting::highlightBlock(const QString& text) { this->highlightKeywords(text); this->formatNumbers(text); this->formatTrueFalse(text); @@ -32,62 +32,64 @@ void ScriptHighlighting::highlightBlock(const QString &text) { this->formatComments(text); } -void ScriptHighlighting::highlightKeywords(const QString &text) { - int index = keywordRegex.indexIn(text); +void ScriptHighlighting::highlightKeywords(const QString& text) { + int index = _keywordRegex.indexIn(text); while (index >= 0) { - int length = keywordRegex.matchedLength(); + int length = _keywordRegex.matchedLength(); setFormat(index, length, Qt::blue); - index = keywordRegex.indexIn(text, index + length); + index = _keywordRegex.indexIn(text, index + length); } } -void ScriptHighlighting::formatComments(const QString &text) { +void ScriptHighlighting::formatComments(const QString& text) { setCurrentBlockState(BlockStateClean); - int start = (previousBlockState() != BlockStateInMultiComment) ? text.indexOf(multiLineCommentBegin) : 0; + int start = (previousBlockState() != BlockStateInMultiComment) ? text.indexOf(_multiLineCommentBegin) : 0; while (start > -1) { - int end = text.indexOf(multiLineCommentEnd, start); - int length = (end == -1 ? text.length() : (end + multiLineCommentEnd.matchedLength())) - start; + int end = text.indexOf(_multiLineCommentEnd, start); + int length = (end == -1 ? text.length() : (end + _multiLineCommentEnd.matchedLength())) - start; setFormat(start, length, Qt::lightGray); - start = text.indexOf(multiLineCommentBegin, start + length); - if (end == -1) setCurrentBlockState(BlockStateInMultiComment); + start = text.indexOf(_multiLineCommentBegin, start + length); + if (end == -1) { + setCurrentBlockState(BlockStateInMultiComment); + } } - int index = singleLineComment.indexIn(text); + int index = _singleLineComment.indexIn(text); while (index >= 0) { - int length = singleLineComment.matchedLength(); + int length = _singleLineComment.matchedLength(); setFormat(index, length, Qt::lightGray); - index = singleLineComment.indexIn(text, index + length); + index = _singleLineComment.indexIn(text, index + length); } } -void ScriptHighlighting::formatQoutedText(const QString &text){ - int index = qoutedTextRegex.indexIn(text); +void ScriptHighlighting::formatQoutedText(const QString& text){ + int index = _qoutedTextRegex.indexIn(text); while (index >= 0) { - int length = qoutedTextRegex.matchedLength(); + int length = _qoutedTextRegex.matchedLength(); setFormat(index, length, Qt::red); - index = qoutedTextRegex.indexIn(text, index + length); + index = _qoutedTextRegex.indexIn(text, index + length); } } -void ScriptHighlighting::formatNumbers(const QString &text){ - int index = numberRegex.indexIn(text); +void ScriptHighlighting::formatNumbers(const QString& text){ + int index = _numberRegex.indexIn(text); while (index >= 0) { - int length = numberRegex.matchedLength(); + int length = _numberRegex.matchedLength(); setFormat(index, length, Qt::green); - index = numberRegex.indexIn(text, index + length); + index = _numberRegex.indexIn(text, index + length); } } -void ScriptHighlighting::formatTrueFalse(const QString text){ - int index = truefalseRegex.indexIn(text); +void ScriptHighlighting::formatTrueFalse(const QString& text){ + int index = _truefalseRegex.indexIn(text); while (index >= 0) { - int length = truefalseRegex.matchedLength(); + int length = _truefalseRegex.matchedLength(); QFont* font = new QFont(this->document()->defaultFont()); font->setBold(true); setFormat(index, length, *font); - index = truefalseRegex.indexIn(text, index + length); + index = _truefalseRegex.indexIn(text, index + length); } } \ No newline at end of file diff --git a/interface/src/ScriptHighlighting.h b/interface/src/ScriptHighlighting.h index 9cbbf277cc..d86d6f4d77 100644 --- a/interface/src/ScriptHighlighting.h +++ b/interface/src/ScriptHighlighting.h @@ -18,7 +18,7 @@ class ScriptHighlighting : public QSyntaxHighlighter { Q_OBJECT public: - ScriptHighlighting(QTextDocument* parent = 0); + ScriptHighlighting(QTextDocument* parent = NULL); enum BlockState { BlockStateClean, @@ -31,16 +31,16 @@ protected: void formatComments(const QString& text); void formatQoutedText(const QString& text); void formatNumbers(const QString& text); - void formatTrueFalse(const QString text); + void formatTrueFalse(const QString& text); private: - QRegExp keywordRegex; - QRegExp qoutedTextRegex; - QRegExp multiLineCommentBegin; - QRegExp multiLineCommentEnd; - QRegExp numberRegex; - QRegExp singleLineComment; - QRegExp truefalseRegex; + QRegExp _keywordRegex; + QRegExp _qoutedTextRegex; + QRegExp _multiLineCommentBegin; + QRegExp _multiLineCommentEnd; + QRegExp _numberRegex; + QRegExp _singleLineComment; + QRegExp _truefalseRegex; }; #endif // hifi_ScriptHighlighting_h diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 91e3efe1df..d24c68a613 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -27,40 +27,39 @@ #include "ScriptHighlighting.h" ScriptEditorWidget::ScriptEditorWidget() : - ui(new Ui::ScriptEditorWidget) + _scriptEditorWidgetUI(new Ui::ScriptEditorWidget), + _scriptEngine(NULL) { - ui->setupUi(this); + _scriptEditorWidgetUI->setupUi(this); - scriptEngine = NULL; - - connect(ui->scriptEdit->document(), SIGNAL(modificationChanged(bool)), this, SIGNAL(scriptModified())); - connect(ui->scriptEdit->document(), SIGNAL(contentsChanged()), this, SLOT(onScriptModified())); + connect(_scriptEditorWidgetUI->scriptEdit->document(), SIGNAL(modificationChanged(bool)), this, SIGNAL(scriptModified())); + connect(_scriptEditorWidgetUI->scriptEdit->document(), SIGNAL(contentsChanged()), this, SLOT(onScriptModified())); // remove the title bar (see the Qt docs on setTitleBarWidget) setTitleBarWidget(new QWidget()); - QFontMetrics fm(this->ui->scriptEdit->font()); - this->ui->scriptEdit->setTabStopWidth(fm.width('0') * 4); - ScriptHighlighting* highlighting = new ScriptHighlighting(this->ui->scriptEdit->document()); - QTimer::singleShot(0, this->ui->scriptEdit, SLOT(setFocus())); + QFontMetrics fm(_scriptEditorWidgetUI->scriptEdit->font()); + _scriptEditorWidgetUI->scriptEdit->setTabStopWidth(fm.width('0') * 4); + ScriptHighlighting* highlighting = new ScriptHighlighting(_scriptEditorWidgetUI->scriptEdit->document()); + QTimer::singleShot(0, _scriptEditorWidgetUI->scriptEdit, SLOT(setFocus())); } ScriptEditorWidget::~ScriptEditorWidget() { - delete ui; + delete _scriptEditorWidgetUI; } void ScriptEditorWidget::onScriptModified() { - if(ui->onTheFlyCheckBox->isChecked() && isRunning()) { + if(_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isRunning()) { setRunning(false); setRunning(true); } } bool ScriptEditorWidget::isModified() { - return ui->scriptEdit->document()->isModified(); + return _scriptEditorWidgetUI->scriptEdit->document()->isModified(); } bool ScriptEditorWidget::isRunning() { - return (scriptEngine != NULL) ? scriptEngine->isRunning() : false; + return (_scriptEngine != NULL) ? _scriptEngine->isRunning() : false; } bool ScriptEditorWidget::setRunning(bool run) { @@ -72,15 +71,15 @@ bool ScriptEditorWidget::setRunning(bool run) { disconnect(this, SLOT(onScriptPrint(const QString&))); if (run) { - scriptEngine = Application::getInstance()->loadScript(this->currentScript, false); - connect(scriptEngine, SIGNAL(runningStateChanged()), this, SIGNAL(runningStateChanged())); + _scriptEngine = Application::getInstance()->loadScript(_currentScript, false); + connect(_scriptEngine, SIGNAL(runningStateChanged()), this, SIGNAL(runningStateChanged())); // Make new connections. - connect(scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(onScriptError(const QString&))); - connect(scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(onScriptPrint(const QString&))); + connect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(onScriptError(const QString&))); + connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(onScriptPrint(const QString&))); } else { - Application::getInstance()->stopScript(this->currentScript); - scriptEngine = NULL; + Application::getInstance()->stopScript(_currentScript); + _scriptEngine = NULL; } return true; } @@ -88,18 +87,19 @@ bool ScriptEditorWidget::setRunning(bool run) { bool ScriptEditorWidget::saveFile(const QString &scriptPath) { QFile file(scriptPath); if (!file.open(QFile::WriteOnly | QFile::Text)) { - QMessageBox::warning(this, tr("Interface"), tr("Cannot write script %1:\n%2.").arg(scriptPath).arg(file.errorString())); + QMessageBox::warning(this, tr("Interface"), tr("Cannot write script %1:\n%2.").arg(scriptPath) + .arg(file.errorString())); return false; } QTextStream out(&file); - out << ui->scriptEdit->toPlainText(); + out << _scriptEditorWidgetUI->scriptEdit->toPlainText(); setScriptFile(scriptPath); return true; } -void ScriptEditorWidget::loadFile(const QString &scriptPath) { +void ScriptEditorWidget::loadFile(const QString& scriptPath) { QFile file(scriptPath); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("Interface"), tr("Cannot read script %1:\n%2.").arg(scriptPath).arg(file.errorString())); @@ -107,23 +107,23 @@ void ScriptEditorWidget::loadFile(const QString &scriptPath) { } QTextStream in(&file); - ui->scriptEdit->setPlainText(in.readAll()); + _scriptEditorWidgetUI->scriptEdit->setPlainText(in.readAll()); setScriptFile(scriptPath); disconnect(this, SLOT(onScriptError(const QString&))); disconnect(this, SLOT(onScriptPrint(const QString&))); - scriptEngine = Application::getInstance()->getScriptEngine(scriptPath); - if (scriptEngine != NULL) { - connect(scriptEngine, SIGNAL(runningStateChanged()), this, SIGNAL(runningStateChanged())); - connect(scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(onScriptError(const QString&))); - connect(scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(onScriptPrint(const QString&))); + _scriptEngine = Application::getInstance()->getScriptEngine(scriptPath); + if (_scriptEngine != NULL) { + connect(_scriptEngine, SIGNAL(runningStateChanged()), this, SIGNAL(runningStateChanged())); + connect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(onScriptError(const QString&))); + connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(onScriptPrint(const QString&))); } } bool ScriptEditorWidget::save() { - return currentScript.isEmpty() ? saveAs() : saveFile(currentScript); + return _currentScript.isEmpty() ? saveAs() : saveFile(_currentScript); } bool ScriptEditorWidget::saveAs() { @@ -132,25 +132,27 @@ bool ScriptEditorWidget::saveAs() { } void ScriptEditorWidget::setScriptFile(const QString& scriptPath) { - currentScript = scriptPath; - ui->scriptEdit->document()->setModified(false); + _currentScript = scriptPath; + _scriptEditorWidgetUI->scriptEdit->document()->setModified(false); setWindowModified(false); emit scriptnameChanged(); } bool ScriptEditorWidget::questionSave() { - if (ui->scriptEdit->document()->isModified()) { - QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Interface"), tr("The script has been modified.\nDo you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); + if (_scriptEditorWidgetUI->scriptEdit->document()->isModified()) { + QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Interface"), + tr("The script has been modified.\nDo you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | + QMessageBox::Cancel, QMessageBox::Save); return button == QMessageBox::Save ? save() : (button == QMessageBox::Cancel ? false : true); } return true; } void ScriptEditorWidget::onScriptError(const QString& message) { - ui->debugText->appendPlainText("ERROR: "+ message); + _scriptEditorWidgetUI->debugText->appendPlainText("ERROR: " + message); } void ScriptEditorWidget::onScriptPrint(const QString& message) { - ui->debugText->appendPlainText("> "+message); + _scriptEditorWidgetUI->debugText->appendPlainText("> " + message); } \ No newline at end of file diff --git a/interface/src/ui/ScriptEditorWidget.h b/interface/src/ui/ScriptEditorWidget.h index 5fed373658..3e50280a62 100644 --- a/interface/src/ui/ScriptEditorWidget.h +++ b/interface/src/ui/ScriptEditorWidget.h @@ -17,7 +17,7 @@ #include "ScriptEngine.h" namespace Ui { -class ScriptEditorWidget; + class ScriptEditorWidget; } class ScriptEditorWidget : public QDockWidget { @@ -36,7 +36,8 @@ public: bool save(); bool saveAs(); bool questionSave(); - const QString getScriptName() const { return currentScript; }; + const QString getScriptName() const { return _currentScript; }; + signals: void runningStateChanged(); void scriptnameChanged(); @@ -48,9 +49,9 @@ private slots: void onScriptModified(); private: - Ui::ScriptEditorWidget* ui; - ScriptEngine* scriptEngine; - QString currentScript; + Ui::ScriptEditorWidget* _scriptEditorWidgetUI; + ScriptEngine* _scriptEngine; + QString _currentScript; }; #endif // hifi_ScriptEditorWidget_h diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 69283feccf..00a3ef9f0c 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -29,19 +29,19 @@ #include "FlowLayout.h" ScriptEditorWindow::ScriptEditorWindow() : - ui(new Ui::ScriptEditorWindow) + _ScriptEditorWindowUI(new Ui::ScriptEditorWindow), + _loadMenu(new QMenu), + _saveMenu(new QMenu) { - ui->setupUi(this); + _ScriptEditorWindowUI->setupUi(this); show(); addScriptEditorWidget("New script"); - loadMenu = new QMenu(); - connect(loadMenu, SIGNAL(aboutToShow()), this, SLOT(loadMenuAboutToShow())); - ui->loadButton->setMenu(loadMenu); + connect(_loadMenu, SIGNAL(aboutToShow()), this, SLOT(loadMenuAboutToShow())); + _ScriptEditorWindowUI->loadButton->setMenu(_loadMenu); - saveMenu = new QMenu(); - saveMenu->addAction("Save as..", this, SLOT(saveScriptAsClicked()), Qt::CTRL|Qt::SHIFT|Qt::Key_S); + _saveMenu->addAction("Save as..", this, SLOT(saveScriptAsClicked()), Qt::CTRL | Qt::SHIFT | Qt::Key_S); - ui->saveButton->setMenu(saveMenu); + _ScriptEditorWindowUI->saveButton->setMenu(_saveMenu); connect(new QShortcut(QKeySequence("Ctrl+N"), this), SIGNAL(activated()), this, SLOT(newScriptClicked())); connect(new QShortcut(QKeySequence("Ctrl+S"), this), SIGNAL(activated()), this, SLOT(saveScriptClicked())); @@ -50,19 +50,21 @@ ScriptEditorWindow::ScriptEditorWindow() : } ScriptEditorWindow::~ScriptEditorWindow() { - delete ui; + delete _ScriptEditorWindowUI; } void ScriptEditorWindow::setRunningState(bool run) { - if (ui->tabWidget->currentIndex() != -1) { - ((ScriptEditorWidget*)ui->tabWidget->currentWidget())->setRunning(run); + if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) { + static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->setRunning(run); } this->updateButtons(); } void ScriptEditorWindow::updateButtons() { - ui->toggleRunButton->setEnabled(ui->tabWidget->currentIndex() != -1); - ui->toggleRunButton->setIcon(ui->tabWidget->currentIndex() != -1 && ((ScriptEditorWidget*)ui->tabWidget->currentWidget())->isRunning() ? QIcon("../resources/icons/stop-script.svg"):QIcon("../resources/icons/start-script.svg")); + _ScriptEditorWindowUI->toggleRunButton->setEnabled(_ScriptEditorWindowUI->tabWidget->currentIndex() != -1); + _ScriptEditorWindowUI->toggleRunButton->setIcon(_ScriptEditorWindowUI->tabWidget->currentIndex() != -1 && + static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning() ? + QIcon("../resources/icons/stop-script.svg") : QIcon("../resources/icons/start-script.svg")); } void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) { @@ -79,21 +81,21 @@ void ScriptEditorWindow::loadScriptClicked() { } void ScriptEditorWindow::loadMenuAboutToShow() { - loadMenu->clear(); + _loadMenu->clear(); QStringList runningScripts = Application::getInstance()->getRunningScripts(); if (runningScripts.count() > 0) { QSignalMapper* signalMapper = new QSignalMapper(this); foreach (const QString& runningScript, runningScripts) { - QAction* runningScriptAction = new QAction(runningScript, loadMenu); + QAction* runningScriptAction = new QAction(runningScript, _loadMenu); connect(runningScriptAction, SIGNAL(triggered()), signalMapper, SLOT(map())); signalMapper->setMapping(runningScriptAction, runningScript); - loadMenu->addAction(runningScriptAction); + _loadMenu->addAction(runningScriptAction); } - connect(signalMapper, SIGNAL(mapped(const QString &)), this, SLOT(loadScriptMenu(const QString &))); + connect(signalMapper, SIGNAL(mapped(const QString &)), this, SLOT(loadScriptMenu(const QString&))); } else { - QAction* naAction = new QAction("(no running scripts)",loadMenu); + QAction* naAction = new QAction("(no running scripts)", _loadMenu); naAction->setDisabled(true); - loadMenu->addAction(naAction); + _loadMenu->addAction(naAction); } } @@ -102,19 +104,22 @@ void ScriptEditorWindow::newScriptClicked() { } void ScriptEditorWindow::toggleRunScriptClicked() { - this->setRunningState(!(ui->tabWidget->currentIndex() !=-1 && ((ScriptEditorWidget*)ui->tabWidget->currentWidget())->isRunning())); + this->setRunningState(!(_ScriptEditorWindowUI->tabWidget->currentIndex() !=-1 + && static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning())); } void ScriptEditorWindow::saveScriptClicked() { - if (ui->tabWidget->currentIndex() != -1) { - ScriptEditorWidget* currentScriptWidget = (ScriptEditorWidget*)ui->tabWidget->currentWidget(); + if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) { + ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget + ->currentWidget()); currentScriptWidget->save(); } } void ScriptEditorWindow::saveScriptAsClicked() { - if (ui->tabWidget->currentIndex() != -1) { - ScriptEditorWidget* currentScriptWidget = (ScriptEditorWidget*)ui->tabWidget->currentWidget(); + if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) { + ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget + ->currentWidget()); currentScriptWidget->saveAs(); } } @@ -124,8 +129,8 @@ ScriptEditorWidget* ScriptEditorWindow::addScriptEditorWidget(QString title) { connect(newScriptEditorWidget, SIGNAL(scriptnameChanged()), this, SLOT(updateScriptNameOrStatus())); connect(newScriptEditorWidget, SIGNAL(scriptModified()), this, SLOT(updateScriptNameOrStatus())); connect(newScriptEditorWidget, SIGNAL(runningStateChanged()), this, SLOT(updateButtons())); - ui->tabWidget->addTab(newScriptEditorWidget, title); - ui->tabWidget->setCurrentWidget(newScriptEditorWidget); + _ScriptEditorWindowUI->tabWidget->addTab(newScriptEditorWidget, title); + _ScriptEditorWindowUI->tabWidget->setCurrentWidget(newScriptEditorWidget); newScriptEditorWidget->setUpdatesEnabled(true); newScriptEditorWidget->adjustSize(); return newScriptEditorWidget; @@ -133,13 +138,14 @@ ScriptEditorWidget* ScriptEditorWindow::addScriptEditorWidget(QString title) { void ScriptEditorWindow::tabSwitched(int tabIndex) { this->updateButtons(); - if (ui->tabWidget->currentIndex() != -1) { - ScriptEditorWidget* currentScriptWidget = (ScriptEditorWidget*)ui->tabWidget->currentWidget(); - QString modifiedStar = (currentScriptWidget->isModified()?"*":""); + if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) { + ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget + ->currentWidget()); + QString modifiedStar = (currentScriptWidget->isModified() ? "*" : ""); if (currentScriptWidget->getScriptName().length() > 0) { - this->setWindowTitle("Script Editor ["+currentScriptWidget->getScriptName()+modifiedStar+"]"); + this->setWindowTitle("Script Editor [" + currentScriptWidget->getScriptName() + modifiedStar + "]"); } else { - this->setWindowTitle("Script Editor [New script"+modifiedStar+"]"); + this->setWindowTitle("Script Editor [New script" + modifiedStar + "]"); } } else { this->setWindowTitle("Script Editor"); @@ -147,21 +153,25 @@ void ScriptEditorWindow::tabSwitched(int tabIndex) { } void ScriptEditorWindow::tabCloseRequested(int tabIndex) { - ScriptEditorWidget* closingScriptWidget = (ScriptEditorWidget*)ui->tabWidget->widget(tabIndex); + ScriptEditorWidget* closingScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget + ->widget(tabIndex)); if(closingScriptWidget->questionSave()) { - ui->tabWidget->removeTab(tabIndex); + _ScriptEditorWindowUI->tabWidget->removeTab(tabIndex); } } void ScriptEditorWindow::closeEvent(QCloseEvent *event) { bool unsaved_docs_warning = false; - for (int i = 0; i < ui->tabWidget->count(); i++ && !unsaved_docs_warning){ - if(((ScriptEditorWidget*)ui->tabWidget->widget(i))->isModified()){ + for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){ + if(static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->widget(i))->isModified()){ unsaved_docs_warning = true; + break; } } - if (!unsaved_docs_warning || QMessageBox::warning(this, tr("Interface"), tr("There are some unsaved scripts, are you sure you want to close the editor? Changes will be lost!"), QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Discard) { + if (!unsaved_docs_warning || QMessageBox::warning(this, tr("Interface"), + tr("There are some unsaved scripts, are you sure you want to close the editor? Changes will be lost!"), + QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Discard) { event->accept(); } else { event->ignore(); @@ -172,19 +182,19 @@ void ScriptEditorWindow::updateScriptNameOrStatus() { ScriptEditorWidget* source = (ScriptEditorWidget*)QObject::sender(); QString modifiedStar = (source->isModified()?"*":""); if (source->getScriptName().length() > 0) { - for (int i = 0; i < ui->tabWidget->count(); i++){ - if (ui->tabWidget->widget(i) == source) { - ui->tabWidget->setTabText(i,modifiedStar+QFileInfo(source->getScriptName()).fileName()); - ui->tabWidget->setTabToolTip(i, source->getScriptName()); + for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){ + if (_ScriptEditorWindowUI->tabWidget->widget(i) == source) { + _ScriptEditorWindowUI->tabWidget->setTabText(i,modifiedStar + QFileInfo(source->getScriptName()).fileName()); + _ScriptEditorWindowUI->tabWidget->setTabToolTip(i, source->getScriptName()); } } } - if (ui->tabWidget->currentWidget() == source) { + if (_ScriptEditorWindowUI->tabWidget->currentWidget() == source) { if (source->getScriptName().length() > 0) { - this->setWindowTitle("Script Editor ["+source->getScriptName()+modifiedStar+"]"); + this->setWindowTitle("Script Editor [" + source->getScriptName() + modifiedStar + "]"); } else { - this->setWindowTitle("Script Editor [New script"+modifiedStar+"]"); + this->setWindowTitle("Script Editor [New script" + modifiedStar + "]"); } } } \ No newline at end of file diff --git a/interface/src/ui/ScriptEditorWindow.h b/interface/src/ui/ScriptEditorWindow.h index a1b72423ec..0bf5015ccf 100644 --- a/interface/src/ui/ScriptEditorWindow.h +++ b/interface/src/ui/ScriptEditorWindow.h @@ -15,7 +15,7 @@ #include "ScriptEditorWidget.h" namespace Ui { -class ScriptEditorWindow; + class ScriptEditorWindow; } class ScriptEditorWindow : public QWidget { @@ -26,12 +26,13 @@ public: ~ScriptEditorWindow(); protected: - void closeEvent(QCloseEvent *event); + void closeEvent(QCloseEvent* event); private: - Ui::ScriptEditorWindow* ui; - QMenu* loadMenu; - QMenu* saveMenu; + Ui::ScriptEditorWindow* _ScriptEditorWindowUI; + QMenu* _loadMenu; + QMenu* _saveMenu; + ScriptEditorWidget* addScriptEditorWidget(QString title); void setRunningState(bool run); void setScriptName(const QString& scriptName); From 9faee0d82d9a42938778075f5bc43d38bf16e21d Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Mon, 21 Apr 2014 21:37:49 +0200 Subject: [PATCH 09/11] - Style - Script Editor can run script file once at time, but you can still start multiple scripts through the original ways. --- interface/src/Application.cpp | 6 +++--- interface/src/Application.h | 2 +- interface/src/ui/ScriptEditorWidget.cpp | 2 +- interface/src/ui/ScriptEditorWindow.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 79d3e7597e..4ba465bbe1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3377,8 +3377,8 @@ void Application::uploadSkeleton() { uploadFST(false); } -ScriptEngine* Application::loadScript(const QString& scriptName, bool focusMainWindow) { - if(_scriptEnginesHash.contains(scriptName) && !_scriptEnginesHash[scriptName]->isFinished()){ +ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) { + if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptName) && !_scriptEnginesHash[scriptName]->isFinished()){ return _scriptEnginesHash[scriptName]; } @@ -3436,7 +3436,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool focusMainW workerThread->start(); // restore the main window's active state - if (focusMainWindow) { + if (!loadScriptFromEditor) { _window->activateWindow(); } bumpSettings(); diff --git a/interface/src/Application.h b/interface/src/Application.h index e66e7e2975..fb48acb721 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -121,7 +121,7 @@ public: ~Application(); void restoreSizeAndPosition(); - ScriptEngine* loadScript(const QString& fileNameString, bool focusMainWindow = true); + ScriptEngine* loadScript(const QString& fileNameString, bool loadScriptFromEditor = false); void loadScripts(); void storeSizeAndPosition(); void clearScriptsBeforeRunning(); diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index d24c68a613..74b74e1ad6 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -71,7 +71,7 @@ bool ScriptEditorWidget::setRunning(bool run) { disconnect(this, SLOT(onScriptPrint(const QString&))); if (run) { - _scriptEngine = Application::getInstance()->loadScript(_currentScript, false); + _scriptEngine = Application::getInstance()->loadScript(_currentScript, true); connect(_scriptEngine, SIGNAL(runningStateChanged()), this, SIGNAL(runningStateChanged())); // Make new connections. diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 00a3ef9f0c..26488f0223 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -180,11 +180,11 @@ void ScriptEditorWindow::closeEvent(QCloseEvent *event) { void ScriptEditorWindow::updateScriptNameOrStatus() { ScriptEditorWidget* source = (ScriptEditorWidget*)QObject::sender(); - QString modifiedStar = (source->isModified()?"*":""); + QString modifiedStar = (source->isModified()? "*" : ""); if (source->getScriptName().length() > 0) { for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){ if (_ScriptEditorWindowUI->tabWidget->widget(i) == source) { - _ScriptEditorWindowUI->tabWidget->setTabText(i,modifiedStar + QFileInfo(source->getScriptName()).fileName()); + _ScriptEditorWindowUI->tabWidget->setTabText(i, modifiedStar + QFileInfo(source->getScriptName()).fileName()); _ScriptEditorWindowUI->tabWidget->setTabToolTip(i, source->getScriptName()); } } From 70ac93c20d8153ca32fbc7a6f49633462c6c17f8 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Mon, 21 Apr 2014 21:44:50 +0200 Subject: [PATCH 10/11] Style --- interface/src/ui/ScriptEditorWindow.cpp | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 26488f0223..ec63e0341d 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -179,7 +179,7 @@ void ScriptEditorWindow::closeEvent(QCloseEvent *event) { } void ScriptEditorWindow::updateScriptNameOrStatus() { - ScriptEditorWidget* source = (ScriptEditorWidget*)QObject::sender(); + ScriptEditorWidget* source = static_cast<ScriptEditorWidget*>(QObject::sender()); QString modifiedStar = (source->isModified()? "*" : ""); if (source->getScriptName().length() > 0) { for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){ diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index eeb1cebe09..2e92567fe7 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -45,7 +45,7 @@ static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* eng static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){ qDebug() << "script:print()<<" << context->argument(0).toString(); - engine->evaluate("Script.print('"+context->argument(0).toString()+"')"); + engine->evaluate("Script.print('" + context->argument(0).toString() + "')"); return QScriptValue(); } From 6c89521f1d136486fde387c256e85c7c31650701 Mon Sep 17 00:00:00 2001 From: Thijs Wenker <me@thoys.nl> Date: Tue, 22 Apr 2014 13:12:21 +0200 Subject: [PATCH 11/11] Style --- interface/src/ScriptHighlighting.cpp | 6 +++--- interface/src/ui/ScriptEditorWidget.cpp | 2 +- interface/src/ui/ScriptEditorWindow.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/ScriptHighlighting.cpp b/interface/src/ScriptHighlighting.cpp index 9b58298b62..3ab1394097 100644 --- a/interface/src/ScriptHighlighting.cpp +++ b/interface/src/ScriptHighlighting.cpp @@ -29,7 +29,7 @@ void ScriptHighlighting::highlightBlock(const QString& text) { this->formatNumbers(text); this->formatTrueFalse(text); this->formatQoutedText(text); - this->formatComments(text); + this->formatComments(text); } void ScriptHighlighting::highlightKeywords(const QString& text) { @@ -54,7 +54,7 @@ void ScriptHighlighting::formatComments(const QString& text) { start = text.indexOf(_multiLineCommentBegin, start + length); if (end == -1) { setCurrentBlockState(BlockStateInMultiComment); - } + } } int index = _singleLineComment.indexIn(text); @@ -92,4 +92,4 @@ void ScriptHighlighting::formatTrueFalse(const QString& text){ setFormat(index, length, *font); index = _truefalseRegex.indexIn(text, index + length); } -} \ No newline at end of file +} diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 74b74e1ad6..1765a5ea1a 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -155,4 +155,4 @@ void ScriptEditorWidget::onScriptError(const QString& message) { void ScriptEditorWidget::onScriptPrint(const QString& message) { _scriptEditorWidgetUI->debugText->appendPlainText("> " + message); -} \ No newline at end of file +} diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index ec63e0341d..0c34959353 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -197,4 +197,4 @@ void ScriptEditorWindow::updateScriptNameOrStatus() { this->setWindowTitle("Script Editor [New script" + modifiedStar + "]"); } } -} \ No newline at end of file +}