Print.js 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619
  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/File/File.js");
  20. include("scripts/sprintf.js");
  21. if (RSettings.isGuiEnabled() && typeof(PrintPreview)=="undefined") {
  22. include("scripts/File/PrintPreview/PrintPreview.js");
  23. }
  24. if (typeof(PageSettings)=="undefined") {
  25. include("scripts/Edit/DrawingPreferences/PageSettings/PageSettings.js");
  26. }
  27. /**
  28. * Used to print the given document with the settings stored inside the document
  29. * or the default settings.
  30. */
  31. function Print(guiAction, document, view) {
  32. File.call(this, guiAction);
  33. this.document = document;
  34. this.view = view;
  35. if (!isNull(view)) {
  36. this.scene = view.getScene();
  37. }
  38. }
  39. Print.prototype = new File();
  40. Print.defaultPrinter = undefined;
  41. Print.getDefaultPrinter = function() {
  42. if (isNull(Print.defaultPrinter)) {
  43. Print.defaultPrinter = new QPrinter();
  44. }
  45. return Print.defaultPrinter;
  46. };
  47. Print.setProxy = function(p) {
  48. Print.proxy = p;
  49. };
  50. Print.prototype.beginEvent = function() {
  51. File.prototype.beginEvent.call(this);
  52. // switch to print preview:
  53. if (!PrintPreview.isRunning()) {
  54. var guiAction = RGuiAction.getByScriptFile("scripts/File/PrintPreview/PrintPreview.js");
  55. var action = new PrintPreview(guiAction);
  56. action.initialAction = "Print";
  57. var di = EAction.getDocumentInterface();
  58. di.setCurrentAction(action);
  59. }
  60. else {
  61. var pp = PrintPreview.getInstance();
  62. pp.slotPrint();
  63. }
  64. this.terminate();
  65. };
  66. Print.prototype.createPrinter = function(pdfFile, printerName, pdfVersion) {
  67. var printer = undefined;
  68. // print directly to given printer or default printer:
  69. if (!isNull(printerName)) {
  70. if (printerName==="") {
  71. printerName = getDefaultPrinterName();
  72. }
  73. printer = createPrinter(printerName);
  74. if (isNull(printer)) {
  75. qWarning("invalid printer name: ", printerName);
  76. printer = undefined;
  77. }
  78. }
  79. if (isNull(pdfVersion)) {
  80. pdfVersion = "1.4";
  81. }
  82. if (isNull(printer)) {
  83. // create printer on the fly:
  84. printer = new QPrinter(QPrinter.HighResolution);
  85. if (isString(pdfFile)) {
  86. printer.setOutputFormat(QPrinter.PdfFormat);
  87. if (pdfVersion.toLowerCase()==="a-1b" || pdfVersion.toLowerCase()==="a1b" || pdfVersion.toLowerCase()==="a") {
  88. printer.setPdfVersion(1 /*QPagedPaintDevice.PdfVersion_A1b*/);
  89. }
  90. else if (pdfVersion.toLowerCase()==="1.6") {
  91. printer.setPdfVersion(2 /*QPagedPaintDevice.PdfVersion_1_6*/);
  92. }
  93. else {
  94. printer.setPdfVersion(0 /*QPagedPaintDevice.PdfVersion_1_4*/);
  95. }
  96. printer.setOutputFileName(pdfFile);
  97. }
  98. }
  99. // always use custom page size to work around Qt page size limitations:
  100. var paperSizeMM = Print.getPaperSizeMM(this.document);
  101. if (RSettings.getQtVersion() >= 0x060000) {
  102. printer.setPageSize(new QPageSize(paperSizeMM, QPageSize.Millimeter));
  103. printer.setFullPage(true);
  104. printer.setPageOrientation(Print.getPageOrientationEnum(this.document));
  105. }
  106. else {
  107. printer.setPaperSize(paperSizeMM, QPrinter.Millimeter);
  108. printer.setFullPage(true);
  109. printer.setOrientation(Print.getPageOrientationEnum(this.document));
  110. }
  111. var colorMode = Print.getColorMode(this.document);
  112. if (colorMode == RGraphicsView.FullColor) {
  113. printer.setColorMode(QPrinter.Color);
  114. } else {
  115. printer.setColorMode(QPrinter.GrayScale);
  116. }
  117. // show printer dialog if we are not printing to a PDF file
  118. // or running as command line tool:
  119. var appWin = EAction.getMainWindow();
  120. if (!isString(pdfFile) && !isNull(appWin) && isNull(printerName)) {
  121. Print.cancel = false;
  122. Print.printDialog = new QPrintDialog(printer, appWin);
  123. if (RSettings.isQt(5)) {
  124. Print.printDialog.rejected.connect(function() { Print.cancel = true; });
  125. Print.printDialog.exec();
  126. destr(Print.printDialog);
  127. EAction.activateMainWindow();
  128. }
  129. else {
  130. // Mac, Win: exec() never returns without destroying the dialog through these signals:
  131. // Linux: make sure that cancel is caught correctly:
  132. Print.printDialog["accepted(QPrinter*)"].connect(
  133. function() {
  134. Print.cancel = false;
  135. Print.printDialog.close();
  136. if (RS.getSystemId()==="osx") {
  137. destr(Print.printDialog);
  138. EAction.activateMainWindow();
  139. }
  140. });
  141. Print.printDialog.rejected.connect(
  142. function() {
  143. Print.cancel = true;
  144. Print.printDialog.close();
  145. if (RS.getSystemId()==="osx") {
  146. destr(Print.printDialog);
  147. EAction.activateMainWindow();
  148. }
  149. });
  150. // Windows:
  151. if (RS.getSystemId()==="win") {
  152. // slot 'dummy' is never called:
  153. Print.printDialog.open(this, "dummy");
  154. }
  155. // macOS, Linux, various other unices:
  156. else {
  157. Print.printDialog.exec();
  158. }
  159. }
  160. if (Print.cancel===true) {
  161. destr(printer);
  162. return undefined;
  163. }
  164. }
  165. return printer;
  166. };
  167. /**
  168. * Prints the given document.
  169. *
  170. * \param pdfFile Name of PDF file.
  171. * \param printerName Name of printer to print to or "" for default printer.
  172. * \param printer QPrinter object or undefined to create on the fly.
  173. */
  174. Print.prototype.print = function(pdfFile, printerName, pdfVersion) {
  175. // make sure selected entities are not printed with selection color:
  176. var di = EAction.getDocumentInterface();
  177. if (!isNull(di)) {
  178. di.deselectAll();
  179. }
  180. var printer = this.createPrinter(pdfFile, printerName, pdfVersion);
  181. if (isNull(printer)) {
  182. qWarning("Print.prototype.print: no printer created");
  183. return false;
  184. }
  185. var painter = new QPainter();
  186. if (!painter.begin(printer)) {
  187. destr(printer);
  188. return false;
  189. }
  190. //for (var i=1; i<=printer.copyCount(); i++) {
  191. //if (i>1) {
  192. // printer.newPage();
  193. //}
  194. this.printCurrentBlock(printer, painter);
  195. //}
  196. painter.end();
  197. destr(printer);
  198. return true;
  199. };
  200. /**
  201. * Prints / exports the given block on a single or on multiple pages (if columns/rows are > 1).
  202. */
  203. Print.prototype.printCurrentBlock = function(printer, painter) {
  204. // set background color of view to match printing preference:
  205. var bgColor = this.view.getBackgroundColor();
  206. var scale = Print.getScale(this.document);
  207. this.view.setBackgroundColor(Print.getBackgroundColor(this.document));
  208. this.view.setPrinting(true);
  209. // 20191007: avoid invisible lines in prints and PDF output:
  210. var minLineweightSet = false;
  211. if (this.view.getMinimumLineweight()<RS.PointTolerance) {
  212. // no minimum lineweight defined: force minimum lineweight of 0.01mm for printing:
  213. this.view.setMinimumLineweight(RUnit.convert(0.01/scale, RS.Millimeter, this.document.getUnit()));
  214. minLineweightSet = true;
  215. }
  216. var draftMode = false;
  217. var screenBasedLinetypes = false;
  218. if (!isNull(this.scene)) {
  219. draftMode = this.scene.getDraftMode();
  220. screenBasedLinetypes = this.scene.getScreenBasedLinetypes();
  221. this.scene.setDraftMode(false);
  222. this.scene.setScreenBasedLinetypes(false);
  223. this.scene.regenerate();
  224. }
  225. // scale factor from drawing unit to mm:
  226. var unitScale = Print.getUnitScale(this.document);
  227. var widthInMM = printer.paperRect(QPrinter.Millimeter).width();
  228. var heightInMM = printer.paperRect(QPrinter.Millimeter).height();
  229. // factor from mm to printer unit:
  230. var paperRect;
  231. if (RSettings.getQtVersion() >= 0x060000) {
  232. paperRect = printer.pageLayout().fullRectPixels(printer.resolution());
  233. }
  234. else {
  235. paperRect = printer.paperRect();
  236. }
  237. var printerFactor = new RVector(
  238. paperRect.width() / widthInMM,
  239. paperRect.height() / heightInMM
  240. );
  241. // printer calibration:
  242. var printerName = printer.printerName();
  243. if (printerName.length===0) {
  244. if (printer.outputFileName().length!==0) {
  245. // PDF output:
  246. printerName = "PDF";
  247. }
  248. }
  249. printerFactor.x *= RSettings.getDoubleValue(printerName + "/FactorX", 1.0);
  250. printerFactor.y *= RSettings.getDoubleValue(printerName + "/FactorY", 1.0);
  251. this.view.setPrintPointSize(new RVector(1.0/printerFactor.x, 1.0/printerFactor.y));
  252. var offset = Print.getOffset(this.document);
  253. var previousPixelSizeHint = this.scene.getPixelSizeHint();
  254. var widthInDrawingUnits = RUnit.convert(widthInMM, RS.Millimeter, this.document.getUnit());
  255. if (paperRect.width()>0) {
  256. var pixelSizeHint = 1.0/paperRect.width()*widthInDrawingUnits;
  257. pixelSizeHint = pixelSizeHint / scale;
  258. this.scene.setPixelSizeHint(pixelSizeHint);
  259. }
  260. // iterate through all pages and print the appropriate area
  261. var firstPage = true;
  262. var fromPage = printer.fromPage();
  263. var toPage = printer.toPage();
  264. var pages = Print.getPages(this.document);
  265. for (var i = 0; i < pages.length; ++i) {
  266. if (fromPage!==0) {
  267. if (i+1<fromPage) {
  268. continue;
  269. }
  270. }
  271. if (toPage!==0) {
  272. if (i+1>toPage) {
  273. continue;
  274. }
  275. }
  276. // if this is not the first page, add new page:
  277. if (!firstPage) {
  278. printer.newPage();
  279. }
  280. else {
  281. firstPage = false;
  282. }
  283. var c = Print.getBackgroundColor(this.document);
  284. var qclr = new QColor(c.red(),c.green(),c.blue());
  285. if (!qclr.equals(new QColor(Qt.white))) {
  286. painter.setWorldTransform(new QTransform());
  287. painter.setBackground(new QBrush(qclr, Qt.SolidPattern));
  288. painter.eraseRect(paperRect);
  289. }
  290. // paper size in mm:
  291. var paperBorder = Print.getPaperBorder(this.document, pages[i]);
  292. var paperBorderTransformed = Print.getTransformed(this.document, paperBorder);
  293. var pageBorderTransformed = Print.getTransformed(this.document, pages[i]);
  294. // scale paper border from mm to unit measures:
  295. // paperBorderTransformed.setRect(paperBorderTransformed.x()/unitScale,
  296. // paperBorderTransformed.y()/unitScale,
  297. // paperBorderTransformed.width()/unitScale,
  298. // paperBorderTransformed.height()/unitScale);
  299. // pageBorderTransformed.setRect(pageBorderTransformed.x()/unitScale,
  300. // pageBorderTransformed.y()/unitScale,
  301. // pageBorderTransformed.width()/unitScale,
  302. // pageBorderTransformed.height()/unitScale);
  303. // set up transform (TODO: move to function):
  304. var transform = new QTransform();
  305. // move zero to bottom left corner, set up X/Y axis:
  306. transform.scale(1, -1);
  307. // scale to printer units:
  308. transform.scale(printerFactor.x, printerFactor.y);
  309. transform.translate(-paperBorder.x(), -paperBorder.y()-paperBorder.height());
  310. // apply user defined scale:
  311. transform.scale(scale, scale);
  312. // scale drawing unit to mm:
  313. transform.scale(unitScale, unitScale);
  314. painter.setWorldTransform(transform);
  315. // apply offset here to avoid huge values in transformation matrix:
  316. this.view.setPaintOffset(offset.getNegated());
  317. this.printPage(painter, paperBorderTransformed);
  318. this.view.setPaintOffset(new RVector(0,0));
  319. if (Print.getPrintCropMarks(this.document)) {
  320. Print.drawCropMarks(
  321. this.document,
  322. painter,
  323. pageBorderTransformed,
  324. true
  325. );
  326. }
  327. if (Print.getEnablePageTags(this.document)) {
  328. Print.drawPageTags(this.document, painter, i, pageBorderTransformed, true, printerFactor);
  329. }
  330. if (Print.hasFooter(this.document)) {
  331. Print.drawPageFooter(this.document, painter, i, pageBorderTransformed, true, printerFactor);
  332. }
  333. }
  334. this.scene.setPixelSizeHint(previousPixelSizeHint);
  335. this.scene.setScreenBasedLinetypes(screenBasedLinetypes);
  336. this.scene.setDraftMode(draftMode);
  337. this.scene.regenerate();
  338. this.view.setBackgroundColor(bgColor);
  339. this.view.setPrinting(false);
  340. if (minLineweightSet) {
  341. this.view.setMinimumLineweight(0.0);
  342. }
  343. //return true;
  344. };
  345. /**
  346. * Prints a single page to the given printer. The area to print is given
  347. * as coordinates x/y and width/height.
  348. *
  349. * \param rect QRectF object that represents the page border.
  350. */
  351. Print.prototype.printPage = function(painter, rect) {
  352. this.view.paintEntities(
  353. painter,
  354. new RBox(
  355. new RVector(rect.x(), rect.y()),
  356. new RVector(rect.x()+rect.width(), rect.y()+rect.height())
  357. )
  358. );
  359. this.view.paintOverlay(painter);
  360. };
  361. /**
  362. * \return Maximum extents of paper
  363. */
  364. Print.getPaperBox = function(document) {
  365. //var document = this.getDocument();
  366. var pages = Print.getPages(document);
  367. var box = new RBox();
  368. for (var i=0; i<pages.length; ++i) {
  369. var paperBorder = Print.getPaperBorder(document, pages[i]);
  370. var paperBorderTransformed = Print.getTransformed(document, paperBorder);
  371. var paperBox = new RBox(paperBorderTransformed);
  372. if (!box.isValid()) {
  373. box = paperBox;
  374. }
  375. else {
  376. box.growToIncludeBox(paperBox);
  377. }
  378. }
  379. return box;
  380. };
  381. /**
  382. * Auto fit drawing to page size.
  383. * \param ori: True: auto set page orientation
  384. */
  385. Print.autoFitDrawing = function(di, ori) {
  386. if (isNull(ori)) {
  387. ori = false;
  388. }
  389. var document = di.getDocument();
  390. // drawing bounding box in drawing units:
  391. var bBox = document.getBoundingBox(true, true);
  392. //qDebug("bb: ", bBox);
  393. if (ori) {
  394. if (bBox.getWidth()>bBox.getHeight()) {
  395. Print.setPageOrientationEnum(di, RS.Landscape);
  396. }
  397. else {
  398. Print.setPageOrientationEnum(di, RS.Portrait);
  399. }
  400. }
  401. Print.autoFitBox(di, bBox);
  402. Print.centerBox(di, bBox);
  403. };
  404. /**
  405. * Auto fit given box to page size.
  406. */
  407. Print.autoFitBox = function(di, bBox) {
  408. var document = di.getDocument();
  409. var paperUnit = Print.getPaperUnit(document);
  410. // paper bounding box in drawing units, multiplied by scale:
  411. var pBox = Print.getPaperBox(document);
  412. var scale = Print.getScale(document);
  413. // margins in paper unit:
  414. var glueWidth = Print.getGlueMarginLeft(document) + Print.getGlueMarginRight(document);
  415. var glueHeight = Print.getGlueMarginTop(document) + Print.getGlueMarginBottom(document);
  416. glueWidth = RUnit.convert(glueWidth, paperUnit, document.getUnit());
  417. glueHeight = RUnit.convert(glueHeight, paperUnit, document.getUnit());
  418. var wf = undefined;
  419. var hf = undefined;
  420. if (bBox.getWidth()>1.0e-6) {
  421. wf = (pBox.getWidth() * scale - glueWidth) / bBox.getWidth();
  422. }
  423. if (bBox.getHeight()>1.0e-6) {
  424. hf = (pBox.getHeight() * scale - glueHeight) / bBox.getHeight();
  425. }
  426. var f = 1.0;
  427. if (!isNull(wf) && !isNull(hf)) {
  428. f = Math.min(wf, hf);
  429. }
  430. else if (!isNull(wf)) {
  431. f = wf;
  432. }
  433. else if (!isNull(hf)) {
  434. f = hf;
  435. }
  436. if (f<0) {
  437. f = 1.0;
  438. }
  439. //qDebug("f:", f);
  440. Print.setScale(di, f);
  441. Print.centerBox(di, bBox);
  442. };
  443. Print.autoCenter = function(di) {
  444. var document = di.getDocument();
  445. var bBox = document.getBoundingBox(true, true);
  446. if (!bBox.isValid()) {
  447. return;
  448. }
  449. Print.centerBox(di, bBox);
  450. };
  451. Print.centerBox = function(di, bBox) {
  452. var document = di.getDocument();
  453. var paperUnit = Print.getPaperUnit(document);
  454. var glueLeft = Print.getGlueMarginLeft(document);
  455. glueLeft = RUnit.convert(glueLeft, paperUnit, document.getUnit());
  456. var glueRight = Print.getGlueMarginRight(document);
  457. glueRight = RUnit.convert(glueRight, paperUnit, document.getUnit());
  458. var glueTop = Print.getGlueMarginTop(document);
  459. glueTop = RUnit.convert(glueTop, paperUnit, document.getUnit());
  460. var glueBottom = Print.getGlueMarginBottom(document);
  461. glueBottom = RUnit.convert(glueBottom, paperUnit, document.getUnit());
  462. var glueWidth = glueLeft + glueRight;
  463. var glueHeight = glueTop + glueBottom;
  464. var pBox = Print.getPaperBox(document);
  465. var scale = Print.getScale(document);
  466. var w2 = (pBox.getWidth() - bBox.getWidth()) / 2;
  467. var h2 = (pBox.getHeight() - bBox.getHeight()) / 2;
  468. var dw = (glueRight - glueLeft) / scale;
  469. var dh = (glueTop - glueBottom) / scale;
  470. var offset = bBox.getMinimum().operator_subtract(new RVector(w2, h2));
  471. offset = offset.operator_add(new RVector(dw/2, dh/2));
  472. Print.setOffset(di, offset);
  473. };
  474. /**
  475. * Draws the crop marks for the given page.
  476. * \param painter QPainter object if we are printing, RPainterPath for print preview.
  477. */
  478. Print.drawCropMarks = function(document, painter, border, printing) {
  479. var isPainter = isFunction(painter.drawLinesF);
  480. var clipping = false;
  481. if (isPainter) {
  482. clipping = painter.hasClipping();
  483. painter.setClipping(false);
  484. }
  485. var scale = Print.getScale(document);
  486. var offset = Print.getOffset(document);
  487. var unitScale = Print.getUnitScale(document);
  488. var colorMode = Print.getColorMode(document);
  489. var backgroundColor = Print.getBackgroundColor(document);
  490. var width = printing ? 0.1 / scale / unitScale : 1.5;
  491. var color = new QColor("darkBlue");
  492. if (colorMode == RGraphicsView.BlackWhite || colorMode == RGraphicsView.GrayScale) {
  493. if (backgroundColor.value() < 64) {
  494. color = new QColor("white");
  495. } else {
  496. color = new QColor("black");
  497. }
  498. }
  499. var pen = new QPen(new QBrush(color), width, Qt.SolidLine, Qt.FlatCap, Qt.MiterJoin);
  500. painter.setPen(pen);
  501. painter.setBrush(new QBrush(Qt.NoBrush));
  502. var lines = [];
  503. Print.pushCropMarkLines(document, lines, border.bottomLeft(), printing);
  504. Print.pushCropMarkLines(document, lines, border.topLeft(), printing);
  505. Print.pushCropMarkLines(document, lines, border.topRight(), printing);
  506. Print.pushCropMarkLines(document, lines, border.bottomRight(), printing);
  507. // printing:
  508. if (isPainter) {
  509. for (var k=0; k<lines.length; ++k) {
  510. lines[k].translate(-offset.x, -offset.y);
  511. }
  512. painter.drawLinesF(lines);
  513. }
  514. // preview:
  515. else {
  516. for (var i=0; i<lines.length; ++i) {
  517. painter.moveTo(new RVector(lines[i].x1(), lines[i].y1()));
  518. painter.lineTo(new RVector(lines[i].x2(), lines[i].y2()));
  519. }
  520. }
  521. if (isPainter) {
  522. painter.setClipping(clipping);
  523. }
  524. };
  525. /**
  526. * Helper function for drawCropMarks.
  527. */
  528. Print.pushCropMarkLines = function(document, lineArray, center, printing) {
  529. var scale = Print.getScale(document);
  530. var unitScale = Print.getUnitScale(document);
  531. var l = printing ? 10 / 2 / scale / unitScale : 10/2;
  532. lineArray.push(new QLineF(center.x() - l, center.y(), center.x() + l, center.y()));
  533. lineArray.push(new QLineF(center.x(), center.y() - l, center.x(), center.y() + l));
  534. };
  535. /**
  536. * \return A printable ID for the page with the given index, e.g. "B6".
  537. */
  538. Print.getPageId = function(document, index) {
  539. var columns = Print.getColumns(document);
  540. var column = index % columns;
  541. var row = Math.ceil((index + 1) / columns);
  542. var str = sprintf("%c%d", 65 + column, row);
  543. return str;
  544. }
  545. /**
  546. * Draws the page tags for printing (black, small, border area).
  547. * \param index page index
  548. * \param border page border geometry of the page
  549. * \param painter QPainter object if we are printing, RPainterPath for print preview.
  550. * \param printerFactor Factor from Millimeter to printer unit.
  551. */
  552. Print.drawPageTags = function(document, painter, index, border, printing, printerFactor) {
  553. var font, fm, x, y, width, height;
  554. var path = new QPainterPath();
  555. if (isNull(printing)) {
  556. printing = false;
  557. }
  558. var backgroundColor = Print.getBackgroundColor(document);
  559. var scale = Print.getScale(document);
  560. var offset = Print.getOffset(document);
  561. var str = Print.getPageId(document, index);
  562. // border of visible area after gluing:
  563. var correctedBorder = border.translated(0,0);
  564. var top = correctedBorder.top();
  565. correctedBorder.setTop(correctedBorder.bottom());
  566. correctedBorder.setBottom(top);
  567. font = Print.getTagFont(document);
  568. font.setPointSizeF(1.0);
  569. var sf = 1.0;
  570. // font size is given in points:
  571. sf *= Print.getTagFont(document).pointSizeF();
  572. // convert points to mm:
  573. sf = sf * 25.4 / 72;
  574. // font scaling for printing:
  575. if (printing) {
  576. // convert mm to drawing unit:
  577. sf = RUnit.convert(sf, RS.Millimeter, document.getUnit());
  578. // scale:
  579. sf /= scale;
  580. //sf = 1.0;
  581. }
  582. // font scaling for print preview:
  583. else {
  584. //sf = 25.4 / 72;
  585. }
  586. path.addText(0,0, font, str);
  587. // mirror text that is currently upside down:
  588. var t = new QTransform();
  589. t.scale(sf,-sf);
  590. path = t.map(path);
  591. var outside = (Print.getTagAlignment(document) === "Outside");
  592. width = path.boundingRect().width();
  593. height = path.boundingRect().height();
  594. switch (Print.getTagPosition(document)) {
  595. case "Top":
  596. case "Bottom":
  597. x = (correctedBorder.left() + correctedBorder.right()) / 2 - width / 2;
  598. break;
  599. default:
  600. case "Left":
  601. case "TopLeft":
  602. case "BottomLeft":
  603. x = correctedBorder.left();
  604. if (outside) {
  605. x-=width*1.25;
  606. }
  607. break;
  608. case "Right":
  609. case "TopRight":
  610. case "BottomRight":
  611. x = correctedBorder.right() - width;
  612. if (outside) {
  613. x+=width*1.25;
  614. }
  615. break;
  616. }
  617. switch (Print.getTagPosition(document)) {
  618. case "Top":
  619. case "TopLeft":
  620. case "TopRight":
  621. default:
  622. y = correctedBorder.top();
  623. if (outside) {
  624. //y+=height*1.25;
  625. }
  626. else {
  627. y -= height*1.25;
  628. }
  629. break;
  630. case "Left":
  631. case "Right":
  632. y = (correctedBorder.top() + correctedBorder.bottom()) / 2 - height / 2;
  633. break;
  634. case "Bottom":
  635. case "BottomLeft":
  636. case "BottomRight":
  637. y = correctedBorder.bottom();
  638. if (outside) {
  639. y -= height*1.25;
  640. }
  641. break;
  642. }
  643. //qDebug("correctedBorder: ", correctedBorder);
  644. //qDebug("x,y: ", x, y);
  645. var color;
  646. if (backgroundColor.value() > 128) {
  647. color = new QColor("black");
  648. } else {
  649. color = new QColor("white");
  650. }
  651. var pen = new QPen(Qt.NoPen);
  652. painter.setPen(pen);
  653. painter.setBrush(new QBrush(color));
  654. path.translate(x,y);
  655. if (printing) {
  656. var of = offset.getNegated();
  657. path.translate(of.x, of.y);
  658. painter.drawPath(path);
  659. }
  660. else {
  661. painter.addPath(new RPainterPath(path));
  662. }
  663. };
  664. /**
  665. * Draws the page footer for printing (black, small, border area).
  666. * \param index page index
  667. * \param border page border geometry of the page
  668. * \param painter QPainter object if we are printing, RTextData for print preview.
  669. * \param printerFactor Factor from Millimeter to printer unit.
  670. */
  671. Print.drawPageFooter = function(document, painterOrText, index, border, printing, printerFactor) {
  672. if (!isNull(Print.proxy)) {
  673. Print.proxy.drawPageFooter(document, painterOrText, index, border, printing, printerFactor);
  674. }
  675. };
  676. /**
  677. * \return All pages (printable areas) as QRectF objects in Millimeter
  678. * without any offset or scale applied.
  679. */
  680. Print.getPages = function(document) {
  681. var paperUnit;
  682. if (!isNull(document)) {
  683. paperUnit = Print.getPaperUnit(document);
  684. }
  685. else {
  686. paperUnit = Print.getDefaultPaperUnit();
  687. }
  688. var glueWidth = Print.getGlueMarginLeft(document) + Print.getGlueMarginRight(document);
  689. var glueHeight = Print.getGlueMarginTop(document) + Print.getGlueMarginBottom(document);
  690. var glueMarginLeft = Print.getGlueMarginLeft(document);
  691. var glueMarginBottom = Print.getGlueMarginBottom(document);
  692. glueWidth = RUnit.convert(glueWidth, paperUnit, RS.Millimeter);
  693. glueHeight = RUnit.convert(glueHeight, paperUnit, RS.Millimeter);
  694. glueMarginLeft = RUnit.convert(glueMarginLeft, paperUnit, RS.Millimeter);
  695. glueMarginBottom = RUnit.convert(glueMarginBottom, paperUnit, RS.Millimeter);
  696. var ret = [];
  697. var w;
  698. var h;
  699. var paperSizeMM = Print.getPaperSizeMM(document);
  700. if (Print.getPageOrientationEnum(document) === RS.Portrait) {
  701. w = paperSizeMM.width();
  702. h = paperSizeMM.height();
  703. } else {
  704. w = paperSizeMM.height();
  705. h = paperSizeMM.width();
  706. }
  707. var rows = Print.getRows(document);
  708. var columns = Print.getColumns(document);
  709. for (var r = rows-1; r >= 0; --r) {
  710. for (var c = 0; c < columns; ++c) {
  711. var rect = new QRectF(
  712. c * (w - glueWidth) + glueMarginLeft,
  713. r * (h - glueHeight) + glueMarginBottom,
  714. w - glueWidth,
  715. h - glueHeight
  716. );
  717. ret.push(rect);
  718. }
  719. }
  720. return ret;
  721. };
  722. /**
  723. * \return Paper border for the given printable area in mm.
  724. * \param border QRectF rectangle.
  725. */
  726. Print.getPaperBorder = function(document, border) {
  727. var paperUnit;
  728. if (!isNull(document)) {
  729. paperUnit = Print.getPaperUnit(document);
  730. }
  731. else {
  732. paperUnit = Print.getDefaultPaperUnit();
  733. }
  734. var glueMarginLeft = Print.getGlueMarginLeft(document);
  735. var glueMarginTop = Print.getGlueMarginTop(document);
  736. var glueMarginRight = Print.getGlueMarginRight(document);
  737. var glueMarginBottom = Print.getGlueMarginBottom(document);
  738. glueMarginLeft = RUnit.convert(glueMarginLeft, paperUnit, RS.Millimeter);
  739. glueMarginTop = RUnit.convert(glueMarginTop, paperUnit, RS.Millimeter);
  740. glueMarginRight = RUnit.convert(glueMarginRight, paperUnit, RS.Millimeter);
  741. glueMarginBottom = RUnit.convert(glueMarginBottom, paperUnit, RS.Millimeter);
  742. return border.adjusted(
  743. -glueMarginLeft,
  744. -glueMarginBottom,
  745. glueMarginRight,
  746. glueMarginTop
  747. );
  748. };
  749. /**
  750. * \return The given rectangle (QRectF) in Millimeter, transformed to the
  751. * model space unit and with the scale and offset used to print the given
  752. * document.
  753. */
  754. Print.getTransformed = function(document, rect) {
  755. var unitScale = Print.getUnitScale(document);
  756. var scale = Print.getScale(document);
  757. var offset = Print.getOffset(document);
  758. var ret = rect.translated(0,0);
  759. ret.setLeft(ret.left()/scale/unitScale);
  760. ret.setRight(ret.right()/scale/unitScale);
  761. ret.setTop(ret.top()/scale/unitScale);
  762. ret.setBottom(ret.bottom()/scale/unitScale);
  763. ret = ret.translated(offset.x, offset.y);
  764. return ret;
  765. };
  766. Print.getColorMode = function(document) {
  767. var colorModeString = Print.getValue("ColorSettings/ColorMode", "FullColor", document);
  768. return Print.getColorModeEnum(colorModeString);
  769. };
  770. Print.setColorMode = function(di, colorMode) {
  771. if (isString(colorMode)) {
  772. Print.setValue("ColorSettings/ColorMode", colorMode, di);
  773. }
  774. else {
  775. Print.setColorMode(di, Print.getColorModeString(colorMode));
  776. }
  777. };
  778. Print.getHairlineMode = function(document) {
  779. return Print.getBoolValue("Print/HairlineMode", false, document);
  780. };
  781. Print.setHairlineMode = function(di, onOff) {
  782. Print.setValue("Print/HairlineMode", onOff, di);
  783. };
  784. /**
  785. * Converts the given color mode as string into a color mode enum
  786. * (RGraphicsView::ColorMode).
  787. */
  788. Print.getColorModeEnum = function(colorModeString) {
  789. switch (colorModeString) {
  790. case "FullColor":
  791. return RGraphicsView.FullColor;
  792. case "Grayscale":
  793. return RGraphicsView.GrayScale;
  794. case "BlackWhite":
  795. return RGraphicsView.BlackWhite;
  796. default:
  797. return RGraphicsView.FullColor;
  798. }
  799. };
  800. /**
  801. * Converts the given color mode as enum (RGraphicsView::ColorMode) into a
  802. * color mode string as stored in a document as variable.
  803. */
  804. Print.getColorModeString = function(colorModeEnum) {
  805. switch (colorModeEnum) {
  806. case RGraphicsView.FullColor:
  807. return "FullColor";
  808. case RGraphicsView.GrayScale:
  809. return "Grayscale";
  810. case RGraphicsView.BlackWhite:
  811. return "BlackWhite";
  812. default:
  813. return "FullColor";
  814. }
  815. };
  816. /**
  817. * \return Default page rect of default printer in paper units.
  818. */
  819. Print.getDefaultPageRect = function(document, paperUnit) {
  820. var r = Print.getDefaultPrinter().pageRect(QPrinter.Millimeter);
  821. if (isNull(paperUnit)) {
  822. if (!isNull(document)) {
  823. paperUnit = Print.getPaperUnit(document);
  824. }
  825. else {
  826. paperUnit = Print.getDefaultPaperUnit();
  827. }
  828. }
  829. var x = RUnit.convert(r.x(), RS.Millimeter, paperUnit);
  830. var y = RUnit.convert(r.y(), RS.Millimeter, paperUnit);
  831. var w = RUnit.convert(r.width(), RS.Millimeter, paperUnit);
  832. var h = RUnit.convert(r.height(), RS.Millimeter, paperUnit);
  833. return new QRectF(x, y, w, h);
  834. };
  835. /**
  836. * \return Default paper rect of default printer in paper units.
  837. */
  838. Print.getDefaultPaperRect = function(document, paperUnit) {
  839. var r = Print.getDefaultPrinter().paperRect(QPrinter.Millimeter);
  840. if (isNull(paperUnit)) {
  841. if (!isNull(document)) {
  842. paperUnit = Print.getPaperUnit(document);
  843. }
  844. else {
  845. paperUnit = Print.getDefaultPaperUnit();
  846. }
  847. }
  848. var x = RUnit.convert(r.x(), RS.Millimeter, paperUnit);
  849. var y = RUnit.convert(r.y(), RS.Millimeter, paperUnit);
  850. var w = RUnit.convert(r.width(), RS.Millimeter, paperUnit);
  851. var h = RUnit.convert(r.height(), RS.Millimeter, paperUnit);
  852. return new QRectF(x, y, w, h);
  853. };
  854. /**
  855. * \return Value for given variable from current layout block, document or settings.
  856. */
  857. Print.getValue = function(key, def, document) {
  858. var ret = def;
  859. if (isNull(document) || document.getCurrentBlockId()===document.getModelSpaceBlockId()) {
  860. ret = EAction.getValue(key, def, document);
  861. }
  862. else {
  863. var block = document.queryCurrentBlock();
  864. if (!isNull(block)) {
  865. // fall back on document wide value for blocks:
  866. def = EAction.getValue(key, def, document);
  867. ret = block.getCustomProperty("QCAD", key, def);
  868. }
  869. }
  870. return ret;
  871. };
  872. Print.getDoubleValue = function(key, def, document) {
  873. var val = Print.getValue(key, def, document);
  874. val = parseFloat(val);
  875. if (!RMath.isSane(val)) {
  876. val = def;
  877. }
  878. return val;
  879. };
  880. Print.getIntValue = function(key, def, document) {
  881. var val = Print.getValue(key, def, document);
  882. val = parseInt(val);
  883. if (!RMath.isSane(val)) {
  884. val = def;
  885. }
  886. return val;
  887. };
  888. Print.getBoolValue = function(key, def, document) {
  889. var val = Print.getValue(key, def, document);
  890. if (typeof(val)==="string") {
  891. return val==="true" || val==="yes";
  892. }
  893. if (typeof(val)==="number") {
  894. return parseInt(val)===1
  895. }
  896. return val;
  897. };
  898. Print.setValue = function(key, val, di) {
  899. if (isNull(di)) {
  900. qWarning("di is NULL");
  901. return;
  902. }
  903. var document = di.getDocument();
  904. if (document.getCurrentBlockId()===document.getModelSpaceBlockId()) {
  905. document.setVariable(key, val);
  906. }
  907. else {
  908. var block = document.queryCurrentBlock();
  909. //if (block.hasLayout()) {
  910. if (block.getCustomProperty("QCAD", key, undefined)!==val) {
  911. block.setCustomProperty("QCAD", key, val.toString());
  912. if (!isNull(di)) {
  913. var op = new RAddObjectOperation(block);
  914. op.setRecordAffectedObjects(false);
  915. op.setSpatialIndexDisabled(true);
  916. di.applyOperation(op);
  917. }
  918. }
  919. //}
  920. }
  921. };
  922. Print.getGlueMarginLeft = function(document) {
  923. return Print.getDoubleValue("MultiPageSettings/GlueMarginsLeft", Print.getDefaultPrintMarginLeft(document), document);
  924. };
  925. Print.getDefaultPrintMarginLeft = function(document, paperUnit) {
  926. var pageRect = Print.getDefaultPageRect(document, paperUnit);
  927. var ret = parseFloat(pageRect.left().toFixed(4));
  928. if (!isNumber(ret)) {
  929. return 0.0;
  930. }
  931. return ret;
  932. };
  933. Print.getGlueMarginTop = function(document) {
  934. return Print.getDoubleValue("MultiPageSettings/GlueMarginsTop", Print.getDefaultPrintMarginTop(document), document);
  935. };
  936. Print.getDefaultPrintMarginTop = function(document, paperUnit) {
  937. var pageRect = Print.getDefaultPageRect(document, paperUnit);
  938. var ret = parseFloat(pageRect.top().toFixed(4));
  939. if (!isNumber(ret)) {
  940. return 0.0;
  941. }
  942. return ret;
  943. };
  944. Print.getGlueMarginRight = function(document) {
  945. return Print.getDoubleValue("MultiPageSettings/GlueMarginsRight", Print.getDefaultPrintMarginRight(document), document);
  946. };
  947. Print.getDefaultPrintMarginRight = function(document, paperUnit) {
  948. var paperRect = Print.getDefaultPaperRect(document, paperUnit);
  949. var pageRect = Print.getDefaultPageRect(document, paperUnit);
  950. var ret = parseFloat((paperRect.right() - pageRect.right()).toFixed(4));
  951. if (!isNumber(ret)) {
  952. return 0.0;
  953. }
  954. return ret;
  955. };
  956. Print.getGlueMarginBottom = function(document) {
  957. return Print.getDoubleValue("MultiPageSettings/GlueMarginsBottom", Print.getDefaultPrintMarginBottom(document), document);
  958. };
  959. Print.getDefaultPrintMarginBottom = function(document, paperUnit) {
  960. var paperRect = Print.getDefaultPaperRect(document, paperUnit);
  961. var pageRect = Print.getDefaultPageRect(document, paperUnit);
  962. var ret = parseFloat((paperRect.bottom() - pageRect.bottom()).toFixed(4));
  963. if (!isNumber(ret)) {
  964. return 0.0;
  965. }
  966. return ret;
  967. };
  968. Print.getOffset = function(document) {
  969. var x = Print.getDoubleValue("PageSettings/OffsetX", 0, document);
  970. var y = Print.getDoubleValue("PageSettings/OffsetY", 0, document);
  971. // x += Print.getGlueMarginLeft(document);
  972. // y += Print.getGlueMarginBottom(document);
  973. return new RVector(x, y);
  974. };
  975. Print.setOffset = function(di, offset) {
  976. Print.setValue("PageSettings/OffsetX", offset.x, di);
  977. Print.setValue("PageSettings/OffsetY", offset.y, di);
  978. };
  979. /**
  980. * \return Paper size in MM as QSizeF object.
  981. */
  982. Print.getPaperSizeMM = function(document) {
  983. //var defaultPaperSizeMM = Print.getDefaultPrinter().paperSize(QPrinter.Millimeter);
  984. var wMM = RUnit.convert(Print.getPaperWidth(document), Print.getPaperUnit(document), RS.Millimeter);
  985. var hMM = RUnit.convert(Print.getPaperHeight(document), Print.getPaperUnit(document), RS.Millimeter);
  986. return new QSizeF(wMM, hMM);
  987. };
  988. /**
  989. * \return Default paper size in MM as QSizeF object from configuration file
  990. * or QPrinter.
  991. */
  992. Print.getDefaultPaperSizeMM = function() {
  993. var defaultPrinter = Print.getDefaultPrinter();
  994. var dwMM;
  995. var dhMM;
  996. if (RSettings.getQtVersion() >= 0x060000) {
  997. var defaultPaperSize = defaultPrinter.pageLayout().pageSize();
  998. // paper size in appropriate unit:
  999. var size = defaultPaperSize.definitionSize();
  1000. var wUnit = size.width();
  1001. var hUnit = size.height();
  1002. // unit of paper size:
  1003. var unit = defaultPaperSize.definitionUnits();
  1004. // convert unit to mm:
  1005. var factor = 1.0;
  1006. switch (unit) {
  1007. case QPageSize.Point:
  1008. factor = 72 / 25.4;
  1009. break;
  1010. case QPageSize.Inch:
  1011. factor = 25.4;
  1012. break;
  1013. case QPageSize.Pica:
  1014. factor = 6 / 25.4;
  1015. break;
  1016. case QPageSize.Didot:
  1017. factor = 1 / 0.365;
  1018. break;
  1019. case QPageSize.Cicero:
  1020. factor = 1 / 4.5;
  1021. break;
  1022. default:
  1023. case QPageSize.Millimeter:
  1024. factor = 1.0;
  1025. break;
  1026. }
  1027. dwMM = wUnit * factor;
  1028. dhMM = hUnit * factor;
  1029. }
  1030. else {
  1031. var defaultPaperSizeMM = defaultPrinter.paperSize(QPrinter.Millimeter);
  1032. dwMM = defaultPaperSizeMM.width();
  1033. dhMM = defaultPaperSizeMM.height();
  1034. }
  1035. // get w / h in paper unit from settings:
  1036. var dw = RUnit.convert(dwMM, RS.Millimeter, Print.getDefaultPaperUnit());
  1037. var dh = RUnit.convert(dhMM, RS.Millimeter, Print.getDefaultPaperUnit());
  1038. var w = RSettings.getDoubleValue("PageSettings/PaperWidth", dw);
  1039. var h = RSettings.getDoubleValue("PageSettings/PaperHeight", dh);
  1040. // convert to mm:
  1041. w = RUnit.convert(w, Print.getDefaultPaperUnit(), RS.Millimeter);
  1042. h = RUnit.convert(h, Print.getDefaultPaperUnit(), RS.Millimeter);
  1043. return new QSizeF(w, h);
  1044. };
  1045. /**
  1046. * \return Paper width in PaperUnit.
  1047. */
  1048. Print.getPaperWidth = function(document) {
  1049. var defaultPaperSizeMM = Print.getDefaultPaperSizeMM();
  1050. var dwMM = defaultPaperSizeMM.width();
  1051. var dw = RUnit.convert(dwMM, RS.Millimeter, Print.getPaperUnit(document));
  1052. var w = Print.getValue("PageSettings/PaperWidth", dw, document);
  1053. // compat:
  1054. if (isArray(w)) {
  1055. w = w[0];
  1056. }
  1057. if (isString(w)) {
  1058. w = parseFloat(w);
  1059. }
  1060. return w;
  1061. };
  1062. /**
  1063. * \return Paper height in PaperUnit.
  1064. */
  1065. Print.getPaperHeight = function(document) {
  1066. var defaultPaperSizeMM = Print.getDefaultPaperSizeMM();
  1067. var dhMM = defaultPaperSizeMM.height();
  1068. var dh = RUnit.convert(dhMM, RS.Millimeter, Print.getPaperUnit(document));
  1069. var h = Print.getValue("PageSettings/PaperHeight", dh, document);
  1070. // compat:
  1071. if (isArray(h)) {
  1072. h = h[0];
  1073. }
  1074. if (isString(h)) {
  1075. h = parseFloat(h);
  1076. }
  1077. return h;
  1078. };
  1079. /**
  1080. * \return Paper unit enum.
  1081. */
  1082. Print.getPaperUnit = function(document) {
  1083. var def = Print.getDefaultPaperUnit();
  1084. return Print.getIntValue("UnitSettings/PaperUnit", def, document);
  1085. };
  1086. Print.getDefaultPaperUnit = function() {
  1087. return RSettings.getIntValue("UnitSettings/PaperUnit", RS.Millimeter);
  1088. };
  1089. Print.getPaperSizeEnum = function(document) {
  1090. var paperSizeMM = Print.getPaperSizeMM(document);
  1091. for (var i=0; i<PageSettings.paperSizes.length; ++i) {
  1092. // paper[0]: name
  1093. // paper[1]: QSizeF
  1094. // paper[2]: QPrinter::PaperSize
  1095. var paper = PageSettings.paperSizes[i];
  1096. var sizeMM = paper[1];
  1097. if (Math.abs(sizeMM.width()-paperSizeMM.width()) < 1.0e-2 &&
  1098. Math.abs(sizeMM.height()-paperSizeMM.height()) < 1.0e-2) {
  1099. return paper[2];
  1100. }
  1101. }
  1102. return undefined;
  1103. };
  1104. /**
  1105. * \return paper size name for given paper size.
  1106. *
  1107. * \param paperSizeMM QSizeF paper size in mm.
  1108. */
  1109. Print.getPaperSizeNameFromSize = function(paperSizeMM) {
  1110. for (var i=0; i<PageSettings.paperSizes.length; ++i) {
  1111. // paper[0]: name
  1112. // paper[1]: QSizeF
  1113. // paper[2]: QPrinter::PaperSize
  1114. var paper = PageSettings.paperSizes[i];
  1115. var sizeMM = paper[1];
  1116. var cw = sizeMM.width();
  1117. var ch = sizeMM.height();
  1118. var w = paperSizeMM.width();
  1119. var h = paperSizeMM.height();
  1120. if ((Math.abs(cw-w) < 1.0e-2 && Math.abs(ch-h) < 1.0e-2) ||
  1121. (Math.abs(cw-h) < 1.0e-2 && Math.abs(ch-w) < 1.0e-2)) {
  1122. //qDebug("found match: ", paper);
  1123. //qDebug("found match: ", paper[0]);
  1124. return paper[0];
  1125. }
  1126. }
  1127. return "";
  1128. };
  1129. /**
  1130. * \return paper size for given paper size name.
  1131. *
  1132. * \param paperSizeName paper size name (A4, letter, ...).
  1133. */
  1134. Print.getPaperSizeFromSizeName = function(paperSizeName) {
  1135. for (var i=0; i<PageSettings.paperSizes.length; ++i) {
  1136. // paper[0]: name
  1137. // paper[1]: QSizeF
  1138. // paper[2]: QPrinter::PaperSize
  1139. var paper = PageSettings.paperSizes[i];
  1140. var sizeName = paper[0];
  1141. var sizeNameAlt1 = "";
  1142. var sizeNameAlt2 = "";
  1143. if (sizeName.indexOf("ISO")===0) {
  1144. sizeNameAlt1 = paper[0].replace("ISO ", "");
  1145. }
  1146. if (sizeName==="ANSI A (Letter)") {
  1147. sizeName = "ANSI A";
  1148. sizeNameAlt1 = "Letter";
  1149. }
  1150. if (sizeName==="ANSI B (Ledger, Tabloid)") {
  1151. sizeName = "ANSI B";
  1152. sizeNameAlt1 = "Ledger";
  1153. sizeNameAlt2 = "Tabloid";
  1154. }
  1155. if (sizeName==="F4 (Folio, Foolscap)") {
  1156. sizeName = "F4";
  1157. sizeNameAlt1 = "Folio";
  1158. sizeNameAlt2 = "Foolscap";
  1159. }
  1160. var sizeMM = paper[1];
  1161. var cw = sizeMM.width();
  1162. var ch = sizeMM.height();
  1163. //var w = paperSizeMM.width();
  1164. //var h = paperSizeMM.height();
  1165. if (sizeName.toLowerCase()===paperSizeName.toLowerCase() ||
  1166. sizeNameAlt1.toLowerCase()===paperSizeName.toLowerCase() ||
  1167. sizeNameAlt2.toLowerCase()===paperSizeName.toLowerCase()) {
  1168. //qDebug("found match: ", paper);
  1169. //qDebug("found match: ", paper[0]);
  1170. return paper[1];
  1171. }
  1172. }
  1173. return new QSizeF();
  1174. };
  1175. /**
  1176. * \return Paper size name (always based on paper size values).
  1177. */
  1178. Print.getPaperSizeName = function(document) {
  1179. var paperSizeMM = Print.getPaperSizeMM(document);
  1180. var ret = Print.getPaperSizeNameFromSize(paperSizeMM);
  1181. if (ret==="") {
  1182. // return translated 'Custom':
  1183. return PageSettings.paperSizes[0][0];
  1184. }
  1185. return ret;
  1186. };
  1187. /**
  1188. * \return Default paper size name as configured (config file) or from QPrinter.
  1189. */
  1190. Print.getDefaultPaperSizeName = function(document) {
  1191. var paperSizeMM = Print.getDefaultPaperSizeMM();
  1192. var ret = Print.getPaperSizeNameFromSize(paperSizeMM);
  1193. if (ret==="") {
  1194. // return translated 'Custom':
  1195. return PageSettings.paperSizes[0][0];
  1196. }
  1197. return ret;
  1198. };
  1199. /**
  1200. * \return Page orientation as QPrinter::Orientation enum.
  1201. */
  1202. Print.getPageOrientationEnum = function(document) {
  1203. var pageOrientationString = Print.getPageOrientationString(document);
  1204. if (pageOrientationString==="Landscape") {
  1205. return RS.Landscape;
  1206. }
  1207. else {
  1208. return RS.Portrait;
  1209. }
  1210. };
  1211. Print.getPageOrientationString = function(document) {
  1212. return Print.getValue("PageSettings/PageOrientation", "Portrait", document);
  1213. };
  1214. Print.setPageOrientationString = function(di, pageOrientation) {
  1215. Print.setValue("PageSettings/PageOrientation", pageOrientation, di);
  1216. };
  1217. Print.setPageOrientationEnum = function(di, pageOrientation) {
  1218. if (pageOrientation===RS.Landscape) {
  1219. Print.setPageOrientationString(di, "Landscape");
  1220. }
  1221. else {
  1222. Print.setPageOrientationString(di, "Portrait");
  1223. }
  1224. };
  1225. Print.getShowPaperBorders = function(document) {
  1226. return Print.getBoolValue("PageSettings/ShowPaperBorders", true, document);
  1227. };
  1228. Print.setShowPaperBorders = function(di, showPaperBorders) {
  1229. Print.setValue("PageSettings/ShowPaperBorders", showPaperBorders, di);
  1230. };
  1231. Print.getPrintCropMarks = function(document) {
  1232. return Print.getBoolValue("MultiPageSettings/PrintCropMarks", true, document);
  1233. };
  1234. Print.setPrintCropMarks = function(di, printCropMarks) {
  1235. Print.setValue("MultiPageSettings/PrintCropMarks", printCropMarks, di);
  1236. };
  1237. Print.getScaleString = function(document) {
  1238. var str = Print.getValue("PageSettings/Scale", "1:1", document);
  1239. // round:
  1240. if (/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/.test(str)) {
  1241. var v = parseFloat(str);
  1242. if (v>1) {
  1243. str = sprintf("%.2f", v);
  1244. }
  1245. else if (v>0.1) {
  1246. str = sprintf("%.3f", v);
  1247. }
  1248. else if (v>0.01) {
  1249. str = sprintf("%.4f", v);
  1250. }
  1251. else if (v>0.001) {
  1252. str = sprintf("%.5f", v);
  1253. }
  1254. else if (v>0.0001) {
  1255. str = sprintf("%.6f", v);
  1256. }
  1257. else if (v>0.00001) {
  1258. str = sprintf("%.7f", v);
  1259. }
  1260. else if (v>0.000001) {
  1261. str = sprintf("%.8f", v);
  1262. }
  1263. else {
  1264. str = sprintf("%.12f", v);
  1265. }
  1266. }
  1267. return str;
  1268. };
  1269. /**
  1270. * \return Drawing scale as factor.
  1271. */
  1272. Print.getScale = function(document) {
  1273. var scaleString = Print.getScaleString(document);
  1274. return Print.parseScale(scaleString);
  1275. };
  1276. /**
  1277. * \return Scale factor from drawing unit to mm.
  1278. */
  1279. Print.getUnitScale = function(document) {
  1280. return RUnit.convert(1.0, document.getUnit(), RS.Millimeter);
  1281. };
  1282. Print.setScale = function(di, scale) {
  1283. this.setScaleString(di, scale.toString());
  1284. };
  1285. Print.setScaleString = function(di, scaleString) {
  1286. Print.setValue("PageSettings/Scale", scaleString, di);
  1287. };
  1288. Print.getColumns = function(document) {
  1289. return Print.getIntValue("MultiPageSettings/Columns", 1, document);
  1290. };
  1291. Print.setColumns = function(di, columns) {
  1292. Print.setValue("MultiPageSettings/Columns", columns, di);
  1293. };
  1294. Print.getRows = function(document) {
  1295. return Print.getIntValue("MultiPageSettings/Rows", 1, document);
  1296. };
  1297. Print.setRows = function(di, rows) {
  1298. Print.setValue("MultiPageSettings/Rows", rows, di);
  1299. };
  1300. Print.getBackgroundColor = function(document) {
  1301. // this might return a string or an RColor object:
  1302. var color = Print.getValue("ColorSettings/BackgroundColor", new RColor("white"), document);
  1303. if (isOfType(color, RColor)) {
  1304. return color;
  1305. }
  1306. else if (isString(color)) {
  1307. var ret = new RColor(color);
  1308. if (ret.isValid()) {
  1309. return ret;
  1310. }
  1311. // invalid color name: default to white:
  1312. return new RColor("white");
  1313. }
  1314. else {
  1315. debugger;
  1316. return new RColor("white");
  1317. }
  1318. };
  1319. Print.getEnablePageTags = function(document) {
  1320. return Print.getBoolValue("PageTagSettings/EnablePageTags", false, document);
  1321. };
  1322. Print.hasFooter = function(document) {
  1323. return Print.getIntValue("FooterSettings/Footer", 0, document) > 0;
  1324. };
  1325. //Print.getIdentifyPageTags = function(document) {
  1326. // return Print.getBoolValue("PageTagSettings/IdentifyPageTags", false, document);
  1327. //};
  1328. Print.getTagFont = function(document) {
  1329. var ret = Print.getValue("PageTagSettings/TagFont", new QFont(), document);
  1330. if (isOfType(ret, QFont)) {
  1331. return ret;
  1332. }
  1333. if (isString(ret)) {
  1334. var f = new QFont();
  1335. f.fromString(ret);
  1336. return f;
  1337. }
  1338. qWarning("TagFont is not a valid font");
  1339. return new QFont();
  1340. };
  1341. Print.getTagPosition = function(document) {
  1342. return Print.getValue("PageTagSettings/TagPosition", "TopLeft", document);
  1343. };
  1344. Print.getTagAlignment = function(document) {
  1345. return Print.getValue("PageTagSettings/TagAlignment", "Inside", document);
  1346. };
  1347. Print.getFooterPosition = function(document) {
  1348. return Print.getValue("FooterSettings/FooterPosition", "TopLeft", document);
  1349. };
  1350. Print.getFooterFont = function(document) {
  1351. var ret = Print.getValue("FooterSettings/FooterFont", new QFont(), document);
  1352. if (isOfType(ret, QFont)) {
  1353. return ret;
  1354. }
  1355. if (isString(ret)) {
  1356. var f = new QFont();
  1357. f.fromString(ret);
  1358. return f;
  1359. }
  1360. qWarning("FooterFont is not a valid font");
  1361. return new QFont();
  1362. };
  1363. /**
  1364. * Parses the given scale string (e.g. "1:2") and returns the scale as number (e.g. 0.5).
  1365. */
  1366. Print.parseScale = function(scaleString) {
  1367. if (!isString(scaleString)) {
  1368. return 1.0;
  1369. }
  1370. return RMath.parseScale(scaleString);
  1371. };