DrawFmsLanes.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /**
  2. * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
  3. *
  4. * Various changes added 2014 by Robert S.
  5. *
  6. * This file is part of the QCAD project.
  7. *
  8. * QCAD is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * QCAD is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with QCAD.
  20. */
  21. include("scripts/Draw/Polyline/Polyline.js");
  22. include("scripts/Snap/RestrictAngleLength/RestrictAngleLength.js");
  23. /**
  24. * \class DrawFmsLanes
  25. * \brief Draw polyline, segment by segment.
  26. * This is also the base class for PolylineAppendNode.
  27. * \ingroup ecma_draw_polyline
  28. */
  29. function DrawFmsLanes(guiAction) {
  30. Polyline.call(this, guiAction);
  31. this.polylineEntity = undefined;
  32. this.leftBoundaryEntity = undefined;
  33. this.rightBoundaryEntity = undefined;
  34. this.arcSegment = false;
  35. this.laneWidth = 20; // 20meters
  36. this.laneWidthCm = this.laneWidth * 100;
  37. this.radius = 1.0;
  38. this.prepend = false;
  39. this.segment = undefined;
  40. this.redoList = [];
  41. this.sweep = 0.0;
  42. this.setUiOptions(DrawFmsLanes.includeBasePath + "/DrawFmsLanes.ui");
  43. }
  44. DrawFmsLanes.prototype = new Polyline();
  45. DrawFmsLanes.includeBasePath = includeBasePath;
  46. DrawFmsLanes.State = {
  47. SettingFirstVertex : 0,
  48. SettingNextVertex : 1
  49. };
  50. DrawFmsLanes.prototype.beginEvent = function() {
  51. Polyline.prototype.beginEvent.call(this);
  52. this.setState(DrawFmsLanes.State.SettingFirstVertex);
  53. this.updateButtonStates();
  54. };
  55. DrawFmsLanes.prototype.initState = function(state) {
  56. Polyline.prototype.initState.call(this, state);
  57. this.setCrosshairCursor();
  58. switch (this.state) {
  59. case DrawFmsLanes.State.SettingFirstVertex:
  60. // do not move this outside of the case, since inheriting actions
  61. // might add more states:
  62. this.getDocumentInterface().setClickMode(RAction.PickCoordinate);
  63. var trFirstVertex = qsTr("First vertex");
  64. this.setCommandPrompt(trFirstVertex);
  65. this.setLeftMouseTip(trFirstVertex);
  66. this.setRightMouseTip(EAction.trCancel);
  67. this.segment = undefined;
  68. this.leftBoundaryEntity = new RPolylineEntity(this.getDocument(), new RPolylineData());
  69. this.rightBoundaryEntity = new RPolylineEntity(this.getDocument(), new RPolylineData());
  70. EAction.showSnapTools();
  71. this.redoList = [];
  72. break;
  73. case DrawFmsLanes.State.SettingNextVertex:
  74. this.getDocumentInterface().setClickMode(RAction.PickCoordinate);
  75. var trNextVertex = qsTr("Next vertex");
  76. this.setCommandPrompt(trNextVertex);
  77. this.setLeftMouseTip(trNextVertex);
  78. this.setRightMouseTip(EAction.trDone);
  79. EAction.showSnapTools();
  80. break;
  81. }
  82. };
  83. /***
  84. *
  85. * @param lineStartPoint - RVector
  86. * @param lineEndPoint - RVector
  87. */
  88. DrawFmsLanes.prototype.drawRibsBasedOnLine = function(lineStartPoint, lineEndPoint, isLastVertex) {
  89. // create left rib based on directionVector to next vertex, multiplied by input laneWidth
  90. var ribLeft = new RLine(lineStartPoint, lineEndPoint);
  91. // get leftRib from directionVector rotated 90-deg
  92. ribLeft.rotate(Math.PI/2, ribLeft.startPoint);
  93. // get a normalized ribLeft so can multiply it with laneWidth,
  94. // couldn't see RLine.normalize function, so use RVector to normalize and then scale it
  95. var ribLeftVec = new RVector(
  96. ribLeft.endPoint.getX() - ribLeft.startPoint.getX(),
  97. ribLeft.endPoint.getY() - ribLeft.startPoint.getY());
  98. var ribLeftVecNorm = ribLeftVec.getNormalized();
  99. var scaled = ribLeftVecNorm.scale(this.laneWidth);
  100. var ribLeftFinalEndPoint = new RVector(
  101. ribLeft.startPoint.getX() + scaled.getX(),
  102. ribLeft.startPoint.getY() + scaled.getY());
  103. var ribRight = new RLine(lineStartPoint, lineEndPoint);
  104. ribRight.rotate(-Math.PI/2, ribRight.startPoint);
  105. var ribRightVec = new RVector(
  106. ribRight.endPoint.getX() - ribRight.startPoint.getX(),
  107. ribRight.endPoint.getY() - ribRight.startPoint.getY());
  108. var ribRightVecNorm = ribRightVec.getNormalized();
  109. var ribRightVecScaled = ribRightVecNorm.scale(this.laneWidth);
  110. var ribRightFinalEndPoint = new RVector(
  111. ribRight.startPoint.getX() + ribRightVecScaled.getX(),
  112. ribRight.startPoint.getY() + ribRightVecScaled.getY());
  113. // todo use this.applyOperation ?
  114. var rib = new RPolylineEntity(
  115. this.getDocument(),
  116. new RPolylineData()
  117. );
  118. rib.appendVertex(ribLeftFinalEndPoint);
  119. rib.appendVertex(lineStartPoint);
  120. rib.appendVertex(ribRightFinalEndPoint);
  121. rib.setCustomProperty("QCAD", "distance_left_cm", this.laneWidthCm / 2);
  122. rib.setCustomProperty("QCAD", "distance_right_cm", this.laneWidthCm / 2);
  123. var line = new RLine(lineStartPoint, lineEndPoint);
  124. rib.setCustomProperty("QCAD", "yaw_crad", line.getAngle() * 100);
  125. rib.setCustomProperty("QCAD", "type", "ribs");
  126. rib.setCustomProperty("QCAD", "center_point_x", lineStartPoint.getX());
  127. rib.setCustomProperty("QCAD", "center_point_y", lineStartPoint.getY());
  128. if (isLastVertex) {
  129. this.leftBoundaryEntity.appendVertex(ribRightFinalEndPoint);
  130. this.rightBoundaryEntity.appendVertex(ribLeftFinalEndPoint);
  131. this.leftBoundaryEntity.appendVertex(this.rightBoundaryEntity.getVertexAt(this.rightBoundaryEntity.countVertices()-1));
  132. this.rightBoundaryEntity.prependVertex(this.leftBoundaryEntity.getVertexAt(0));
  133. var line = new RLine(lineEndPoint, lineStartPoint);
  134. rib.setCustomProperty("QCAD", "yaw_crad", line.getAngle() * 100);
  135. }
  136. else {
  137. this.leftBoundaryEntity.appendVertex(ribLeftFinalEndPoint);
  138. this.rightBoundaryEntity.appendVertex(ribRightFinalEndPoint);
  139. var line = new RLine(lineStartPoint, lineEndPoint);
  140. rib.setCustomProperty("QCAD", "yaw_crad", line.getAngle() * 100);
  141. }
  142. var op = new RAddObjectsOperation();
  143. op.addObject(rib);
  144. this.getDocumentInterface().applyOperation(op);
  145. // debugger;
  146. // Todo:
  147. // - check to not add centerPoint if ribs will intersect
  148. // - associate centerLine with ribs, so no need to compute it ?
  149. // - automatically add polygon based on ribs endpoint ?
  150. }
  151. DrawFmsLanes.prototype.escapeEvent = function() {
  152. switch (this.state) {
  153. case DrawFmsLanes.State.SettingFirstVertex:
  154. EAction.prototype.escapeEvent.call(this);
  155. break;
  156. case DrawFmsLanes.State.SettingNextVertex:
  157. if (!isNull(this.polylineEntity)) {
  158. // remove polyline with one or zero vertices:
  159. if (this.polylineEntity.countVertices() <= 1) {
  160. var op = new RDeleteObjectOperation(this.polylineEntity, false);
  161. this.applyOperation(op);
  162. }
  163. else {
  164. // add rib to last vertex
  165. this.drawRibsBasedOnLine(this.segment.endPoint, this.segment.startPoint, true);
  166. var op = new RAddObjectsOperation();
  167. var allBoundary = new RPolylineEntity(this.getDocument(), this.leftBoundaryEntity.getData());
  168. for (var i = this.rightBoundaryEntity.countVertices()-1; i >= 0 ; i--) {
  169. allBoundary.appendVertex(this.rightBoundaryEntity.getVertexAt(i));
  170. }
  171. allBoundary.normalize(0.001);
  172. op.addObject(allBoundary);
  173. // op.addObject(this.rightBoundaryEntity);
  174. this.getDocumentInterface().applyOperation(op);
  175. }
  176. }
  177. this.setState(DrawFmsLanes.State.SettingFirstVertex);
  178. this.polylineEntity = undefined;
  179. this.leftBoundaryEntity = undefined;
  180. this.rightBoundaryEntity = undefined;
  181. this.updateButtonStates();
  182. break;
  183. }
  184. };
  185. DrawFmsLanes.prototype.keyPressEvent = function(event) {
  186. var di = this.getDocumentInterface();
  187. if ((event.key() === Qt.Key_Enter.valueOf()) || (event.key() === Qt.Key_Return.valueOf())) {
  188. if (this.state === DrawFmsLanes.State.SettingFirstVertex) {
  189. var view = di.getLastKnownViewWithFocus();
  190. var pos = di.getLastPosition();
  191. var e = new RCoordinateEvent(pos, view.getScene(), getRGraphicsView(view));
  192. this.pickCoordinate(e, false);
  193. }
  194. } else {
  195. EAction.prototype.keyPressEvent(event);
  196. }
  197. };
  198. DrawFmsLanes.prototype.showUiOptions = function(resume) {
  199. Draw.prototype.showUiOptions.call(this, resume);
  200. var optionsToolBar = EAction.getOptionsToolBar();
  201. var w = optionsToolBar.findChild("Restrict");
  202. var guiAction = RGuiAction.getByScriptFile("scripts/Snap/RestrictAngleLength/RestrictAngleLength.js");
  203. w.setDefaultAction(guiAction);
  204. this.updateButtonStates();
  205. };
  206. DrawFmsLanes.prototype.pickCoordinate = function(event, preview) {
  207. var point, op;
  208. var pointLeft;
  209. var di = this.getDocumentInterface();
  210. var document = this.getDocument();
  211. switch (this.state) {
  212. // set first vertex, create polyline entity:
  213. case DrawFmsLanes.State.SettingFirstVertex:
  214. if (!preview) {
  215. point = event.getModelPosition();
  216. var pl = new RPolylineEntity(document, new RPolylineData());
  217. pl.appendVertex(point);
  218. op = new RAddObjectOperation(pl, this.getToolTitle());
  219. this.applyOperation(op);
  220. di.setRelativeZero(point);
  221. if (!isNull(this.polylineEntity)) {
  222. this.setState(DrawFmsLanes.State.SettingNextVertex);
  223. }
  224. }
  225. break;
  226. // set next vertex:
  227. case DrawFmsLanes.State.SettingNextVertex:
  228. point = event.getModelPosition();
  229. // debugger;
  230. // number of existing vertices:
  231. var numberOfVertices;
  232. if (isNull(this.polylineEntity)) {
  233. numberOfVertices = 0;
  234. }
  235. else {
  236. numberOfVertices = this.polylineEntity.countVertices();
  237. }
  238. if (numberOfVertices>0) {
  239. var bulge;
  240. var vertex;
  241. var ribLeft;
  242. var ribRight;
  243. var appendPoint;
  244. if (this.prepend) {
  245. appendPoint = this.polylineEntity.getStartPoint();
  246. }
  247. else {
  248. appendPoint = this.polylineEntity.getEndPoint();
  249. }
  250. if (this.arcSegment===true) {
  251. var dir = 0.0;
  252. if (numberOfVertices>1) {
  253. if (this.prepend) {
  254. dir = this.polylineEntity.getDirection1() + Math.PI;
  255. }
  256. else {
  257. dir = this.polylineEntity.getDirection2() + Math.PI;
  258. }
  259. }
  260. this.segment = RArc.createTangential(
  261. appendPoint,
  262. point,
  263. dir,
  264. this.radius);
  265. // handle sweep here
  266. // change end angle
  267. // if sweep equals zero then do nothing
  268. if (this.sweep < 0.0 || this.sweep > 360.0) {
  269. // print error message
  270. this.sweep = 0.0;
  271. }
  272. if (this.sweep !== 0.0) {
  273. var curSweep = this.segment.getSweep();
  274. if (curSweep !== this.sweep) {
  275. var startAngle = RMath.rad2deg(this.segment.getStartAngle());
  276. var reversed = this.segment.isReversed();
  277. if (reversed) {
  278. var endAngle = startAngle - this.sweep;
  279. if (endAngle < 0.0) {
  280. endAngle = endAngle + 360.0;
  281. }
  282. } else {
  283. endAngle = startAngle + this.sweep;
  284. if (endAngle > 360.0) {
  285. endAngle = endAngle - 360.0;
  286. }
  287. }
  288. this.segment.setEndAngle(RMath.deg2rad(endAngle));
  289. }
  290. }
  291. vertex = this.segment.getEndPoint();
  292. if (this.prepend) {
  293. this.segment.reverse();
  294. }
  295. bulge = this.segment.getBulge();
  296. this.center = this.segment.getCenter();
  297. this.angle = this.segment.getEndAngle();
  298. }
  299. else {
  300. this.segment = new RLine(appendPoint, point);
  301. var angle = this.segment.getAngle();
  302. bulge = 0.0;
  303. vertex = point;
  304. this.center = undefined;
  305. this.angle = undefined;
  306. }
  307. // append or prepend vertex:
  308. if (!preview) {
  309. if (this.prepend) {
  310. this.polylineEntity.prependVertex(vertex, bulge);
  311. }
  312. else {
  313. this.polylineEntity.setBulgeAt(numberOfVertices-1, bulge);
  314. this.polylineEntity.appendVertex(vertex, 0.0);
  315. this.drawRibsBasedOnLine(this.segment.startPoint, vertex, false);
  316. }
  317. }
  318. }
  319. if (preview) {
  320. this.updatePreview();
  321. }
  322. else {
  323. op = this.getOperation(false);
  324. if (!isNull(op)) {
  325. this.applyOperation(op);
  326. di.setRelativeZero(vertex);
  327. this.uncheckArcSegment();
  328. }
  329. }
  330. break;
  331. }
  332. if (!preview) {
  333. this.updateButtonStates();
  334. }
  335. };
  336. DrawFmsLanes.prototype.getOperation = function(preview) {
  337. if (isNull(this.polylineEntity)) {
  338. return undefined;
  339. }
  340. // for preview, only add current segment:
  341. if (preview) {
  342. var entity;
  343. if (isLineShape(this.segment)) {
  344. entity = new RLineEntity(
  345. this.getDocument(),
  346. new RLineData(this.segment)
  347. );
  348. }
  349. else if (isArcShape(this.segment)) {
  350. entity = new RArcEntity(
  351. this.getDocument(),
  352. new RArcData(this.segment)
  353. );
  354. }
  355. if (!isEntity(entity)) {
  356. return undefined;
  357. }
  358. var e;
  359. if (isFunction(this.polylineEntity.data)) {
  360. e = this.polylineEntity.data();
  361. }
  362. else {
  363. e = this.polylineEntity;
  364. }
  365. entity.copyAttributesFrom(e);
  366. return new RAddObjectOperation(entity, false);
  367. }
  368. else {
  369. return new RAddObjectOperation(this.polylineEntity, this.getToolTitle(), true, false);
  370. }
  371. };
  372. /**
  373. * Updates the polyline in storage and makes sure that this.polylineEntity
  374. * points to new new clone of the original entity.
  375. */
  376. DrawFmsLanes.prototype.applyOperation = function(op) {
  377. this.polylineEntity = undefined;
  378. var di = this.getDocumentInterface();
  379. var document = this.getDocument();
  380. var transaction = di.applyOperation(op);
  381. // find out ID of polyline, that was added to the document:
  382. var ids = transaction.getAffectedObjects();
  383. for (var i=0; i<ids.length; ++i) {
  384. var id = ids[i];
  385. var entity = document.queryEntity(id);
  386. if (isPolylineEntity(entity)) {
  387. this.polylineEntity = entity;
  388. break;
  389. }
  390. }
  391. };
  392. /**
  393. * Called when user clicks the 'Close' button to close the polyline.
  394. */
  395. DrawFmsLanes.prototype.slotClose = function() {
  396. if (isNull(this.polylineEntity)) {
  397. return;
  398. }
  399. if (this.polylineEntity.countVertices() >= 3) {
  400. var di = this.getDocumentInterface();
  401. di.setRelativeZero(this.polylineEntity.getVertexAt(0));
  402. this.polylineEntity.setClosed(true);
  403. var op = this.getOperation(false);
  404. if (!isNull(op)) {
  405. this.applyOperation(op);
  406. }
  407. this.setState(DrawFmsLanes.State.SettingFirstVertex);
  408. this.polylineEntity = undefined;
  409. }
  410. this.updateButtonStates();
  411. };
  412. /**
  413. * Called when user clicks the 'Undo' button to remove the last added vertex.
  414. */
  415. DrawFmsLanes.prototype.slotUndo = function() {
  416. if (isNull(this.polylineEntity)) {
  417. return;
  418. }
  419. if (this.polylineEntity.countVertices() >= 2) {
  420. var di = this.getDocumentInterface();
  421. var bulge = this.polylineEntity.getBulgeAt(this.polylineEntity.countVertices() - 1);
  422. var vertex = this.polylineEntity.getVertexAt(this.polylineEntity.countVertices() - 1);
  423. this.polylineEntity.removeLastVertex();
  424. di.setRelativeZero(this.polylineEntity.getVertexAt(this.polylineEntity.countVertices() - 1));
  425. di.clearPreview();
  426. var op = this.getOperation(false);
  427. if (!isNull(op)) {
  428. this.applyOperation(op);
  429. // add last vertex and bulge to redoList
  430. this.redoList.push(bulge);
  431. this.redoList.push(vertex);
  432. }
  433. this.simulateMouseMoveEvent();
  434. }
  435. this.updateButtonStates();
  436. };
  437. /**
  438. * Called when user clicks the 'Redo' button to redo the last vertex.
  439. */
  440. DrawFmsLanes.prototype.slotRedo = function() {
  441. if (isNull(this.polylineEntity)) {
  442. return;
  443. }
  444. if (this.redoList.length >= 2) {
  445. var di = this.getDocumentInterface();
  446. // redo last vertex and bulge
  447. var vertex = this.redoList.pop();
  448. var bulge = this.redoList.pop();
  449. this.polylineEntity.appendVertex(vertex, bulge);
  450. di.clearPreview();
  451. var op = this.getOperation(false);
  452. if (!isNull(op)) {
  453. this.applyOperation(op);
  454. }
  455. di.setRelativeZero(vertex);
  456. this.simulateMouseMoveEvent();
  457. }
  458. this.updateButtonStates();
  459. };
  460. /**
  461. * Called when user toggles 'Arc segment' check box to indicate if the next
  462. * segment is a line or an arc segment.
  463. */
  464. DrawFmsLanes.prototype.slotArcSegmentChanged = function(value) {
  465. this.arcSegment = value;
  466. };
  467. /**
  468. * Called when user enters a radius for the next arc segment.
  469. */
  470. DrawFmsLanes.prototype.slotRadiusChanged = function(value) {
  471. this.radius = value;
  472. };
  473. /**
  474. * Called when user enters a sweep for the next arc segment.
  475. */
  476. DrawFmsLanes.prototype.slotSweepChanged = function(value) {
  477. this.sweep = value;
  478. };
  479. /**
  480. * Called internally to automatically uncheck the 'Arc segment' check box.
  481. */
  482. DrawFmsLanes.prototype.uncheckArcSegment = function() {
  483. var w = objectFromPath("MainWindow::Options::ArcSegment");
  484. w.checked = false;
  485. };
  486. /**
  487. * Updates the state (enabled / disabled) of the undo and the close buttons
  488. * depending on the current progress.
  489. */
  490. DrawFmsLanes.prototype.updateButtonStates = function() {
  491. var w;
  492. if (this.state === DrawFmsLanes.State.SettingFirstVertex) {
  493. this.uncheckArcSegment();
  494. }
  495. var optionsToolBar = EAction.getOptionsToolBar();
  496. w = optionsToolBar.findChild("Close");
  497. if (!isNull(this.polylineEntity)) {
  498. w.enabled = (this.polylineEntity.countVertices() >= 3) ? true : false;
  499. }
  500. else {
  501. w.enabled = false;
  502. }
  503. w = optionsToolBar.findChild("Undo");
  504. if (!isNull(this.polylineEntity)) {
  505. w.enabled = (this.polylineEntity.countVertices() >= 2) ? true : false;
  506. }
  507. else {
  508. w.enabled = false;
  509. }
  510. w = optionsToolBar.findChild("Redo");
  511. w.enabled = (this.redoList.length >= 2) ? true : false;
  512. };
  513. DrawFmsLanes.prototype.getAuxPreview = function() {
  514. var ret = [];
  515. if (this.state === DrawFmsLanes.State.SettingNextVertex) {
  516. if (!isNull(this.center) && !isNull(this.angle)) {
  517. var v = RVector.createPolar(this.radius, this.angle);
  518. ret.push(new RLine(this.center, this.center.operator_add(v)));
  519. }
  520. }
  521. return ret;
  522. };
  523. /**
  524. * Allows commands to be entered in command line
  525. * Using the 'startsWith' function allows the user to enter only as many characters
  526. * as needed to distinguish between commands
  527. * In this case only the first character is needed. (But entering 'c', 'cl', 'clo', 'clos'
  528. * or 'close' would all invoke the close command. Similarly with undo and redo)
  529. */
  530. DrawFmsLanes.prototype.commandEvent = function(event) {
  531. var str;
  532. var cmd = event.getCommand();
  533. cmd = cmd.toLowerCase();
  534. str = qsTr("close");
  535. if (str.startsWith(cmd)) {
  536. this.slotClose();
  537. event.accept();
  538. return;
  539. }
  540. str = qsTr("undo");
  541. if (str.startsWith(cmd)) {
  542. this.slotUndo();
  543. event.accept();
  544. return;
  545. }
  546. str = qsTr("redo");
  547. if (str.startsWith(cmd)) {
  548. this.slotRedo();
  549. event.accept();
  550. return;
  551. }
  552. str = qsTr("arc");
  553. if (str.startsWith(cmd)) {
  554. var ob = objectFromPath("MainWindow::Options::ArcSegment");
  555. ob.checked = !ob.checked
  556. this.slotArcSegmentChanged(ob.checked);
  557. event.accept();
  558. return;
  559. }
  560. };