library.js 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468
  1. /**
  2. * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
  3. *
  4. * Function stringToDirectDistanceEntry added 2013 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. // Version check is disabled for now. This can be used in the future to
  22. // ensure compatibility between scripts and script bindings.
  23. //requiresFramework([3,0,9,0], [3,1,0,0]);
  24. // don't include sprintf.js here to keep library footprint small:
  25. //include("sprintf.js");
  26. if (typeof(global)==="undefined") {
  27. global = this;
  28. global.gMainWindow = undefined;
  29. global.gDocumentInterface = undefined;
  30. }
  31. /**
  32. * \param file File path argument given on command line (might be absolute or relative).
  33. * \return Absolute path of given file.
  34. */
  35. function getAbsolutePathForArg(file) {
  36. // detect URL (TODO: breaks under win):
  37. // var url = new QUrl(file);
  38. // if (url.isValid() && url.scheme().length!==0 && !url.isLocalFile()) {
  39. // return file;
  40. // }
  41. // detect absolute path:
  42. var fi = new QFileInfo(file);
  43. if (fi.isAbsolute() || file.startsWith(":")){
  44. return file;
  45. }
  46. // relative path (prepend application dir):
  47. return RSettings.getLaunchPath() + QDir.separator + file;
  48. }
  49. /**
  50. * Checks if the QCAD Application Framework is at least of version minVersion
  51. * and not newer than maxVersion.
  52. *
  53. * \param minVersion array in the format [major,minor,revision,build]
  54. * \param maxVersion array in the format [major,minor,revision,build]
  55. */
  56. function requiresFramework(minVersion, maxVersion) {
  57. var frameworkV = getVersionNumber(RSettings.getMajorVersion(), RSettings.getMinorVersion(), RSettings.getRevisionVersion(), RSettings.getBuildVersion());
  58. var minV = getVersionNumber(minVersion[0], minVersion[1], minVersion[2], minVersion[3]);
  59. var maxV = getVersionNumber(maxVersion[0], maxVersion[1], maxVersion[2], maxVersion[3]);
  60. if (frameworkV < minV) {
  61. qCritical("QCAD Application Framework is too old for script plugin ", includeBasePath);
  62. debugger;
  63. }
  64. if (frameworkV > maxV) {
  65. qCritical("QCAD Application Framework is too new for script plugin", includeBasePath);
  66. debugger;
  67. }
  68. }
  69. function getVersionNumber(major, minor, revision, build) {
  70. return major*1e9 + minor*1e6 + revision*1e3 + build;
  71. }
  72. /**
  73. * Check the real type of the given object.
  74. *
  75. * Standard ECMAScript typeof returns "string" for a string literal but
  76. * "object" for a string object constructed with new. Same goes for
  77. * arrays, etc. This function provides a workaround.
  78. */
  79. function getTypeOf(v) {
  80. if (typeof(v)==="object") {
  81. if (v === null) {
  82. return "null";
  83. }
  84. if (v.constructor == (new String()).constructor) {
  85. return "string";
  86. }
  87. if (v.constructor == (new Array()).constructor) {
  88. return "array";
  89. }
  90. if (v.constructor == (new Date()).constructor) {
  91. return "date";
  92. }
  93. if (v.constructor == (new RegExp()).constructor) {
  94. return "regex";
  95. }
  96. return "object";
  97. }
  98. return typeof(v);
  99. }
  100. /**
  101. * Checks if the given object is of the given type. E.g.
  102. * isOfType(myObject, QLabel) returns true if myObject is a QLabel. Note
  103. * that isOfType(myObject, QWidget) returns false even though QLabel is
  104. * derived from QWidget.
  105. */
  106. function isOfType(obj, type) {
  107. if (RSettings.getQtVersion() < 0x060000) {
  108. return !isNull(obj) && obj.constructor===type;
  109. }
  110. else {
  111. //return !isNull(obj) && (obj.constructor===type || (isFunction(obj.getObjectType) && obj.getObjectType()===type.getObjectType()));
  112. return !isNull(obj) && isFunction(obj.getObjectType) && obj.getObjectType()===type.getObjectType();
  113. }
  114. }
  115. /**
  116. * Destroys the given object with C++ ownership.
  117. */
  118. function destr(obj) {
  119. if (RSettings.getQtVersion() >= 0x060000) {
  120. // destroy does not work in Qt 6 / QJSEngine:
  121. // ("Invalid attempt to destroy() an indestructible object")
  122. obj.destr();
  123. }
  124. else {
  125. if (isFunction(obj.destroy)) {
  126. obj.destroy();
  127. }
  128. }
  129. }
  130. /**
  131. * Get pointer from shared pointer object using data() (Qt5) or implicitly (Qt6).
  132. */
  133. function getPtr(p) {
  134. if (RSettings.getQtVersion() > 0x060000) {
  135. return p;
  136. }
  137. else {
  138. if (isFunction(p.data)) {
  139. return p.data();
  140. }
  141. else {
  142. return p;
  143. }
  144. }
  145. }
  146. /**
  147. * Checks if the given object is undefined or null.
  148. *
  149. * \return true if the given object is defined and not null.
  150. * This method also supports shared pointers, i.e. obj.isNull()==true.
  151. */
  152. function isNull(obj) {
  153. if (isDeleted(obj)) {
  154. return true;
  155. }
  156. return (
  157. obj==null ||
  158. // wrapped object is NULL:
  159. (typeof(obj.isNullWrapper)==="function" && obj.isNullWrapper()===true) ||
  160. // shared pointer is NULL:
  161. (typeof(obj.data)==="function" && typeof(obj.isNull)==="function" && obj.isNull()===true)
  162. );
  163. }
  164. /**
  165. * Checks if the given object is a valid number.
  166. *
  167. * \return true if the given object is a number and not NaN or +/-Infinity
  168. * or NULL or undefined.
  169. */
  170. function isNumber(obj) {
  171. return (typeof(obj)==="number" && !isNaN(obj) && isFinite(obj));
  172. }
  173. function isNumberGreaterEqualZero(n) {
  174. return !isNaN(n) && n>=0;
  175. };
  176. function isNumberGreaterZero(n) {
  177. return !isNaN(n) && n>0;
  178. };
  179. /**
  180. * Checks if the given object is a string.
  181. *
  182. * \return true if the given object is a string
  183. */
  184. function isString(obj) {
  185. return (typeof(obj)==="string");
  186. }
  187. /**
  188. * Checks if the given object is of type RVector.
  189. *
  190. * \return true if the given object is an RVector object.
  191. */
  192. function isVector(obj) {
  193. return (typeof(obj)==="object" && isOfType(obj, RVector));
  194. }
  195. /**
  196. * Checks if the given object is a valid vector.
  197. *
  198. * \return true if the given object is a valid RVector object.
  199. */
  200. function isValidVector(obj) {
  201. return (isVector(obj) && obj.isValid() && isNumber(obj.x) && isNumber(obj.y));
  202. }
  203. /**
  204. * Checks if the given object is a color.
  205. *
  206. * \return true if the given object is an RColor object.
  207. */
  208. function isColor(obj) {
  209. return (typeof(obj)==="object" && isOfType(obj, RColor));
  210. }
  211. /**
  212. * Checks if the given object is a valid color.
  213. *
  214. * \return true if the given object is a valid RColor object.
  215. */
  216. function isValidColor(obj) {
  217. return (isColor(obj) && obj.isValid());
  218. }
  219. /**
  220. * Checks if the given object is a valid boolean value.
  221. *
  222. * \return true if the given object is a boolean and not NULL or undefined.
  223. */
  224. function isBoolean(obj) {
  225. return (typeof(obj)==="boolean");
  226. }
  227. /**
  228. * Checks if the given object is a valid function.
  229. *
  230. * \return true if the given object is a function.
  231. */
  232. function isFunction(obj) {
  233. return (typeof(obj)==="function");
  234. }
  235. /**
  236. * Checks if the given object is a valid QObject.
  237. *
  238. * \return true if the given object is a QObject.
  239. */
  240. function isQObject(obj) {
  241. return (typeof(obj)==="object" && !isNull(obj.objectName));
  242. }
  243. /**
  244. * Checks if the given object is a valid QWidget.
  245. *
  246. * \return true if the given object is a QWidget.
  247. */
  248. function isQWidget(obj) {
  249. return (isQObject(obj) && typeof(obj.show)==="function");
  250. }
  251. /**
  252. * \return true if the given object is a separator (a frame of type vertical line).
  253. */
  254. function isSeparator(obj) {
  255. return isOfType(obj, QFrame) && obj.frameShape==QFrame.VLine;
  256. }
  257. /**
  258. * Checks if the given object is a layer.
  259. *
  260. * \return true if the given object is a layer.
  261. */
  262. function isLayer(obj) {
  263. if (RSettings.getQtVersion() < 0x060000) {
  264. return isOfType(obj, RLayer) || isOfType(obj, RLayerPointer);
  265. }
  266. else {
  267. return isOfType(obj, RLayer);
  268. }
  269. }
  270. /**
  271. * Checks if the given object is a block (RBlock).
  272. *
  273. * \return true if the given object is a block.
  274. */
  275. function isBlock(obj) {
  276. if (RSettings.getQtVersion() < 0x060000) {
  277. return isOfType(obj, RBlock) || isOfType(obj, RBlockPointer);
  278. }
  279. else {
  280. return isOfType(obj, RBlock);
  281. }
  282. }
  283. /**
  284. * Checks if the given object is a layout (RLayout).
  285. *
  286. * \return true if the given object is a layout.
  287. */
  288. function isLayout(obj) {
  289. if (RSettings.getQtVersion() < 0x060000) {
  290. return isOfType(obj, RLayout) || isOfType(obj, RLayoutPointer);
  291. }
  292. else {
  293. return isOfType(obj, RLayout);
  294. }
  295. }
  296. /**
  297. * Checks if the given object is an RObject.
  298. *
  299. * \return true if the given object is an object (derived from RObject).
  300. */
  301. function isObject(obj) {
  302. return !isNull(obj) &&
  303. isFunction(obj.getType) &&
  304. isNumber(obj.getType());
  305. }
  306. /**
  307. * Checks if the given object is a graphics entity.
  308. *
  309. * \return true if the given object is an entity (derived from REntity).
  310. */
  311. function isEntity(obj) {
  312. return !isNull(obj) &&
  313. isFunction(obj.getType) &&
  314. isFunction(obj.getData) &&
  315. isNumber(obj.getType());
  316. }
  317. /**
  318. * Checks if the given object is a dimension entity of any kind.
  319. *
  320. * \return true if the given object is a dimension entity
  321. * (RDimensionEntity).
  322. */
  323. function isDimensionEntity(obj) {
  324. return isDimAlignedEntity(obj)
  325. || isDimAngularEntity(obj)
  326. || isDimArcLengthEntity(obj)
  327. || isDimDiametricEntity(obj)
  328. || isDimLinearEntity(obj)
  329. || isDimOrdinateEntity(obj)
  330. || isDimRadialEntity(obj)
  331. || isDimRotatedEntity(obj);
  332. }
  333. /**
  334. * Checks if the given object is a diametric dimension entity.
  335. *
  336. * \return true if the given object is a diametric dimension entity
  337. * (RDimDiametricEntity).
  338. */
  339. function isDimDiametricEntity(obj) {
  340. if (RSettings.getQtVersion() < 0x060000) {
  341. return isOfType(obj, RDimDiametricEntity) || isOfType(obj, RDimDiametricEntityPointer);
  342. }
  343. else {
  344. return isOfType(obj, RDimDiametricEntity);
  345. }
  346. }
  347. /**
  348. * Checks if the given object is an aligned dimension entity.
  349. *
  350. * \return true if the given object is an aligned dimension entity
  351. * (RDimAlignedEntity).
  352. */
  353. function isDimAlignedEntity(obj) {
  354. if (RSettings.getQtVersion() < 0x060000) {
  355. return isOfType(obj, RDimAlignedEntity) || isOfType(obj, RDimAlignedEntityPointer);
  356. }
  357. else {
  358. return isOfType(obj, RDimAlignedEntity);
  359. }
  360. }
  361. /**
  362. * Checks if the given object is a rotated dimension entity.
  363. *
  364. * \return true if the given object is a rotated dimension entity
  365. * (RDimRotatedEntity).
  366. */
  367. function isDimRotatedEntity(obj) {
  368. if (RSettings.getQtVersion() < 0x060000) {
  369. return isOfType(obj, RDimRotatedEntity) || isOfType(obj, RDimRotatedEntityPointer);
  370. }
  371. else {
  372. return isOfType(obj, RDimRotatedEntity);
  373. }
  374. }
  375. /**
  376. * Checks if the given object is an ordinate dimension entity.
  377. *
  378. * \return true if the given object is an ordinate dimension entity
  379. * (RDimOrdinateEntity).
  380. */
  381. function isDimOrdinateEntity(obj) {
  382. if (RSettings.getQtVersion() < 0x060000) {
  383. return isOfType(obj, RDimOrdinateEntity) || isOfType(obj, RDimOrdinateEntityPointer);
  384. }
  385. else {
  386. return isOfType(obj, RDimOrdinateEntity);
  387. }
  388. }
  389. /**
  390. * Checks if the given object is a radial dimension entity.
  391. *
  392. * \return true if the given object is a radial dimension entity
  393. * (RDimRadialEntity).
  394. */
  395. function isDimRadialEntity(obj) {
  396. if (RSettings.getQtVersion() < 0x060000) {
  397. return isOfType(obj, RDimRadialEntity) || isOfType(obj, RDimRadialEntityPointer);
  398. }
  399. else {
  400. return isOfType(obj, RDimRadialEntity);
  401. }
  402. }
  403. /**
  404. * Checks if the given object is an angular dimension entity.
  405. *
  406. * \return true if the given object is an angular dimension entity
  407. * (RDimAngular2LEntity or RDimAngular3PEntity).
  408. */
  409. function isDimAngularEntity(obj) {
  410. return isDimAngular2LEntity(obj) || isDimAngular3PEntity(obj);
  411. }
  412. /**
  413. * Checks if the given object is an angular dimension from 2 lines entity.
  414. *
  415. * \return true if the given object is an angular dimension entity
  416. * (RDimAngular2LEntity).
  417. */
  418. function isDimAngular2LEntity(obj) {
  419. if (RSettings.getQtVersion() < 0x060000) {
  420. return isOfType(obj, RDimAngular2LEntity) || isOfType(obj, RDimAngular2LEntityPointer);
  421. }
  422. else {
  423. return isOfType(obj, RDimAngular2LEntity);
  424. }
  425. }
  426. /**
  427. * Checks if the given object is an angular dimension from 3 points entity.
  428. *
  429. * \return true if the given object is an angular dimension entity
  430. * (RDimAngular3PEntity).
  431. */
  432. function isDimAngular3PEntity(obj) {
  433. if (RSettings.getQtVersion() < 0x060000) {
  434. return isOfType(obj, RDimAngular3PEntity) || isOfType(obj, RDimAngular3PEntityPointer);
  435. }
  436. else {
  437. return isOfType(obj, RDimAngular3PEntity);
  438. }
  439. }
  440. /**
  441. * Checks if the given object is an arc length dimension entity.
  442. *
  443. * \return true if the given object is an arc length dimension entity
  444. * (RDimArcLengthEntity).
  445. */
  446. function isDimArcLengthEntity(obj) {
  447. if (RSettings.getQtVersion() < 0x060000) {
  448. return isOfType(obj, RDimArcLengthEntity) || isOfType(obj, RDimArcLengthEntityPointer);
  449. }
  450. else {
  451. return isOfType(obj, RDimArcLengthEntity);
  452. }
  453. }
  454. /**
  455. * Checks if the given object is a linear dimension entity.
  456. *
  457. * \return true if the given object is a linear dimension entity
  458. * (RDimLinearEntity).
  459. */
  460. function isDimLinearEntity(obj) {
  461. if (RSettings.getQtVersion() < 0x060000) {
  462. return isOfType(obj, RDimLinearEntity) || isOfType(obj, RDimLinearEntityPointer);
  463. }
  464. else {
  465. return isOfType(obj, RDimLinearEntity);
  466. }
  467. }
  468. /**
  469. * Checks if the given object is a hatch entity.
  470. *
  471. * \return true if the given object is an arc entity (RHatchEntity).
  472. */
  473. function isHatchEntity(obj) {
  474. if (RSettings.getQtVersion() < 0x060000) {
  475. return isOfType(obj, RHatchEntity) || isOfType(obj, RHatchEntityPointer);
  476. }
  477. else {
  478. return isOfType(obj, RHatchEntity);
  479. }
  480. }
  481. /**
  482. * Checks if the given object is an arc entity.
  483. *
  484. * \return true if the given object is an arc entity (RArcEntity).
  485. */
  486. function isArcEntity(obj) {
  487. if (RSettings.getQtVersion() < 0x060000) {
  488. return isOfType(obj, RArcEntity) || isOfType(obj, RArcEntityPointer);
  489. }
  490. else {
  491. return isOfType(obj, RArcEntity);
  492. }
  493. }
  494. /**
  495. * Checks if the given object is a circle entity.
  496. *
  497. * \return true if the given object is a line entity (RCircleEntity).
  498. */
  499. function isCircleEntity(obj) {
  500. if (RSettings.getQtVersion() < 0x060000) {
  501. return isOfType(obj, RCircleEntity) || isOfType(obj, RCircleEntityPointer);
  502. }
  503. else {
  504. return isOfType(obj, RCircleEntity);
  505. }
  506. }
  507. /**
  508. * Checks if the given object is an ellipse entity.
  509. *
  510. * \return true if the given object is an ellipse entity (REllipseEntity).
  511. */
  512. function isEllipseEntity(obj) {
  513. if (RSettings.getQtVersion() < 0x060000) {
  514. return isOfType(obj, REllipseEntity) || isOfType(obj, REllipseEntityPointer);
  515. }
  516. else {
  517. return isOfType(obj, REllipseEntity);
  518. }
  519. }
  520. /**
  521. * Checks if the given object is an ellipse entity and represents an ellipse arc (not a full ellipse).
  522. *
  523. * \return true if the given object is an ellipse arc entity (REllipseEntity).
  524. */
  525. function isEllipseArcEntity(obj) {
  526. if (RSettings.getQtVersion() < 0x060000) {
  527. return (isOfType(obj, REllipseEntity) || isOfType(obj, REllipseEntityPointer)) && !obj.isFullEllipse();
  528. }
  529. else {
  530. return isOfType(obj, REllipseEntity);
  531. }
  532. }
  533. /**
  534. * Checks if the given object is an ellipse entity and represents a full ellipse.
  535. *
  536. * \return true if the given object is an ellipse entity (REllipseEntity).
  537. */
  538. function isFullEllipseEntity(obj) {
  539. return isEllipseEntity(obj) && obj.isFullEllipse();
  540. }
  541. /**
  542. * Checks if the given object is a line entity.
  543. *
  544. * \return true if the given object is a line entity (RLineEntity).
  545. */
  546. function isLineEntity(obj) {
  547. if (RSettings.getQtVersion() < 0x060000) {
  548. return isOfType(obj, RLineEntity) || isOfType(obj, RLineEntityPointer);
  549. }
  550. else {
  551. return isOfType(obj, RLineEntity);
  552. }
  553. }
  554. /**
  555. * Checks if the given object is a line, xline or ray entity.
  556. *
  557. * \return true if the given object is a line based entity (RLineEntity, RXLineEntity, RRayEntity).
  558. */
  559. function isLineBasedEntity(obj) {
  560. return isLineEntity(obj) || isXLineEntity(obj) || isRayEntity(obj);
  561. }
  562. /**
  563. * Checks if the given object is an xline entity.
  564. *
  565. * \return true if the given object is an xline entity (RXLineEntity).
  566. */
  567. function isXLineEntity(obj) {
  568. if (RSettings.getQtVersion() < 0x060000) {
  569. return isOfType(obj, RXLineEntity) || isOfType(obj, RXLineEntityPointer);
  570. }
  571. else {
  572. return isOfType(obj, RXLineEntity);
  573. }
  574. }
  575. /**
  576. * Checks if the given object is a ray entity.
  577. *
  578. * \return true if the given object is a ray entity (RRayEntity).
  579. */
  580. function isRayEntity(obj) {
  581. if (RSettings.getQtVersion() < 0x060000) {
  582. return isOfType(obj, RRayEntity) || isOfType(obj, RRayEntityPointer);
  583. }
  584. else {
  585. return isOfType(obj, RRayEntity);
  586. }
  587. }
  588. /**
  589. * Checks if the given object is a point entity.
  590. *
  591. * \return true if the given object is a point entity (RPointEntity).
  592. */
  593. function isPointEntity(obj) {
  594. if (RSettings.getQtVersion() < 0x060000) {
  595. return isOfType(obj, RPointEntity) || isOfType(obj, RPointEntityPointer);
  596. }
  597. else {
  598. return isOfType(obj, RPointEntity);
  599. }
  600. }
  601. /**
  602. * Checks if the given object is an image entity.
  603. *
  604. * \return true if the given object is an image entity (RImageEntity).
  605. */
  606. function isImageEntity(obj) {
  607. if (RSettings.getQtVersion() < 0x060000) {
  608. return isOfType(obj, RImageEntity) || isOfType(obj, RImageEntityPointer);
  609. }
  610. else {
  611. return isOfType(obj, RImageEntity);
  612. }
  613. }
  614. /**
  615. * \return true if the given object is a polyline entity (RPolylineEntity).
  616. */
  617. function isPolylineEntity(obj) {
  618. if (RSettings.getQtVersion() < 0x060000) {
  619. return isOfType(obj, RPolylineEntity) || isOfType(obj, RPolylineEntityPointer);
  620. }
  621. else {
  622. return isOfType(obj, RPolylineEntity);
  623. }
  624. }
  625. /**
  626. * \return true if the given object is a geometrically closed polyline entity.
  627. */
  628. function isClosedPolylineEntity(obj, tolerance) {
  629. if (isNull(tolerance)) {
  630. return isPolylineEntity(obj) && obj.isGeometricallyClosed();
  631. }
  632. else {
  633. return isPolylineEntity(obj) && obj.isGeometricallyClosed(tolerance);
  634. }
  635. }
  636. /**
  637. * \return true if the given object is a geometrically open polyline entity.
  638. */
  639. function isOpenPolylineEntity(obj, tolerance) {
  640. if (isNull(tolerance)) {
  641. return isPolylineEntity(obj) && !obj.isGeometricallyClosed();
  642. }
  643. else {
  644. return isPolylineEntity(obj) && !obj.isGeometricallyClosed(tolerance);
  645. }
  646. }
  647. /**
  648. * Checks if the given object is a solid entity.
  649. *
  650. * \return true if the given object is a solid entity (RSolidEntity).
  651. */
  652. function isSolidEntity(obj) {
  653. if (RSettings.getQtVersion() < 0x060000) {
  654. return isOfType(obj, RSolidEntity) || isOfType(obj, RSolidEntityPointer);
  655. }
  656. else {
  657. return isOfType(obj, RSolidEntity);
  658. }
  659. }
  660. /**
  661. * Checks if the given object is a trace entity.
  662. *
  663. * \return true if the given object is a trace entity (RTraceEntity).
  664. */
  665. function isTraceEntity(obj) {
  666. if (RSettings.getQtVersion() < 0x060000) {
  667. return isOfType(obj, RTraceEntity) || isOfType(obj, RTraceEntityPointer);
  668. }
  669. else {
  670. return isOfType(obj, RTraceEntity);
  671. }
  672. }
  673. /**
  674. * Checks if the given object is a face entity.
  675. *
  676. * \return true if the given object is a face entity (RFaceEntity).
  677. */
  678. function isFaceEntity(obj) {
  679. if (RSettings.getQtVersion() < 0x060000) {
  680. return isOfType(obj, RFaceEntity) || isOfType(obj, RFaceEntityPointer);
  681. }
  682. else {
  683. return isOfType(obj, RFaceEntity);
  684. }
  685. }
  686. /**
  687. * Checks if the given object is a viewport entity.
  688. *
  689. * \return true if the given object is a viewport entity (RViewportEntity).
  690. */
  691. function isViewportEntity(obj) {
  692. if (RSettings.getQtVersion() < 0x060000) {
  693. return isOfType(obj, RViewportEntity) || isOfType(obj, RViewportEntityPointer);
  694. }
  695. else {
  696. return isOfType(obj, RViewportEntity);
  697. }
  698. }
  699. /**
  700. * Checks if the given object is a spline entity.
  701. *
  702. * \return true if the given object is a spline entity (RSplineEntity).
  703. */
  704. function isSplineEntity(obj) {
  705. if (RSettings.getQtVersion() < 0x060000) {
  706. return isOfType(obj, RSplineEntity) || isOfType(obj, RSplineEntityPointer);
  707. }
  708. else {
  709. return isOfType(obj, RSplineEntity);
  710. }
  711. }
  712. /**
  713. * Checks if the given object is a spline entity with fit points.
  714. *
  715. * \return true if the given object is a spline entity (RSplineEntity) with fit points.
  716. */
  717. function isSplineEntityWithFitPoints(obj) {
  718. return isSplineEntity(obj) && obj.hasFitPoints();
  719. }
  720. function isClosedSplineEntity(obj, tolerance) {
  721. if (isNull(tolerance)) {
  722. return isSplineEntity(obj) && obj.isGeometricallyClosed();
  723. }
  724. else {
  725. return isSplineEntity(obj) && obj.isGeometricallyClosed(tolerance);
  726. }
  727. }
  728. /**
  729. * Checks if the given object is a text, attribute or attribute definition entity.
  730. *
  731. * \return true if the given object is a text based entity (RTextBasedEntity).
  732. */
  733. function isTextBasedEntity(obj) {
  734. return isTextEntity(obj) || isAttributeDefinitionEntity(obj) || isAttributeEntity(obj);
  735. }
  736. /**
  737. * Checks if the given object is a text entity.
  738. *
  739. * \return true if the given object is a text entity (RTextEntity).
  740. */
  741. function isTextEntity(obj) {
  742. if (RSettings.getQtVersion() < 0x060000) {
  743. return isOfType(obj, RTextEntity) || isOfType(obj, RTextEntityPointer);
  744. }
  745. else {
  746. return isOfType(obj, RTextEntity);
  747. }
  748. }
  749. /**
  750. * Checks if the given object is a simple text entity.
  751. *
  752. * \return true if the given object is a text entity (RTextEntity) and simple.
  753. */
  754. function isSimpleTextEntity(obj) {
  755. return isTextEntity(obj) && obj.isSimple();
  756. }
  757. /**
  758. * Checks if the given object is a block reference entity.
  759. *
  760. * \return true if the given object is a block reference entity (RBlockReferenceEntity).
  761. */
  762. function isBlockReferenceEntity(obj) {
  763. if (RSettings.getQtVersion() < 0x060000) {
  764. return isOfType(obj, RBlockReferenceEntity) || isOfType(obj, RBlockReferenceEntityPointer);
  765. }
  766. else {
  767. return isOfType(obj, RBlockReferenceEntity);
  768. }
  769. }
  770. /**
  771. * Checks if the given object is an attribute definition entity.
  772. *
  773. * \return true if the given object is an attribute definition entity (RAttributeDefinitionEntity).
  774. */
  775. function isAttributeDefinitionEntity(obj) {
  776. if (RSettings.getQtVersion() < 0x060000) {
  777. return isOfType(obj, RAttributeDefinitionEntity) || isOfType(obj, RAttributeDefinitionEntityPointer);
  778. }
  779. else {
  780. return isOfType(obj, RAttributeDefinitionEntity);
  781. }
  782. }
  783. /**
  784. * Checks if the given object is an attribute entity.
  785. *
  786. * \return true if the given object is an attribute entity (RAttributeEntity).
  787. */
  788. function isAttributeEntity(obj) {
  789. if (RSettings.getQtVersion() < 0x060000) {
  790. return isOfType(obj, RAttributeEntity) || isOfType(obj, RAttributeEntityPointer);
  791. }
  792. else {
  793. return isOfType(obj, RAttributeEntity);
  794. }
  795. }
  796. /**
  797. * Checks if the given object is a leader entity.
  798. *
  799. * \return true if the given object is a leader entity
  800. * (RLeaderEntity).
  801. */
  802. function isLeaderEntity(obj) {
  803. if (RSettings.getQtVersion() < 0x060000) {
  804. return isOfType(obj, RLeaderEntity) || isOfType(obj, RLeaderEntityPointer);
  805. }
  806. else {
  807. return isOfType(obj, RLeaderEntity);
  808. }
  809. }
  810. /**
  811. * Checks if the given object is a tolerance entity.
  812. *
  813. * \return true if the given object is a tolerance entity (RToleranceEntity).
  814. */
  815. function isToleranceEntity(obj) {
  816. if (RSettings.getQtVersion() < 0x060000) {
  817. return isOfType(obj, RToleranceEntity) || isOfType(obj, RToleranceEntityPointer);
  818. }
  819. else {
  820. return isOfType(obj, RToleranceEntity);
  821. }
  822. }
  823. /**
  824. * Checks if the given object is an entity of the given type.
  825. */
  826. function isEntityType(obj, type) {
  827. if (!isEntity(obj)) {
  828. return false;
  829. }
  830. if (obj.getType()===type) {
  831. return true;
  832. }
  833. if (type===RS.EntityTextBased) {
  834. if (isTextBasedEntity(obj)) {
  835. return true;
  836. }
  837. }
  838. if (type===RS.EntityDimension) {
  839. if (isDimensionEntity(obj)) {
  840. return true;
  841. }
  842. }
  843. if (type===RS.EntityAll) {
  844. return true;
  845. }
  846. return false;
  847. }
  848. /**
  849. * Checks if the given object is a shape.
  850. *
  851. * \return true if the given object is a shape (derived from RShape).
  852. */
  853. function isShape(obj) {
  854. return !isNull(obj) &&
  855. isFunction(obj.getBoundingBox) &&
  856. isFunction(obj.getClosestPointOnShape);
  857. }
  858. /**
  859. * Checks if the given object is a directed shape.
  860. *
  861. * \return true if the given object is a directed shape.
  862. */
  863. function isDirectedShape(obj) {
  864. return isShape(obj) && obj.isDirected();
  865. }
  866. /**
  867. * Checks if the given object is an arc shape.
  868. *
  869. * \return true if the given object is an arc shape (RArc).
  870. */
  871. function isArcShape(obj) {
  872. if (RSettings.getQtVersion() < 0x060000) {
  873. return isOfType(obj, RArc) || isOfType(obj, RArcPointer);
  874. }
  875. else {
  876. return isOfType(obj, RArc);
  877. }
  878. }
  879. /**
  880. * Checks if the given object is a circle shape.
  881. *
  882. * \return true if the given object is a circle shape (RCircle).
  883. */
  884. function isCircleShape(obj) {
  885. if (RSettings.getQtVersion() < 0x060000) {
  886. return isOfType(obj, RCircle) || isOfType(obj, RCirclePointer);
  887. }
  888. else {
  889. return isOfType(obj, RCircle);
  890. }
  891. }
  892. /**
  893. * Checks if the given object is an ellipse shape.
  894. *
  895. * \return true if the given object is an ellipse shape (REllipse).
  896. */
  897. function isEllipseShape(obj) {
  898. if (RSettings.getQtVersion() < 0x060000) {
  899. return isOfType(obj, REllipse) || isOfType(obj, REllipsePointer);
  900. }
  901. else {
  902. return isOfType(obj, REllipse);
  903. }
  904. }
  905. /**
  906. * Checks if the given object is a full ellipse shape.
  907. *
  908. * \return true if the given object is a full ellipse shape (REllipse).
  909. */
  910. function isFullEllipseShape(obj) {
  911. return isEllipseShape(obj) && obj.isFullEllipse();
  912. }
  913. /**
  914. * Checks if the given object is an ellipse arc shape.
  915. *
  916. * \return true if the given object is an ellipse arc shape (REllipse).
  917. */
  918. function isEllipseArcShape(obj) {
  919. return isEllipseShape(obj) && !obj.isFullEllipse();
  920. }
  921. /**
  922. * Checks if the given object is a line based shape.
  923. *
  924. * \return true if the given object is a line based shape (RLine, RXline, RRay).
  925. */
  926. function isLineBasedShape(obj) {
  927. return isLineShape(obj) || isXLineShape(obj) || isRayShape(obj);
  928. }
  929. /**
  930. * Checks if the given object is a line shape.
  931. *
  932. * \return true if the given object is a line shape (RLine).
  933. */
  934. function isLineShape(obj) {
  935. if (RSettings.getQtVersion() < 0x060000) {
  936. return isOfType(obj, RLine) || isOfType(obj, RLinePointer);
  937. }
  938. else {
  939. return isOfType(obj, RLine);
  940. }
  941. }
  942. /**
  943. * Checks if the given object is an xline shape.
  944. *
  945. * \return true if the given object is an xline shape (RXLine).
  946. */
  947. function isXLineShape(obj) {
  948. if (RSettings.getQtVersion() < 0x060000) {
  949. return isOfType(obj, RXLine) || isOfType(obj, RXLinePointer);
  950. }
  951. else {
  952. return isOfType(obj, RXLine);
  953. }
  954. }
  955. /**
  956. * Checks if the given object is a ray shape.
  957. *
  958. * \return true if the given object is a ray shape (RRay).
  959. */
  960. function isRayShape(obj) {
  961. if (RSettings.getQtVersion() < 0x060000) {
  962. return isOfType(obj, RRay) || isOfType(obj, RRayPointer);
  963. }
  964. else {
  965. return isOfType(obj, RRay);
  966. }
  967. }
  968. /**
  969. * Checks if the given object is a point shape.
  970. *
  971. * \return true if the given object is a point shape (RPoint).
  972. */
  973. function isPointShape(obj) {
  974. if (RSettings.getQtVersion() < 0x060000) {
  975. return isOfType(obj, RPoint) || isOfType(obj, RPointPointer);
  976. }
  977. else {
  978. return isOfType(obj, RPoint);
  979. }
  980. }
  981. /**
  982. * Checks if the given object is a polyline shape.
  983. *
  984. * \return true if the given object is a polyline shape (RPolyline).
  985. */
  986. function isPolylineShape(obj) {
  987. if (RSettings.getQtVersion() < 0x060000) {
  988. return isOfType(obj, RPolyline) || isOfType(obj, RPolylinePointer);
  989. }
  990. else {
  991. return isOfType(obj, RPolyline);
  992. }
  993. }
  994. /**
  995. * \return true if the given object is a geometrically closed polyline shape.
  996. */
  997. function isClosedPolylineShape(obj) {
  998. return isPolylineShape(obj) && obj.isGeometricallyClosed();
  999. }
  1000. /**
  1001. * Checks if the given object is a spline shape.
  1002. *
  1003. * \return true if the given object is a spline shape (RSpline).
  1004. */
  1005. function isSplineShape(obj) {
  1006. if (RSettings.getQtVersion() < 0x060000) {
  1007. return isOfType(obj, RSpline) || isOfType(obj, RSplinePointer);
  1008. }
  1009. else {
  1010. return isOfType(obj, RSpline);
  1011. }
  1012. }
  1013. /**
  1014. * Checks if the given object is a closed spline shape.
  1015. *
  1016. * \return true if the given object is a closed spline shape (RSpline).
  1017. */
  1018. function isClosedSplineShape(obj, tolerance) {
  1019. if (isNull(tolerance)) {
  1020. return isSplineShape(obj) && obj.isGeometricallyClosed();
  1021. }
  1022. else {
  1023. return isSplineShape(obj) && obj.isGeometricallyClosed(tolerance);
  1024. }
  1025. }
  1026. /**
  1027. * Checks if the given object is a triangle shape.
  1028. *
  1029. * \return true if the given object is a triangle shape (RTriangle).
  1030. */
  1031. function isTriangleShape(obj) {
  1032. if (RSettings.getQtVersion() < 0x060000) {
  1033. return isOfType(obj, RTriangle) || isOfType(obj, RTrianglePointer);
  1034. }
  1035. else {
  1036. return isOfType(obj, RTriangle);
  1037. }
  1038. }
  1039. /**
  1040. * Converts the given entity type enum to the class name.
  1041. *
  1042. * \return Class name (e.g. "RLineEntity" for RS.EntityLine
  1043. *
  1044. * \param type Entity type (RS::EntityType)
  1045. */
  1046. function entityTypeToClass(type) {
  1047. switch (type) {
  1048. case RS.ObjectAll:
  1049. return "RObject";
  1050. case RS.ObjectUnknown:
  1051. return "RObject";
  1052. case RS.ObjectBlock:
  1053. return "RBlock";
  1054. case RS.ObjectLayer:
  1055. return "RLayer";
  1056. case RS.ObjectLayout:
  1057. return "RLayout";
  1058. case RS.ObjectLinetype:
  1059. return "RLinetype";
  1060. case RS.ObjectView:
  1061. return "RView";
  1062. case RS.ObjectDimStyle:
  1063. return "RDimStyle";
  1064. case RS.EntityAll:
  1065. return "REntity";
  1066. case RS.EntityBlockRef:
  1067. return "RBlockReferenceEntity";
  1068. case RS.EntityArc:
  1069. return "RArcEntity";
  1070. case RS.EntityAttribute:
  1071. return "RAttributeEntity";
  1072. case RS.EntityAttributeDefinition:
  1073. return "RAttributeDefinitionEntity";
  1074. case RS.EntityCircle:
  1075. return "RCircleEntity";
  1076. case RS.EntityDimension:
  1077. return "RDimensionEntity";
  1078. case RS.EntityDimAligned:
  1079. return "RDimAlignedEntity";
  1080. case RS.EntityDimAngular:
  1081. return "RDimAngularEntity";
  1082. case RS.EntityDimAngular2L:
  1083. return "RDimAngular2LEntity";
  1084. case RS.EntityDimAngular3P:
  1085. return "RDimAngular3PEntity";
  1086. case RS.EntityDimArcLength:
  1087. return "RDimArcLengthEntity";
  1088. case RS.EntityDimDiametric:
  1089. return "RDimDiametricEntity";
  1090. case RS.EntityDimOrdinate:
  1091. return "RDimOrdinateEntity";
  1092. case RS.EntityDimRotated:
  1093. return "RDimRotatedEntity";
  1094. case RS.EntityDimRadial:
  1095. return "RDimRadialEntity";
  1096. case RS.EntityEllipse:
  1097. return "REllipseEntity";
  1098. case RS.EntityHatch:
  1099. return "RHatchEntity";
  1100. case RS.EntityImage:
  1101. return "RImageEntity";
  1102. case RS.EntityLeader:
  1103. return "RLeaderEntity";
  1104. case RS.EntityTolerance:
  1105. return "RToleranceEntity";
  1106. case RS.EntityLine:
  1107. return "RLineEntity";
  1108. case RS.EntityXLine:
  1109. return "RXLineEntity";
  1110. case RS.EntityRay:
  1111. return "RRayEntity";
  1112. case RS.EntityPoint:
  1113. return "RPointEntity";
  1114. case RS.EntityPolyline:
  1115. return "RPolylineEntity";
  1116. case RS.EntitySolid:
  1117. return "RSolidEntity";
  1118. case RS.EntityTrace:
  1119. return "RTraceEntity";
  1120. case RS.EntityFace:
  1121. return "RFaceEntity";
  1122. case RS.EntitySpline:
  1123. return "RSplineEntity";
  1124. case RS.EntityTextBased:
  1125. return "RTextBasedEntity";
  1126. case RS.EntityText:
  1127. return "RTextEntity";
  1128. case RS.EntityViewport:
  1129. return "RViewportEntity";
  1130. default:
  1131. return undefined;
  1132. }
  1133. }
  1134. /**
  1135. * Converts the given entity type enum to a human readable,
  1136. * translated string.
  1137. *
  1138. * \return A translated string for the given entity type.
  1139. *
  1140. * \param type Entity type (RS::EntityType)
  1141. * \param plural True to return plural, false (default) to return singular.
  1142. */
  1143. function entityTypeToString(type, plural) {
  1144. if (isNull(plural)) {
  1145. plural = false;
  1146. }
  1147. switch (type) {
  1148. case RS.ObjectAll:
  1149. return plural ? qsTr("Objects") : qsTr("Object");
  1150. case RS.ObjectUnknown:
  1151. return plural ? qsTr("Unknown Objects") : qsTr("Unknown Object");
  1152. case RS.ObjectBlock:
  1153. return plural ? qsTr("Blocks") : qsTr("Block");
  1154. case RS.ObjectLayer:
  1155. return plural ? qsTr("Layers") : qsTr("Layer");
  1156. case RS.ObjectLayout:
  1157. return plural ? qsTr("Layouts") : qsTr("Layout");
  1158. case RS.ObjectLinetype:
  1159. return plural ? qsTr("Linetypes") : qsTr("Linetype");
  1160. case RS.ObjectView:
  1161. return plural ? qsTr("Views") : qsTr("View");
  1162. case RS.ObjectDimStyle:
  1163. return plural ? qsTr("Dimension Styles") : qsTr("Dimension Style");
  1164. case RS.EntityAll:
  1165. return plural ? qsTr("Entities") : qsTr("Entity");
  1166. case RS.Entity3dFace:
  1167. return plural ? qsTr("3dFaces") : qsTr("3dFace");
  1168. case RS.EntityBlockRef:
  1169. return plural ? qsTr("Block References") : qsTr("Block Reference");
  1170. case RS.EntityBlockRefAttr:
  1171. return plural ? qsTr("Block References and Attributes") : qsTr("Block Reference and Attributes");
  1172. case RS.EntityArc:
  1173. return plural ? qsTr("Arcs") : qsTr("Arc");
  1174. case RS.EntityAttribute:
  1175. return plural ? qsTr("Attributes") : qsTr("Attribute");
  1176. case RS.EntityAttributeDefinition:
  1177. return plural ? qsTr("Attribute Definitions") : qsTr("Attribute Definition");
  1178. case RS.EntityCircle:
  1179. return plural ? qsTr("Circles") : qsTr("Circle");
  1180. case RS.EntityDimension:
  1181. return plural ? qsTr("Dimensions") : qsTr("Dimension");
  1182. case RS.EntityDimAligned:
  1183. return plural ? qsTr("Aligned Dimensions") : qsTr("Aligned Dimension");
  1184. case RS.EntityDimAngular:
  1185. return plural ? qsTr("Angular Dimensions") : qsTr("Angular Dimension");
  1186. case RS.EntityDimAngular2L:
  1187. return plural ? qsTr("Angular Dimensions (2 Line)") : qsTr("Angular Dimension (2 Line)");
  1188. case RS.EntityDimAngular3P:
  1189. return plural ? qsTr("Angular Dimensions (3 Point)") : qsTr("Angular Dimension (3 Point)");
  1190. case RS.EntityDimArcLength:
  1191. return plural ? qsTr("Arc Dimension") : qsTr("Arc Dimension");
  1192. case RS.EntityDimDiametric:
  1193. return plural ? qsTr("Diametric Dimensions") : qsTr("Diametric Dimension");
  1194. case RS.EntityDimOrdinate:
  1195. return plural ? qsTr("Ordinate Dimensions") : qsTr("Ordinate Dimension");
  1196. case RS.EntityDimRotated:
  1197. return plural ? qsTr("Rotated Dimensions") : qsTr("Rotated Dimension");
  1198. case RS.EntityDimRadial:
  1199. return plural ? qsTr("Radial Dimensions") : qsTr("Radial Dimension");
  1200. case RS.EntityEllipse:
  1201. return plural ? qsTr("Ellipses") : qsTr("Ellipse");
  1202. case RS.EntityHatch:
  1203. return plural ? qsTr("Hatches") : qsTr("Hatch");
  1204. case RS.EntityImage:
  1205. return plural ? qsTr("Images") : qsTr("Image");
  1206. case RS.EntityLeader:
  1207. return plural ? qsTr("Leaders") : qsTr("Leader");
  1208. case RS.EntityTolerance:
  1209. return plural ? qsTr("Tolerances") : qsTr("Tolerance");
  1210. case RS.EntityLine:
  1211. return plural ? qsTr("Lines") : qsTr("Line");
  1212. case RS.EntityXLine:
  1213. return plural ? qsTr("Infinite Lines") : qsTr("Infinite Line");
  1214. case RS.EntityRay:
  1215. return plural ? qsTr("Rays") : qsTr("Ray");
  1216. case RS.EntityPoint:
  1217. return plural ? qsTr("Points") : qsTr("Point");
  1218. case RS.EntityPolyline:
  1219. return plural ? qsTr("Polylines") : qsTr("Polyline");
  1220. case RS.EntitySolid:
  1221. return plural ? qsTr("Solids") : qsTr("Solid");
  1222. case RS.EntityTrace:
  1223. return plural ? qsTr("Traces") : qsTr("Trace");
  1224. case RS.EntityFace:
  1225. return plural ? qsTr("Faces") : qsTr("Face");
  1226. case RS.EntitySpline:
  1227. return plural ? qsTr("Splines") : qsTr("Spline");
  1228. case RS.EntityTextBased:
  1229. return plural ? qsTr("Text based") : qsTr("Text based");
  1230. case RS.EntityText:
  1231. return plural ? qsTr("Texts") : qsTr("Text");
  1232. case RS.EntityViewport:
  1233. return plural ? qsTr("Viewports") : qsTr("Viewport");
  1234. case RS.EntityUnknown:
  1235. default:
  1236. return plural ? qsTr("Unknown Entities") : qsTr("Unknown Entity");
  1237. }
  1238. }
  1239. /**
  1240. * Converts the given entity type name to the entity type enum.
  1241. *
  1242. * \return entity type enum.
  1243. *
  1244. * \param typeName Entity type name ("Line", "Arc", ...)
  1245. */
  1246. function getEntityType(typeName) {
  1247. switch (typeName) {
  1248. case "Block":
  1249. return RS.ObjectBlock;
  1250. case "Layer":
  1251. return RS.ObjectLayer;
  1252. case "Layout":
  1253. return RS.ObjectLayout;
  1254. case "Linetype":
  1255. return RS.ObjectLinetype;
  1256. case "View":
  1257. return RS.ObjectView;
  1258. case "Entity":
  1259. return RS.EntityAll;
  1260. case "3dFace":
  1261. return RS.Entity3dFace;
  1262. case "Block Reference":
  1263. return RS.EntityBlockRef;
  1264. case "Block Reference and Attributes":
  1265. return RS.EntityBlockRefAttr;
  1266. case "Arc":
  1267. return RS.EntityArc;
  1268. case "Attribute":
  1269. return RS.EntityAttribute;
  1270. case "Attribute Definition":
  1271. return RS.EntityAttributeDefinition;
  1272. case "Circle":
  1273. return RS.EntityCircle;
  1274. case "Dimension":
  1275. return RS.EntityDimension;
  1276. case "Aligned Dimension":
  1277. return RS.EntityDimAligned;
  1278. case "Angular Dimension":
  1279. return RS.EntityDimAngular;
  1280. case "Angular Dimension (2 Line)":
  1281. return RS.EntityDimAngular2L;
  1282. case "Angular Dimension (3 Point)":
  1283. return RS.EntityDimAngular3P;
  1284. case "Arc Dimension":
  1285. return RS.EntityDimArcLength;
  1286. case "Diametric Dimension":
  1287. return RS.EntityDimDiametric;
  1288. case "Ordinate Dimension":
  1289. return RS.EntityDimOrdinate;
  1290. case "Rotated Dimension":
  1291. return RS.EntityDimRotated;
  1292. case "Radial Dimension":
  1293. return RS.EntityDimRadial;
  1294. case "Ellipse":
  1295. return RS.EntityEllipse;
  1296. case "Hatch":
  1297. return RS.EntityHatch;
  1298. case "Image":
  1299. return RS.EntityImage;
  1300. case "Leader":
  1301. return RS.EntityLeader;
  1302. case "Tolerance":
  1303. return RS.EntityTolerance;
  1304. case "Line":
  1305. return RS.EntityLine;
  1306. case "Infinite Line":
  1307. case "XLine":
  1308. return RS.EntityXLine;
  1309. case "Ray":
  1310. return RS.EntityRay;
  1311. case "Point":
  1312. return RS.EntityPoint;
  1313. case "Polyline":
  1314. return RS.EntityPolyline;
  1315. case "Solid":
  1316. return RS.EntitySolid;
  1317. case "Trace":
  1318. return RS.EntityTrace;
  1319. case "Face":
  1320. return RS.EntityFace;
  1321. case "Spline":
  1322. return RS.EntitySpline;
  1323. case "Text based":
  1324. return RS.EntityTextBased;
  1325. case "Text":
  1326. return RS.EntityText;
  1327. case "Viewport":
  1328. return RS.EntityViewport;
  1329. default:
  1330. return RS.ObjectUnknown;
  1331. }
  1332. }
  1333. function translateFilterStrings(filterStrings) {
  1334. for (var i=0; i<filterStrings.length; i++) {
  1335. filterStrings[i] = filterStrings[i].replace("All CAD Files", qsTr("All CAD Files"));
  1336. filterStrings[i] = filterStrings[i].replace("DXF Files", qsTr("DXF Files"));
  1337. filterStrings[i] = filterStrings[i].replace("SVG Files", qsTr("SVG Files"));
  1338. filterStrings[i] = filterStrings[i].replace("DXF Drawing", qsTr("DXF Drawing"));
  1339. filterStrings[i] = filterStrings[i].replace("DWG Drawing", qsTr("DWG Drawing"));
  1340. filterStrings[i] = filterStrings[i].replace("PDF File", qsTr("PDF File"));
  1341. filterStrings[i] = filterStrings[i].replace("PDF/A-1B File", qsTr("PDF/A-1B File"));
  1342. }
  1343. return filterStrings;
  1344. }
  1345. /**
  1346. * Checks the type of the given object.
  1347. *
  1348. * \return true if the given object is a combo box.
  1349. */
  1350. function isComboBox(obj) {
  1351. return !isNull(obj) &&
  1352. (
  1353. isOfType(obj, QComboBox) ||
  1354. isOfType(obj, RColorCombo) ||
  1355. isOfType(obj, RLineweightCombo) ||
  1356. isOfType(obj, RLinetypeCombo)
  1357. );
  1358. }
  1359. /**
  1360. * Gets an object from its object path.
  1361. * Object paths are separated by <tt>::</tt>.
  1362. * \param path the object path
  1363. * \param widget the widget [optional, used for the recursive call], obsolete
  1364. * \return Object or undefined
  1365. */
  1366. function objectFromPath(path) {
  1367. var child = getMainWindow();
  1368. var children = path.split("::");
  1369. for (var i = 1; i < children.length; ++i) {
  1370. if (typeof(child)==="undefined") {
  1371. return undefined;
  1372. }
  1373. child = child.findChild(children[i]);
  1374. }
  1375. return child;
  1376. }
  1377. /**
  1378. * Gets the widget path for the given widget.
  1379. * The widgets in the path are separated with <tt>::</tt>,
  1380. * e.g. <tt>MainWindow::LayerListDock::LayerWidget::btAdd</tt>
  1381. * \param widget the widget
  1382. * \return the widget path
  1383. */
  1384. function getWidgetPath(widget) {
  1385. var pw = widget.parentWidget();
  1386. var str = widget.objectName !== "" ? widget.objectName : widget.toString();
  1387. if (isNull(pw)) {
  1388. return str;
  1389. }
  1390. return getWidgetPath(pw) + "::" + str;
  1391. }
  1392. /**
  1393. * Gets all child widgets and stores them in an array.
  1394. *
  1395. * All child widgets are retrieved (recursively).
  1396. *
  1397. * Use of this function as shown in the example below
  1398. * (formWidget is the parent widget).
  1399. * <tt>
  1400. * var widgets = getWidgets(formWidget);
  1401. * widgets["FindText"].text = text;
  1402. * </tt>
  1403. *
  1404. * \param widget the parent widget
  1405. * \param ca the initial array which holds some child widgets for
  1406. * recursive calls
  1407. * \param allowDuplicates True to collect widgets with same name under
  1408. * a different key ("MyField", "MyField_1", "MyField_2").
  1409. * \return Array of child widgets.
  1410. */
  1411. function getWidgets(widget, ca, allowDuplicates) {
  1412. if (isNull(widget) || isDeleted(widget)) {
  1413. return undefined;
  1414. }
  1415. if (isNull(allowDuplicates)) {
  1416. allowDuplicates = false;
  1417. }
  1418. if (isNull(ca)) {
  1419. ca = {};
  1420. }
  1421. var children = widget.children();
  1422. for (var i = 0; i < children.length; ++i) {
  1423. var child = children[i];
  1424. if (isNull(child) || isDeleted(child)) {
  1425. continue;
  1426. }
  1427. if (!isNull(child.objectName) && child.objectName !== "") {
  1428. if (isNull(ca[child.objectName]) || allowDuplicates===false) {
  1429. // new child or overwrite child:
  1430. ca[child.objectName] = child;
  1431. }
  1432. else {
  1433. // find alternative key for child:
  1434. for (var k=1; k<10000; k++) {
  1435. if (isNull(ca[child.objectName + "_" + k])) {
  1436. ca[child.objectName + "_" + k] = child;
  1437. break;
  1438. }
  1439. }
  1440. }
  1441. }
  1442. if (!isNull(child.children) && child.children().length !== 0) {
  1443. getWidgets(child, ca, allowDuplicates);
  1444. }
  1445. }
  1446. return ca;
  1447. }
  1448. /**
  1449. * Converts radiant to degrees.
  1450. * \param val the value in radiant
  1451. * \return the value in degrees
  1452. */
  1453. function rad2deg(val) {
  1454. return val * (180 / Math.PI);
  1455. }
  1456. /**
  1457. * Converts degrees to radiant.
  1458. * \param val the value in degrees
  1459. * \return the value in radiant
  1460. */
  1461. function deg2rad(val) {
  1462. return val * (Math.PI / 180);
  1463. }
  1464. function roundDouble(num, dec) {
  1465. return Math.round(num*Math.pow(10, dec)) / Math.pow(10, dec);
  1466. }
  1467. function roundVector(v, dec) {
  1468. var x = roundDouble(v.x, dec);
  1469. var y = roundDouble(v.y, dec);
  1470. return new RVector(x, y);
  1471. }
  1472. /**
  1473. * Copies a directory recursively.
  1474. * Existing files are not overridden.
  1475. * \param sourceDirPath The source directory.
  1476. * \param destDirPath The destination directory.
  1477. * \return true, if the directory was deleted successfully
  1478. */
  1479. function copyDirectory(sourceDirPath, destDirPath) {
  1480. var sourceDir = new QDir(sourceDirPath);
  1481. if (!sourceDir.exists()) {
  1482. return false;
  1483. }
  1484. var destDir = new QDir(destDirPath);
  1485. if (!destDir.exists()) {
  1486. destDir.mkdir(destDirPath);
  1487. }
  1488. var i;
  1489. var files;
  1490. var srcName;
  1491. var destName;
  1492. var filterFlags = makeQDirFilters(QDir.Files);
  1493. var sortFlags = makeQDirSortFlags(QDir.NoSort);
  1494. files = sourceDir.entryList(filterFlags, sortFlags);
  1495. for(i = 0; i< files.length; i++) {
  1496. srcName = sourceDirPath + QDir.separator + files[i];
  1497. destName = destDirPath + QDir.separator + files[i];
  1498. if (!QFile.copy(srcName, destName)) {
  1499. qWarning("library.js:", "copyDirectory(): Warning: File exists:", destName);
  1500. }
  1501. }
  1502. var flags = makeQDirFilters(QDir.AllDirs, QDir.NoDotAndDotDot);
  1503. files = sourceDir.entryList(flags);
  1504. for(i = 0; i< files.length; i++) {
  1505. srcName = sourceDirPath + QDir.separator + files[i];
  1506. destName = destDirPath + QDir.separator + files[i];
  1507. copyDirectory(srcName, destName);
  1508. }
  1509. return true;
  1510. }
  1511. /**
  1512. * Removes a directory recursively.
  1513. * \param dirPath The directory to remove.
  1514. * \return true, if no errors occurs
  1515. */
  1516. function removeDirectory(dirPath) {
  1517. var dir = new QDir(dirPath);
  1518. var hasErr = false;
  1519. if (dir.exists()) {
  1520. var flags = makeQDirFilters(QDir.NoDotAndDotDot, QDir.Dirs, QDir.Files, QDir.Hidden);
  1521. var entries = dir.entryInfoList(flags);
  1522. for (var i = 0; i < entries.length; i++) {
  1523. var entryInfo = entries[i];
  1524. var path = entryInfo.absoluteFilePath();
  1525. if (entryInfo.isDir()) {
  1526. hasErr = removeDirectory(path);
  1527. } else {
  1528. var file = new QFile(path);
  1529. if (!file.remove()) {
  1530. hasErr = true;
  1531. }
  1532. }
  1533. if (hasErr) {
  1534. break;
  1535. }
  1536. }
  1537. if (!dir.rmdir(dir.absolutePath())) {
  1538. hasErr = true;
  1539. }
  1540. }
  1541. return hasErr;
  1542. }
  1543. /**
  1544. * Finds a file recursively.
  1545. * \param dirPath The directory to search.
  1546. * \param fileName File name.
  1547. * \return Path of the file or undefined.
  1548. */
  1549. function findFile(dirPath, fileName, ignoreDirs) {
  1550. if (isNull(ignoreDirs)) {
  1551. ignoreDirs = [];
  1552. }
  1553. var res = [];
  1554. var dir = new QDir(dirPath);
  1555. if (!dir.exists()) {
  1556. return res;
  1557. }
  1558. var i;
  1559. var files;
  1560. var name;
  1561. var filterFlags = makeQDirFilters(QDir.Files);
  1562. var sortFlags = makeQDirSortFlags(QDir.NoSort);
  1563. files = dir.entryList([fileName], filterFlags, sortFlags);
  1564. for (i=0; i<files.length; i++) {
  1565. res = res.concat(dirPath + QDir.separator + files[i]);
  1566. }
  1567. var flags = makeQDirFilters(QDir.AllDirs, QDir.NoDotAndDotDot);
  1568. files = dir.entryList(flags);
  1569. for (i = 0; i< files.length; i++) {
  1570. var nextDir = dirPath + QDir.separator + files[i];
  1571. if (ignoreDirs.indexOf(files[i])==-1) {
  1572. res = res.concat(findFile(nextDir, fileName, ignoreDirs));
  1573. }
  1574. }
  1575. return res;
  1576. }
  1577. /**
  1578. * Clones the given object (deep copy).
  1579. */
  1580. function deepCopy(obj) {
  1581. if (Object.prototype.toString.call(obj) === '[object Array]') {
  1582. var out = [], i = 0, len = obj.length;
  1583. for ( ; i < len; i++ ) {
  1584. out[i] = arguments.callee(obj[i]);
  1585. }
  1586. return out;
  1587. }
  1588. if (typeof obj === 'object') {
  1589. var out = {}, i;
  1590. for ( i in obj ) {
  1591. out[i] = arguments.callee(obj[i]);
  1592. }
  1593. return out;
  1594. }
  1595. return obj;
  1596. }
  1597. function hasOwnPropertyCI(obj, prop) {
  1598. return Object.keys(obj)
  1599. .filter(function (v) {
  1600. return v.toLowerCase() === prop.toLowerCase();
  1601. }).length > 0;
  1602. }
  1603. function getOwnPropertyCI(obj, prop) {
  1604. var ret = Object.keys(obj)
  1605. .filter(function (v) {
  1606. return v.toLowerCase() === prop.toLowerCase();
  1607. });
  1608. if (ret.length>0) {
  1609. return obj[ret[0]];
  1610. }
  1611. return undefined;
  1612. }
  1613. /**
  1614. * \return A new array which contains every unique item of this array only once.
  1615. */
  1616. Array.prototype.unique = function(method) {
  1617. var a = [], i, l = this.length;
  1618. for (i = 0; i < l; i++) {
  1619. if (isNull(method)) {
  1620. if (a.indexOf(this[i], 0) < 0) {
  1621. a.push(this[i]);
  1622. }
  1623. }
  1624. else {
  1625. if (!a.contains(this[i], method)) {
  1626. a.push(this[i]);
  1627. }
  1628. }
  1629. }
  1630. return a;
  1631. };
  1632. /**
  1633. * \return True if this array contains the given value or object 'obj'.
  1634. * \param method Name of method to call from obj to compare it to anther object.
  1635. * Opptional, defaults to == operator for the comparison.
  1636. */
  1637. Array.prototype.contains = function(obj, method) {
  1638. for (var i = 0; i < this.length; i++) {
  1639. // method is a function(a,b):
  1640. if (isFunction(method)) {
  1641. if (method(this[i], obj)) {
  1642. return true;
  1643. }
  1644. }
  1645. else if (isFunction(this[i][method])) {
  1646. // method is the name of a member method that compares
  1647. // two objects, eg. "equals":
  1648. if (this[i][method](obj)) {
  1649. return true;
  1650. }
  1651. }
  1652. else {
  1653. if (this[i] == obj) {
  1654. return true;
  1655. }
  1656. }
  1657. }
  1658. return false;
  1659. };
  1660. /**
  1661. * \return True if this array contains the given string (case insensitive).
  1662. */
  1663. Array.prototype.containsIgnoreCase = function(obj) {
  1664. return this.contains(obj, function(a,b) { return a.toUpperCase()===b.toUpperCase(); });
  1665. };
  1666. /**
  1667. * \return True if this array contains all items of the given array.
  1668. */
  1669. Array.prototype.containsAll = function(obj) {
  1670. if (obj.length>this.length) {
  1671. return false;
  1672. }
  1673. for (var i=0; i<obj.length; i++) {
  1674. if (this.indexOf(obj[i])<0) {
  1675. return false;
  1676. }
  1677. }
  1678. return true;
  1679. };
  1680. /**
  1681. * \return Array with all elements of this array that are not also
  1682. * in the given array (subtract).
  1683. */
  1684. Array.prototype.difference = function(a) {
  1685. return this.filter(function(i) { return !(a.indexOf(i) > -1); } );
  1686. };
  1687. /**
  1688. * \return True if this array is identical with the given array in
  1689. * length and contents.
  1690. */
  1691. Array.prototype.isEqual = function(b) {
  1692. if (this.length!==b.length) {
  1693. return false;
  1694. }
  1695. for (var i=0; i<this.length; i++) {
  1696. if (this[i]!==b[i]) {
  1697. return false;
  1698. }
  1699. }
  1700. return true;
  1701. };
  1702. /**
  1703. * \return True if the length of this array is zero.
  1704. */
  1705. Array.prototype.isEmpty = function() {
  1706. return (this.length == 0);
  1707. };
  1708. /**
  1709. * Empties the array (sets its length to 0).
  1710. */
  1711. Array.prototype.clear = function() {
  1712. this.length = 0;
  1713. };
  1714. /**
  1715. * Remove the first match of the given value from the array.
  1716. * \param val The value to remove.
  1717. */
  1718. Array.prototype.remove = function(val, compareFunction) {
  1719. for (var i=0; i<this.length; i++) {
  1720. var match = false;
  1721. if (!isNull(compareFunction)) {
  1722. match = compareFunction(this[i], val);
  1723. }
  1724. else {
  1725. match = (this[i] == val);
  1726. }
  1727. if (match) {
  1728. this.splice(i, 1);
  1729. break;
  1730. }
  1731. }
  1732. };
  1733. /**
  1734. * Removes all matches of the given value from the array.
  1735. * \param The value(s) to remove.
  1736. */
  1737. Array.prototype.removeAll = function() {
  1738. var what, a = arguments, l = a.length, ax;
  1739. while (l && this.length) {
  1740. what = a[--l];
  1741. while ((ax = this.indexOf(what)) !== -1) {
  1742. this.splice(ax, 1);
  1743. }
  1744. }
  1745. return this;
  1746. };
  1747. /**
  1748. * Remove the first case insensitive match of the given string value from the array.
  1749. * \param val The value to remove.
  1750. */
  1751. Array.prototype.removeIgnoreCase = function(val) {
  1752. this.remove(val, function(a,b) { return a.toUpperCase()===b.toUpperCase(); });
  1753. };
  1754. /**
  1755. * Remove the given parameter from an array (by default 'undefined').
  1756. *
  1757. * test = new Array("","One","Two","", "Three","","Four").clean("");
  1758. *
  1759. * test2 = [1,2,,3,,3,,,,,,4,,4,,5,,6,,,,];
  1760. * test2.clean(undefined);
  1761. *
  1762. * \param deleteValue
  1763. * \return {Array}
  1764. */
  1765. Array.prototype.clean = function(deleteValue) {
  1766. for (var i = 0; i < this.length; i++) {
  1767. if (this[i] == deleteValue) {
  1768. this.splice(i, 1);
  1769. i--;
  1770. }
  1771. }
  1772. return this;
  1773. };
  1774. /**
  1775. * Clones (copies) the array.
  1776. *
  1777. * \returns the cloned array
  1778. */
  1779. Array.prototype.clone = function() {
  1780. return this.slice(0);
  1781. };
  1782. /**
  1783. * Sorts this array with numerical items (ascending)
  1784. */
  1785. Array.prototype.sortNumerical = function() {
  1786. Array.prototype.sort.call(this, function(a,b) { return a - b });
  1787. }
  1788. Array.alphaNumericalSorter = function(a, b) {
  1789. return RS.compareAlphanumerical(a, b);
  1790. };
  1791. Array.prototype.filter = function(func, thisArg) {
  1792. if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
  1793. throw new TypeError();
  1794. var len = this.length >>> 0,
  1795. res = new Array(len), // preallocate array
  1796. t = this, c = 0, i = -1;
  1797. var kValue;
  1798. if (thisArg === undefined){
  1799. while (++i !== len){
  1800. // checks to see if the key was set
  1801. if (i in this){
  1802. kValue = t[i]; // in case t is changed in callback
  1803. if (func(t[i], i, t)){
  1804. res[c++] = kValue;
  1805. }
  1806. }
  1807. }
  1808. }
  1809. else{
  1810. while (++i !== len){
  1811. // checks to see if the key was set
  1812. if (i in this){
  1813. kValue = t[i];
  1814. if (func.call(thisArg, t[i], i, t)){
  1815. res[c++] = kValue;
  1816. }
  1817. }
  1818. }
  1819. }
  1820. res.length = c; // shrink down array to proper size
  1821. return res;
  1822. };
  1823. /**
  1824. * Sorts this array with string items (case insensitive)
  1825. */
  1826. //Array.prototype.sortCaseInsensitive = function() {
  1827. // Array.prototype.sort.call(this, function (a, b) {
  1828. // return a.toLowerCase().localeCompare(b.toLowerCase());
  1829. // });
  1830. //};
  1831. Array.union = function(x, y) {
  1832. var i;
  1833. var obj = {};
  1834. for (i=x.length-1; i>=0; --i) {
  1835. obj[x[i]] = x[i];
  1836. }
  1837. for (i=y.length-1; i>=0; --i) {
  1838. obj[y[i]] = y[i];
  1839. }
  1840. var res = []
  1841. for (var k in obj) {
  1842. res.push(obj[k]);
  1843. }
  1844. return res;
  1845. };
  1846. /* Finds the intersection of two sorted arrays.
  1847. *
  1848. * \param a first array, must already be sorted
  1849. * \param b second array, must already be sorted
  1850. *
  1851. * Items must be sorted NUMERICALLY (sortNumerical) if arrays contain numbers or
  1852. * ALPHABETICALLY (sort) if arrays contain strings.
  1853. *
  1854. * Should have O(n) operations, where n is
  1855. * n = MIN(a.length(), b.length())
  1856. */
  1857. Array.intersectSafe = function(a, b) {
  1858. var ai=0;
  1859. var bi=0;
  1860. var result = [];
  1861. while (ai < a.length && bi < b.length) {
  1862. if (a[ai] < b[bi]) {
  1863. ai++;
  1864. }
  1865. else if (a[ai] > b[bi]) {
  1866. bi++;
  1867. }
  1868. else {
  1869. result.push(a[ai]);
  1870. ai++;
  1871. bi++;
  1872. }
  1873. }
  1874. return result;
  1875. };
  1876. /**
  1877. * Destructively finds the intersection of
  1878. * two arrays.
  1879. *
  1880. * \param a first array, must already be sorted
  1881. * \param b second array, must already be sorted
  1882. *
  1883. * Items must be sorted NUMERICALLY (sortNumerical) if arrays contain numbers or
  1884. * ALPHABETICALLY (sort) if arrays contain strings.
  1885. *
  1886. * State of input arrays is undefined when
  1887. * the function returns.
  1888. */
  1889. Array.intersect = function(a, b) {
  1890. var result = [];
  1891. while (a.length > 0 && b.length > 0 ) {
  1892. if (a[0] < b[0]) {
  1893. a.shift();
  1894. }
  1895. else if (a[0] > b[0]) {
  1896. b.shift();
  1897. }
  1898. else {
  1899. result.push(a.shift());
  1900. b.shift();
  1901. }
  1902. }
  1903. return result;
  1904. };
  1905. /**
  1906. * Escapes a string for use as literlal match in regular expression.
  1907. */
  1908. RegExp.escape = function(s) {
  1909. return s.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  1910. };
  1911. /**
  1912. * Checks the type of the given object.
  1913. *
  1914. * \return true if the given object is an array.
  1915. */
  1916. function isArray(obj) {
  1917. return getTypeOf(obj)==="array";
  1918. //return obj && !(obj.propertyIsEnumerable('length'))
  1919. // && typeof obj === 'object' && typeof(obj.length) === 'number';
  1920. }
  1921. /**
  1922. * \class String
  1923. * \brief ECMAScript Script class.
  1924. */
  1925. /**
  1926. * Capitalize words in a text string.
  1927. * \return New string with capitalized words.
  1928. */
  1929. String.prototype.capitalize = function(){
  1930. return this.replace( /(^|\s)([a-z])/g , function(m, p1, p2){
  1931. return p1 + p2.toUpperCase();
  1932. });
  1933. };
  1934. /**
  1935. * Trims white space.
  1936. * \return New string with removed whitespace at start and end of this string.
  1937. */
  1938. String.prototype.trim = function() {
  1939. return this.replace(/^\s+|\s+$/g, '');
  1940. };
  1941. /**
  1942. * Shortens a string.
  1943. * \return New string shortened to the given number of pixels using ellipsis (...).
  1944. */
  1945. String.prototype.elidedText = function(font, pixel) {
  1946. var fm = new QFontMetrics(font);
  1947. var s = this;
  1948. if (!isString(s)) {
  1949. s = s.toString();
  1950. }
  1951. var t = fm.elidedText(s, Qt.ElideMiddle, pixel);
  1952. destr(fm);
  1953. // replace HORIZONTAL ELLIPSIS (not every GUI font has those):
  1954. t = t.replace(/\u2026/g, '...');
  1955. return t;
  1956. };
  1957. /**
  1958. * Returns true if this string starts with \c str.
  1959. */
  1960. String.prototype.startsWith = function(str) {
  1961. return (this.indexOf(str) === 0);
  1962. };
  1963. /**
  1964. * Returns true if this string ends with \c str.
  1965. */
  1966. String.prototype.endsWith = function(str) {
  1967. return this.indexOf(str, this.length - str.length) !== -1;
  1968. };
  1969. /**
  1970. * Returns true if this string is empty.
  1971. */
  1972. String.prototype.isEmpty = function() {
  1973. return (this == "");
  1974. };
  1975. /**
  1976. * Returns true if this string contains \c str.
  1977. */
  1978. String.prototype.contains = function(str) {
  1979. return this.indexOf(str)!==-1;
  1980. };
  1981. /**
  1982. * Returns true if this string contains \c str. Case insensitive.
  1983. */
  1984. String.prototype.containsIgnoreCase = function(str) {
  1985. return this.toLowerCase().indexOf(str.toLowerCase())!==-1;
  1986. };
  1987. /**
  1988. * Returns the number of occurrences of \c ch in this string.
  1989. */
  1990. String.prototype.count = function(ch) {
  1991. return this.split(ch).length - 1;
  1992. };
  1993. /**
  1994. * Returns a substring that contains the \c num leftmost characters of this string.
  1995. */
  1996. String.prototype.left = function(num) {
  1997. if (num>this.length) {
  1998. return this;
  1999. }
  2000. return this.substr(0,num);
  2001. };
  2002. /**
  2003. * Returns a substring that contains the \c num rightmost characters of this string.
  2004. */
  2005. String.prototype.right = function(num) {
  2006. if (num>this.length) {
  2007. return this;
  2008. }
  2009. return this.substr(this.length-num, num);
  2010. };
  2011. /**
  2012. * Returns a string that contains \c n characters of this string,
  2013. * starting at the specified \c position index.
  2014. */
  2015. String.prototype.mid = function(position, n) {
  2016. return this.substr(position, n);
  2017. };
  2018. /**
  2019. * Returns true if this string equals "true".
  2020. */
  2021. String.prototype.toBoolean = function() {
  2022. return (/^true$/i).test(this);
  2023. };
  2024. /**
  2025. * Converts this string into a float value if possible. If not, returns NaN.
  2026. */
  2027. String.prototype.toFloat = function() {
  2028. return parseFloat(this);
  2029. };
  2030. /**
  2031. * Converts this string into an int value if possible. If not, returns NaN.
  2032. */
  2033. String.prototype.toInt = function() {
  2034. return parseInt(this, 10);
  2035. };
  2036. /**
  2037. * Wraps a string after the given number of characters.
  2038. *
  2039. * Example:
  2040. * "long string".wordWrap(80, true, "\n")
  2041. * Wraps after 80 characters, break words, too, uses a "\n" character
  2042. * for new lines.
  2043. *
  2044. * @param m the number of characters to wrap after
  2045. * @param c true: break words, false: don't break words
  2046. * @param b line break character, usually "\n"
  2047. * @returns the wrapped text
  2048. */
  2049. String.prototype.wordWrap = function(m, c, b){
  2050. if(isNull(m)){
  2051. m = 80;
  2052. }
  2053. if(isNull(c)){
  2054. c = false;
  2055. }
  2056. if(isNull(b)){
  2057. b = "\n";
  2058. }
  2059. var i, j, s, r = this.split("\n");
  2060. if(m > 0) for(i in r){
  2061. for(s = r[i], r[i] = ""; s.length > m;
  2062. j = c ? m : (j = s.substr(0, m).match(/\S*$/)).input.length - j[0].length
  2063. || m,
  2064. r[i] += s.substr(0, j) + ((s = s.substr(j)).length ? b : "")
  2065. );
  2066. r[i] += s;
  2067. }
  2068. return r.join("\n");
  2069. };
  2070. String.prototype.regexIndexOf = function(regex, startpos) {
  2071. var indexOf = this.substring(startpos || 0).search(regex);
  2072. return (indexOf >= 0) ? (indexOf + (startpos || 0)) : indexOf;
  2073. };
  2074. String.prototype.regexLastIndexOf = function(regex, startpos) {
  2075. regex = (regex.global) ? regex : new RegExp(regex.source, "g" + (regex.ignoreCase ? "i" : "") + (regex.multiLine ? "m" : ""));
  2076. if(typeof (startpos) == "undefined") {
  2077. startpos = this.length;
  2078. } else if(startpos < 0) {
  2079. startpos = 0;
  2080. }
  2081. var stringToWorkWith = this.substring(0, startpos + 1);
  2082. var lastIndexOf = -1;
  2083. var nextStop = 0;
  2084. while((result = regex.exec(stringToWorkWith)) != null) {
  2085. lastIndexOf = result.index;
  2086. regex.lastIndex = ++nextStop;
  2087. }
  2088. return lastIndexOf;
  2089. };
  2090. String.prototype.padStart = function(targetLength, padString) {
  2091. targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
  2092. padString = String(typeof padString !== 'undefined' ? padString : ' ');
  2093. if (this.length > targetLength) {
  2094. return String(this);
  2095. } else {
  2096. targetLength = targetLength - this.length;
  2097. if (targetLength > padString.length) {
  2098. padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
  2099. }
  2100. return padString.slice(0, targetLength) + String(this);
  2101. }
  2102. };
  2103. String.prototype.repeat = function(count) {
  2104. var str = '' + this;
  2105. // To convert string to integer.
  2106. count = +count;
  2107. // Check NaN
  2108. if (count != count)
  2109. count = 0;
  2110. if (count < 0)
  2111. throw new RangeError('repeat count must be non-negative');
  2112. if (count == Infinity)
  2113. throw new RangeError('repeat count must be less than infinity');
  2114. count = Math.floor(count);
  2115. if (str.length == 0 || count == 0)
  2116. return '';
  2117. // Ensuring count is a 31-bit integer allows us to heavily optimize the
  2118. // main part. But anyway, most current (August 2014) browsers can't handle
  2119. // strings 1 << 28 chars or longer, so:
  2120. if (str.length * count >= 1 << 28)
  2121. throw new RangeError('repeat count must not overflow maximum string size');
  2122. var maxCount = str.length * count;
  2123. count = Math.floor(Math.log(count) / Math.log(2));
  2124. while (count) {
  2125. str += str;
  2126. count--;
  2127. }
  2128. str += str.substring(0, maxCount - str.length);
  2129. return str;
  2130. };
  2131. /**
  2132. * Modulo which works also for negative numbers (workaround for
  2133. * ECMAScript modulo bug).
  2134. */
  2135. Number.prototype.mod = function(n) {
  2136. return ((this%n)+n)%n;
  2137. };
  2138. Math.sign = Math.sign || function(x) {
  2139. x = +x; // convert to a number
  2140. if (x === 0 || isNaN(x)) {
  2141. return Number(x);
  2142. }
  2143. return x > 0 ? 1 : -1;
  2144. };
  2145. /**
  2146. * Formats the given number into a locale aware string.
  2147. */
  2148. function numberToString(num, decimals) {
  2149. //var ret = "%1".arg(num, 0, 'f', decimals);
  2150. var formatString = "%." + decimals + "f";
  2151. var ret = sprintf(formatString, num);
  2152. var decimalPoint = RSettings.getStringValue("Input/DecimalPoint", ".");
  2153. if (decimalPoint!==".") {
  2154. ret = ret.replace(".", decimalPoint);
  2155. }
  2156. return ret;
  2157. }
  2158. function angleToString(num, decimals) {
  2159. var formatString = "%." + decimals + "f";
  2160. var ret = sprintf(formatString, num);
  2161. var decimalPoint = RSettings.getStringValue("Input/DecimalPoint", ".");
  2162. if (decimalPoint!==".") {
  2163. ret = ret.replace(".", decimalPoint);
  2164. }
  2165. return ret;
  2166. }
  2167. /**
  2168. * Formats the given coordinate (RVector) into a locale aware string.
  2169. */
  2170. function coordinateToString(coordinate, decimals, relative, polar, doc) {
  2171. if (isNull(decimals)) {
  2172. decimals = 3;
  2173. }
  2174. if (isNull(relative)) {
  2175. relative = false;
  2176. }
  2177. if (isNull(polar)) {
  2178. polar = false;
  2179. }
  2180. var first;
  2181. var second;
  2182. var sep;
  2183. if (polar) {
  2184. sep = RSettings.getPolarCoordinateSeparator();
  2185. if (!isNull(doc)) {
  2186. first = doc.formatLinear(coordinate.getMagnitude());
  2187. second = doc.formatAngle(coordinate.getAngle());
  2188. }
  2189. else {
  2190. first = numberToString(coordinate.getMagnitude(), decimals);
  2191. second = angleToString(coordinate.getAngle() / (2 * Math.PI) * 360, decimals);
  2192. }
  2193. }
  2194. else {
  2195. sep = RSettings.getCartesianCoordinateSeparator();
  2196. if (!isNull(doc)) {
  2197. first = doc.formatLinear(coordinate.x);
  2198. second = doc.formatLinear(coordinate.y);
  2199. }
  2200. else {
  2201. first = numberToString(coordinate.x, decimals);
  2202. second = numberToString(coordinate.y, decimals);
  2203. }
  2204. }
  2205. var prefix;
  2206. if (relative) {
  2207. prefix = RSettings.getRelativeCoordinatePrefix();
  2208. }
  2209. else {
  2210. prefix = "";
  2211. }
  2212. return prefix + first + sep + second;
  2213. }
  2214. /**
  2215. * Parses the given string as coordinate.
  2216. *
  2217. * \param relativeZero RVector position of relative zero point.
  2218. * \param str String to parse (e.g. "34,15.6" or "@10,30" or "50<60", ...)
  2219. *
  2220. * \return undefined if the string is not a coordinate, an invalid RVector
  2221. * if str is an invalid coordinate or the RVector result.
  2222. */
  2223. function stringToCoordinate(relativeZero, str) {
  2224. return RMath.parseCoordinate(str, relativeZero);
  2225. }
  2226. /**
  2227. * Parses the given string as direct distance entry.
  2228. *
  2229. * \author Robert S
  2230. *
  2231. * \param relativeZero RVector position of relative zero point.
  2232. * \param cursorPosition RVector position of cursor.
  2233. * \param str String to parse (e.g. "34" or "15.123", ...)
  2234. *
  2235. * \return Invalid RVector if str is an invalid dde or
  2236. * return the dde point.
  2237. */
  2238. function stringToDirectDistanceEntry(relativeZero, cursorPosition, str) {
  2239. var cartCoordSep =
  2240. RSettings.getStringValue("Input/CartesianCoordinateSeparator", ',');
  2241. var polCoordSep =
  2242. RSettings.getStringValue("Input/PolarCoordinateSeparator", '<');
  2243. if (str.contains(cartCoordSep) || str.contains(polCoordSep)) {
  2244. return undefined;
  2245. }
  2246. var value = RMath.eval(str);
  2247. if (isNumber(value)) {
  2248. var point1 = relativeZero;
  2249. if (!isValidVector(point1)) { // if this is the first action
  2250. point1 = new RVector(0.0, 0.0); // of a new drawing relativezero
  2251. } // is not valid
  2252. var point2 = cursorPosition;
  2253. if (point1.equalsFuzzy(point2)) {
  2254. // cursor at same pos as relative zero:
  2255. return RVector.invalid;
  2256. }
  2257. var angle = point1.getAngleTo(point2);
  2258. var v = new RVector();
  2259. v.setPolar(value, angle);
  2260. var point = point1.operator_add(v);
  2261. return point;
  2262. } else {
  2263. // not a direct distance entry (not an error):
  2264. return undefined;
  2265. }
  2266. }
  2267. /**
  2268. * Creates and returns a new entity based on the given shape.
  2269. */
  2270. function shapeToEntity(document, shape) {
  2271. var s = shape;
  2272. if (isFunction(s.data)) {
  2273. s = s.data();
  2274. }
  2275. if (isPointShape(s)) {
  2276. return new RPointEntity(document, new RPointData(s.getPosition()));
  2277. }
  2278. else if (isLineShape(s)) {
  2279. return new RLineEntity(document, new RLineData(s));
  2280. }
  2281. else if (isRayShape(s)) {
  2282. return new RRayEntity(document, new RRayData(s));
  2283. }
  2284. else if (isXLineShape(s)) {
  2285. return new RXLineEntity(document, new RXLineData(s));
  2286. }
  2287. else if (isArcShape(s)) {
  2288. return new RArcEntity(document, new RArcData(s));
  2289. }
  2290. else if (isCircleShape(s)) {
  2291. return new RCircleEntity(document, new RCircleData(s));
  2292. }
  2293. else if (isEllipseShape(s)) {
  2294. return new REllipseEntity(document, new REllipseData(s));
  2295. }
  2296. else if (isPolylineShape(s)) {
  2297. return new RPolylineEntity(document, new RPolylineData(s));
  2298. }
  2299. else if (isSplineShape(s)) {
  2300. return new RSplineEntity(document, new RSplineData(s));
  2301. }
  2302. else if (isTriangleShape(s)) {
  2303. return new RSolidEntity(document, new RSolidData(s));
  2304. }
  2305. qWarning("shapeToEntity: unknown shape: ", s);
  2306. return undefined;
  2307. }
  2308. function getClosestSimpleShape(entity, pos) {
  2309. return entity.getClosestSimpleShape(pos);
  2310. }
  2311. function trimStartPoint(shape, trimPoint, clickPoint) {
  2312. shape.trimStartPoint(trimPoint, clickPoint);
  2313. if (isXLineShape(shape)) {
  2314. return xLineToRay(shape);
  2315. }
  2316. else {
  2317. return shape;
  2318. }
  2319. }
  2320. function trimEndPoint(shape, trimPoint, clickPoint) {
  2321. shape.trimEndPoint(trimPoint, clickPoint);
  2322. if (isXLineShape(shape)) {
  2323. return xLineToRay(shape);
  2324. }
  2325. else if (isRayShape(shape)) {
  2326. return rayToLine(shape);
  2327. }
  2328. else {
  2329. return shape;
  2330. }
  2331. }
  2332. function xLineToRay(xline) {
  2333. return new RRay(xline.getBasePoint(), xline.getDirectionVector());
  2334. };
  2335. function rayToLine(ray) {
  2336. return new RLine(ray.getBasePoint(), ray.getSecondPoint());
  2337. };
  2338. /**
  2339. * Modify the given entity to represent the given shape.
  2340. *
  2341. * Possible conversions:
  2342. * Line -> XLine, Ray
  2343. * XLine -> Line, Ray
  2344. * Ray -> XLine, Line
  2345. * Circle -> Arc
  2346. */
  2347. function modifyEntity(op, entity, shape) {
  2348. if ((isXLineEntity(entity) && (isRayShape(shape) || isLineShape(shape))) ||
  2349. (isRayEntity(entity) && (isXLineShape(shape) || isLineShape(shape))) ||
  2350. (isLineEntity(entity) && (isXLineShape(shape) || isRayShape(shape))) ||
  2351. (isCircleEntity(entity) && isArcShape(shape))) {
  2352. var e = shapeToEntity(entity.getDocument(), shape);
  2353. // if (isFunction(entity.data)) {
  2354. // e.copyAttributesFrom(entity.data());
  2355. // op.deleteObject(entity.data());
  2356. // }
  2357. // else {
  2358. e.copyAttributesFrom(entity);
  2359. op.deleteObject(entity);
  2360. // }
  2361. op.addObject(e, false);
  2362. return true;
  2363. }
  2364. if (isFunction(entity.setShape)) {
  2365. entity.setShape(shape);
  2366. op.addObject(entity, false);
  2367. return true;
  2368. }
  2369. return false;
  2370. };
  2371. /**
  2372. * Insert CAD fonts at the top into the given font combo box.
  2373. */
  2374. function initFontComboBox(comboBox) {
  2375. if (RSettings.getBoolValue("Text/UseReducedFontList", false)===true) {
  2376. var list = RSettings.getValue("Text/ReducedFontList", []);
  2377. if (list.length!==0) {
  2378. comboBox.clear();
  2379. comboBox.addItems(list);
  2380. }
  2381. }
  2382. else {
  2383. var fontList = RFontList.getNames();
  2384. for (var i=fontList.length-1; i>=0; --i) {
  2385. // ignore shape definition files:
  2386. if (fontList[i]==="ltypeshp" || fontList[i]==="qcadshp") {
  2387. continue;
  2388. }
  2389. comboBox.insertItem(0, new QIcon(), fontList[i]);
  2390. }
  2391. }
  2392. if (RSettings.getBoolValue("Text/ShowFontPreview", true)===false) {
  2393. // disables the font preview which is known to be slow
  2394. // on some Linux installations:
  2395. var view = comboBox.view();
  2396. view.setItemDelegate(new QItemDelegate(comboBox));
  2397. }
  2398. }
  2399. function activateFont(fontComboBox, fontName) {
  2400. var index = fontComboBox.findText(fontName, Qt.MatchFixedString);
  2401. fontComboBox.setCurrentIndex(index);
  2402. }
  2403. function setMainWindow(w) {
  2404. global.gMainWindow = w;
  2405. }
  2406. function getMainWindow() {
  2407. if (!isNull(global.gMainWindow)) {
  2408. return global.gMainWindow;
  2409. }
  2410. return RMainWindowQt.getMainWindow();
  2411. }
  2412. function getCurrentDateTime(format) {
  2413. if (RSettings.getQtVersion() >= 0x060000) {
  2414. return QDateTime.currentDateTime().toString(format);
  2415. }
  2416. else {
  2417. return new QDateTime(QDateTime.currentDateTime()).toString(format);
  2418. }
  2419. }
  2420. function mergeProperties(obj1,obj2) {
  2421. var obj3 = {};
  2422. var attrname;
  2423. for (attrname in obj1) { obj3[attrname] = obj1[attrname]; }
  2424. for (attrname in obj2) { obj3[attrname] = obj2[attrname]; }
  2425. return obj3;
  2426. }
  2427. /**
  2428. * Fixes the given symbol table name (e.g. block or layer name).
  2429. *
  2430. * \param name Suggested name, for example coming from a file base name.
  2431. * \return Fixed name or undefined if the name cannot be fixed
  2432. * (i.e. contains invalid characters).
  2433. */
  2434. function fixSymbolTableName(name) {
  2435. // trim white space at beginning and end to avoid invalid block name:
  2436. name = name.trim();
  2437. // max length:
  2438. if (name.length>255) {
  2439. name = name.left(255);
  2440. }
  2441. // invalid block name characters:
  2442. var rx = new RegExp("^[^<>/\\\\\":;\?\*|,=`]*$");
  2443. if (!rx.test(name)) {
  2444. return undefined;
  2445. }
  2446. return name;
  2447. }
  2448. function getClipboard() {
  2449. if (RSettings.isQt(5)) {
  2450. return QGuiApplication.clipboard()
  2451. }
  2452. else {
  2453. return QApplication.clipboard();
  2454. }
  2455. }
  2456. function stripDirtyFlag(title) {
  2457. return title.replace("[*] ", "");
  2458. }
  2459. function addDirtyFlag(title) {
  2460. return "[*] " + title;
  2461. }
  2462. function hasPlugin(name) {
  2463. // TODO: refactor:
  2464. if (name==="PROTOOLS") {
  2465. if (new QFileInfo("scripts/Pro").exists()) {
  2466. // PROTOOLS available not as plugins but as scripts folder:
  2467. return true;
  2468. }
  2469. }
  2470. return RPluginLoader.hasPlugin(name);
  2471. }
  2472. /**
  2473. * Enable / disable easy drag and drop for the given entity.
  2474. * Entities tagged for easy drag and drop can be moved by dragging
  2475. * them while a block reference is selected.
  2476. */
  2477. function setInBlockEasyDragAndDrop(entity, v) {
  2478. return entity.setCustomProperty("QCAD", "InBlockEasyDragAndDrop", v ? "1" : "0");
  2479. }
  2480. function getInBlockEasyDragAndDrop(entity) {
  2481. return entity.getCustomProperty("QCAD", "InBlockEasyDragAndDrop", "0")==="1";
  2482. }
  2483. /**
  2484. * Enable / disable in block text editing for the given entity.
  2485. */
  2486. function setInBlockTextEdit(entity, v) {
  2487. return entity.setCustomProperty("QCAD", "InBlockTextEdit", v ? "1" : "0");
  2488. }
  2489. function getInBlockTextEdit(entity) {
  2490. return entity.getCustomProperty("QCAD", "InBlockTextEdit", "0")==="1";
  2491. }
  2492. function setOverrideWaitCursor() {
  2493. if (!RSettings.isGuiEnabled()) {
  2494. return;
  2495. }
  2496. setOverrideCursor(new QCursor(Qt.WaitCursor));
  2497. }
  2498. function setOverrideCursor(cursor) {
  2499. if (!RSettings.isGuiEnabled()) {
  2500. return;
  2501. }
  2502. if (RSettings.isQt(5)) {
  2503. QGuiApplication.setOverrideCursor(cursor);
  2504. }
  2505. else {
  2506. QApplication.setOverrideCursor(cursor);
  2507. }
  2508. }
  2509. function restoreOverrideCursor() {
  2510. if (!RSettings.isGuiEnabled()) {
  2511. return;
  2512. }
  2513. if (RSettings.isQt(5)) {
  2514. QGuiApplication.restoreOverrideCursor();
  2515. }
  2516. else {
  2517. QApplication.restoreOverrideCursor();
  2518. }
  2519. }
  2520. function initUserShortcuts() {
  2521. var keys = RSettings.getAllKeys("Shortcuts");
  2522. var i, key, action;
  2523. for (i=0; i<keys.length; i++) {
  2524. key = keys[i];
  2525. action = RGuiAction.getByScriptFile(key);
  2526. if (isNull(action)) {
  2527. continue;
  2528. }
  2529. var match = action.getScriptFile().contains("OpenFile");
  2530. var scStringList = RSettings.getValue("Shortcuts/" + key);
  2531. if (match) qDebug("scStringList", scStringList);
  2532. // explicitly no shortcuts:
  2533. if (isNull(scStringList)) {
  2534. if (match) qDebug("explicitly no shortcuts");
  2535. action.setShortcuts([]);
  2536. action.removeShortcuts();
  2537. continue;
  2538. }
  2539. if (match) qDebug("setting shortcuts to ", scStringList);
  2540. //action.setShortcutsFromStrings(scStringList);
  2541. //action.setShortcuts(scStringList);
  2542. var scList = [];
  2543. for (var k=0; k<scStringList.length; k++) {
  2544. var sc = new QKeySequence(scStringList[k]);
  2545. scList.push(sc);
  2546. }
  2547. action.removeShortcuts();
  2548. action.setShortcuts(scList);
  2549. }
  2550. keys = RSettings.getAllKeys("Commands");
  2551. for (i=0; i<keys.length; i++) {
  2552. key = keys[i];
  2553. action = RGuiAction.getByScriptFile(key);
  2554. if (isNull(action)) {
  2555. continue;
  2556. }
  2557. var cmStringList = RSettings.getValue("Commands/" + key);
  2558. // explicitly no commands:
  2559. if (isNull(cmStringList)) {
  2560. action.setCommands([]);
  2561. continue;
  2562. }
  2563. action.setCommands(cmStringList);
  2564. }
  2565. }
  2566. function addActionsToWidgets() {
  2567. initUserShortcuts();
  2568. var appWin = RMainWindowQt.getMainWindow();
  2569. // delete previous shortcut delegates:
  2570. // part of workaround for QTBUG-38256, QTBUG-57990:
  2571. /*
  2572. if ((RSettings.getQtVersion()<0x050500 && RSettings.getQtVersion()>=0x050000) ||
  2573. (RSettings.getQtVersion()===0x050800 && RS.getSystemId()==="linux")) {
  2574. var scObjs = appWin.property("DelegatedShortcutsObjs");
  2575. if (!isNull(scObjs)) {
  2576. for (var si=0; si<scObjs.length; si++) {
  2577. if (isNull(scObjs[si])) {
  2578. continue;
  2579. }
  2580. destr(scObjs[si]);
  2581. }
  2582. }
  2583. appWin.setProperty("DelegatedShortcutsObjs", []);
  2584. }
  2585. */
  2586. var actions = RGuiAction.getActions();
  2587. var widgetTypes = ["Menu", "ToolBar", "MatrixPanel", "Panel", "UserToolBar1", "UserToolBar2"];
  2588. for (var c=0; c<actions.length; ++c) {
  2589. var a = actions[c];
  2590. if (a.icon.isNull() && !a.isIconDisabled()) {
  2591. a.setIcon(autoPath("scripts/Empty.svg"));
  2592. }
  2593. var className = a.getScriptClass();
  2594. var wns = a.getWidgetNames();
  2595. var addedToWidget = false;
  2596. for (var k=0; k<wns.length; k++) {
  2597. var wn = wns[k];
  2598. if (wn.length===0) {
  2599. continue;
  2600. }
  2601. var visibility = true;
  2602. if (wn[0]==="!") {
  2603. // action not visible by default in this widget:
  2604. visibility = false;
  2605. wn = wn.substring(1);
  2606. }
  2607. // check tool visibility based on user preferences:
  2608. if (className.length!==0) {
  2609. var key;
  2610. for (var j=0; j<widgetTypes.length; j++) {
  2611. var widgetType = widgetTypes[j];
  2612. var keyPostfix = widgetType;
  2613. if (keyPostfix==="Panel") {
  2614. keyPostfix = "CadToolBar";
  2615. }
  2616. if (wn.endsWith(widgetType)) {
  2617. key = className + "/VisibleIn" + keyPostfix;
  2618. visibility = RSettings.getBoolValue(key, visibility);
  2619. RSettings.setValue(key, visibility, false);
  2620. break;
  2621. }
  2622. }
  2623. }
  2624. var w = appWin.findChild(wn);
  2625. if (!isNull(w)) {
  2626. // workaround for QTBUG-38256 (action not triggered for letter based shortcuts in SUB menus):
  2627. // workaround for QTBUG-57990 (action not triggered for letter based shortcuts in ALL menus):
  2628. /*
  2629. if ((RSettings.getQtVersion()<0x050500 && RSettings.getQtVersion()>=0x050000) ||
  2630. (RSettings.getQtVersion()===0x050800 && RS.getSystemId()==="linux")) {
  2631. if (k===0) {
  2632. var shortcuts = a.shortcuts();
  2633. var scObjs = appWin.property("DelegatedShortcutsObjs");
  2634. if (isNull(scObjs)) {
  2635. scObjs=[];
  2636. }
  2637. for (var si=0; si<shortcuts.length; si++) {
  2638. var scObj = new QShortcut(shortcuts[si], a.parentWidget(), 0, 0, Qt.WindowShortcut)
  2639. scObj.activated.connect(a, "trigger");
  2640. scObjs.push(scObj);
  2641. }
  2642. appWin.setProperty("DelegatedShortcutsObjs", scObjs);
  2643. var sc = a.shortcut.toString();
  2644. if (sc.length>0) {
  2645. if (RS.getSystemId()==="linux") {
  2646. a.setShortcutText("[" + sc + "]");
  2647. }
  2648. else {
  2649. a.setShortcutText(" " + sc);
  2650. }
  2651. }
  2652. a.setProperty("DelegatedShortcuts", shortcuts);
  2653. a.setDefaultShortcuts([]);
  2654. }
  2655. }
  2656. */
  2657. if (visibility) {
  2658. RGuiAction.addToWidget(a, w);
  2659. addedToWidget = true;
  2660. if (isFunction(w.widgetForAction)) {
  2661. // if action was added to tool bar: set object name of tool button:
  2662. var tb = w.widgetForAction(a);
  2663. if (!isNull(tb)) {
  2664. tb.objectName = "ToolButton" + a.objectName.replace(/Action$/, "");
  2665. }
  2666. }
  2667. }
  2668. else {
  2669. // action not visible in this widget:
  2670. RGuiAction.removeFromWidget(a, w);
  2671. }
  2672. }
  2673. }
  2674. if ((RSettings.getQtVersion()<0x050500 && RSettings.getQtVersion()>=0x050000) ||
  2675. (RSettings.getQtVersion()===0x050800 && RS.getSystemId()==="linux") ||
  2676. !addedToWidget) {
  2677. // always add action to main window to make sure keycodes
  2678. // are active even if action is invisible:
  2679. RGuiAction.addToWidget(a, appWin);
  2680. }
  2681. }
  2682. }
  2683. /**
  2684. * \return Array of QUrl objects with all URLs extracted from
  2685. * the mime data (usually from drag and drop).
  2686. */
  2687. function getUrlsFromMimeData(mimeData) {
  2688. var urls = [];
  2689. if (mimeData.hasFormat("text/uri-list")) {
  2690. urls = mimeData.urls();
  2691. }
  2692. else if (mimeData.hasFormat("text/plain")) {
  2693. var text = mimeData.text();
  2694. var url = new QUrl(text);
  2695. if (!url.isValid()) {
  2696. return [];
  2697. }
  2698. if (!isUrl(url)) {
  2699. return [];
  2700. }
  2701. urls = [url];
  2702. }
  2703. return urls;
  2704. }
  2705. /**
  2706. * \return True if the urlString is a URL that can be loaded.
  2707. */
  2708. function isUrl(urlString) {
  2709. var url = new QUrl(urlString);
  2710. var scheme = url.scheme();
  2711. return scheme==="file" || scheme==="http" || scheme==="https" || scheme==="ftp";
  2712. }
  2713. function getDontUseNativeDialog() {
  2714. // don't use KDE file dialog (workaround for file type filter bug):
  2715. return RS.getWindowManagerId()==="kde" || RSettings.getBoolValue("SaveAs/UseSystemFileDialog", true)===false;
  2716. };
  2717. function autoPath(path) {
  2718. if (new QFileInfo(path).exists()) {
  2719. return path;
  2720. }
  2721. else {
  2722. return ":" + path;
  2723. }
  2724. }
  2725. function exists(path) {
  2726. return new QFileInfo(autoPath(path)).exists();
  2727. }
  2728. function neutralPath(path) {
  2729. if (path.startsWith(":/")) {
  2730. return path.substring(2);
  2731. }
  2732. if (path.startsWith(":")) {
  2733. return path.substring(1);
  2734. }
  2735. return path;
  2736. }
  2737. /**
  2738. * \return Mapped icon path for the given icon for the current theme or
  2739. * mapped icon path for a dark theme (-inverse) or the same path or undefined if no such
  2740. * icon can be found.
  2741. */
  2742. function autoIconPath(path) {
  2743. // set theme specific icon:
  2744. var themePath = RSettings.getThemePath();
  2745. var themeIconFile = undefined;
  2746. if (themePath.length>0) {
  2747. var fi = new QFileInfo(path);
  2748. var iconFileName = fi.fileName();
  2749. themeIconFile = themePath + "/icons/" + iconFileName;
  2750. if (!new QFileInfo(themeIconFile).exists()) {
  2751. // no SVG found, look up PNG:
  2752. var iconBaseName = fi.baseName();
  2753. themeIconFile = themePath + "/icons/" + iconBaseName + ".png";
  2754. if (!new QFileInfo(themeIconFile).exists()) {
  2755. // no PNG found, use default icon:
  2756. themeIconFile = undefined;
  2757. }
  2758. }
  2759. }
  2760. if (!isNull(themeIconFile)) {
  2761. // got icon from theme:
  2762. return themeIconFile;
  2763. }
  2764. // no theme icon, try dark mode icon:
  2765. var darkModeIconFile = undefined;
  2766. if (RSettings.hasDarkGuiBackground()) {
  2767. darkModeIconFile = path.replace(/\.svg$/, "-inverse.svg");
  2768. darkModeIconFile = darkModeIconFile.replace(/\.png$/, "-inverse.png");
  2769. if (!new QFileInfo(darkModeIconFile).exists()) {
  2770. darkModeIconFile = undefined;
  2771. }
  2772. }
  2773. if (!isNull(darkModeIconFile)) {
  2774. // got dark mode icon:
  2775. return darkModeIconFile;
  2776. }
  2777. if (!new QFileInfo(path).exists()) {
  2778. // given icon does not exist (for icons based on object names, e.g. in options toolbar):
  2779. return undefined;
  2780. }
  2781. return path;
  2782. }
  2783. function applyTheme() {
  2784. var systemId = RS.getSystemId();
  2785. var theme = RSettings.getValue("Theme/ThemeName", undefined);
  2786. if (systemId!=="osx" && !isNull(theme)) {
  2787. var path = "themes/" + theme + "/";
  2788. qApp.styleSheet = "";
  2789. // load stylesheet.css, stylesheet_[win|macos|linux].css:
  2790. var found = false;
  2791. if (systemId==="osx") systemId = "macos";
  2792. var postfixes = ["", "_" + systemId];
  2793. for (var i=0; i<postfixes.length; i++) {
  2794. var postfix = postfixes[i];
  2795. var fn = path + "stylesheet" + postfix + ".css";
  2796. qDebug("trying to load theme stylesheet: ", fn);
  2797. if (new QFileInfo(fn).exists()) {
  2798. var css = readTextFile(fn);
  2799. if (css.contains("RequiresPlugin:true")) {
  2800. // only load theme if plugin loaded:
  2801. var pluginId = theme.toUpperCase() + "STYLE";
  2802. if (!RPluginLoader.hasPlugin(pluginId)) {
  2803. qWarning("Theme not loaded: ", theme);
  2804. qWarning("Theme plugin not found:", pluginId);
  2805. return;
  2806. }
  2807. }
  2808. css = css.replace(/url\(/g, "url(" + path);
  2809. qApp.styleSheet = qApp.styleSheet + "\n" + css;
  2810. found = true;
  2811. }
  2812. }
  2813. if (!found) {
  2814. if (theme!=="Default") {
  2815. qWarning("Cannot open theme: ", theme);
  2816. }
  2817. }
  2818. }
  2819. }
  2820. function setUtf8Codec(ts) {
  2821. if (RSettings.getQtVersion() >= 0x060000) {
  2822. ts.setEncoding(QStringConverter.Utf8);
  2823. }
  2824. else {
  2825. ts.setCodec("UTF-8");
  2826. }
  2827. }
  2828. function readTextFile(fileName) {
  2829. var file = new QFile(fileName);
  2830. var flags = makeQIODeviceOpenMode(QIODevice.ReadOnly, QIODevice.Text);
  2831. if (file.open(flags)) {
  2832. var textStream = new QTextStream(file);
  2833. setUtf8Codec(textStream);
  2834. var contents = textStream.readAll();
  2835. file.close();
  2836. return contents;
  2837. }
  2838. return undefined;
  2839. }
  2840. function writeTextFile(fileName, str) {
  2841. var file = new QFile(fileName);
  2842. var flags = makeQIODeviceOpenMode(QIODevice.WriteOnly, QIODevice.Text);
  2843. if (file.open(flags)) {
  2844. var textStream = new QTextStream(file);
  2845. setUtf8Codec(textStream);
  2846. textStream.writeString(str);
  2847. file.close();
  2848. }
  2849. }
  2850. function getKeyboardModifiers(event) {
  2851. if (!isNull(event)) {
  2852. if (isFunction(event.getModifiers)) {
  2853. return event.getModifiers();
  2854. }
  2855. else {
  2856. return event.modifiers();
  2857. }
  2858. }
  2859. if (RSettings.isQt(5)) {
  2860. return QGuiApplication.queryKeyboardModifiers();
  2861. }
  2862. else {
  2863. return QApplication.queryKeyboardModifiers();
  2864. }
  2865. }
  2866. function isShiftPressed(event) {
  2867. return (getKeyboardModifiers(event) & Qt.ShiftModifier) > 0 ||
  2868. (getKeyboardModifiers() & Qt.ShiftModifier) > 0;
  2869. }
  2870. function isAltPressed(event) {
  2871. return (getKeyboardModifiers(event) & Qt.AltModifier) > 0 ||
  2872. (getKeyboardModifiers() & Qt.AltModifier) > 0;
  2873. }
  2874. function isControlPressed(event) {
  2875. return (getKeyboardModifiers(event) & Qt.ControlModifier) > 0 ||
  2876. (getKeyboardModifiers() & Qt.ControlModifier) > 0;
  2877. }
  2878. function createSpatialIndex() {
  2879. if (!isNull(global.SpatialIndexClass)) {
  2880. // use class defined as global variable "SpatialIndexClass":
  2881. // allows plugins to override the default spatial index class:
  2882. return new global[global.SpatialIndexClass]();
  2883. }
  2884. //return new RSpatialIndexSimple();
  2885. return new RSpatialIndexNavel();
  2886. }
  2887. // Qt 4 API workaround:
  2888. function qsTranslate2(context, sourceText, disambiguation, n) {
  2889. // Qt 4:
  2890. if (RSettings.getQtVersion() < 0x050000) {
  2891. if (isNull(disambiguation)) {
  2892. return qsTranslate(context, sourceText);
  2893. }
  2894. if (isNull(n)) {
  2895. return qsTranslate(context, sourceText, disambiguation);
  2896. }
  2897. return qsTranslate(context, sourceText, disambiguation, "UnicodeUTF8", n);
  2898. }
  2899. // Qt > 5
  2900. return qsTranslate(context, sourceText, disambiguation, n);
  2901. }
  2902. function makeQDirFilters() {
  2903. var argumentsNew = [].slice.call(arguments, 0);
  2904. argumentsNew.unshift(QDir.Filters);
  2905. return makeFlags.apply(null, argumentsNew);
  2906. }
  2907. function makeQDirSortFlags() {
  2908. var argumentsNew = [].slice.call(arguments, 0);
  2909. argumentsNew.unshift(QDir.SortFlags);
  2910. return makeFlags.apply(this, argumentsNew);
  2911. }
  2912. function makeQtMatchFlags() {
  2913. var argumentsNew = [].slice.call(arguments, 0);
  2914. argumentsNew.unshift(Qt.MatchFlags);
  2915. return makeFlags.apply(this, argumentsNew);
  2916. }
  2917. function makeQtToolBarAreas() {
  2918. var argumentsNew = [].slice.call(arguments, 0);
  2919. argumentsNew.unshift(Qt.ToolBarAreas);
  2920. return makeFlags.apply(this, argumentsNew);
  2921. }
  2922. function makeQtWindowFlags() {
  2923. var argumentsNew = [].slice.call(arguments, 0);
  2924. argumentsNew.unshift(Qt.WindowFlags);
  2925. return makeFlags.apply(this, argumentsNew);
  2926. }
  2927. function makeQtAlignment() {
  2928. var argumentsNew = [].slice.call(arguments, 0);
  2929. argumentsNew.unshift(Qt.Alignment);
  2930. return makeFlags.apply(this, argumentsNew);
  2931. }
  2932. function makeQIODeviceOpenMode() {
  2933. var argumentsNew = [].slice.call(arguments, 0);
  2934. argumentsNew.unshift(QIODevice.OpenMode);
  2935. return makeFlags.apply(this, argumentsNew);
  2936. }
  2937. function makeQMessageBoxStandardButtons() {
  2938. var argumentsNew = [].slice.call(arguments, 0);
  2939. argumentsNew.unshift(QMessageBox.StandardButtons);
  2940. return makeFlags.apply(this, argumentsNew);
  2941. }
  2942. function makeQtItemFlags() {
  2943. var argumentsNew = [].slice.call(arguments, 0);
  2944. argumentsNew.unshift(Qt.ItemFlags);
  2945. return makeFlags.apply(this, argumentsNew);
  2946. }
  2947. function makeQtKeyboardModifiers() {
  2948. var argumentsNew = [].slice.call(arguments, 0);
  2949. argumentsNew.unshift(Qt.KeyboardModifiers);
  2950. return makeFlags.apply(this, argumentsNew);
  2951. }
  2952. function makeQtMouseButtons() {
  2953. var argumentsNew = [].slice.call(arguments, 0);
  2954. argumentsNew.unshift(Qt.MouseButtons);
  2955. return makeFlags.apply(this, argumentsNew);
  2956. }
  2957. function makeQEventLoopProcessEventsFlags() {
  2958. var argumentsNew = [].slice.call(arguments, 0);
  2959. argumentsNew.unshift(QEventLoop.ProcessEventsFlags);
  2960. return makeFlags.apply(this, argumentsNew);
  2961. }
  2962. function makeQItemSelectionModelSelectionFlags() {
  2963. var argumentsNew = [].slice.call(arguments, 0);
  2964. argumentsNew.unshift(QItemSelectionModel.SelectionFlags);
  2965. return makeFlags.apply(this, argumentsNew);
  2966. }
  2967. function makeQAbstractItemViewEditTriggers() {
  2968. var argumentsNew = [].slice.call(arguments, 0);
  2969. argumentsNew.unshift(QAbstractItemView.EditTriggers);
  2970. return makeFlags.apply(this, argumentsNew);
  2971. }
  2972. function makeFlags() {
  2973. if (RSettings.isQt(6)) {
  2974. var ret = 0;
  2975. for (var i=1; i<arguments.length; i++) {
  2976. ret |= arguments[i];
  2977. }
  2978. return ret;
  2979. }
  2980. else {
  2981. var argumentsNew = [].slice.call(arguments, 0);
  2982. var flgs = argumentsNew.shift();
  2983. return flgs.apply(this, argumentsNew);
  2984. }
  2985. }
  2986. function getRGraphicsView(view) {
  2987. if (RSettings.getQtVersion()>=0x060000) {
  2988. return view;
  2989. }
  2990. else {
  2991. if (isFunction(view.getRGraphicsView)) {
  2992. return view.getRGraphicsView();
  2993. }
  2994. else {
  2995. return view;
  2996. }
  2997. }
  2998. }
  2999. /**
  3000. * Open files given as arguments args
  3001. *
  3002. * \param createNew Creates a new document if no files are given
  3003. * \param close Closes existing open MDI widgets
  3004. */
  3005. function openFiles(args, createNew, close) {
  3006. qDebug("openFiles: " + args);
  3007. var appWin = RMainWindowQt.getMainWindow();
  3008. if (isNull(appWin)) {
  3009. // application is shutting down..
  3010. return;
  3011. }
  3012. var mdiArea = appWin.getMdiArea();
  3013. var mdiChildren = mdiArea.subWindowList();
  3014. var foundFile = false;
  3015. var filter = undefined;
  3016. for (var i = 0; i < args.length; ++i) {
  3017. // arguments with one parameter:
  3018. if (args[i] === "-locale" || args[i] === "-autostart"
  3019. || args[i] === "-app-id" || args[i] === "-ignore"
  3020. || args[i] === "-config") {
  3021. // skip 2 arguments
  3022. i++;
  3023. if (i>=args.length) {
  3024. break;
  3025. }
  3026. continue;
  3027. }
  3028. // argument with two parameters
  3029. if (args[i] === "-font-substitution" || args[i] === "-fs" || args[i] === "-ts") {
  3030. // skip 3 arguments
  3031. i+=2;
  3032. if (i>=args.length) {
  3033. break;
  3034. }
  3035. continue;
  3036. }
  3037. if (isNull(args[i])) {
  3038. continue;
  3039. }
  3040. // all arguments after -exec are script files or script arguments:
  3041. if (args[i] === "-exec") {
  3042. break;
  3043. }
  3044. if (args[i] === "-filter") {
  3045. if (++i>=args.length) {
  3046. break;
  3047. }
  3048. filter = args[i];
  3049. continue;
  3050. }
  3051. // skip other arguments without parameter:
  3052. if (args[i][0] === "-") {
  3053. continue;
  3054. }
  3055. foundFile = true;
  3056. var foundExisting = false;
  3057. var arg = args[i];
  3058. var isLocalFile = true;
  3059. if (isUrl(arg)) {
  3060. var url = new QUrl(arg);
  3061. if (url.isLocalFile()) {
  3062. // arg is now a path:
  3063. arg = url.toLocalFile();
  3064. }
  3065. else {
  3066. isLocalFile = false;
  3067. }
  3068. }
  3069. if (isLocalFile) {
  3070. // if the file is already open, activate that appropriate sub window instead
  3071. // of opening the file again:
  3072. var document = undefined;
  3073. var fileName = undefined;
  3074. var fileInfo = undefined;
  3075. var argFileInfo = undefined;
  3076. for (var k=0; k<mdiChildren.length; k++) {
  3077. document = mdiChildren[k].getDocument();
  3078. fileName = document.getFileName();
  3079. fileInfo = new QFileInfo(fileName);
  3080. argFileInfo = new QFileInfo(getAbsolutePathForArg(arg));
  3081. if (fileInfo.absoluteFilePath()===argFileInfo.absoluteFilePath()) {
  3082. mdiArea.setActiveSubWindow(mdiChildren[k]);
  3083. if (close) {
  3084. mdiArea.closeActiveSubWindow();
  3085. }
  3086. else {
  3087. foundExisting = true;
  3088. }
  3089. break;
  3090. }
  3091. }
  3092. }
  3093. // open the file if it is not already open:
  3094. if (!foundExisting) {
  3095. if (isLocalFile) {
  3096. NewFile.createMdiChild(getAbsolutePathForArg(arg), filter);
  3097. }
  3098. else {
  3099. NewFile.createMdiChild(arg, filter);
  3100. }
  3101. }
  3102. }
  3103. // create new document if no files were loaded:
  3104. if (!foundFile && createNew===true) {
  3105. var fileNewAction = RGuiAction.getByScriptFile("scripts/File/NewFile/NewFile.js");
  3106. if (!isNull(fileNewAction)) {
  3107. fileNewAction.slotTrigger();
  3108. }
  3109. }
  3110. }
  3111. // fix QPlainTextEdit API for Qt 5:
  3112. if (!isFunction(QPlainTextEdit.prototype.toPlainText)) {
  3113. QPlainTextEdit.prototype.toPlainText = function() {
  3114. return this.plainText;
  3115. }
  3116. }
  3117. // add QUrl.isLocalFile to API for Qt 4.7:
  3118. if (!isFunction(QUrl.prototype.isLocalFile)) {
  3119. QUrl.prototype.isLocalFile = function() {
  3120. return this.scheme().toLowerCase()==="file";
  3121. }
  3122. }