ConvertUnit.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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("scripts/EAction.js");
  20. /**
  21. * \brief This tool converts a drawing from the current drawing unit to another unit.
  22. * The coordinates in the drawing are scaled accordingly.
  23. */
  24. function ConvertUnit(guiAction) {
  25. EAction.call(this, guiAction);
  26. this.fromUnit = undefined;
  27. this.toUnit = undefined;
  28. this.setUiOptions("ConvertUnit.ui");
  29. }
  30. ConvertUnit.prototype = new EAction();
  31. ConvertUnit.includeBasePath = includeBasePath;
  32. ConvertUnit.prototype.beginEvent = function() {
  33. EAction.prototype.beginEvent.call(this);
  34. var di = this.getDocumentInterface();
  35. var doc = di.getDocument();
  36. var optionsToolBar = EAction.getOptionsToolBar();
  37. // fill combo boxes with available units
  38. var fromCombo = optionsToolBar.findChild("From");
  39. ConvertUnit.initUnitCombo(fromCombo);
  40. var toCombo = optionsToolBar.findChild("To");
  41. ConvertUnit.initUnitCombo(toCombo);
  42. this.fromUnit = doc.getUnit();
  43. fromCombo.currentIndex = this.fromUnit;
  44. this.toUnit = RS.None;
  45. toCombo.currentIndex = this.toUnit;
  46. };
  47. ConvertUnit.prototype.doConvert = function() {
  48. var ret = ConvertUnit.convert(this.getDocumentInterface(), this.fromUnit, this.toUnit);
  49. if (!isNull(ret)) {
  50. if (ret[0]===0) {
  51. EAction.handleUserMessage(ret[1]);
  52. }
  53. if (ret[0]===1) {
  54. EAction.handleUserWarning(ret[1]);
  55. }
  56. }
  57. // The focus ends up in ToolMatrix filter box, for unknown reason
  58. // Change it back to drawing
  59. var mdiChild = EAction.getMdiChild();
  60. mdiChild.setFocus();
  61. this.terminate();
  62. };
  63. ConvertUnit.convert = function(di, fromUnit, toUnit) {
  64. if (isNull(di)) {
  65. return;
  66. }
  67. var doc = di.getDocument();
  68. //var fromUnit = doc.getUnit();
  69. if (fromUnit===toUnit) {
  70. return [1, qsTr("Nothing to be done.")];
  71. }
  72. if (fromUnit === RS.None || toUnit === RS.None) {
  73. return [1, qsTr("Unit \"%1\" selected. Nothing to be done").arg(RUnit.unitToName(RS.None))];
  74. }
  75. var factor = RUnit.convert(1.0, fromUnit, toUnit);
  76. doc.startTransactionGroup();
  77. var dimStyle = doc.queryDimStyle();
  78. var docVars = doc.queryDocumentVariables();
  79. // make sure we don't end up with a metric document with imperial dimension format:
  80. if (doc.getLinearFormat()===RS.Engineering || doc.getLinearFormat()===RS.ArchitecturalStacked || doc.getLinearFormat()===RS.Architectural) {
  81. if (!RUnit.isMetric(doc.getUnit()) && RUnit.isMetric(toUnit)) {
  82. dimStyle.setInt(RS.DIMLUNIT, RS.Decimal);
  83. }
  84. }
  85. docVars.setUnit(toUnit);
  86. // scale dimension sizes:
  87. var dimscale = dimStyle.getDouble(RS.DIMSCALE);
  88. dimStyle.setDouble(RS.DIMSCALE, dimscale*factor);
  89. var op = new RAddObjectsOperation();
  90. op.setTransactionGroup(doc.getTransactionGroup());
  91. op.addObject(docVars);
  92. op.addObject(dimStyle);
  93. di.applyOperation(op);
  94. op = new RAddObjectsOperation();
  95. op.setTransactionGroup(doc.getTransactionGroup());
  96. op.setAllowAll(true);
  97. var ids, i, id;
  98. // all entities on all blocks:
  99. ids = doc.queryAllEntities(false, true);
  100. for (i=0; i<ids.length; i++) {
  101. id = ids[i];
  102. var entity = doc.queryEntity(id);
  103. if (isNull(entity)) {
  104. continue;
  105. }
  106. var blockId = entity.getBlockId();
  107. var block = doc.queryBlockDirect(blockId);
  108. if (!isNull(block) && block.isPixelUnit()) {
  109. // don't touch entities in pixel unit blocks:
  110. continue;
  111. }
  112. // don't scale block references as block content is scaled instead:
  113. if (isBlockReferenceEntity(entity)) {
  114. var p = entity.getPosition();
  115. entity.setPosition(p.operator_multiply(factor));
  116. var cs = entity.getColumnSpacing();
  117. entity.setColumnSpacing(cs*factor);
  118. var rs = entity.getRowSpacing();
  119. entity.setRowSpacing(rs*factor);
  120. } else if (isViewportEntity(entity)) {
  121. var s = entity.getScale();
  122. entity.scale(factor);
  123. entity.setScale(s);
  124. var vc = entity.getViewCenter();
  125. vc.scale(factor);
  126. entity.setViewCenter(vc);
  127. var tc = entity.getViewTarget();
  128. tc.scale(factor);
  129. entity.setViewTarget(tc);
  130. } else if (isDimensionEntity(entity)) {
  131. entity.scale(factor);
  132. var s = entity.getDimscale();
  133. if (entity.hasOverride(RS.DIMSCALE)) {
  134. // dimension has individual scale factor (property, override):
  135. entity.setDimscale(s*factor);
  136. }
  137. } else {
  138. entity.scale(factor);
  139. }
  140. op.addObject(entity, false);
  141. }
  142. // adjust views:
  143. ids = doc.queryAllViews();
  144. for (i=0; i<ids.length; i++) {
  145. id = ids[i];
  146. var v = doc.queryView(id);
  147. v.scale(factor);
  148. op.addObject(v, false);
  149. }
  150. // adjust view:
  151. var view = di.getLastKnownViewWithFocus();
  152. if (!isNull(view)) {
  153. var box = view.getBox();
  154. var c1 = box.getCorner1();
  155. var c2 = box.getCorner2();
  156. c1.scale(factor);
  157. c2.scale(factor);
  158. view.zoomTo(new RBox(c1, c2));
  159. }
  160. // convert all print offsets in all blocks:
  161. // convert all stored block zoom factors / offsets:
  162. var views = EAction.getGraphicsViews(di);
  163. var blockIds = doc.queryAllBlocks();
  164. for (var k=0; k<blockIds.length; k++) {
  165. var blockId = blockIds[k];
  166. var block = doc.queryBlock(blockId);
  167. var offsetX = block.getCustomProperty("QCAD", "PageSettings/OffsetX", undefined);
  168. var offsetY = block.getCustomProperty("QCAD", "PageSettings/OffsetY", undefined);
  169. if (!isNull(offsetX)) {
  170. block.setCustomProperty("QCAD", "PageSettings/OffsetX", offsetX*factor);
  171. block.setCustomProperty("QCAD", "PageSettings/OffsetY", offsetY*factor);
  172. }
  173. op.addObject(block);
  174. for (i=0; i<views.length; i++) {
  175. view = views[i];
  176. if (!isFunction(view.property)) {
  177. continue;
  178. }
  179. var blockZoom = view.property("blockZoom");
  180. if (isNull(blockZoom)) {
  181. continue;
  182. }
  183. blockZoom[blockId] = [view.getFactor() * factor, view.getOffset().operator_multiply(factor)];
  184. view.setProperty("blockZoom", blockZoom);
  185. }
  186. }
  187. di.applyOperation(op);
  188. //var offset = Print.getOffset(doc);
  189. //offset.scale(factor);
  190. //Print.setOffset(di, offset);
  191. doc.rebuildSpatialIndex();
  192. return [0, qsTr("Converted drawing from %1 to %2").arg(RUnit.unitToName(fromUnit)).arg(RUnit.unitToName(toUnit)) ];
  193. };
  194. ConvertUnit.initUnitCombo = function(unitCombo) {
  195. // available units in DXF/DWG
  196. // int values correspond to unit codes from DXF spec
  197. unitCombo.clear();
  198. for (var u=RS.None; u<=RS.MaxUnit; u++) {
  199. unitCombo.addItem(RUnit.unitToName(u), u);
  200. }
  201. };
  202. ConvertUnit.prototype.slotFromChanged = function(value) {
  203. this.fromUnit = value;
  204. };
  205. ConvertUnit.prototype.slotToChanged = function(value) {
  206. this.toUnit = value;
  207. };
  208. ConvertUnit.prototype.slotConvert = function() {
  209. this.doConvert();
  210. };