diff --git a/Pipfile b/Pipfile index 6f22d9d76..9ff4d1f8a 100644 --- a/Pipfile +++ b/Pipfile @@ -9,6 +9,8 @@ pygments = "*" sphinx = "*" readthedocs-sphinx-ext = "*" "doc8" = "*" +urllib3 = "==1.24.2" +jinja2 = "==2.10.1" [dev-packages] pylint = "<2.0.0" diff --git a/Pipfile.lock b/Pipfile.lock index e6e87c489..c91c83feb 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "df9393f239f6ab1cb7db0bba0d309313548c55cfeffc31f47ffcebfd04f619f6" + "sha256": "3015027cab3fe037fb0f242030478d824a607e6eff04919add4b768cd9985f38" }, "pipfile-spec": 6, "requires": { @@ -32,10 +32,10 @@ }, "certifi": { "hashes": [ - "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7", - "sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033" + "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", + "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae" ], - "version": "==2018.11.29" + "version": "==2019.3.9" }, "chardet": { "hashes": [ @@ -44,6 +44,14 @@ ], "version": "==3.0.4" }, + "colorama": { + "hashes": [ + "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", + "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.1" + }, "doc8": { "hashes": [ "sha256:2df89f9c1a5abfb98ab55d0175fed633cae0cf45025b8b1e0ee5ea772be28543", @@ -76,43 +84,44 @@ }, "jinja2": { "hashes": [ - "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", - "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" + "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", + "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" ], - "version": "==2.10" + "index": "pypi", + "version": "==2.10.1" }, "markupsafe": { "hashes": [ - "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432", - "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b", - "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9", - "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af", - "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834", - "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd", - "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d", - "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7", - "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b", - "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3", - "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c", - "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2", - "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7", - "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36", - "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1", - "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e", - "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1", - "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c", - "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856", - "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550", - "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492", - "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672", - "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401", - "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6", - "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6", - "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c", - "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd", - "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1" - ], - "version": "==1.1.0" + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "version": "==1.1.1" }, "packaging": { "hashes": [ @@ -123,10 +132,10 @@ }, "pbr": { "hashes": [ - "sha256:f59d71442f9ece3dffc17bc36575768e1ee9967756e6b6535f0ee1f0054c3d68", - "sha256:f6d5b23f226a2ba58e14e49aa3b1bfaf814d0199144b95d78458212444de1387" + "sha256:6901995b9b686cb90cceba67a0f6d4d14ae003cd59bc12beb61549bdfbe3bc89", + "sha256:d950c64aeea5456bbd147468382a5bb77fe692c13c9f00f0219814ce5b642755" ], - "version": "==5.1.1" + "version": "==5.2.0" }, "pygments": { "hashes": [ @@ -138,25 +147,25 @@ }, "pyparsing": { "hashes": [ - "sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a", - "sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3" + "sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", + "sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03" ], - "version": "==2.3.1" + "version": "==2.4.0" }, "pytz": { "hashes": [ - "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9", - "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c" + "sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", + "sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141" ], - "version": "==2018.9" + "version": "==2019.1" }, "readthedocs-sphinx-ext": { "hashes": [ - "sha256:42b1c63d63dd483a188b541599bd08a540b2d08ec2b166660179618b6ccc3bb0", - "sha256:e73770f53a226f6db8199916a12bcee1808e0c0cbe028422668e8c1c7f2fa80c" + "sha256:21097cbb37c9a0590e2cb444b55bd87302fc8f69640fa2d4f2d113e98e9558ff", + "sha256:d0fd65a9dffc187da94136ff5485e5b3ea96a4734559b1adc7954c1bc1658aa3" ], "index": "pypi", - "version": "==0.5.16" + "version": "==0.5.17" }, "requests": { "hashes": [ @@ -167,9 +176,9 @@ }, "restructuredtext-lint": { "hashes": [ - "sha256:82880a8de8a41bfc84f533744091b1ead8e2ab9ad6c0a3f60f4750ef6c802350" + "sha256:97b3da356d5b3a8514d8f1f9098febd8b41463bed6a1d9f126cf0a048b6fd908" ], - "version": "==1.2.2" + "version": "==1.3.0" }, "six": { "hashes": [ @@ -187,19 +196,19 @@ }, "sphinx": { "hashes": [ - "sha256:429e3172466df289f0f742471d7e30ba3ee11f3b5aecd9a840480d03f14bcfe5", - "sha256:c4cb17ba44acffae3d3209646b6baec1e215cad3065e852c68cc569d4df1b9f8" + "sha256:9f3e17c64b34afc653d7c5ec95766e03043cc6d80b0de224f59b6b6e19d37c3c", + "sha256:c7658aab75c920288a8cf6f09f244c6cfdae30d82d803ac1634d9f223a80ca08" ], "index": "pypi", - "version": "==1.8.3" + "version": "==1.8.5" }, "sphinx-rtd-theme": { "hashes": [ - "sha256:02f02a676d6baabb758a20c7a479d58648e0f64f13e07d1b388e9bb2afe86a09", - "sha256:d0f6bc70f98961145c5b0e26a992829363a197321ba571b31b24ea91879e0c96" + "sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4", + "sha256:728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a" ], "index": "pypi", - "version": "==0.4.2" + "version": "==0.4.3" }, "sphinxcontrib-websupport": { "hashes": [ @@ -210,10 +219,10 @@ }, "stevedore": { "hashes": [ - "sha256:b92bc7add1a53fb76c634a178978d113330aaf2006f9498d9e2414b31fbfc104", - "sha256:c58b7c231a9c4890cd3c2b5d2b23bd63fa807ff934d68579e3f6c3a1735e8a7c" + "sha256:7be098ff53d87f23d798a7ce7ae5c31f094f3deb92ba18059b1aeb1ca9fec0a0", + "sha256:7d1ce610a87d26f53c087da61f06f9b7f7e552efad2a7f6d2322632b5f932ea2" ], - "version": "==1.30.0" + "version": "==1.30.1" }, "typing": { "hashes": [ @@ -226,34 +235,44 @@ }, "urllib3": { "hashes": [ - "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", - "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" + "sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0", + "sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3" ], - "version": "==1.24.1" + "index": "pypi", + "version": "==1.24.2" } }, "develop": { "astroid": { "hashes": [ - "sha256:0ef2bf9f07c3150929b25e8e61b5198c27b0dca195e156f0e4d5bdd89185ca1a", - "sha256:fc9b582dba0366e63540982c3944a9230cbc6f303641c51483fa547dcc22393a" + "sha256:87de48a92e29cedf7210ffa853d11441e7ad94cb47bacd91b023499b51cbc756", + "sha256:d25869fc7f44f1d9fb7d24fd7ea0639656f5355fc3089cd1f3d18c6ec6b124c7" ], - "version": "==1.6.5" + "version": "==1.6.6" }, "backports.functools-lru-cache": { "hashes": [ "sha256:9d98697f088eb1b0fa451391f91afb5e3ebde16bbdb272819fd091151fda4f1a", "sha256:f0b0e4eba956de51238e17573b7087e852dfe9854afd2e9c873f73fc0ca0a6dd" ], - "markers": "python_version == '2.7'", + "markers": "python_version < '3.4'", "version": "==1.5" }, + "colorama": { + "hashes": [ + "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", + "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.1" + }, "configparser": { "hashes": [ - "sha256:5308b47021bc2340965c371f0f058cc6971a04502638d4244225c49d80db273a" + "sha256:8be81d89d6e7b4c0d4e44bcc525845f6da25821de80cb5e06e7e0238a2899e32", + "sha256:da60d0014fd8c55eb48c1c5354352e363e2d30bbf7057e5e171a468390184c75" ], "markers": "python_version == '2.7'", - "version": "==3.5.0" + "version": "==3.7.4" }, "enum34": { "hashes": [ @@ -270,15 +289,15 @@ "sha256:9ec02aa7d674acb8618afb127e27fde7fc68994c0437ad759fa094a574adb265", "sha256:ec0a6cb848cc212002b9828c3e34c675e0c9ff6741dc445cab6fdd4e1085d1f1" ], + "markers": "python_version < '3.2'", "version": "==3.2.0" }, "isort": { "hashes": [ - "sha256:1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af", - "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8", - "sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497" + "sha256:01cb7e1ca5e6c5b3f235f0385057f70558b70d2f00320208825fa62887292f43", + "sha256:268067462aed7eb2a1e237fcb287852f22077de3fb07964e87e00f829eea2d1a" ], - "version": "==4.3.4" + "version": "==4.3.17" }, "lazy-object-proxy": { "hashes": [ @@ -290,7 +309,6 @@ "sha256:2c1b21b44ac9beb0fc848d3993924147ba45c4ebc24be19825e57aabbe74a99e", "sha256:2df72ab12046a3496a92476020a1a0abf78b2a7db9ff4dc2036b8dd980203ae6", "sha256:320ffd3de9699d3892048baee45ebfbbf9388a7d65d832d7e580243ade426d2b", - "sha256:4e263e56b27ed395a6a8d0526f349e3fa9a58df68c849866a5befa988ba63d5a", "sha256:50e3b9a464d5d08cc5227413db0d1c4707b6172e4d4d915c1c70e4de0bbff1f5", "sha256:5276db7ff62bb7b52f77f1f51ed58850e315154249aceb42e7f4c611f0f847ff", "sha256:61a6cf00dcb1a7f0c773ed4acc509cb636af2d6337a08f362413c76b2b47a8dd", @@ -347,8 +365,7 @@ }, "wrapt": { "hashes": [ - "sha256:4aea003270831cceb8a90ff27c4031da6ead7ec1886023b80ce0dfe0adf61533", - "sha256:75b753eb0c8f2cf4fd4b551a5a9337cc225e345941977a5950de2678ffb75700" + "sha256:4aea003270831cceb8a90ff27c4031da6ead7ec1886023b80ce0dfe0adf61533" ], "version": "==1.11.1" } diff --git a/bin/ControlzEx.pdb b/bin/ControlzEx.pdb deleted file mode 100644 index 60d6fe2bb..000000000 Binary files a/bin/ControlzEx.pdb and /dev/null differ diff --git a/bin/DocoptNet.pdb b/bin/DocoptNet.pdb deleted file mode 100644 index e597db467..000000000 Binary files a/bin/DocoptNet.pdb and /dev/null differ diff --git a/bin/LibGit2Sharp.pdb b/bin/LibGit2Sharp.pdb deleted file mode 100644 index 752124697..000000000 Binary files a/bin/LibGit2Sharp.pdb and /dev/null differ diff --git a/bin/MahApps.Metro.pdb b/bin/MahApps.Metro.pdb deleted file mode 100644 index 8cd7cc10d..000000000 Binary files a/bin/MahApps.Metro.pdb and /dev/null differ diff --git a/bin/Nett.pdb b/bin/Nett.pdb deleted file mode 100644 index 758d2f76b..000000000 Binary files a/bin/Nett.pdb and /dev/null differ diff --git a/bin/Newtonsoft.Json.pdb b/bin/Newtonsoft.Json.pdb deleted file mode 100644 index 0cfd89345..000000000 Binary files a/bin/Newtonsoft.Json.pdb and /dev/null differ diff --git a/bin/git2-4aecb64.pdb b/bin/git2-4aecb64.pdb deleted file mode 100644 index bf2b4981f..000000000 Binary files a/bin/git2-4aecb64.pdb and /dev/null differ diff --git a/bin/pyRevitLabs.Common.dll b/bin/pyRevitLabs.Common.dll index 8aee76a60..1d9f8173f 100644 Binary files a/bin/pyRevitLabs.Common.dll and b/bin/pyRevitLabs.Common.dll differ diff --git a/bin/pyRevitLabs.Common.pdb b/bin/pyRevitLabs.Common.pdb deleted file mode 100644 index 242834af3..000000000 Binary files a/bin/pyRevitLabs.Common.pdb and /dev/null differ diff --git a/bin/pyRevitLabs.CommonCLI.dll b/bin/pyRevitLabs.CommonCLI.dll index 570f99c40..6dd1f8511 100644 Binary files a/bin/pyRevitLabs.CommonCLI.dll and b/bin/pyRevitLabs.CommonCLI.dll differ diff --git a/bin/pyRevitLabs.CommonCLI.pdb b/bin/pyRevitLabs.CommonCLI.pdb deleted file mode 100644 index 094f17e48..000000000 Binary files a/bin/pyRevitLabs.CommonCLI.pdb and /dev/null differ diff --git a/bin/pyRevitLabs.CommonWPF.dll b/bin/pyRevitLabs.CommonWPF.dll index 72636fc0a..e141a0e9c 100644 Binary files a/bin/pyRevitLabs.CommonWPF.dll and b/bin/pyRevitLabs.CommonWPF.dll differ diff --git a/bin/pyRevitLabs.CommonWPF.pdb b/bin/pyRevitLabs.CommonWPF.pdb deleted file mode 100644 index c8c8cd194..000000000 Binary files a/bin/pyRevitLabs.CommonWPF.pdb and /dev/null differ diff --git a/bin/pyRevitLabs.Language.dll b/bin/pyRevitLabs.Language.dll index 45179f461..e08423984 100644 Binary files a/bin/pyRevitLabs.Language.dll and b/bin/pyRevitLabs.Language.dll differ diff --git a/bin/pyRevitLabs.Language.pdb b/bin/pyRevitLabs.Language.pdb deleted file mode 100644 index c60a5f13f..000000000 Binary files a/bin/pyRevitLabs.Language.pdb and /dev/null differ diff --git a/bin/pyRevitLabs.TargetApps.Revit.dll b/bin/pyRevitLabs.TargetApps.Revit.dll index 2c176b6cc..162bf7e64 100644 Binary files a/bin/pyRevitLabs.TargetApps.Revit.dll and b/bin/pyRevitLabs.TargetApps.Revit.dll differ diff --git a/bin/pyRevitLabs.TargetApps.Revit.pdb b/bin/pyRevitLabs.TargetApps.Revit.pdb deleted file mode 100644 index 83ec29888..000000000 Binary files a/bin/pyRevitLabs.TargetApps.Revit.pdb and /dev/null differ diff --git a/bin/pyRevitUpdater.exe b/bin/pyRevitUpdater.exe deleted file mode 100644 index 3a13bff72..000000000 Binary files a/bin/pyRevitUpdater.exe and /dev/null differ diff --git a/bin/pyrevit.exe b/bin/pyrevit.exe index 7a409bf72..608ff450b 100644 Binary files a/bin/pyrevit.exe and b/bin/pyrevit.exe differ diff --git a/bin/pyrevit.pdb b/bin/pyrevit.pdb deleted file mode 100644 index 1abf6825a..000000000 Binary files a/bin/pyrevit.pdb and /dev/null differ diff --git a/dev/WPFEdit/WPFEdit/WPFEdit.csproj b/dev/WPFEdit/WPFEdit/WPFEdit.csproj index af0f406d2..d4ca04af7 100644 --- a/dev/WPFEdit/WPFEdit/WPFEdit.csproj +++ b/dev/WPFEdit/WPFEdit/WPFEdit.csproj @@ -192,6 +192,11 @@ MSBuild:Compile Designer + + Forms\ParameterItemStyle.xaml + MSBuild:Compile + Designer + Forms\ProgressBar.xaml MSBuild:Compile diff --git a/dev/pyRevitLabs/pyRevitLabs.Common/pyRevitLabs.Common.csproj b/dev/pyRevitLabs/pyRevitLabs.Common/pyRevitLabs.Common.csproj index e75a5c3ad..52217be9d 100644 --- a/dev/pyRevitLabs/pyRevitLabs.Common/pyRevitLabs.Common.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.Common/pyRevitLabs.Common.csproj @@ -29,10 +29,11 @@ none false bin\Release\ - TRACE + + prompt 4 - AnyCPU + x64 false @@ -103,7 +104,6 @@ - - + copy "$(TargetPath)" "$(TargetDir)..\..\..\..\..\bin" \ No newline at end of file diff --git a/dev/pyRevitLabs/pyRevitLabs.CommonCLI/pyRevitLabs.CommonCLI.csproj b/dev/pyRevitLabs/pyRevitLabs.CommonCLI/pyRevitLabs.CommonCLI.csproj index 0382b68f2..ebd8f773a 100644 --- a/dev/pyRevitLabs/pyRevitLabs.CommonCLI/pyRevitLabs.CommonCLI.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.CommonCLI/pyRevitLabs.CommonCLI.csproj @@ -27,10 +27,11 @@ none true bin\Release\ - TRACE + + prompt 4 - AnyCPU + x64 true @@ -64,7 +65,6 @@ - - + copy "$(TargetPath)" "$(TargetDir)..\..\..\..\..\bin" \ No newline at end of file diff --git a/dev/pyRevitLabs/pyRevitLabs.CommonWPF/pyRevitLabs.CommonWPF.csproj b/dev/pyRevitLabs/pyRevitLabs.CommonWPF/pyRevitLabs.CommonWPF.csproj index 24c4397f8..c089a7ed3 100644 --- a/dev/pyRevitLabs/pyRevitLabs.CommonWPF/pyRevitLabs.CommonWPF.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.CommonWPF/pyRevitLabs.CommonWPF.csproj @@ -27,10 +27,11 @@ none true bin\Release\ - TRACE + + prompt 4 - AnyCPU + x64 false @@ -103,7 +104,6 @@ - - + copy "$(TargetPath)" "$(TargetDir)..\..\..\..\..\bin" \ No newline at end of file diff --git a/dev/pyRevitLabs/pyRevitLabs.DeffrelDB/pyRevitLabs.DeffrelDB.csproj b/dev/pyRevitLabs/pyRevitLabs.DeffrelDB/pyRevitLabs.DeffrelDB.csproj index 17a744486..0e1532a3f 100644 --- a/dev/pyRevitLabs/pyRevitLabs.DeffrelDB/pyRevitLabs.DeffrelDB.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.DeffrelDB/pyRevitLabs.DeffrelDB.csproj @@ -27,9 +27,11 @@ pdbonly true bin\Release\ - TRACE + + prompt 4 + x64 true diff --git a/dev/pyRevitLabs/pyRevitLabs.Language/pyRevitLabs.Language.csproj b/dev/pyRevitLabs/pyRevitLabs.Language/pyRevitLabs.Language.csproj index acab14cdc..374d60bf2 100644 --- a/dev/pyRevitLabs/pyRevitLabs.Language/pyRevitLabs.Language.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.Language/pyRevitLabs.Language.csproj @@ -27,9 +27,11 @@ pdbonly true bin\Release\ - TRACE + + prompt 4 + x64 true @@ -64,4 +66,7 @@ + + copy "$(TargetPath)" "$(TargetDir)..\..\..\..\..\bin" + \ No newline at end of file diff --git a/dev/pyRevitLabs/pyRevitLabs.TargetApps.AutoCAD/pyRevitLabs.TargetApps.AutoCAD.csproj b/dev/pyRevitLabs/pyRevitLabs.TargetApps.AutoCAD/pyRevitLabs.TargetApps.AutoCAD.csproj index 1b4f00f31..283100504 100644 --- a/dev/pyRevitLabs/pyRevitLabs.TargetApps.AutoCAD/pyRevitLabs.TargetApps.AutoCAD.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.TargetApps.AutoCAD/pyRevitLabs.TargetApps.AutoCAD.csproj @@ -27,9 +27,11 @@ none true bin\Release\ - TRACE + + prompt 4 + x64 true diff --git a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Navisworks/pyRevitLabs.TargetApps.Navisworks.csproj b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Navisworks/pyRevitLabs.TargetApps.Navisworks.csproj index b40b77a0f..8ba772923 100644 --- a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Navisworks/pyRevitLabs.TargetApps.Navisworks.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Navisworks/pyRevitLabs.TargetApps.Navisworks.csproj @@ -27,9 +27,11 @@ none true bin\Release\ - TRACE + + prompt 4 + x64 true diff --git a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/Properties/AssemblyInfo.cs b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/Properties/AssemblyInfo.cs index 8351c5dfb..032bd38b0 100644 --- a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/Properties/AssemblyInfo.cs +++ b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.8.8.0")] -[assembly: AssemblyFileVersion("0.8.8.0")] +[assembly: AssemblyVersion("0.8.9.0")] +[assembly: AssemblyFileVersion("0.8.9.0")] diff --git a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/RevitController.cs b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/RevitController.cs index 127250169..d124823e6 100644 --- a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/RevitController.cs +++ b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/RevitController.cs @@ -421,6 +421,10 @@ public class RevitProduct { {"20181217_1515", ("19.2.0.65", "2019.2 (Update)")}, {"20190108_1515", ("19.2.1.1", "2019.2 (Full Install)")}, // reported by: https://twitter.com/JarodJSchultz/status/1100459171491676160 {"20190225_1515", ("19.2.10.7", "2019.2.1")}, // release notes https://up.autodesk.com/2019/RVT/Autodesk_Revit_2019_2_1_Readme.html + + // 2020 + {"20190327_2315", ("20.0.0.377", "2020 First Customer Ship")}, + {"20190412_1200", ("20.0.1.2", "2020.0.1")}, }; private static Regex BuildNumberFinder = new Regex(@".*(?\d{8}_\d{4}).*"); diff --git a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/pyRevitLabs.TargetApps.Revit.csproj b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/pyRevitLabs.TargetApps.Revit.csproj index 36a114a3a..5e436074a 100644 --- a/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/pyRevitLabs.TargetApps.Revit.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.TargetApps.Revit/pyRevitLabs.TargetApps.Revit.csproj @@ -29,9 +29,11 @@ none true bin\Release\ - TRACE + + prompt 4 + x64 true @@ -40,12 +42,10 @@ - ..\..\..\..\..\..\..\..\Program Files\Autodesk\Revit 2019\RevitAPI.dll - False + ..\..\..\..\..\..\..\..\Program Files\Autodesk\Revit 2020\RevitAPI.dll - ..\..\..\..\..\..\..\..\Program Files\Autodesk\Revit 2019\RevitAPIUI.dll - False + ..\..\..\..\..\..\..\..\Program Files\Autodesk\Revit 2020\RevitAPIUI.dll diff --git a/dev/pyRevitLabs/pyRevitManager/Properties/AssemblyInfo.cs b/dev/pyRevitLabs/pyRevitManager/Properties/AssemblyInfo.cs index 49b8f3f02..10ba5cca3 100644 --- a/dev/pyRevitLabs/pyRevitManager/Properties/AssemblyInfo.cs +++ b/dev/pyRevitLabs/pyRevitManager/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.9.7.0")] -[assembly: AssemblyFileVersion("0.9.7.0")] +[assembly: AssemblyVersion("0.9.8.0")] +[assembly: AssemblyFileVersion("0.9.8.0")] diff --git a/dev/pyRevitLabs/pyRevitManager/pyRevitManager.csproj b/dev/pyRevitLabs/pyRevitManager/pyRevitManager.csproj index a6316da59..e31ce91ff 100644 --- a/dev/pyRevitLabs/pyRevitManager/pyRevitManager.csproj +++ b/dev/pyRevitLabs/pyRevitManager/pyRevitManager.csproj @@ -44,11 +44,12 @@ false - AnyCPU + x64 pdbonly true - bin\Release\ - TRACE + ..\..\..\bin\ + + prompt 4 false @@ -132,19 +133,26 @@ {614720ba-c0e3-4199-9a5e-d2468ffcbfe5} pyRevitLabs.CommonCLI + False + False {c5a03112-6ee1-415f-b53d-5d732d9f47ad} pyRevitLabs.Common + False + False {269fe01f-093a-4774-8017-fefc2342abf5} pyRevitLabs.Language + False + False {ed0fb7a2-e4a8-4490-a020-73140bfbce0b} pyRevitLabs.TargetApps.Revit False + False @@ -172,6 +180,9 @@ 1.0.2 + + 0.25.4 + 2.0.3 @@ -186,9 +197,9 @@ - copy "$(TargetDir)lib\win32\x64\git2-8e0b172.dll" "$(TargetDir)git2-8e0b172.dll" + copy "$(TargetDir)lib\win32\x64\git2-4aecb64.dll" "$(TargetDir)git2-4aecb64.dll" rd /S /Q "$(TargetDir)lib" -REM del /Q "$(TargetDir)*.pdb" +del /Q "$(TargetDir)*.pdb" REM del /Q "$(TargetDir)*.config" REM del /Q "$(TargetDir)*.xml" signtool sign /n "Ehsan Iran Nejad" /t http://timestamp.digicert.com /fd sha256 "$(TargetPath)" diff --git a/dev/pyRevitLabs/pyRevitUpdater/pyRevitUpdater.csproj b/dev/pyRevitLabs/pyRevitUpdater/pyRevitUpdater.csproj index e6c8a056d..1631b2bb0 100644 --- a/dev/pyRevitLabs/pyRevitUpdater/pyRevitUpdater.csproj +++ b/dev/pyRevitLabs/pyRevitUpdater/pyRevitUpdater.csproj @@ -40,13 +40,15 @@ false - AnyCPU + x64 pdbonly true bin\Release\ - TRACE + + prompt 4 + false pyRevit.ico diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/SettingsWindow.xaml b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/SettingsWindow.xaml index b27f4a475..6a4905b0b 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/SettingsWindow.xaml +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/SettingsWindow.xaml @@ -375,6 +375,9 @@ Revit versions from here. This effectively removes the pyRevit.addin manifest file from %appdata%/Autodesk/Revit/Addins folders. + + Autodesk Revit 2020 + Autodesk Revit 2019 diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/script.py index 1c3e3c0c4..e6b8fa920 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/script.py +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/Settings.smartbutton/script.py @@ -80,7 +80,8 @@ def __init__(self, xaml_file_name): '2016': self.revit2016_cb, '2017': self.revit2017_cb, '2018': self.revit2018_cb, - '2019': self.revit2019_cb} + '2019': self.revit2019_cb, + '2020': self.revit2020_cb} self.set_image_source(self.lognone, 'lognone.png') self.set_image_source(self.logverbose, 'logverbose.png') diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Inspect.pulldown/Find Referencing Sheets.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Inspect.pulldown/Find Referencing Sheets.pushbutton/script.py index 5cc2079c1..1c91731c4 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Inspect.pulldown/Find Referencing Sheets.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Inspect.pulldown/Find Referencing Sheets.pushbutton/script.py @@ -1,36 +1,35 @@ +"""Find all sheets referencing the current view. +Especially useful for finding legends. +""" +#pylint: disable=import-error,invalid-name,broad-except from pyrevit import revit, DB +from pyrevit import forms +from pyrevit import script +__author__ = "{{author}}" -__doc__ = 'Find all sheets referencing the current view.'\ - ' Especially useful for finding legends.' - - -cl_views = DB.FilteredElementCollector(revit.doc) -shts = cl_views.OfCategory(DB.BuiltInCategory.OST_Sheets)\ - .WhereElementIsNotElementType()\ - .ToElements() - -sheets = sorted(shts, key=lambda x: x.SheetNumber) +output = script.get_output() curview = revit.activeview count = 0 -print('Searching All Sheets for {0} ID:{1}\n'.format(curview.Name, curview.Id)) -for s in sheets: - vpsIds = [revit.doc.GetElement(x).ViewId for x in s.GetAllViewports()] + +print('Searching All Sheets for {} {}\n' + .format(curview.Name, output.linkify(curview.Id))) + +for sheet in revit.query.get_sheets(include_placeholders=False): + vps_ids = [revit.doc.GetElement(x).ViewId for x in sheet.GetAllViewports()] curviewelements = DB.FilteredElementCollector(revit.doc)\ - .OwnedByView(s.Id)\ + .OwnedByView(sheet.Id)\ .WhereElementIsNotElementType()\ .ToElements() for el in curviewelements: if isinstance(el, DB.ScheduleSheetInstance): - vpsIds.append(el.ScheduleId) + vps_ids.append(el.ScheduleId) - if curview.Id in vpsIds: + if curview.Id in vps_ids: count += 1 - print('NUMBER: {0} NAME:{1}' - .format(s.Parameter[DB.BuiltInParameter.SHEET_NUMBER].AsString().rjust(10), - s.Parameter[DB.BuiltInParameter.SHEET_NAME].AsString().ljust(50))) + revit.report.print_sheet(sheet) print('\n\nView is referenced on {0} sheets.'.format(count)) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/keynotesdb.py b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/keynotesdb.py index 61720e1ec..9be3e1e3b 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/keynotesdb.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Keynotes.pushbutton/keynotesdb.py @@ -363,9 +363,14 @@ def get_keynotes_tree(conn): for catroot_rkey in keynote_records: if catroot_rkey.key in parents: - catroot_rkey.children.extend(parents[catroot_rkey.key]) + catroot_rkey.children.extend( + natsorted( + parents[catroot_rkey.key], + key=lambda x: x.key + ) + ) - return sorted(cat_roots, key=lambda x: x.key) + return natsorted(cat_roots, key=lambda x: x.key) def find(conn, key): diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py index bc494b273..239854d51 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/Sheets.pulldown/ReOrder Sheets.pushbutton/script.py @@ -37,7 +37,7 @@ def __init__(self, xaml_file_name): @property def items_list(self): - return self.items_dg.ItemsSource + return self.items_dg.ItemsSource or [] @items_list.setter def items_list(self, value): diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/Create Parallel Section.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/Create Parallel Section.pushbutton/icon.png new file mode 100644 index 000000000..04581b6a1 Binary files /dev/null and b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/Create Parallel Section.pushbutton/icon.png differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/Create Parallel Section.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/Create Parallel Section.pushbutton/script.py new file mode 100644 index 000000000..c914b4381 --- /dev/null +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/Create Parallel Section.pushbutton/script.py @@ -0,0 +1,67 @@ +"""Create section parallel to the plane of selected walls or planar element.""" +#pylint: disable=import-error,invalid-name,broad-except +from pyrevit import revit, DB +from pyrevit import script + +# adapted from https://thebuildingcoder.typepad.com/blog/2012/06/create-section-view-parallel-to-wall.html +__author__ = 'Source: Jeremy Tammik\nAdapted by: {{author}}' + +logger = script.get_logger() +output = script.get_output() + + +def create_section(wall, section_type): + # ensure wall is straight + line = wall.Location.Curve + # determine section box + p = line.GetEndPoint(0) + q = line.GetEndPoint(1) + v = q - p + + bb = wall.get_BoundingBox(None) + minZ = bb.Min.Z + maxZ = bb.Max.Z + + w = v.GetLength() + # h = maxZ - minZ + # d = wall.WallType.Width + offset = 0.1 * w + + bbox_min = DB.XYZ(-w, minZ - offset, -offset) + bbox_max = DB.XYZ(w, maxZ + offset, 0) + + midpoint = p + 0.5 * v + walldir = v.Normalize() + up = DB.XYZ.BasisZ + viewdir = walldir.CrossProduct(up) + + t = DB.Transform.Identity + t.Origin = midpoint + t.BasisX = walldir + t.BasisY = up + t.BasisZ = viewdir + + section_box = DB.BoundingBoxXYZ() + section_box.Transform = t + section_box.Min = bbox_min + section_box.Max = bbox_max + + DB.ViewSection.CreateSection(revit.doc, section_type, section_box) + + +def get_walls(): + """retrieve wall from selection set""" + return [x for x in revit.get_selection() if isinstance(x, DB.Wall)] + + +def get_section_viewfamily(): + return revit.doc.GetDefaultElementTypeId( + DB.ElementTypeGroup.ViewTypeSection + ) + + +doc_section_type = get_section_viewfamily() + +with revit.Transaction("Create Parallel Section"): + for selected_wall in get_walls(): + create_section(selected_wall, doc_section_type) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/_layout b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/_layout index 9de468458..b176eb39f 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/_layout +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Drawing Set.panel/views.stack3/Views.pulldown/_layout @@ -12,6 +12,7 @@ Find Used View Templates Filters Copy View Templates to Open Documents Toggle All Grid Bubbles in Current View Match Title on Sheet in Open Docs +Create Parallel Section Add Views to Sheets Remove Empty Tags Remove Underlay From Selected Views diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/icon.png new file mode 100644 index 000000000..2413566ca Binary files /dev/null and b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/icon.png differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/script.py new file mode 100644 index 000000000..1775b7d6e --- /dev/null +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/script.py @@ -0,0 +1,140 @@ +"""Match instance or type properties between elements and their types. + +Shift+Click: +Reapply the previous match properties. + +""" +#pylint: disable=import-error,invalid-name,broad-except +import pickle + +from pyrevit import revit, DB +from pyrevit import forms +from pyrevit import script + +__author__ = "{{author}}" + +logger = script.get_logger() +output = script.get_output() + + +class PropKeyValue(object): + """Storage class for matched property info and value.""" + def __init__(self, name, datatype, value, istype): + self.name = name + self.datatype = datatype + self.value = value + self.istype = istype + + def __repr__(self): + return str(self.__dict__) + + +MEMFILE = script.get_document_data_file( + file_id='MatchSelectedProperties', + file_ext='pym', + add_cmd_name=False + ) + + +def get_source_properties(src_element): + """Return info on selected properties.""" + props = [] + + src_type = revit.query.get_type(src_element) + + selected_params = forms.select_parameter( + src_element, + title='Select Parameters', + multiple=True, + include_instance=True, + include_type=True + ) or [] + + logger.debug('Selected parameters: %s', [x.name for x in selected_params]) + + for sparam in selected_params: + logger.debug('Reading %s', sparam.name) + target = src_type if sparam.istype else src_element + tparam = target.LookupParameter(sparam.name) + if tparam: + if tparam.StorageType == DB.StorageType.Integer: + value = tparam.AsInteger() + elif tparam.StorageType == DB.StorageType.Double: + value = tparam.AsDouble() + elif tparam.StorageType == DB.StorageType.ElementId: + value = tparam.AsElementId().IntegerValue + else: + value = tparam.AsString() + + props.append( + PropKeyValue( + name=sparam.name, + datatype=tparam.StorageType, + value=value, + istype=sparam.istype + )) + + return props + + +def pick_and_match_types(src_props): + """Match property values for selected types.""" + with forms.WarningBar(title='Pick objects to match type properties:'): + while True: + dest_element = revit.pick_element() + + if not dest_element: + break + + dest_type = revit.query.get_type(dest_element) + if dest_type: + with revit.Transaction('Match Type Properties'): + for pkv in src_props: + logger.debug('Applying %s', pkv.name) + target = dest_type if pkv.istype else dest_element + logger.debug('Target is %s', target) + dparam = target.LookupParameter(pkv.name) + if dparam and pkv.datatype == dparam.StorageType: + if dparam.StorageType == DB.StorageType.ElementId: + dparam.Set(DB.ElementId(pkv.value)) + else: + dparam.Set(pkv.value) + + +def recall(): + """Load last matched properties from memory.""" + data = [] + try: + with open(MEMFILE, 'r') as mf: + data = pickle.load(mf) + except Exception as ex: + logger.debug( + 'Failed loading matched properties from memory | %s', str(ex) + ) + return data + + +def remember(src_props): + """Save selected matched properties to memory.""" + with open(MEMFILE, 'w') as mf: + pickle.dump(src_props, mf) + + +# main +source_props = [] +if __shiftclick__: #pylint: disable=undefined-variable + source_props = recall() + logger.debug('Recalled data: %s', source_props) + +if not source_props: + with forms.WarningBar(title='Pick source object:'): + source_element = revit.pick_element() + + if source_element: + if not source_props: + source_props = get_source_properties(source_element) + remember(source_props) + + +if source_props: + pick_and_match_types(source_props) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/tooltip.mp4 b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/tooltip.mp4 new file mode 100644 index 000000000..2a71e4ab6 Binary files /dev/null and b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/Match Properties.pushbutton/tooltip.mp4 differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/_layout b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/_layout index 00c18bccf..c9f4a5f93 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/_layout +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Match.splitpushbutton/_layout @@ -1,2 +1,3 @@ Match -Match Paint \ No newline at end of file +Match Paint +Match Properties \ No newline at end of file diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Patterns.splitpushbutton/Make Pattern.pushbutton/patmaker.py b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Patterns.splitpushbutton/Make Pattern.pushbutton/patmaker.py index 9803c82a9..bf0eb1d3c 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Patterns.splitpushbutton/Make Pattern.pushbutton/patmaker.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/Patterns.splitpushbutton/Make Pattern.pushbutton/patmaker.py @@ -713,10 +713,10 @@ def _make_filledregion(fillpattern_name, fillpattern_id): def _export_pat(revit_pat, export_dir): pat_file_contents = revit_pat.get_pat_data() - with open(op.join(export_dir, - '{}.pat'.format( - coreutils.cleanup_filename(revit_pat.name) - )), 'w') as pat_file: + pat_file_name = coreutils.cleanup_filename(revit_pat.name) + pat_file_path = op.join(export_dir, '{}.pat'.format(pat_file_name)) + logger.debug('Exporting pattern to: %s', pat_file_path) + with open(pat_file_path, 'w') as pat_file: pat_file.write(pat_file_contents) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Edit.pulldown/Convert Line Styles.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Edit.pulldown/Convert Line Styles.pushbutton/script.py index 6d64e10bb..4134ddc41 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Edit.pulldown/Convert Line Styles.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Edit.pulldown/Convert Line Styles.pushbutton/script.py @@ -23,7 +23,7 @@ def __str__(self): return '{} ({} {} {})'.format( self.name, self.weight, - self.colorhex, + self.color_hex, self.pattern_name ) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Override.pulldown/Override VG.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Override.pulldown/Override VG.pushbutton/script.py index 82a87441d..c11cb9230 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Override.pulldown/Override VG.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/edit2.stack3/Override.pulldown/Override VG.pushbutton/script.py @@ -14,6 +14,8 @@ logger = script.get_logger() selection = revit.get_selection() +# select all individual elements inside a group +selection.expand_groups() def find_solid_fillpat(): diff --git a/extensions/pyRevitTemplates.extension/pyRevit.tab/Templates.panel/Cycle Family Types.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/Cycle Family Types.pushbutton/icon.png similarity index 100% rename from extensions/pyRevitTemplates.extension/pyRevit.tab/Templates.panel/Cycle Family Types.pushbutton/icon.png rename to extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/Cycle Family Types.pushbutton/icon.png diff --git a/extensions/pyRevitTemplates.extension/pyRevit.tab/Templates.panel/Cycle Family Types.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/Cycle Family Types.pushbutton/script.py similarity index 94% rename from extensions/pyRevitTemplates.extension/pyRevit.tab/Templates.panel/Cycle Family Types.pushbutton/script.py rename to extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/Cycle Family Types.pushbutton/script.py index d8193a4c4..edaca0b02 100644 --- a/extensions/pyRevitTemplates.extension/pyRevit.tab/Templates.panel/Cycle Family Types.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/Cycle Family Types.pushbutton/script.py @@ -4,7 +4,7 @@ from pyrevit import forms __title__ = "Cycle\nTypes" -__author__ = "{{author}}" +__author__ = "{{author}}\nGui Talarico" forms.check_familydoc(doc=revit.doc, exitscript=True) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/_layout b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/_layout index 2791049e7..2619420c9 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/_layout +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/_layout @@ -1,3 +1,4 @@ ptools2 +Cycle Family Types ptools Wipe \ No newline at end of file diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Family.pulldown/Import Family Config.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Family.pulldown/Import Family Config.pushbutton/icon.png new file mode 100644 index 000000000..ed68a2180 Binary files /dev/null and b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Family.pulldown/Import Family Config.pushbutton/icon.png differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Family.pulldown/Import Family Config.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Family.pulldown/Import Family Config.pushbutton/script.py new file mode 100644 index 000000000..9ffc9ff3f --- /dev/null +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Project.panel/ptools.stack3/Family.pulldown/Import Family Config.pushbutton/script.py @@ -0,0 +1,230 @@ +"""Import family configurations from yaml file and modify current family. + +Family configuration file is expected to be a yaml file, +providing info about the parameters and types to be created. + +The structure of this config file is as shown below: + +parameters: + : + type: + category: + instance: +types: + : + : + : + ... + + +Example: + +parameters: + Shelf Height (Upper): + type: Length + category: PG_GEOMETRY + instance: false +types: + 24D"x36H": + Shelf Height (Upper): 3'-0" +""" +#pylint: disable=import-error,invalid-name,broad-except +# TODO: fix parameter ordering +from collections import namedtuple + +from pyrevit import coreutils +from pyrevit import revit, DB +from pyrevit import forms +from pyrevit import script + +from winterops import yaml + + +__author__ = "{{author}}" + + +logger = script.get_logger() +output = script.get_output() + + +DEFAULT_TYPE = 'Text' +DEFAULT_BIP_CATEGORY = 'PG_CONSTRUCTION' + +PARAM_SECTION_NAME = 'parameters' +TYPES_SECTION_NAME = 'types' + + +ParamConfig = \ + namedtuple( + 'ParamConfig', + ['name', 'bicat', 'bitype', 'isinst', 'formula'] + ) + + +ParamValueConfig = \ + namedtuple( + 'ParamValueConfig', + ['name', 'value'] + ) + + +TypeConfig = \ + namedtuple( + 'TypeConfig', + ['name', 'param_values'] + ) + + +def get_symbol(symbol_name): + for fsym in DB.FilteredElementCollector(revit.doc)\ + .OfClass(DB.FamilySymbol)\ + .ToElements(): + name = revit.query.get_name(fsym) + if name == symbol_name: + return fsym.Id + + +def get_param_config(param_name, param_opts): + # Extract parameter configurations from given dict + # extract configured values + param_bip_cat = coreutils.get_enum_value( + DB.BuiltInParameterGroup, + param_opts.get('category', DEFAULT_BIP_CATEGORY) + ) + param_type = coreutils.get_enum_value( + DB.ParameterType, + param_opts.get('type', DEFAULT_TYPE) + ) + param_isinst = param_opts.get('instance', 'false').lower() == 'true' + param_formula = param_opts.get('formula', None) + + if not param_bip_cat: + logger.critical( + 'can not determine parameter category for %s', param_name + ) + return + elif not param_type: + logger.critical( + 'can not determine parameter type', param_name + ) + return + + return ParamConfig( + name=param_name, + bicat=param_bip_cat, + bitype=param_type, + isinst=param_isinst, + formula=param_formula + ) + + +def ensure_param(param_name, param_opts): + # Create family parameter based on name and options + fm = revit.doc.FamilyManager + if param_name and param_opts: + logger.debug('ensuring parameter: %s', param_name) + + # extract param config from dict + pcfg = get_param_config(param_name, param_opts) + + if pcfg: + logger.debug('%s %s %s', pcfg.bicat, pcfg.bitype, pcfg.isinst) + fparam = revit.query.get_family_parameter(param_name, revit.doc) + if not fparam: + # create param in family doc + fparam = fm.AddParameter( + pcfg.name, + pcfg.bicat, + pcfg.bitype, + pcfg.isinst + ) + + if pcfg.formula: + fm.SetFormula(fparam, pcfg.formula) + + return fparam + + +def ensure_params(fconfig): + param_cfgs = fconfig.get(PARAM_SECTION_NAME, None) + if param_cfgs: + for pname, popts in param_cfgs.items(): + ensure_param(pname, popts) + + +def get_type_config(type_name, type_opts): + if type_name and type_opts: + pvalue_cfgs = [] + for pname, pvalue in type_opts.items(): + pvalue_cfgs.append(ParamValueConfig(name=pname, value=pvalue)) + + return TypeConfig(name=type_name, param_values=pvalue_cfgs) + + +def ensure_type(type_config): + fm = revit.doc.FamilyManager + # extract type config from dict + logger.debug('%s %s', type_config.name, type_config.param_values) + ftype = revit.query.get_family_type(type_config.name, revit.doc) + if not ftype: + # create type in family doc + ftype = fm.NewType(type_config.name) + + return ftype + + +def ensure_types(fconfig): + fm = revit.doc.FamilyManager + type_cfgs = fconfig.get(TYPES_SECTION_NAME, None) + if type_cfgs: + for tname, topts in type_cfgs.items(): + logger.debug('ensuring type: %s', tname) + tcfg = get_type_config(tname, topts) + if tcfg: + ftype = ensure_type(tcfg) + if ftype: + logger.debug('setting type values: %s', tname) + fm.CurrentType = ftype + for pvcfg in tcfg.param_values: + fparam = \ + revit.query.get_family_parameter( + pvcfg.name, + revit.doc + ) + logger.debug('setting value for: %s', pvcfg.name) + if fparam: + if fparam.StorageType == DB.StorageType.ElementId \ + and fparam.Definition.ParameterType == DB.ParameterType.FamilyType: + fsym_id = get_symbol(pvcfg.value) + fm.Set(fparam, fsym_id) + elif fparam.StorageType == DB.StorageType.String: + fm.Set(fparam, pvcfg.value) + elif fparam.StorageType == DB.StorageType.Integer \ + and fparam.Definition.ParameterType.YesNo: + fm.Set(fparam, 1 if pvcfg.value.lower() == 'true' else 0) + else: + fm.SetValueString(fparam, pvcfg.value) + else: + logger.warning('can not find parameter: %s', pvcfg.name) + + +def get_config_file(): + # Get parameter definition yaml file from user + return forms.pick_file(file_ext='yaml') + + +def load_configs(parma_file): + # Load contents of yaml file into an ordered dict + return yaml.load_as_dict(parma_file) + + +if __name__ == '__main__': + forms.check_familydoc(exitscript=True) + + family_cfg_file = get_config_file() + if family_cfg_file: + family_configs = load_configs(family_cfg_file) + logger.debug(family_configs) + with revit.Transaction('Import Params from Config'): + ensure_params(family_configs) + ensure_types(family_configs) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Select Element Types.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Select Element Types.pushbutton/script.py index 9b8b9d4c7..bb09154c6 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Select Element Types.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Select Element Types.pushbutton/script.py @@ -22,7 +22,7 @@ all_options = list(element_types) all_options.extend(graphic_styles) -all_options.extend(['Fill Patterns', 'Area Schemes']) +all_options.extend(['Fill Patterns', 'Area Schemes', 'Line Styles']) selected_option = \ forms.CommandSwitchWindow.show(all_options, message='Pick type category:') @@ -33,10 +33,13 @@ fill_patterns = revit.query.get_types_by_class(DB.FillPatternElement, doc=revit.doc) selection.set_to(list(fill_patterns)) - if selected_option == 'Area Schemes': + elif selected_option == 'Area Schemes': area_schemes = revit.query.get_types_by_class(DB.AreaScheme, doc=revit.doc) selection.set_to(list(area_schemes)) + elif selected_option == 'Line Styles': + line_styles = revit.query.get_line_styles(doc=revit.doc) + selection.set_to(list(line_styles)) elif selected_option.startswith('Graphics Styles: '): graphic_style_cat = selected_option.replace('Graphics Styles: ', '') graphic_styles = \ diff --git a/pyrevitlib/pyrevit/compat.py b/pyrevitlib/pyrevit/compat.py index 59072bfad..2bceb195e 100644 --- a/pyrevitlib/pyrevit/compat.py +++ b/pyrevitlib/pyrevit/compat.py @@ -11,10 +11,12 @@ PY3 = sys.version_info[0] == 3 IRONPY273 = sys.version_info[:3] == (2, 7, 3) IRONPY277 = sys.version_info[:3] == (2, 7, 7) +IRONPY279 = sys.version_info[:3] == (2, 7, 9) #pylint: disable=C0103 safe_strtype = str if PY2: - safe_strtype = unicode #pylint: disable=E0602 + # https://gist.github.com/gornostal/1f123aaf838506038710 + safe_strtype = lambda x: unicode(x) #pylint: disable=E0602,unnecessary-lambda diff --git a/pyrevitlib/pyrevit/coreutils/__init__.py b/pyrevitlib/pyrevit/coreutils/__init__.py index de1fd2cca..f72f4df7d 100644 --- a/pyrevitlib/pyrevit/coreutils/__init__.py +++ b/pyrevitlib/pyrevit/coreutils/__init__.py @@ -841,9 +841,12 @@ def cleanup_filename(file_name): Example: >>> cleanup_filename('Myfile-(3).txt') - "Myfile3.txt" + "Myfile(3).txt" + + >>> cleanup_filename('Perforations 1/8" (New)') + "Perforations 18 (New).txt" """ - return re.sub(r'[^\w_.)( -#]', '', file_name) + return re.sub(r'[^\w_.() -#]|["]', '', file_name) def _inc_or_dec_string(str_id, shift): diff --git a/pyrevitlib/pyrevit/forms/ParameterItemStyle.xaml b/pyrevitlib/pyrevit/forms/ParameterItemStyle.xaml new file mode 100644 index 000000000..a06ae9774 --- /dev/null +++ b/pyrevitlib/pyrevit/forms/ParameterItemStyle.xaml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/pyrevitlib/pyrevit/forms/__init__.py b/pyrevitlib/pyrevit/forms/__init__.py index 5b60bc84f..8b46cca40 100644 --- a/pyrevitlib/pyrevit/forms/__init__.py +++ b/pyrevitlib/pyrevit/forms/__init__.py @@ -8,7 +8,7 @@ import os import os.path as op import string -from collections import OrderedDict +from collections import OrderedDict, namedtuple import threading from functools import wraps import datetime @@ -49,6 +49,18 @@ WPF_VISIBLE = framework.Windows.Visibility.Visible +XAML_FILES_DIR = op.dirname(__file__) + + +ParamDef = namedtuple('ParamDef', ['name', 'istype']) +"""Parameter definition tuple. + +Attributes: + name (str): parameter name + istype (bool): true if type parameter, otherwise false +""" + + class WPFWindow(framework.Windows.Window): r"""WPF Window base class for all pyRevit forms. @@ -77,8 +89,7 @@ def __init__(self, xaml_source, literal_string=False, handle_esc=True): if not op.exists(xaml_source): wpf.LoadComponent(self, os.path.join(EXEC_PARAMS.command_path, - xaml_source) - ) + xaml_source)) else: wpf.LoadComponent(self, xaml_source) else: @@ -232,7 +243,7 @@ class TemplateUserInputWindow(WPFWindow): def __init__(self, context, title, width, height, **kwargs): """Initialize user input window.""" WPFWindow.__init__(self, - op.join(op.dirname(__file__), self.xaml_source), + op.join(XAML_FILES_DIR, self.xaml_source), handle_esc=True) self.Title = title or 'pyRevit' self.Width = width @@ -862,7 +873,7 @@ class TemplatePromptBar(WPFWindow): def __init__(self, height=32, **kwargs): """Initialize user prompt window.""" WPFWindow.__init__(self, - op.join(op.dirname(__file__), self.xaml_source)) + op.join(XAML_FILES_DIR, self.xaml_source)) self.user_height = height self.update_window() @@ -1123,7 +1134,7 @@ class SearchPrompt(WPFWindow): def __init__(self, search_db, width, height, **kwargs): """Initialize search prompt window.""" WPFWindow.__init__(self, - op.join(op.dirname(__file__), 'SearchPrompt.xaml')) + op.join(XAML_FILES_DIR, 'SearchPrompt.xaml')) self.Width = width self.MinWidth = self.Width self.Height = height @@ -1716,10 +1727,9 @@ def select_swatch(title='Select Color Swatch', button_name='Select'): >>> forms.select_swatch(title="Select Text Color") ... """ - itemplate_xaml_file = \ - os.path.join(op.dirname(__file__), "SwatchContainerStyle.xaml") - itemplate = \ - wpf.LoadComponent(Controls.ControlTemplate(), itemplate_xaml_file) + itemplate = utils.load_ctrl_template( + os.path.join(XAML_FILES_DIR, "SwatchContainerStyle.xaml") + ) swatch = SelectFromList.show( colors.COLORS.values(), title=title, @@ -1751,15 +1761,13 @@ def select_image(images, title='Select Image', button_name='Select'): title="Select Variation") ... 'C:/path/to/image1.png' """ - ptemplate_xaml_file = \ - os.path.join(op.dirname(__file__), "ImageListPanelStyle.xaml") - ptemplate = \ - wpf.LoadComponent(Controls.ItemsPanelTemplate(), ptemplate_xaml_file) + ptemplate = utils.load_itemspanel_template( + os.path.join(XAML_FILES_DIR, "ImageListPanelStyle.xaml") + ) - itemplate_xaml_file = \ - os.path.join(op.dirname(__file__), "ImageListContainerStyle.xaml") - itemplate = \ - wpf.LoadComponent(Controls.ControlTemplate(), itemplate_xaml_file) + itemplate = utils.load_ctrl_template( + os.path.join(XAML_FILES_DIR, "ImageListContainerStyle.xaml") + ) bitmap_images = {} for imageobj in images: @@ -1783,6 +1791,74 @@ def select_image(images, title='Select Image', button_name='Select'): return bitmap_images.get(selected_image, None) +def select_parameter(src_element, + title='Select Parameters', + button_name='Select', + multiple=True, + filterfunc=None, + include_instance=True, + include_type=True): + """Standard form for selecting parameters from given element. + + Args: + src_element (DB.Element): source element + title (str, optional): list window title + button_name (str, optional): list window button caption + multiselect (bool, optional): + allow multi-selection (uses check boxes). defaults to True + filterfunc (function): + filter function to be applied to context items. + include_instance (bool, optional): list instance parameters + include_type (bool, optional): list type parameters + + Returns: + list[:obj:`ParamDef`]: list of paramdef objects + + Example: + >>> selected_params = forms.select_parameter( + ... src_element, + ... title='Select Parameters', + ... multiple=True, + ... include_instance=True, + ... include_type=True) + ... [, ] + """ + param_defs = [] + if include_instance: + # collect instance parameters + param_defs.extend( + [ParamDef(name=x.Definition.Name, istype=False) + for x in src_element.Parameters + if not x.IsReadOnly and x.StorageType != DB.StorageType.None] + ) + + if include_type: + # collect type parameters + src_type = revit.query.get_type(src_element) + param_defs.extend( + [ParamDef(name=x.Definition.Name, istype=True) + for x in src_type.Parameters + if not x.IsReadOnly and x.StorageType != DB.StorageType.None] + ) + + if filterfunc: + param_defs = filter(filterfunc, param_defs) + + itemplate = utils.load_ctrl_template( + os.path.join(XAML_FILES_DIR, "ParameterItemStyle.xaml") + ) + selected_params = SelectFromList.show( + param_defs, + title=title, + button_name=button_name, + width=450, + multiselect=multiple, + item_template=itemplate + ) + + return selected_params + + def alert(msg, title=None, sub_msg=None, expanded=None, footer='', ok=True, cancel=False, yes=False, no=False, retry=False, warn_icon=True, options=None, exitscript=False): @@ -1941,7 +2017,6 @@ def pick_folder(title=None): return fb_dlg.SelectedPath - def pick_file(file_ext='', files_filter='', init_dir='', restore_dir=True, multi_file=False, unc_paths=False): r"""Pick file dialog to select a destination file. diff --git a/pyrevitlib/pyrevit/forms/utils.py b/pyrevitlib/pyrevit/forms/utils.py index 6cdb2d507..dc4b630cb 100644 --- a/pyrevitlib/pyrevit/forms/utils.py +++ b/pyrevitlib/pyrevit/forms/utils.py @@ -1,7 +1,7 @@ """Utility functions to support forms module.""" from pyrevit import framework -from pyrevit.framework import Imaging +from pyrevit.framework import wpf, Controls, Imaging def bitmap_from_file(bitmap_file): @@ -19,3 +19,40 @@ def bitmap_from_file(bitmap_file): bitmap.CacheOption = Imaging.BitmapCacheOption.OnLoad bitmap.EndInit() return bitmap + + +def load_component(xaml_file, comp_type): + """Load WPF component from xaml file. + + Args: + xaml_file (str): xaml file path + comp_type (System.Windows.Controls): WPF control type + + Returns: + System.Windows.Controls: loaded WPF control + """ + return wpf.LoadComponent(comp_type, xaml_file) + + +def load_ctrl_template(xaml_file): + """Load System.Windows.Controls.ControlTemplate from xaml file. + + Args: + xaml_file (str): xaml file path + + Returns: + System.Windows.Controls.ControlTemplate: loaded control template + """ + return load_component(xaml_file, Controls.ControlTemplate()) + + +def load_itemspanel_template(xaml_file): + """Load System.Windows.Controls.ItemsPanelTemplate from xaml file. + + Args: + xaml_file (str): xaml file path + + Returns: + System.Windows.Controls.ControlTemplate: loaded items-panel template + """ + return load_component(xaml_file, Controls.ItemsPanelTemplate()) diff --git a/pyrevitlib/pyrevit/revit/db/query.py b/pyrevitlib/pyrevit/revit/db/query.py index d63be838d..1ef2a2bd8 100644 --- a/pyrevitlib/pyrevit/revit/db/query.py +++ b/pyrevitlib/pyrevit/revit/db/query.py @@ -83,6 +83,19 @@ def get_name(element, title_on_sheet=False): return Element.Name.__get__(element) +def get_type(element): + """Get element type. + + Args: + element (DB.Element): source element + + Returns: + DB.ElementType: type object of given element + """ + type_id = element.GetTypeId() + return element.Document.GetElement(type_id) + + def get_symbol_name(element): return get_name(element.Symbol) @@ -1173,3 +1186,21 @@ def get_schema_field_values(element, schema): field_values[field.FieldName] = value return field_values + + +def get_family_type(type_name, family_doc): + if family_doc.IsFamilyDocument: + for ftype in family_doc.FamilyManager.Types: + if ftype.Name == type_name: + return ftype + else: + raise PyRevitException('Document is not a family') + + +def get_family_parameter(param_name, family_doc): + if family_doc.IsFamilyDocument: + for fparam in family_doc.FamilyManager.GetParameters(): + if fparam.Definition.Name == param_name: + return fparam + else: + raise PyRevitException('Document is not a family') diff --git a/pyrevitlib/pyrevit/revit/selection.py b/pyrevitlib/pyrevit/revit/selection.py index 81364d0dc..2659b3673 100644 --- a/pyrevitlib/pyrevit/revit/selection.py +++ b/pyrevitlib/pyrevit/revit/selection.py @@ -100,6 +100,15 @@ def no_views(self): def only_views(self): return self.include(DB.View) + def expand_groups(self): + expanded_refs = [] + for element in self.elements: + if isinstance(element, DB.Group): + expanded_refs.extend(element.GetMemberIds()) + else: + expanded_refs.append(element.Id) + self._refs = expanded_refs + def _pick_obj(obj_type, pick_message, multiple=False, world=False): refs = [] diff --git a/pyrevitlib/pyrevit/version b/pyrevitlib/pyrevit/version index 6e8d609d9..a40b7f4dd 100644 --- a/pyrevitlib/pyrevit/version +++ b/pyrevitlib/pyrevit/version @@ -1 +1 @@ -4.6.19 \ No newline at end of file +4.6.20 \ No newline at end of file diff --git a/release/pyRevit.aip b/release/pyRevit.aip index 7b1ee633e..cb1d8e252 100644 --- a/release/pyRevit.aip +++ b/release/pyRevit.aip @@ -1,5 +1,5 @@ - + @@ -27,10 +27,10 @@ - + - + @@ -89,10 +89,12 @@ + + @@ -143,6 +145,7 @@ + @@ -175,6 +178,7 @@ + @@ -438,7 +442,7 @@ - + @@ -670,6 +674,7 @@ + @@ -816,6 +821,9 @@ + + + @@ -850,7 +858,6 @@ - @@ -907,7 +914,7 @@ - + @@ -1036,7 +1043,6 @@ - @@ -1063,8 +1069,7 @@ - - + @@ -1265,8 +1270,7 @@ - - + @@ -1303,7 +1307,6 @@ - @@ -1383,13 +1386,11 @@ - - + - @@ -1421,6 +1422,7 @@ + @@ -4763,8 +4765,7 @@ - - + @@ -4783,6 +4784,7 @@ + @@ -4941,6 +4943,9 @@ + + + @@ -5172,21 +5177,16 @@ - + - - - - + + - - - + - - + @@ -5204,7 +5204,6 @@ - @@ -5220,7 +5219,6 @@ - @@ -5282,7 +5280,7 @@ - + @@ -5379,7 +5377,7 @@ - + @@ -5458,6 +5456,10 @@ + + + + @@ -5557,6 +5559,7 @@ +