Transform.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /**
  2. * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
  3. *
  4. * This file is part of the QCAD project.
  5. *
  6. * QCAD is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * QCAD is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with QCAD.
  18. */
  19. include("Modify.js");
  20. /**
  21. * \class Transform
  22. * \brief Base class for all transformation tools (move, copy, rotate, mirror, ...).
  23. */
  24. function Transform(guiAction) {
  25. Modify.call(this, guiAction);
  26. this.useCurrentAttributes = false;
  27. this.copies = 0;
  28. this.copy = undefined;
  29. this.useDialog = true;
  30. }
  31. Transform.prototype = new Modify();
  32. Transform.includeBasePath = includeBasePath;
  33. Transform.prototype.finishEvent = function() {
  34. this.clearCache();
  35. Modify.prototype.finishEvent.call(this);
  36. };
  37. Transform.prototype.verifySelection = function() {
  38. var di = this.getDocumentInterface();
  39. if (!di.hasSelection()) {
  40. EAction.handleUserWarning(qsTr("This tool requires a selection"));
  41. this.terminate();
  42. return false;
  43. }
  44. return true;
  45. };
  46. /**
  47. * Implementation of getOperation for tools that operate on a selection and
  48. * do something with every entity in the selection (e.g. move, rotate, ...).
  49. * The callback function 'this.transform(entity, copy number)' is called for
  50. * every selected entity.
  51. */
  52. Transform.prototype.getOperation = function(preview, selectResult, cache) {
  53. if (isNull(this.copies)) {
  54. return undefined;
  55. }
  56. if (isNull(selectResult)) {
  57. selectResult = true;
  58. }
  59. if (isNull(cache)) {
  60. cache = false;
  61. }
  62. var op, di, ids;
  63. var doc = this.getDocument();
  64. if (cache) {
  65. // return cached document as paste operation:
  66. if (!isNull(this.diTrans) && preview) {
  67. op = new RPasteOperation(this.diTrans.getDocument());
  68. op.setOffset(this.targetPoint);
  69. return op;
  70. }
  71. this.clearCache();
  72. var docTrans = new RDocument(new RMemoryStorage(), new RSpatialIndexSimple());
  73. docTrans.copyVariablesFrom(doc);
  74. this.diTrans = new RDocumentInterface(docTrans);
  75. this.diTrans.setNotifyListeners(false);
  76. // copy selection to cache document:
  77. var copyOp = new RCopyOperation(new RVector(0,0), doc);
  78. copyOp.setClear(false);
  79. this.diTrans.applyOperation(copyOp);
  80. di = this.diTrans;
  81. ids = this.diTrans.getDocument().queryAllEntities();
  82. }
  83. else {
  84. di = this.getDocumentInterface();
  85. ids = di.getDocument().querySelectedEntities();
  86. }
  87. var document = di.getDocument();
  88. var i, k, id, entity, entityP;
  89. var copies = this.getCopies();
  90. var num = copies;
  91. if (num===0) {
  92. num=1;
  93. }
  94. op = new RAddObjectsOperation();
  95. op.setText(this.getToolTitle());
  96. for (k=1; k<=num; k++) {
  97. for (i=0; i<ids.length; i++) {
  98. if (!cache && preview && op.getPreviewCounter()>RSettings.getPreviewEntities()) {
  99. break;
  100. }
  101. // if (i%1000===0) {
  102. // qDebug("progress: %1%".arg(i/ids.length*100));
  103. // }
  104. id = ids[i];
  105. entityP = document.queryEntity(id);
  106. if (isNull(entityP)) {
  107. continue;
  108. }
  109. //qDebug("%1 / %2".arg(i).arg(ids.length-1));
  110. // entity is valid as long as entityP is valid:
  111. //entity = entityP.data();
  112. entity = entityP.clone();
  113. // copy: assign new IDs
  114. if (copies>0) {
  115. if (!preview && !selectResult) {
  116. entity.setSelected(false);
  117. }
  118. }
  119. var f = RAddObjectsOperation.NoFlags;
  120. if (!this.useCurrentAttributes) {
  121. f = RAddObjectsOperation.UseAttributes | RAddObjectsOperation.GeometryOnly;
  122. }
  123. if (cache) {
  124. op.deleteObject(entity);
  125. this.transform(entity, k, op, preview, f | RAddObjectsOperation.ForceNew);
  126. }
  127. else {
  128. if (copies>0) {
  129. f = f | RAddObjectsOperation.ForceNew;
  130. }
  131. this.transform(entity, k, op, preview, f);
  132. }
  133. }
  134. op.endCycle();
  135. }
  136. if (cache) {
  137. di.applyOperation(op);
  138. }
  139. // deselect original entities, all copies are selected:
  140. if (!preview && selectResult) {
  141. di.deselectEntities(ids);
  142. }
  143. if (cache) {
  144. op = new RPasteOperation(this.diTrans.getDocument());
  145. op.setOffset(this.targetPoint);
  146. }
  147. return op;
  148. };
  149. Transform.prototype.clearCache = function() {
  150. // clear cache:
  151. if (!isNull(this.diTrans)) {
  152. destr(this.diTrans);
  153. }
  154. this.diTrans = undefined;
  155. //Modify.prototype.updatePreview.call(this);
  156. };
  157. Transform.prototype.slotCopyChanged = function(checked) {
  158. this.copy = checked;
  159. var optionsToolBar = EAction.getOptionsToolBar();
  160. var w = optionsToolBar.findChild("LabelNumberOfCopies");
  161. if (!isNull(w)) {
  162. w.enabled = checked;
  163. }
  164. w = optionsToolBar.findChild("NumberOfCopies");
  165. if (!isNull(w)) {
  166. w.enabled = checked;
  167. }
  168. };
  169. Transform.prototype.slotNumberOfCopiesChanged = function(v) {
  170. this.copies = v;
  171. };
  172. Transform.prototype.slotUseCurrentAttributesChanged = function(checked) {
  173. this.useCurrentAttributes = checked;
  174. };
  175. Transform.prototype.getCopies = function() {
  176. if (this.copy===false) {
  177. return 0;
  178. }
  179. return this.copies;
  180. };